《Unix环境高级编程》读书笔记 第4章-文件和目录1. stat结构的基本形式:struct stat { mode_t st_mode; /* file type & mode (permissions), suid, sgid */ 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 */ struct timespec st_atim; /* time of last access */ struct timespec st_mtim; /* time of last modification */ struct timespec st_ctim; /* time of last file status change */ blksize_t st_blksize; /* best I/O block size */ blkcnt_t st_blocks; /* number of disk blocks allocated , 512B */};struct timespec { time_t tv_sec; long tv_nsec;}
2. 函数stat、fstat、fstatat、lstat函数名首位的“f”常常代表“该函数是通过文件描述符fd(而不是路径名)对文件进行操作的”#include <sys/stat.h>int stat(const char *restrict pathname, struct stat *restrict buf );int fstat(int fd, struct stat *buf );int lstat(const char *restrict pathname, struct stat *restrict buf ); // 返回该符号链接本身的有关信息int fstatat(int fd, const char *restrict pathname, struct stat *restrict buf, int flag); All four return: 0 if OK, −1 on error
3. 文件类型普通文件 -目录文件 d块特殊文件 b字符特殊文件 cFIFO p套接字 s符号链接 l
文件类型宏:参数为stat结构中的st_mode成员(文件模式字)
ipC类型宏:参数为stat结构的指针
4. 设置用户ID(SUID) 和 设置组ID(SGID)与每个进程关联的用户ID和组ID,包括实际用户ID、有效用户ID、保存的设置用户ID。实际用户ID指的是执行该程序的用户的ID。注意区别于文件的所有者。
每个文件有一个所有者和组所有者,由stat结构中的st_uid, st_gid指定。
当执行一个程序文件时,进程的有效用户ID通常就是实际用户ID。但是,可以在文件模式字(st_mode)中设置一个标志,使其“当执行该程序文件时,将进程的有效用户ID设置为文件所有者的ID(st_uid)”。进程的有效组ID类似,在文件模式字st_mode中的这两位标志被称为SUID和SGID。可使用常量S_ISUID和S_ISGID测试。应用:passwd命令5. 文件访问权限所有文件类型都有访问权限
进程每次打开、创建或删除一个文件时,内核就进行文件访问权限测试,这种测试可能涉及文件的所有者(st_uid和st_gid)、进程的有效ID(有效用户ID和有效组ID)、进程的附属组ID。两个所有者ID是文件的性质,而两个有效ID和附属组ID则是进程的性质。
内核进行的测试具体如下:若进程的有效用户ID是0(超级用户),则运行访问若进程的有效用户ID等于文件的所有者ID(即进程拥有此文件),那么如果所有者适当的访问权限位被设置,则运行访问;否则拒绝访问。适当的访问权限位指的是:若进程为读而打开该文件,则用户读位应为1;若进程为写而打开该文件,则用户写位应为1;若进程将执行该文件,则用户执行位应为1。若进程的有效组ID或进程的附属组ID之一等于文件的组ID,那么如果组适当的访问权限位被设置,则允许访问;否则拒绝访问。若其他用户适当的访问权限位被设置,则允许访问;否则拒绝访问。按顺序执行这4步。一旦前面的被拒绝了,即使后面的组、其他用户拥有相应权限也白搭。6. 新文件和新目录的所有权新文件的用户ID设置为进程的有效用户ID新目录的组ID有两种选择:1. 设置为进程的有效组ID;2. 设置为它的父目录的组ID。linux下如果新目录的父目录的SUID被设置,则选择2
7. 函数access 和 faccessat当open函数打开一个文件时,内核以进程的有效用户ID和有效组ID为基础执行其访问权限测试。有时,进程希望以进程的实际用户ID和实际组ID为基础来执行其访问权限测试。这使用以下两个函数:
#include <unistd.h>int access(const char *pathname, int mode);int faccessat(int fd, const char *pathname, int mode, int flag); Both return: 0 if OK, −1 on error
测试文件是否存在,mode为F_OK;测试读/写/执行权限,mode为R_OK、W_OK、X_OK的按位与
8. 函数umask在进程创建一个新文件或新目录时,一定会使用文件模式创建屏蔽字。在文件模式创建屏蔽字中为1的位,在文件mode中的相应位一定被关闭。常用的几种umask值是002、022、027命令umask [-S]#include <sys/stat.h>mode_t umask(mode_t cmask); Returns: PRevious file mode creation mask
9. 函数chmod、fchmod和fchmodat#include <sys/stat.h>