APUE-文件和目录(二)函数access,mask,chmod和粘着位

4.7 函数access和faccessat
当一个进程使用了设置用户ID和设置组ID作为另一个用户(或者组)运行时,这时候有效用户(组)ID和实际用户(组)ID不一样,但进程仍然希望测试实际用户(组)ID的访问能力。这时候就可以使用access和faccessat。测试步骤同4.5节一样,但将有效改为实际。
#include <unistd.h>
int access(const char *pathname,int mode);
int faccessat(int fd,const char*pathname,int mode,int flag);
//两个函数的返回值:若成功烦怒I0;若出错,返回-1
其中,如果测试文件是否已经存在,mode就为F_OK;否则mode是图4-7中所列常量的按位或。

flag参数可以用于改变faccessat的行为,如果flag设置为AT_EACCESS,访问检查用的是调用进程的有效用户ID和有效组ID,而不是实际用户ID和实际组ID。
4.8 函数umask
umask函数为进程设置文件模式创建屏蔽字,并返回之前的值。
#include <sys/stat.h>
mode_t umask(mode_t cmask);
其中,参数cmask是由图4-6中列出的9个常量中的若干个按位"或“构成的。
在文件模式创建屏蔽字中为1的位,在文件mode中的相应位一定被关闭。
看下面的例子:
首先将屏蔽位设为0,然后创建一个文件,发现默认创建的文件mode为u=rw,g=rw,o=rw(666)
harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ umask 0
harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ umask -S
u=rwx,g=rwx,o=rwx
harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ touch test.txt
harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ ll test.txt
-rw-rw-rw- 1 harlan harlan 0 6月 5 21:02 test.txt
下面更新文件模式屏蔽字,并创建文件:
harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ umask 027
harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ umask -S
u=rwx,g=rx,o=
harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ touch test2.txt
harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ ll test2.txt
-rw-r----- 1 harlan harlan 0 6月 5 21:05 test2.txt
因为group的x和other的rwx被屏蔽掉了,因此得到上面的结果。
umask值表示为8进制数,一位代表一种要屏蔽的权限,见下图所示:

注意: 用数字和符号表示文件模式屏蔽字的不同,数字中的1表示的是要屏蔽的权限,而符号中显示的是支持的权限。
4.9 函数chmod
chmod使得我们可以更改现有文件的访问权限。
#include <sys/stat.h>
int chmod(const char*pathname,mode_t name);
成功返回0;出错返回-1
为了改变一个文件的权限位,进程的有效用户ID必须等于文件的所有者ID,或者该用户必须具有超级用户权限。
疑问:可读可写可执行权限和chmod有关系么?
答:没有任何关系。
看下面一个简单的例子,创建一个其他用户可读可写可执行的文件所有者为root的文件:
harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ ll chmod.txt
-rw-r--rwx 1 root root 0 6月 5 21:16 chmod.txt
在harlan用户下创建下面的程序:
#include <fcntl.h>
#include <stdio.h>
int main(void)
{
struct stat statbuf;
if(stat("chmod.txt",&statbuf)<0)
printf("stat error!\n");
int rv = chmod("chmod.txt",statbuf.st_mode & ~S_IRWXO);//remove the other's read write and execute
if(rv < 0)
{
printf("chmod error!\n");
}
return 0;
}
上面的程序尝试在harlan用户下来修改chmod.txt文件的权限位,harlan用户对chmod.txt是可读可写可执行的。但是它不能修改此文件的权限位,结果打印:
harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ ./a.out
chmod error!
参数mode是图4-11中所示的常量的按位或:

