《UNIX环境高级编程》四文件和目录读书笔记

来源:互联网 发布:开淘宝店收益怎么样 编辑:程序博客网 时间:2024/05/17 01:38

1、函数stat、fstat、fstatat、lstat

#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);若成功,返回0;若出错,返回-1
lstat类似于stat,但是当命名的文件是一个符号链接时,lstat返回该符号链接的有关信息,而stat返回由该符号链接引用的文件的信息。

struct stat{
mode_t st_mode; //文件类型和访问权限
ino_t st_ino; //i-node编号
dev_t st_dev; //设备号
dev_t st_rdev; //设备号(字符特殊设备和块特殊设备)
nlink_t st_nlink; //链接数
uid_t st_uid; //用户ID
gid_t st_gid; //组ID
off_t st_size; //文件长度(字节为单位)
struct timespec st_atime; //访问时间
struct timespec st_mtime; //内容修改时间
struct timespec st_ctime; //状态更改时间
blksize_t st_blksize; //best I/O block size
blkcnt_t st_blocks; //

2、文件类型(文件类型信息包含在stat结构的st_mode成员中)
S_ISREG( ) 普通文件
S_ISDIR( ) 目录文件
S_ISCHR( ) 字符特殊文件
S_ISBLK( ) 块特殊文件
S_ISFIFO( ) 管道或FIFO
S_ISLNK( ) 符号链接
S_ISSOCK( ) 套接字

3、设置用户ID和设置组ID
有效用户ID、有效组ID和附属组ID决定了我们的文件访问权限。
当执行一个程序文件时,进程的有效用户ID通常就是实际用户ID,有效组ID通常是实际组ID。但是可以在st_mode中设置一个特殊标志,其含义是“当执行此文件时,将进程的有效用户ID设置为文件所有者的用户ID”。与此相类似,在文件模式字中可以设置另一位,它将执行此文件的进程的有效组ID设置为文件的组所有者ID。在文件模式字中的这两位被称为设置用户ID和设置组ID。

4、文件访问权限
st_mode也包含了对文件的访问权限位。
S_IRUSR 用户读
S_IWUSR 用户写
S_IXUSR 用户执行
S_IRGRP 组读
S_IWGRP 组写
S_IXGRP 组执行
S_IROTH 其他读
S_IWOTH 其他写
S_IXOTH 其他执行

5、新文件和目录的所有权
(1)新文件的用户ID设置为进程的有效用户ID
(2)新文件的组ID可以是进程的有效组ID,也可以是它所在目录的组ID(当它所在的目录的设置组ID位被设置时)

6、函数access和faccessat

#include <unistd.h>int access(const char *pathname,int mode);int faccessat(int fd,const char *pathname,int mode,int flag);若成功,返回0;若出错,返回-1

其中,mode:
F_OK 测试文件是否存在
R_OK 测试读权限
W_OK 测试写权限
X_OK 测试执行权限

7、函数umask(为进程设置文件模式创建屏蔽字)

#include <sys/stat.h>mode_t umask(mode_t cmask);

其中,cmask是9个常量(S_IRSUR、S_IWUSR等)中的若干个按位“或”构成的。
ex:
umask(S_IRGPR|S_IWGRP|S_IROTH|S_IWOTH);
if(creat(“bar”,S_IRUSR|S_IWUSR|S_IRGPR|S_IWGRP|S_IROTH|S_IWOTH)

umask(S_IRGPR|S_IWGRP|S_IROTH|S_IWOTH);if(creat("bar",S_IRUSR|S_IWUSR|S_IRGPR|S_IWGRP|S_IROTH|S_IWOTH)   err_sys("creat error for bar");

更改进程的文件模式创建屏蔽字并不影响其父进程(常常是shell)的屏蔽字。

8、函数chmod、fchmod和fchmodat

#include <sys/stat.h>int chmod(const char *pathname,mode_t mode);int fchmod(int fd,mode_t mode);int fchmodat(int fd,const char *pathname,mode_t mode,int flag);若成功,返回0;反出错,返回-1.

mode:
除以上9个外:
S_ISUID 执行时设置用户ID
S_ISGID 执行时设置组ID
S_ISVTX 保存正文(粘着位)
S_IRWXU
S_IRWXG
S_IRWXO

9、粘着位
如果对一个目录设置了粘着位,只有对该目录具有写权限的用户并且满足下列条件之一,才能删除或重命名该目录下的文件:
(1)拥有此文件
(2)拥有此目录
(3)是超级用户

如:目录/tmp和/var/tmp设置了粘着位,任何用户都可在这两个目录下创建文件。任一用户对这两个目录的权限通常都是读、写和执行。但是用户不能删除或重命名属于其他人的文件。

10、函数chown、fchown、fchownat和lchown

#include <unistd.h>int chown(const char *pathname,uid_t owner,gid_t group);int fchown(int fd,uid_t owner,gid_t group);int fchownat(int fd,const char *pathname,uid_t owner,gid_t group,int flag);int lchown(const char *pathname,uid_t owner,gid_t group);若成功,返回0;若出错,返回-1.

在符号链接情况下,lchown和fchownat(设置了AT_SYMLINK_NOFOLLOW标志)更改符号链接本身的的所有者,而不是符号链接所指向的文件的所有者。

11、文件截断

#include <unistd.h>int truncate(const char *pathname,off_t length);int ftruncate(int fd,off_t length);若成功,返回0;若出错,返回-1

如果该文件以前的长度大于length,则超过length以为的数据就不再能访问。如果以前的长度小于length,文件长度将增加(在以前的文件尾端和新的文件尾端之间的数据将读作0)。

12、文件系统
i节点包含了文件有关的所有信息:文件类型,文件访问权限位、文件长度和指向文件数据块的指针等。
i节点编号的数据类型是ino_t。
每个i节点中都有一个链接计数,其值是指向该i节点的目录项数。
在stat结构中,链接计数包含在st_nlink成员中,其基本系统数据类型是nlink_t。这种链接类型称为硬链接。
另外一种链接类型称为符号链接,符号链接文件的实际内容(在数据块中)包含了该符号链接所指向的文件的名字。

13、函数link、linkat、unlink、unlinkat和remove
link函数或linkat函数:创建一个指向现有文件的链接

#include <unistd.h>int link(const char *existingpath,const char *newpath);int linkat(int efd,const char *existingpath,int nfd,const char *newpath,int flag);若成功,返回0;若出错,返回-1.

当现有文件是符号链接时,由flag参数来控制linkat函数是创建指向现有符号链接的链接还是创建指向现有符号链接所指向的文件的链接:
flag为AT_SYMLINK_FOLLOW:创建指向符号链接目标的链接。
如果这个标志被清除了,则创建一个指向符号链接本身的链接。

unlink函数:删除一个现有的目录项,并将由pathname所引用文件的链接计数减1.

#include <unstid.h>int unlink(const char *pathname);int unlinkat(int fd,const char *pathname,int flag);若成功,返回0;若出错,返回-1.

关闭一个文件时,内核首先检查打开该文件的进程个数,如果这个计数达到0,内核再去检查其链接计数,如果计数也是0,那么就删除该文件的内容。
进程用open或creat创建一个文件,然后立即调用unlink,因为该文件仍旧是打开的,所以不会将其内容删除。只有当进程关闭该文件或终止时,该文件的内容才被删除。

#include <stdio.h>int remove(const char *pathname);

对于文件,remove与unlink相同。对于目录,remove的功能与rmdir相同。

14、符号链接
不跟随符号链接的函数(改变符号链接本身):
lchown、lstat、readlink、remove、rename、unlink

15、创建和读取符号链接

#include <unistd.h>int symlink(const char *actualpath,const char *sympath);int symlinkat(const char *actualpath,int fd,const char *sympath);若成功,返回0;若出错,返回-1

因为open函数跟随符号链接,所以需要有一种方法打开该链接本身,并读该链接中的名字。readlink和readlinkat函数提供了这种功能。

#include <unistd.h>ssize_t readlink(const char *restrict pathname,char *restrict buf,size_t bufsize);ssize_t reaklinkat(int fd,const char *restrcit pathname,char *restrict buf,size_t bufsize);若成功,返回读取的字节数;若出错,返回-1

16、函数futimens、utimensat和utimes

#include <sys/stat.h>int futimens(int fd,const struct timespec times[2]);int utimensat(int fd,const char *path,const struct timespec times[2],int flag);若成功,返回0;若出错,返回-1
#include <sys/time.h>int utime(const char *pathname,const struct timeval timws[2]);

17、函数mkdir、mkdirat和rmdir

#include <sys/stat.h>int mkdir(const char *pathname,mode_t mode);int mkdirat(int fd,const char *pathname,mode_t mode);若成功,返回0;若出错,返回-1
#include <unistd.h>int rmdir(const char *pathname);删除一个空目录,若成功,返回0;若出错,返回-1.

18、读目录
一个目录的写权限位和执行权限位决定了在该目录中能否创建新文件以及删除文件,它们并不代表能否写目录本身。

#include <dirent.h>DIR *opendir(const char *pathname);DIR *fdopendir(int fd);struct dirnet *readdir(DIR *dp);若成功,返回指针,若出错,返回NULLvoid rewinddir(DIR *dp);int closedir(DIR *dp);若成功,返回0;若出错,返回-1long telldir(DIR *dp);返回值:与dp关联的目录中的当前位置void seekdir(DIR *dp,long loc);

19、函数chdir、fchdir和getcwd

#include <unistd.h>int chdir(const char *pathname);int fchdir(int fd);若成功,返回0;若出错,返回-1

因为当前工作目录是进程的一个属性,所以它影响调用chdir的进程本身,而不影响其他进程。

#include <unistd.h>char *getcwd(char *buf,size_t size);若成功,返回buf;若出错,返回NULL;
0 0
原创粉丝点击