pag72
目录文件:包含其他文件的名字以及指向与这些文件有关信息的指针。(知道目录也时文件)
int stat (const char *restrict pathname, struct stat *restrict buf);
int fstat (int filedes, struct stat *buf);
int lstat (const char *restrict pathname, struct stat *restrict buf); (link stat)
lstat与stat类似,但是当命名的文件是一个符号链接时, lstat返回该符号链接的有关信息,而 不是该符号链接引用文件的信息(stat)。
文件类型:
1、 普通文 件
S_ISREG
2、目录文件。包含 其他文件的名字以及指向这些文件有关信息的指针。
S_ISDIR
3、块特殊文件。提供对设备带缓冲的访问。
S_ISBLK
4、字符特殊文件。提供设备不带缓冲访问(系统中设备要么是 字符特殊文件,要么是块特殊文件)S_ISCHR
5、 FIFO。命名管 道
S_ISFIFO
6、 套接字
S_ISSOCK
7、符号链接。这种文件指向另一个文件
S_ISLNK
所有类型文件都有访问权限
pag75
主要先辨别ID针对的对象:进程还是文件(这个对理解各ID的差异与概念很重要)
两个 所有者ID是 文件的性质,两个 有效ID和附加组ID是 进程的性质。
进程相关联ID:( 执行文件时才说明这些ID)
实际用户ID、实际组ID:进程执行者,当前所在的用户。
有效用户ID、有效组ID、附加组ID:决定访问权限。 大多数情况下为实际用户ID、实际组ID(除了设置了 设置用户ID位及设置组ID位这种情况)。当设置-用户-ID(SUID)位设置,则有效用户ID等于文件的所有者的uid(struct stat中的st_uid,st_gid),而不是实际用户ID;同样,如果设置了设置-用户组-ID(SGID)位,则有效用户组ID等于文件所有者的gid,而不是实际用户组ID。(实际用户是root时可能有点不同)设置用户ID位及设置组ID位都包含在st_mode值中,可用常量S_ISUID和S_ISGID测试。
保存的设置用户ID、保存的设置组ID:有效用户ID、有效组ID的副本。
例:
ls
-rw-r--r-- 1 root ad ..................(这个root表示的是文件所有者,
即最初创建此文件的进程的有效用户ID;ad表示当所属用户组)
whoami
ad
(这个ad表示的是实际用户)
pag76
st_mode屏蔽---------------------------------意义
S_IRUSR
---------------------------------用户-读
S_IWUSR
---------------------------------用户-写
S_IXUSR
---------------------------------用户-执行
S_IRGRP
---------------------------------组-读
S_IWGRP
---------------------------------组-写
S_IXGRP
---------------------------------组-执行
S_IROTH
---------------------------------其他-读
S_IWOTH
---------------------------------其他-写
S_IXOTH
---------------------------------其他-执行
目录读权限与执行权限的差异:
读权限:允许我们读目录获得在该目录中所有文件名的列表。
执行权限:允许我们通过该目录,即搜索该目录,寻找一个特定的名字。
为了删除一个现有文件,必须对 包含该文件的目录具有 写权限和执行权限,对 该文件本身则不需要有读写权限。
在目录中创建文件也一样。 对于目录通常至少要设置一个执行权限位,以允许访问该目录中的文件名。
pag77
新文件的用户ID(所有者ID)设置为进程的有效用户ID。
新文件组ID:1、进程的有效组ID。2、所在目录的组ID。
int a c cess (const char *pathname, int mode);//按 实际用户ID和实际组ID进行访问权限测试
mode:
R_OK
读权限
W_OK
写权限
X_OK
执行权限
F_OK
文件是否存在
pag79
mode_t umask( mode_t cmask )
umask函数为 进程设置文件模式创建屏蔽字并返回以前的值。当调用umask后,在此函数 以下创建的文件都受umask屏蔽字的影响(设置1时关闭),在函数以上的则保持原先的访问权限。pag80中例子必须不在root用户下执行才能得到与书中一致的结果。 更改进程的文件模式创建屏蔽字并不影响其父进程(常常是shell)的屏蔽字。
int chmod( const char *pathname, mode_t mode )
int fchmod( int filedes, mode_t mode )
chmod函数在 指定的文件上进行操作,fchmod对已 打开的文件进行操作。
为改变一个文件的权限位,进程的 有效用户ID必须等于 文件的所有者ID,或者该进程必须 具有超级用户权限。
int chown (const char *pathname, uid_t owner, gid_t group);
int fchown (int filedes, uid_t owner, gid_t group);
int lchown (const char *pathname, uid_t owner, gid_t group);
更改文件的用户ID(文件所有者ID)和组ID。lchown更改符号链接本身的所有者,而不是该符号链接所指向的文件。如两个参数owner或group中的任意一个是-1,则对应的ID不变。
如果这些函数 由非超级用户进程调用,则在成功返回时,该 文件的设置用户ID位和设置组ID位都会被清除。
int truncate (const char *pathname, off_t length);
int ftruncate (int filedes, off_t length);
把文件长度截断为length字节。
pag87
一个磁盘可以分成多个分区,每个分区可以包含一个文件系统。
i节点是固定长度的记录项,他包含有关文件的大部分信息。
关于i节点的理解
i节点包含了大多数与文件有关的信息:文件类型、文件访问权限位、文件长度、 指向该文件所占用的数据块指针等。
要注意引用计数(进程)与链接计数(目录项)
硬链接:文件中为 所指向文件的内容(直接指向文件的i节点)(多个文件名可指向同一索引节点)
每个i节点都有一个链接计数,其值是指向该i节点的目录项数,只有当链接计数减少至0时,才可删除文件。
符号链接:文件中包含 所指向文件的名字(指向一个文件的间接指针)
ln -s () ()创建符号链接,ls -l 可看出符号链接所指向的文件
ln -P () ()创建硬链接,打开创建的硬链接,内容即为硬链接指向文件
硬链接限制:
1.通常要求链接和文件位于同一文件系统中。
2.只有超级用户才能创建指向 目录的硬链接。
任何一个叶目录(不包含任何其他目录的目录)的链接计数总是2,数值2来自于 命名该目录的目录项..和 该目录中的.项。父目录中的每一个子目录都会使该父目录的链接计数增1.
pag89
任何一个文件可以有多个目录项指向其i节点。
int link (const char *existingpath, const char *newpath);//创建一个指向现有文件的链接(硬链接)
只创建newpath中最后一个分量, 路径中的其他部分应当已经存在。
int unlink(const char *pathname);//删除现有目录项
删除目录项,并将由pathname所引用文件的 链接计数减1.(当文件还是打开的时候,不会将其内容删除,只有当进程关闭该文件或终止时该文件内容才会被删除) open或create创建文件时,文件有1个引用计数 (进程指向i节点的文件描述符) ,一个链接计数(所创建文件名所在的目录项),当两者都为0时才释放空间。
int remove(const char *pathname);//解除对一个文件或目录的链接
int rename(const char *oldname, const char *newname);//文件或目录用rename函数更名(如为符号链接,则处理的是符号链接本身)
给出符号链接名的情况下,没有一个函数能删除由该链接所引用的文件。
int symlink(const char *actualpath, const char *sympath);//创建一个符号链接
ssize_t readlink(const char *restrict pathname, char *restrict buf, size_t bufsize);//打开链接本身,并读链接中的名字(open跟随符号链接)
目录是包含目录项(文件名和相关的i节点编号)的文件。
int utime(const char *pathname, const struct utimbuf *times);//修改文件访问和修改时间
int mkdir(const char *pathname, mode_t mode);//创建空目录(.和..目录自动创建)(对目录通常至少要设置1个文件执行权限位,以允许访问该目录中的文件名)
int rmdir(const char *pathname);//删除空目录(空目录是只包含.和..目录的目录)
如果调用此函数后目录链接计数为0,并且没有其他进程打开此目录,则释放此目录占用空间。( 链接计数为0不一定释放空间,还要看有无被进程打开( 引用计数是否变为0))
pag98
为了防止文件系统产生混乱,只有内核才能写目录(一个目录的写、执行权限位决定了在该目录中能否创建新文件以及删除文件,并不表示能否写目录本身)
DIR * opendir(const char *pathname);//返回DIR指针由以下5个函数使用
struct dirent *readdir(DIR *dp);
void rewinddir(DIR *dp);
int closedir(DIR *dp);
long telldir(DIR *dp);
void seekdir(DIR *dp, long loc);
当前工作目录是进程的属性,起始目录是登录名的属性。
int chdir(const char *pathname);//更改 当前目录(影响进程本身)
int fchdir(int filedes);
char * getcwd(char *buf, size_t size)(get current working directory);//从当前目录(.目录)开始,用..目录找到上一级目录,然后读其目录项,直到该目录项中的i节点编号和工作目录i节点编号相同,这样就找到了其对应的文件名。(pwd)
目录文件:包含其他文件的名字以及指向与这些文件有关信息的指针。(知道目录也时文件)
int stat (const char *restrict pathname, struct stat *restrict buf);
int fstat (int filedes, struct stat *buf);
int lstat (const char *restrict pathname, struct stat *restrict buf); (link stat)
lstat与stat类似,但是当命名的文件是一个符号链接时, lstat返回该符号链接的有关信息,而 不是该符号链接引用文件的信息(stat)。
文件类型:
1、 普通文 件
2、目录文件。包含 其他文件的名字以及指向这些文件有关信息的指针。
3、块特殊文件。提供对设备带缓冲的访问。
4、字符特殊文件。提供设备不带缓冲访问(系统中设备要么是 字符特殊文件,要么是块特殊文件)S_ISCHR
5、 FIFO。命名管 道
6、 套接字
7、符号链接。这种文件指向另一个文件
所有类型文件都有访问权限
pag75
主要先辨别ID针对的对象:进程还是文件(这个对理解各ID的差异与概念很重要)
两个 所有者ID是 文件的性质,两个 有效ID和附加组ID是 进程的性质。
进程相关联ID:( 执行文件时才说明这些ID)
实际用户ID、实际组ID:进程执行者,当前所在的用户。
有效用户ID、有效组ID、附加组ID:决定访问权限。 大多数情况下为实际用户ID、实际组ID(除了设置了 设置用户ID位及设置组ID位这种情况)。当设置-用户-ID(SUID)位设置,则有效用户ID等于文件的所有者的uid(struct stat中的st_uid,st_gid),而不是实际用户ID;同样,如果设置了设置-用户组-ID(SGID)位,则有效用户组ID等于文件所有者的gid,而不是实际用户组ID。(实际用户是root时可能有点不同)设置用户ID位及设置组ID位都包含在st_mode值中,可用常量S_ISUID和S_ISGID测试。
保存的设置用户ID、保存的设置组ID:有效用户ID、有效组ID的副本。
例:
ls
-rw-r--r-- 1 root
whoami
ad
pag76
st_mode屏蔽---------------------------------意义
S_IRUSR
S_IWUSR
S_IXUSR
S_IRGRP
S_IWGRP
S_IXGRP
S_IROTH
S_IWOTH
S_IXOTH
目录读权限与执行权限的差异:
读权限:允许我们读目录获得在该目录中所有文件名的列表。
执行权限:允许我们通过该目录,即搜索该目录,寻找一个特定的名字。
为了删除一个现有文件,必须对 包含该文件的目录具有 写权限和执行权限,对 该文件本身则不需要有读写权限。
在目录中创建文件也一样。 对于目录通常至少要设置一个执行权限位,以允许访问该目录中的文件名。
pag77
新文件的用户ID(所有者ID)设置为进程的有效用户ID。
新文件组ID:1、进程的有效组ID。2、所在目录的组ID。
int a c cess (const char *pathname, int mode);//按 实际用户ID和实际组ID进行访问权限测试
mode:
R_OK
W_OK
X_OK
F_OK
pag79
mode_t umask( mode_t cmask )
umask函数为 进程设置文件模式创建屏蔽字并返回以前的值。当调用umask后,在此函数 以下创建的文件都受umask屏蔽字的影响(设置1时关闭),在函数以上的则保持原先的访问权限。pag80中例子必须不在root用户下执行才能得到与书中一致的结果。 更改进程的文件模式创建屏蔽字并不影响其父进程(常常是shell)的屏蔽字。
int chmod( const char *pathname, mode_t mode )
int fchmod( int filedes, mode_t mode )
chmod函数在 指定的文件上进行操作,fchmod对已 打开的文件进行操作。
为改变一个文件的权限位,进程的 有效用户ID必须等于 文件的所有者ID,或者该进程必须 具有超级用户权限。
int chown (const char *pathname, uid_t owner, gid_t group);
int fchown (int filedes, uid_t owner, gid_t group);
int lchown (const char *pathname, uid_t owner, gid_t group);
更改文件的用户ID(文件所有者ID)和组ID。lchown更改符号链接本身的所有者,而不是该符号链接所指向的文件。如两个参数owner或group中的任意一个是-1,则对应的ID不变。
如果这些函数 由非超级用户进程调用,则在成功返回时,该 文件的设置用户ID位和设置组ID位都会被清除。
int truncate (const char *pathname, off_t length);
int ftruncate (int filedes, off_t length);
把文件长度截断为length字节。
pag87
一个磁盘可以分成多个分区,每个分区可以包含一个文件系统。
i节点是固定长度的记录项,他包含有关文件的大部分信息。
关于i节点的理解
i节点包含了大多数与文件有关的信息:文件类型、文件访问权限位、文件长度、 指向该文件所占用的数据块指针等。
要注意引用计数(进程)与链接计数(目录项)
硬链接:文件中为 所指向文件的内容(直接指向文件的i节点)(多个文件名可指向同一索引节点)
每个i节点都有一个链接计数,其值是指向该i节点的目录项数,只有当链接计数减少至0时,才可删除文件。
符号链接:文件中包含 所指向文件的名字(指向一个文件的间接指针)
ln -s () ()创建符号链接,ls -l 可看出符号链接所指向的文件
ln -P () ()创建硬链接,打开创建的硬链接,内容即为硬链接指向文件
硬链接限制:
1.通常要求链接和文件位于同一文件系统中。
2.只有超级用户才能创建指向 目录的硬链接。
任何一个叶目录(不包含任何其他目录的目录)的链接计数总是2,数值2来自于 命名该目录的目录项..和 该目录中的.项。父目录中的每一个子目录都会使该父目录的链接计数增1.
pag89
任何一个文件可以有多个目录项指向其i节点。
int link (const char *existingpath, const char *newpath);//创建一个指向现有文件的链接(硬链接)
只创建newpath中最后一个分量, 路径中的其他部分应当已经存在。
int unlink(const char *pathname);//删除现有目录项
删除目录项,并将由pathname所引用文件的 链接计数减1.(当文件还是打开的时候,不会将其内容删除,只有当进程关闭该文件或终止时该文件内容才会被删除) open或create创建文件时,文件有1个引用计数 (进程指向i节点的文件描述符) ,一个链接计数(所创建文件名所在的目录项),当两者都为0时才释放空间。
int remove(const char *pathname);//解除对一个文件或目录的链接
int rename(const char *oldname, const char *newname);//文件或目录用rename函数更名(如为符号链接,则处理的是符号链接本身)
给出符号链接名的情况下,没有一个函数能删除由该链接所引用的文件。
int symlink(const char *actualpath, const char *sympath);//创建一个符号链接
ssize_t readlink(const char *restrict pathname, char *restrict buf, size_t bufsize);//打开链接本身,并读链接中的名字(open跟随符号链接)
目录是包含目录项(文件名和相关的i节点编号)的文件。
int utime(const char *pathname, const struct utimbuf *times);//修改文件访问和修改时间
int mkdir(const char *pathname, mode_t mode);//创建空目录(.和..目录自动创建)(对目录通常至少要设置1个文件执行权限位,以允许访问该目录中的文件名)
int rmdir(const char *pathname);//删除空目录(空目录是只包含.和..目录的目录)
如果调用此函数后目录链接计数为0,并且没有其他进程打开此目录,则释放此目录占用空间。( 链接计数为0不一定释放空间,还要看有无被进程打开( 引用计数是否变为0))
pag98
为了防止文件系统产生混乱,只有内核才能写目录(一个目录的写、执行权限位决定了在该目录中能否创建新文件以及删除文件,并不表示能否写目录本身)
DIR * opendir(const char *pathname);//返回DIR指针由以下5个函数使用
struct dirent *readdir(DIR *dp);
void rewinddir(DIR *dp);
int closedir(DIR *dp);
long telldir(DIR *dp);
void seekdir(DIR *dp, long loc);
当前工作目录是进程的属性,起始目录是登录名的属性。
int chdir(const char *pathname);//更改 当前目录(影响进程本身)
int fchdir(int filedes);
char * getcwd(char *buf, size_t size)(get current working directory);//从当前目录(.目录)开始,用..目录找到上一级目录,然后读其目录项,直到该目录项中的i节点编号和工作目录i节点编号相同,这样就找到了其对应的文件名。(pwd)