摘自《UNIX 高级环境编程》第4章
本文围绕stat()函数的各个参数值描述unix系统的文件属性
# include <sys/types.h>
# include <sys/stat.h>
int stat(const char *pathname,struct stat *buf);
int fstat(int filedes,struct stat *buf);
int lstat(const char *pathname,struct stat *buf);
其中,lstat()操作链接文件本身,而stat()操作链接文件引用的文件
只要有权限,任何进程可以读目录。但是只有内核可以写目录。
Linux下的文件类型:
普通文件 S_ISREG()
目录文件 S_ISDIR()
字符特殊文件 S_ISCHR()
块特殊文件 S_ISBLK()
FIFO(管道) S_ISFIFO()
套接口 S_ISSOCK()
符号链接文件 S_ISLNK()
文件的类型信息保存在stat结构的st_mode成员中
进程的实际uid为用户登陆系统时所使用的用户id
进程的有效uid为进程运行时正在使用的uid
进程的“保存的uid”为进程初次运行时使用的有效uid
所有者ID是文件的性质,有效ID是进程的性质
程序被设置了SUID位后,在该程序的执行过程中,进程以程序的拥有者作为有效uid运行
打开文件前,必须拥有对该文件所在目录及其父目录的执行权。目录的执行许可权又称为搜索位
读目录许可权,可以用于读出目录下的文件名列表
为了删除一个文件,必须对该文件所在的目录有写、执行的权限,而与文件本身的权限无关。但是当对目录设置了粘住位(stick)时,删除文件不仅需要对目录的写、执行权,还要有:(必须满足以下任一条件)
1. 文件本身的拥有权
2. 目录的拥有权
3. 超级用户
在评定进程的权限时,按以下优先级:
uidàgidàothers
按首先匹配原则,一旦匹配,则不再继续匹配低优先级的权限,而直接做出判断
新文件的uid为创建该文件的进程的有效uid
粘住位(sticky bit)又称为保存-正文位(saved-text bit),用常数S_ISVTX表示
粘住位用于普通文件表示,该(程序)文件的执行将全部被保存在交换区,用于快速执行
符号链接文件的长度就是文件所引用的路径名的长度
用du命令查看出的文件大小,不包括文件内的空洞。所以输出的数值小于等于文件所占用的实际空间
在ext3文件系统中,文件的块长度为4k
truncate()用于文件截断
大多数unix文件系统结构:
自举块+超级块+I表+目录块和数据块
I节点是固定长度的记录项,包括了文件的所有属性信息,每个I节点内有个连接计数器,用于记录指向该节点的记录数;当连接计数器为0,即表示删除文件
POSIX.1将常数LINK_MAX指定为文件的最大连接数
目录块的每个记录包括:I节点号、文件名
硬连接直接指向文件的I节点
当使用以名字引用一个文件的函数时,应当了解该函数是否处理符号连接功能。
大部分的函数将跟随符号连接。除了chown、lchown、lstat、readlink、remove、rename、unlink
可以根据存取时间对一段时间内没有存取过的文件,进行删除操作
修改时间和更改状态时间可以用来归档。
只有内核才能写目录
struct dirent {
ino_t d_ino;
char d_name[NAME_MAX+1];
}
在BSD类文件系统中,NAME_MAX值一般设为255
linux提供了函数nftw处理目录遍历过程中的符号连接问题
还有fts遍历函数可供使用
特殊设备文件:
每个文件的s_dev值是其所在的文件系统的主、次设备号。也就是说,不同的文件系统下的文件的s_dev值也不相同。
只有字符/块特殊设备文件才有st_rdev值。
通常我们用宏:major、minor来存取主次设备号
例如:
major(buf.st_dev);
minor(buf.st_dev);
major(buf.st_rdev);
minor(buf.st_rdev);
# include <unistd.h>
void sync(void);
int fsync(int filedes);
sync只是将所有修改过的块的缓存排入写队列,然后返回。它不等待时间I/O操作结束
函数fsync只引用单个文件,它等待I/O结束。
注意:当调用fsync时,它更新文件内容,而对于O_SYNC,则每次文件执行write函数时就马上更新文件的内容。