注意:chmod函数修改的是i节点最近一次被更改的时间,而并不是最后修改文件内容的时间。
注意:如果新文件的组ID不等于进程的有效组ID或者进程附属组ID中的一个,并且进程没有超级用户权限,那么设置组ID位会被自动关闭。在linux3.2.0中,如果没有超级用户权限的进程写一个文件,则设置用户ID位和设置组ID位会被自动清除。看下面的例子:
对于文件chmod.txt,我们同时设置了设置用户ID和设置组ID,
harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ ll chmod.txt
-rwSr-srwx 1 root root 4 6月 5 22:16 chmod.txt
写一段代码来用普通用户权限写这个文件
#include <fcntl.h>
#include <stdio.h>
void PrintSetUserID(unsigned int st_mode)
{
if(st_mode&S_ISUID)
{
printf("set-user-ID is 1.\n");
}
else
{
printf("set-user-ID is 0.\n");
}
}
void PrintSetGroupID(unsigned int st_mode)
{
if(st_mode&S_ISGID)
{
printf("set-group-ID is 1.\n");
}
else
{
printf("set-group-ID is 0.\n");
}
}
void ClearSetUserID_SetGroupID()
{
struct stat statbuf;
if(stat("chmod.txt",&statbuf)<0)
printf("stat error!-");
else
{
PrintSetUserID(statbuf.st_mode);
PrintSetGroupID(statbuf.st_mode);
}
int fd = open("chmod.txt",O_RDWR);
ssize_t num = write(fd,"test",4);
printf("write num:%d\n",(int)num);
if(stat("chmod.txt",&statbuf)<0)
printf("stat error!--\n");
else
{
PrintSetUserID(statbuf.st_mode);
PrintSetGroupID(statbuf.st_mode);
}
}
int main(void)
{
ClearSetUserID_SetGroupID();
return 0;
}
运行结果:
harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ ./a.out
set-user-ID is 1.
set-group-ID is 1.
write num:4
set-user-ID is 0.
set-group-ID is 0.
4.10 粘着位
- 对于文件的粘着位,因为现今的UNIX系统大多都配置了虚拟存储系统以及快速文件系统,所以不再需要这个设置。
- 对于目录的粘着位,如果你为一个目录设置了粘着位,只有对该目录具有写权限的用户并且满足下列条件之一,才能删除或重命名该目录下的文件:
- 拥有此文件;
- 拥有此目录;
- 是超级用户。
看下面的例子:
harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ mkdir dir
harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ chmod 777 dir
harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ ll
...
drwxrwsrwx 2 harlan harlan 0 6月 5 22:47 dir
...
harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ chmod o+t dir
harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ ll
...
drwxrwsrwt 2 harlan harlan 0 6月 5 22:47 dir
...
疑问:粘着位和其他写是否同时存在?见下面的代码:
#include <fcntl.h>
#include <stdio.h>
void main()
{
struct stat statbuf;
if(stat("dir",&statbuf))
printf("stat error!\n");
if(statbuf.st_mode & S_ISVTX)
{
printf("sticky bit is set!\n");
}
if(statbuf.st_mode & S_IXOTH)
{
printf("other execute bit is set!\n");
}
}
输出结果为:
harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ ./a.out
sticky bit is set!
other execute bit is set!
可见是可以同时存在的。同时存在和只存在黏着位的显示有什么区别呢?见下面的例子:
harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ chmod 776 dir
drwxrwsrw- 2 harlan harlan 0 6月 5 22:47 dir
harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ chmod o+t dir
drwxrwsrwT 2 harlan harlan 0 6月 5 22:47 dir
可见如果只有粘着位其它的第三位为大写的T,如果是小写表示粘着位+可执行。
/var/tmp 目录设置了粘着位+任意用户的可读可写可执行
harlan@DESKTOP-KU8C3K5:/var$ ll
总用量 12
drwxr-xr-x 2 root root 0 4月 11 2014 backups
drwxr-xr-x 2 root root 0 3月 30 14:52 cache
drwxrwxrwt 2 root root 0 3月 30 14:52 crash
drwxr-xr-x 2 root root 0 4月 27 22:17 lib
drwxrwsr-x 2 root staff 0 4月 11 2014 local
lrwxrwxrwx 1 root root 9 3月 30 14:50 lock -> /run/lock
drwxrwxr-x 2 root syslog 0 5月 1 21:38 log
drwxrwsr-x 2 root mail 0 3月 30 14:50 mail
drwxr-xr-x 2 root root 0 3月 30 14:50 opt
lrwxrwxrwx 1 root root 4 3月 30 14:50 run -> /run
drwxr-xr-x 2 root root 0 3月 30 14:50 spool
drwxrwxrwt 2 root root 0 6月 5 22:28 tmp
我们用root用户在tmp目录下面创建一个文件:
root@DESKTOP-KU8C3K5:/var/tmp# ll
总用量 4
drwxrwxrwt 2 root root 0 6月 5 22:28 ./
drwxr-xr-x 2 root root 0 3月 30 14:53 ../
-rw-r--r-- 1 root root 0 6月 5 22:28 test.txt
尝试在harlan用户下删除:
harlan@DESKTOP-KU8C3K5:/var/tmp$ rm test.txt
rm:是否删除有写保护的普通空文件 "test.txt"? y
rm: 无法删除"test.txt": 不允许的操作
虽然harlan用户对这个目录具有写权限,但因为所在目录设置了粘着位,并且不满足上述任意三个条件之一,因此不讷讷个删除文件。
APUE-文件和目录(二)函数access,mask,chmod和粘着位的更多相关文章
- windows中操作文件和目录的函数
1.文件操作函数 CreateFile();//创建或打开文件 ReadFile();//从文件读 WriteFile();//向文件写 SetFilePoi ...
- linux C之判断文件或目录是否存在 access函数
http://blog.sina.com.cn/s/blog_6a1837e90100uh5d.html access():判断是否具有存取文件的权限 相关函数 stat,open,chmod, ...
- [APUE]文件和目录(中)
一.link.unlink.remove和rename 一个文件可以有多个目录项指向其i节点.使用link函数可以创建一个指向现存文件连接 #include <unistd.h> int ...
- [APUE]文件和目录(上)
一.文件权限 1. 各种ID 我在读这一章时遇到了各种ID,根据名字完全不清楚什么意思,幸好看到了这篇文章,http://blog.csdn.net/ccjjnn19890720/article/de ...
- PHP 文件与目录操作函数总结
>>>文件操作 打开 fopen(); 打开文件 读取内容 fread(); 从文件指针 handle 读取最多 length 个字节 readfile(); 读入 ...
- APUE 文件和目录
文件和目录 Unix 所有的文件都对应一个 struct stat,包含了一个文件所有的信息. #include <sys/stat.h> struct stat { mode_t st_ ...
- Linux系统对文件及目录的权限管理(chmod、chown)
本文命令: 4 5 6 ls -l chmod chown 1.身份介绍 在linux系统中,对文件或目录来说访问者的身份有三种: ①.属主用户,拥有者(owner)文件的创建者 ②.属组用户,和文件 ...
- [APUE]文件和目录(下)
一.mkdir和rmdir函数 #include <sys/types.h> #include <sys/stat.h> int mkdir(const char *pathn ...
- php 文件、目录操作函数
目录 opendir readdir closedir mkdir rmdir : 只能删除空目录 文件 filetype filesize is_file basename dirname pat ...
随机推荐
- A New Function LightOJ - 1098()
题意 求 1 - n的的所有数的因子(不包括自身和1)和 对于一个数 i ,以i为因子的数的个数为 n/i 因为不能包括自身 所以 减一 即 n/i-1 这样遍历每一个数 累加即可 但复杂度较 ...
- win10远程连接
提示凭证不工作问题 https://blog.csdn.net/sinat_25926481/article/details/50775616
- BZOJ 1283: 序列
1283: 序列 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 272 Solved: 151[Submit][Status][Discuss] D ...
- Hive权限管理
最近遇到一个hive权限的问题,先简单记录一下,目前自己的理解不一定对,后续根据自己的理解程度更新 一.hive用户的概念 hive本身没有创建用户的命令,hive的用户就是Linux用户,若当前是用 ...
- nodejs进程异常退出处理方法
1. 捕获uncaughtException process.on('uncaughtException', function (err) { //打印出错误 console.log(err); // ...
- where EXISTS (子查询)多对多中通过中间表查对方列表
用户表A,小组表B,小组和用户是多对多关系,中间有个中间表M 已知 小组 id 即teamId ,想知道这个小组中的用户列表信息,可以如下写sql: select * from A a where E ...
- 【Asp.net入门5-01】SportsStore:一个真实的应用程序
- 转:zookeeper中Watcher和Notifications
转自:http://www.tuicool.com/articles/B7FRzm 传统polling远程service服务 传统远程的service往往是这样服务的,服务提供者在远程service注 ...
- CSS3实战之resize
resize属性可以设置是否允许用户缩放网页中元素的大小 总共有4种取值 none vertical horizontal both 举个栗子 <!DOCTYPE html PUBLIC &qu ...
- [HAOI2006]旅行 题解(kruskal)
[HAOI2006]旅行 Description Z小镇是一个景色宜人的地方,吸引来自各地的观光客来此旅游观光.Z小镇附近共有N个景点(编号为1,2,3,-,N),这些景点被M条道路连接着,所有道路都 ...