【Linux之IO系统编程学习】01.open函数使用 代码实现touch命令效果

news/2024/11/7 9:36:18/

 
【Linux之IO系统编程学习】

项目代码获取:https://gitee.com/chenshao777/linux_-io.git
(麻烦点个免费的Star哦,您的Star就是我的写作动力!)

01.open函数使用 & 代码实现touch命令

一、open函数(man手册)

最简单直接的方式就是查看man手册

man 2 open

在这里插入图片描述
这里可以看到使用Open函数需要包含三个头文件
(其实本代码中只包含 <fcntl.h> 头文件即可,另外两个应该是open函数族的其他函数需要包含)

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

二、open函数的使用

open 函数可以打开或者新建一个文件

我们使用下面这个形式的 open 函数

int open(const char *pathname, int flags, mode_t mode);

参数说明:
pathname: 要操作的路径和文件名(可能是新建、打开)
flag: 操作文件的方式,例如

项目含义
O_CRETE创建一个文件
O_RDWR读写
O_RDONLY只读
O_WRONLY只写
O_EXCL创建一个文件时,如果该文件存在,返回错误
O_TRUEC打开文件,会把文件内容都删除
O_APPEND以追加的方式打开文件

mode: 文件权限(例如:0777)

这些参数的说明可以在man手册里看到,如下图所示:
在这里插入图片描述
返回值:
翻译: 返回新的文件描述符,如果发生错误,则返回-1(在这种情况下,会适当设置errno)

man手册使劲往下翻

在这里插入图片描述

open函数使用举例:

open("a.txt", O_CREAT | O_RDWR, 0777);

表示新建一个a.txt文件,该文件可读可写,操作权限是777


三、使用open函数实现touch命令的效果

touch命令常见使用方法如下:

touch a.txt

touch后面跟上一个文件名,即可创建一个新的文件

下面是可以实现与 touch 同样效果的代码 touch.c 文件

#include <stdio.h>
// #include <sys/types.h>
// #include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>int main(int argc, char *argv[])
{/*使用open函数代替touch新建文件*/int fd = open(argv[1], O_CREAT | O_RDWR, 0777);if(fd < 0){printf("create a file failed , fd = %d\n",fd);}else{printf("create a file success , fd = %d\n",fd);}/*关闭文件描述符*/close(fd);return 0;
}

重点说明:
1.使用argv参数传入要新建的文件名
2.判断open函数返回的文件描述符fd,如果fd大于0则成功
3.最后别忘了close()

gcc编译一下

gcc touch.c

运行测试一下

./a.out a.txt

在这里插入图片描述
如图所示,a.txt新建成功了,但是权限却不对,应该是 -rwxrwxrwx才对,最后面的其他用户权限少了个w写权限。

原因是Linux 是注重安全性的操作系统,而安全的基础在于对权限的设定,不仅所有已存在的文件和目录要设定必要的访问权限,创建新的文件和目录时,也要设定必要的初始权限。

查看Linux下默认的创建文件的初始权限掩码

umask

在这里插入图片描述
可以看到我的Linux掩码是0002
那么我创建的新文件的权限不会是我open函数最后给的mode参数0777
而是 mode 减去 umask,也就是0777-0002=0775
实际上他们是以八进制表示的,即
0777 —> 000 111 111 111
0002 —> 000 000 000 010
两者相减,我觉得也可以理解为异或操作,得到结果就是
000 111 111 101 —> 0775

·····················

话说回来,如何能使创建的文件权限就是0777呢,可以修改umask的值为0000就行了
执行 umask 0000 后再新建一个 b.txt
可以发现这次 b.txt 的权限就是0777了

在这里插入图片描述
但是 umask 0000 只能临时有效,一旦重启或重新登陆系统,就会失效。如果想让修改永久生效,则需要修改对应的环境变量配置文件 /etc/profile。例如:

[root@localhost ~]# vim /etc/profile
...省略部分内容...
if [ $UID -gt 199]&&[ "'id -gn'" = "'id -un'" ]; thenumask 002#如果UID大于199(普通用户),则使用此umask值
elseumask 022#如果UID小于199(超级用户),则使用此umask值
fi
…省略部分内容…

这是一段 Shell 脚本程序,不懂也没关系,大家只需要知道,普通用户的 umask 由 if 语句的第一段定义,而超级用户 root 的 umask 值由 else 语句定义即可。 修改此文件,则 umask 值就会永久生效。


http://www.ppmy.cn/news/74453.html

相关文章

Unity使用URP基础介绍文章目录

大家好&#xff0c;我是阿赵&#xff0c;之前写了几篇关于Unity的URP渲染管线的介绍文章&#xff0c;我觉得又可以整理出一个系列的文章目录了。暂时写的内容都比较的基础&#xff0c;之后如果继续写相关的文章&#xff0c;可以继续扩充这个目录。   URP(Universal Render Pi…

c++实现gRPC

无论什么语言&#xff0c;实现grpc的核心是.proto文件&#xff0c;通过protoc命令将.proto文件生成grpc框架的接口文件*gb*, 该文件中包含.proto定义的方法及参数接口&#xff0c;服务器&#xff0c;客户端相关操作接口&#xff1b;然后再编写服务器&#xff0c;客户端代码&…

3-《安卓基础》

3-《安卓基础》 一.Android系统架构二.四大组件1. Activity1.1 生命周期1.2. Activity四种启动模式1.3.Activity任务栈的概念1.4 面试题面试题1&#xff1a;onSaveInstanceState(Bundle outState)&#xff0c;onRestoreInstanceState(Bundle savedInstanceState) 的调用时机&am…

springboot+swagger项目中,controller引入@NotEmpty等校验注解的问题

springboot项目 springbootswagger项目中&#xff0c;controller层如果使用对基本数据类型使用 NotEmpty Length 等校验注解&#xff0c;controller会获取不到值&#xff0c;加了RequestBody后可以获取到了&#xff0c;但是前端传值content-type必须是text/plain。所以建议con…

力扣sql中等篇练习(二十六)

力扣sql中等篇练习(二十六) 1 世界排名的变化 1.1 题目内容 1.1.1 基本题目信息1 1.1.2 基本题目信息2 1.1.3 示例输入输出 a 示例输入 b 示例输出 1.2 示例sql语句 # 分别求出变化前后的排名 然后再进行内连接即可 # row_number()里面也可以用多个字段加减的表达式去进行…

动态ip与静态ip的区别是什么?

动态ip和静态ip的区别在于&#xff1a; 动态ip可以自动获取IP地址&#xff0c;静态ip需要手动设置IP地址。 动态ip一般用于局域网内部或小型企业网中&#xff0c;静态ip一般用于大型企业网或骨干网等对安全性要求高的场合。 在网速上&#xff0c;动态ip和静态ip没有区别。 动…

文心一言和ChatGPT最全对比

文心一言和ChatGPT都是基于深度学习技术的自然语言处理模型&#xff0c;有各自的优势和使用场景&#xff0c;无法简单地比较 ChatGPT 和文心一言哪一个功能更强大&#xff0c;它们各自具有优势和局限性&#xff0c;需要根据具体需求进行选择&#xff0c;以下一些具体对比&#…

生成式AI热潮:一场“添饭碗”的科技革命

今年以来&#xff0c;人工智能&#xff08;AI&#xff09;热潮席卷全球&#xff0c;被认为将掀起新的科技革命。 5月18日的2023天津世界智能大会&#xff0c;以“智行天下 能动未来”为主题&#xff0c;重点关注人工智能发展的新趋势、新技术、新业态。大会开幕式结束之后&…