chmod()函数和fchmod()函数,open()函数和creat()函数,close()函数,umask命令

0
0·
本文详细介绍了Linux系统中文件权限设置方法,包括chmod和fchmod函数的使用,以及open、creat和close函数的功能和参数解释。通过示例代码展示了不同函数在文件创建和操作中的应用。1.chmod 函数和fchmod函数
chmod和fchmod函数包含在头文件<sys/types.h>和<sys/stat,h>中 原型;int chmod(const char *path,mode_t mode); int fchmod(int fildes,mode_t mode); 区别:chmod函数第一个参数是文件名,fchmod以文件描述符作为第一个参数;
参数:第一个参数path是要设置权限的文件名,第二个参数mode
参数mode的数值一般有以下几种组合: S_IRUSR 00400 文件所有者具有可读权限; S_IWUSR 00200 文件所有者具有可写入的权限; S_IXUSR 00100 文件所有者具有可执行的权限; S_IRGRP 00040 用户组具有可读取的权限; S_IWGRP 00020 用户组具有可写入的权限; S_IXGRP 00010 用户组具有可执行的权限; S_IROTH 00004 其它用户具有可读取的权限 S_IWOTH 00002 其它用户具有可写入的权限 S_IXOTH 00001 其它用户具有可执行的权限 S_ISUID 04000 文件的(set user-id on execution)位; S_ISGID 02000 文件的(set group-id on excution)位; S_ISVTX 01000 文件的sticky; sticky位是什么鬼,上网查了一下:sticky也就是粘滞位,普通文件的粘滞位会被内核忽略,如果目录设置有粘滞位,如果用户对目录有写入权限,则可以删除其中的文件,即使不是目录的所有者,对文件并没有写的权限.但是,当设设有粘滞位时,就只能是root,和ower 才有删除里面文件的权限;
2.open()函数creat()函数和close()函数
open函数和creat函数都包含在头文件<sys/types.h>.<sys/stat.h>.<fcntl.h> 原型:int open(const char *pathname,int flag); int open(const char *pathname,int flag,mode_t mode); 其中第一个参数pathname是要打开的或创建的含路径的文件名,第二个参数flags表示flags表示打开文件的方式: 1.O_RDONLY:以只读的方式打开; 2.O_WRONLY:以只写方式打开; 3 .O_RDWR:以可读可写的方式打开; 这三种打开方式是互斥的,不能同时以两种或三种打开,但是他们可以分别与下列标志结合: 1.O_CREAT:若文件不存在则自动建立该文件,只有在文件不存在建立文件的时候才可以用到第三个参数mode; 2.O_EXCL:如果O_CREAT也被设置,此指令会去检查文件是否存在,文件不存在则创建文件,文件存在则导致打开文件失败; 3.O_TRUNC:若文件存在,并且可以以可写方式打开时,此标志则将文件长度清零0,及原文中保存的数据将丢失;文件的属性不变; 4.O_APPEND:所有写入的数据都会以追加的方式加入到文件后面; 5.O_SYNC:以同步的方式打开,任何队文件的修改都会阻塞直到物理磁盘上的数据同步后才返回; 6.O_NOFOLLOW:如果参数pathname所指的文件为一符号连接,则会打开失败; 7.O_DIRECTORY:如果参数所指的文件并非为一目录,则会令文件打开失败; 成功调用open()会返回一个文件描述符,错误返回-1; 参数mode和chmod函数相同;详情请戳:chmod函数和fchmod函数,umask命令; 新文件的实际存取权限是(mode&~umask)运算后的结果; umask是什么鬼,它是权限掩码,什么是权限掩码呢,大家都知道,当你创建一个文件一般不用chmod命令去设置文件的权限,那么是不是,创建一个文件的权限就是666(对于文件来说,系统不允许你在创建的时候就为其赋予执行权限,所以这里我说666, 目录则可以取到777)呢,来看例子:
yang@liu:~$ umask 0022yang@liu:~$ touch 22.cyang@liu:~$ ls -l 22.c-rw-r--r-- 1 yang yang 0 7月 20 11:42 22.c
umask的一般默认值是0022;也就是说权限掩码的左用就是限制其他人对文件的操作权限,在你创建文件时完成,不用自己去手动设置权限;现在,问题来了,这是怎样运算的呢; mode和umask是怎样运算的呢,有很多办法,用最简单的来说: 计算u m a s k值的方法:我们只要记住u m a s k是从权限中“拿走”相应的位即可。 如果umask为023,则对于文件所有者,不拿去任何权限,而新建的文件默认没有执行权限,故对文件所有者的权限位rw-(6);对组所有者,拿去写权限,原本没有执行权限,故为r--(4);对其他用户,拿去写和执行权限,原本没有执行权限,故为r--(4); 如果umask为023,因为没有新建目录没有执行权限的限制。则对于目录所有者,不拿去任何权限,故对目录所有者的权限为rwx(7);对组所有者,拿去写权限,故为r-x(5);对其他用户,拿去写和执行权限,故为r--(4); Creat()函数 原型:int creat(const char *pathname,mode_t mode); 其中第一个参数pathname是要打开或创建的文件名,如果pathname指向的文件不存在,则创建一个新文件,如果pathname指向的文件存在,则原文件,被新文件覆盖,第二个参数mode与open函数相同;creat()相当于这样使用open(); open(const char *pathname,(O_CREAT | O_WRONLY | O_TRUNC)); 成功调用open()会返回一个文件描述符,错误返回-1; 有没有发现什么呢,creat()和open(const char *pathname,(O_CREAT | O_WRONLY | O_TRUNC));打开文件是等价的,仔细一点你会发现open函数是以只写方式打开的,而这样用open()打开的文件和用creat()打开的文件等价,这能说明什么呢,注意 这说明creat() 只能以只写方式打开,也就是说,用creat()函数打开的文件,只能往文件里写数据,而不能从文件里读数据,如果用creat()函数打开文件,调用read()读取数据,就会出现error;来看个例子:
#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <stdlib.h>#include <error.h>#include <string.h>/*自定义的错误处理函数*/void my_err(const char *err_string,int line){fprintf(stderr,"line:%d ",line);perror(err_string);exit(1);}/*自定义的读数据函数*/int my_read(int fd){int len;int ret;int i;char read_buf[64];/*获取文件长度并保持文件读写指针在文件开始处*//*if (lseek(fd,0,SEEK_END)==-1){my_err("lseek",__LINE__);}*/if((len=lseek(fd,0,SEEK_CUR))==-1){my_err("lseek",__LINE__);}if((lseek(fd,0,SEEK_SET))==-1){my_err("lseek",__LINE__);}printf("len:%d\n",len);/*读数据*/if((ret = read(fd,read_buf,len))<0){my_err("read",__LINE__);}/*打印数据*/for(i=0;i<len;i++){printf("%c",read_buf[i]);}printf("\n");return ret;}int main(){int fd;char write_buf[32]="Hello,World!";/*在当前目录下创建文件example_63.c*///if((fd = creat("example_63.c",S_IRWXU))==-1) {去掉注释,if((fd = open("example_63.c",O_RDWR | O_CREAT |加注释O_TRUNC,S_IRWXU))==-1){my_err("open",__LINE__);}else{printf("create file success\n");}/*写数据*/if(write(fd,write_buf,strlen(write_buf)) != strlen(write_buf)){my_err("write",__LINE__);}my_read(fd);/*演示文件的间隔*/printf("/*---------------------------------*/\n");if(lseek(fd,10,SEEK_END)==-1){my_err("lseek",__LINE__);}if(write(fd,write_buf,strlen(write_buf))!=strlen(write_buf)){my_err("write",__LINE__);}my_read(fd);close(fd);return 0;}第一次用open()打开文件运行结果:
yang@liu:~/Linux C$ ./a.outcreate file successlen:12Hello,World!/*---------------------------------*/len:34Hello,World!Hello,World!
第二次:按照代码的注释把"去掉注释的那一行注释去掉","加注释的那一行注释注释掉"也就是第二次以creat()方式打开,运行结果:
yang@liu:~/Linux C$ ./a.outcreate file successlen:12line:40 read: Bad file descriptor可以发现,在第40行读数据的时候产生了错误; close()函数 close()函数包含在头文件<unistd.h> 原型:int close(int fd); close()函数只有一个参数,此参数表示需要关闭的文件的文件描述符,该文件描述符是由open()或creat得到.close调用成功,返回0,发生错误时-1;



















609



























