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

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 
0022
yang@liu:~$ touch  22.c
yang@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.out
create file success
len:12
Hello,World!
/*---------------------------------*/
len:34
Hello,World!Hello,World!

第二次:按照代码的注释把"去掉注释的那一行注释去掉","加注释的那一行注释注释掉"也就是第二次以creat()方式打开,运行结果:

yang@liu:~/Linux C$ ./a.out
create file success
len:12
line:40 read: Bad file descriptor

可以发现,在第40行读数据的时候产生了错误; close()函数 close()函数包含在头文件<unistd.h> 原型:int close(int fd); close()函数只有一个参数,此参数表示需要关闭的文件的文件描述符,该文件描述符是由open()或creat得到.close调用成功,返回0,发生错误时-1;

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值