【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: 操作文件的方式,例如
项目 | Value |
---|---|
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'" ]; then
umask 002
#如果UID大于199(普通用户),则使用此umask值
else
umask 022
#如果UID小于199(超级用户),则使用此umask值
fi
…省略部分内容…
这是一段 Shell 脚本程序,不懂也没关系,大家只需要知道,普通用户的 umask 由 if 语句的第一段定义,而超级用户 root 的 umask 值由 else 语句定义即可。 修改此文件,则 umask 值就会永久生效。