1、函数stat()、fstat()、lstat() --获取文件信息
lstat获取符号连接自身的信息,而不是连接指向的目标文件
stat则获取目标文件的信息
2、struct stat定义示例
struct stat
{
mode_t st_mode; /* file type & mode (permissions) */
ino_t st_ino; /*i-node number (serial number) */
dev_t st_dev; /* device number (file system) */
dev_t st_rdev; /* device number for special files */
nlink_t st_nlink; /* number of links */
uid_t st_uid; /* user ID of owner */
gid_t st_gid; /* group ID of owner */
off_t st_size; /* size in bytes, for regular files */
time_t st_atime; /* time of last access */
time_t st_mtime; /* time of last modification */
time_t st_ctime; /* time of last file status change */
blksize_t st_blksize; /* best I/O block size */
blkcnt_t st_blocks; /* number of disk blocks allocated */
};
3、文件类型
S_ISREG() regular file
S_ISDIR() directory file
S_ISCHR() character special file
S_ISBLK() block special file
S_ISFIFO() pipe or FIFO
S_ISLNK() symbolic link
S_ISSOCK() socket
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/stat.h> int main(int argc, char **argv) { int i; char *ptr; struct stat buf; for( i = 1; i < argc; i++ ) { printf("%s: ", argv[i]); /* 获取文件信息 */ if( lstat(argv[i], &buf) < 0 ) { perror("lstat"); continue; } /* 判别文件类型 */ if( S_ISREG(buf.st_mode) ) ptr = "regular"; else if( S_ISDIR(buf.st_mode) ) ptr = "directory"; else if( S_ISCHR(buf.st_mode) ) ptr = "character special"; else if( S_ISBLK(buf.st_mode) ) ptr = "block special"; else if( S_ISFIFO(buf.st_mode) ) ptr = "fifo"; else if( S_ISLNK(buf.st_mode) ) ptr = "symbolic link"; else if( S_ISSOCK(buf.st_mode) ) ptr = "socket"; else ptr = "** unknown mode **"; printf("%s\n", ptr); } return(0); }
4、设置-用户-ID、设置-组-ID
实际用户ID、实际组ID //实际上我们是谁
有效用户ID、有效组ID、附加组ID //用于文件权限检查
保存的设置-用户-ID、保存的设置-组-ID //由exec()保存
如果程序文件设置了设置-用户-ID,那么进程的有效用户ID等于文件的属主
可以分别使用S_ISUID、S_ISGID检测
5、文件访问权限
此处提及的文件包含前面描述的任何类型的文件,不仅限普通文件
S_IRUSR user-read
S_IWUSR user-write
S_IXUSR user-execute
S_IRGRP group-read
S_IWGRP group-write
S_IXGRP group-execute
S_IROTH other-read
S_IWOTH other-write
S_IXOTH other-execute
访问权限分为三组,共9位
6、文件权限的使用方式
不包含目录时,意指当前工作目录
7、内核对文件权限的检查策略
(a) 若适当的用户存取权限位被设置,则允许存取
(b) 否则拒绝存取
(a) 若适当的组存取权限位被设置,则允许存取
(b) 否则拒绝存取
8、新建文件(或目录)的所有权
(a) 可以设置为进程的组ID
(b) 可以设置为所在目录的组ID
9、函数access() --文件访问权限检测
R_OK test for read permission
W_OK test for write permission
X_OK test for execute permission
F_OK test for existence of file
注意:不是有效用户ID与有效组ID
10、函数umask() --设置文件创建掩码
设置进程的文件创建掩码,并返回之前的取值
umask是少数几个不会返回错误的函数之一
进程的umask设置同样影响新建文件的实际访问权限
文件创建掩码中打开的位,将导致mode中相应的位被关闭
umask -S
11、函数chmod()、fchmod() --修改文件权限
mode取值示例:
S_IRWXU read, write, and execute by user
S_IRGRP read by group
…
(a) 如果进程没有超级用户特权,尝试设置普通文件的粘着位时,粘着位将被清除
(b) 如果新建文件的组ID不等于进程有效组ID或附加组ID之一时,文件的设置-组-ID位将被清除
12、粘着位
程序第一次执行结束时,该程序正文的一个文本被保存在交换区
这使得下次执行该程序时能较快地装入内存区
一种历史遗留技术
只有对该目录具有写权限的用户并且满足下列条件之一,才能删除或更名该目录下的文件:
(a) 超级用户
(b) 拥有此文件
(c) 拥有此目录
drwxrwxrwt 17tbcs staff 167936 Feb 29 09:47 /tmp
13、函数chown()、fchown()、lchown() --修改属主/组
lchown作用于符号连接自身
(a) 普通用户只能修改自己的文件的属组
(b) 且只能改为自己所属的组(有效组ID,或附加组ID之一)
14、文件大小
对于目录,文件大小通常是一个数字的整数倍数
对于符号连接,文件大小是文件名称中的实际字节数
lrwxrwxrwx 1 root system 21 Feb 21 2006 /unix ->/usr/lib/boot/unix_64
15、文件截断
16、文件系统
17、函数link()、unlink()、remove()、rename()
仅当文件的连接计数为0时,文件内容才可能同时被删除;
另外一个限制:只要文件保持打开状态,文件内容不会被删除
oldn是文件时:如果newn存在,也必须是文件,它将首先被删除
oldn是目录时:如果newn存在,也必须是空目录,它将首先被删除
如果oldn或newn引用一个符号连接:将处理连接自身
如果oldn与newn引用相同的文件:函数不做任何处理
18、符号连接
chown、lchown、lstat、readlink、remove、rename、unlink
chown是否跟随符号连接因系统而异
其它函数,如access、stat、chmod、open等,将处理符号连接引用的文件(指定O_CREAT与O_EXCL选项调用open时,不跟随)
$ ls myfile
myfile # 符号连接已创建
$ cat myfile # 显示文件内容
cat: myfile: No such file or directory
$ ls -l myfile # 显示完整信息
lrwxrwxrwx 1 sar 13 Jan 22 00:26 myfile -> /no/such/file
20、文件时间
21、函数utime() --更改文件的访问/修改时间
22、目录操作函数mkdir()、rmdir() …