</pre><pre>

4.1 引言

上一章主要是为荣的I/O进行的(打开文件,读文件,写文件),本章讲描述文件系统的其他特征和文件的性质。从stat函数开始,诸葛说明stat结构的每一个成员以及了解文件的所有属性。在此过程中讲介绍修改这些属性的各个函数(更改所有者和权限),更加详细的说明UNIX文件系统的结构以及符号链接(symbolic links),本章最后介绍对目录操作的各个函数,并且开发一个以降序遍历目录结构的函数

4.2 函数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);

stat:一旦给出pathname,stat函数将返回与此命名文件有关的信息结构

fstat:通过描述符(descriptor)打开文件的有关信息

lstat:与stat类似,但是当命名文件是一个符号链接(symbolic link)时,lstat返回的是符号链接的信息,而不是符号链接所引用的文件的信息(not the file referenced by the symbolic link)

fstatat:为一个相对于当前打开目录(由fd参数指向)的路径名返回文件的统计信息,flag参数控制这是否跟随这个符号链接。

(1)当flag设置AT_SYMLINK_NOFOLLOW标志是,fstatat不会跟随符号链接,而是返回符号链接本身信息。否则默认情况下,返回的是符号链接所指项的实际文件的信息。

(2)如果fd参数的值是AT_FDCWD,并且pathname参数是一个相对路径名,fstatat会计算相对于当前目录的pathname参数。如果pathname是一个绝对路径,fd参数就会被忽略。这两种情况下,根据flag的值,fstata的作用就和stat和lstat一样

buf的结构体

4.3 文件类型

我们已经介绍了两种不同的文件类型:普通文件和目录

文件类型主要包含一下几种

(1)普通文件(regular file)。可以是普通文本或者二进制

(2)目录文件(directory file)。这种文件包含了其他文件的名字已经指向这些文件有关信息的指针

(3)块特殊文件(block special file)。这种类型的文件对设备提供带缓冲的访问,每次访问以固定长度为单位进行

(4)字符特殊文件(character special file)。对设备不带缓冲的访问,每次访问的长度可变。系统中的所有设备要么是字符特殊文件,要么是块特殊文件

(5)FIFO。这种文件用于进程间通信,特成为命名管道(named pipe)。

(6)套接字(socket)。这种类型的文件用于进程间的网络通信,也可以用在一台宿主机上进程之间的非网络通信。

(7)符号链接(symbolic link)。这种类型的文件指向另一个文件。

文件信息包含在stat结构的st_mode成员中,st_mode成员如下

4.4 设置用户ID和设置组ID

与一个进程相关联的ID有6个或者更多
(1)实际用户ID和实际组ID标志我们究竟是谁。这两个字段再登陆时取自己的口令文件(password file)中的登陆项
(2)有效用户ID,有效组ID以及附属组ID决定了文件的访问权限
(3)保存的设置用户ID和保存的设置组ID再执行一个程序是包含了有效用户ID,有效组ID的副本(copies)
文件所有者由stat结构中的st_uid制定,所有组同理
通常 effective user ID == real user ID     effective group ID == real group ID
可以再文件模式字(st_mode)设置一个特殊标志,其含义就是当执行此文件时将有效用户ID设置为文件所有者的用户ID(st_uid)

4.5 文件访问权限

st_mode包含了对文件的访问权限位,不仅是普通文件,所有文件都有访问权限(access permission)
每个文件有9个权限位
进程每次打开,创建或删除一个文件,内核就进行文件访问权限测试
内核进行的测试具体如下
(1)若进程的有效用户是0(超级用户),就允许访问。这就给予超级用户对整个系统的最充分的自由
(2)若进程的有效用ID等于文件的所有者ID(也就是进程拥有此文件),那么如果所有者的适当的访问权限位被设置,泽允许访问
(3)若进程的有效组ID或进程的附属组ID之一等于文件的组ID(注意不要求进程的有效用ID等于文件的所有者ID),那么如果组适当的访问权限被设置,则允许访问
(4)若其他用户适当的访问权限位(S_IROTH, S_IWOTH, S_IXOTH)被设置,则允许访问
这四部是按顺序执行。注意:如果进程拥有此文件(也就是有效ID等于用户ID),用户访问权限批准或者拒绝访问,则不查看组访问权限
同样如果进程的有效用ID不等于文件的所有者ID,若进程属于某个适当的组,则按照组访问权限批准或拒绝,不查看其他用户(other)的权限

4.6 新文件和目录的所有权(Ownership of New Files and Directories)

底单张讲述的open或creat创建新文件时,并没有说明赋予新文件的用户ID和组ID是什么
新文件的用户ID设置为进程的有效用户ID
新文件的组ID
(1) 新文件的组ID可以是进程的有效组ID.
(2) 新文件的组ID可以是它所在目录的组ID

4.7 函数access和faccessat

access和faccessat函数是按实际用户ID实际组ID进行权限测试的
#include <unistd.h>
int access(const char * pathname, int mode);
int faccessat(int fd, const char * pathname, int mode, int flag);

mode为F_OK测试文件是否存在,还可以用

faccessat函数与access函数再下面两种情况下是相同的:
(1)pathname参数为绝对路径
(2)fd参数取值为AT_FDCWD而pathname参数为相对路径。否则faccessat计算相对与打开的目录(由fd参数指向)的pathname
flag参数可以改变faccesssat的行为,如果flag设置为AT_EACCESS,则检查用的是调用进程的有效用户ID和有效组ID,还是实际用户ID和实际组ID

4.8 函数unask

<span style="font-weight: normal;">为每个与进程相关联的文件模式创建屏蔽字umask函数为进程设置文件模式,也就是使用umask之后,该进程所创建的文件的相关权限都会被关闭掉的umask值为0,可以保证任何用户都能读文件用户可以设置umask值控制他们所创建的文件的默认权限</span>

4.9 函数chmod, fchmod和fchmodat

这三个文件可以更改现有文件的访问权限
#include<sys/stat.h>
int chmod(const char *pathname, mode_mode);
int fchmod(int fd, mode_t mode);
int fchmodat(int fd, const char *pathname, mode_t mode, int flag);

flag参数用于改变fchodat的行为,当设置了AT_SYMLINK_NOFOLLOW标志时,fchmodat并不会跟随符号链接(symbolic links)

4.10 粘着位(Sticky Bit)

粘着位主要应用再文件夹上,为了避免一个用户删除另一个用户的文件。用户只能删除自己创建的文件,或者被root用户删除

4.11 函数chown, fchown, fchownat, and lchown

下面的函数可用来更改文件的用户ID和组ID
#include <unistd.h>
int chown(const char *pathname, uid_t owner, git_t group);
int fchown(int fd, uid_t owner, git_t group);
int fchownat(int fd, const char *pathname, uid_t owner, git_t group, int flag);
int lchown(const char *pathname, uid_t owner, git_t group);

如果flag参数中设置了AT_SYMLINK_NOFOLLOW标志,则fchown和lchown效果相同
当_POSIX_CHOWN_RESTRICTED有效时,不能更改其他用户文件的用户ID。可以所用有的文件的组ID,单只能更改你所属的组

4.12 文件长度

stat结构成员st_size表示以字节为单位的文件长度。此字段只对普通文件目录文件符号链接有意义
文件中的空洞(holes in a File):设置的偏移量超过文件尾,并且写入一些数据造成的

4.13 文件截断(File Truncation)

#include <unistd.h>
int truncate(const char *pathname, off_t length);
int ftruncate(int fd, off_t length);

这两个函数将一个现有的文件长度截断为length。如果文件长度小于length,则文件长度变成length

4.14 文件系统

有点没看懂

4.15 函数link, linkat, unlink, unlinkat和remove

任何一个文件可以有多个目录项指向其i节点。使用下列函数link, linkat可以创建一个指向现有文件的链接
#include<unistd.h>
int link(const char *existingpath, const char *newpath);
int linkat(int efd, const char *existingpath, int nfd, const chat *newpath, int flag);

这两个函数创建一个新的目录项newpath, 它引用现有的文件existingpath。如果newpath已经存在则返回出错

对于linkat函数,现有文件是通过efd和existingpath参数制定的,新的文件也是通过nfd和newpath制定的
当现有的文件是符号链接时,由flag参数来控制linkat函数是创建指向现有的符号链接的链接还是创建指向符号链接所指项的文件的链接

为了删除现有的目录项,可以调用unlink函数

#include <unistd.h>
int unlink(const char *pathname);
int unlinkat(int fd, const char *pathname, int flag);

关闭一个文件是,内核会检查打开该文件的进程数,如果个数为0再检查链接计数,如果计数也为0则删除该文件

#include<unistd.h>
int symlink(const char *actualpath, const char *sympath);
int symlinkat(const char *actualpath,int fd, const char *sympath);
unlink的这个特性经常被程序用来确保即使再程序崩溃的时候,它做创建的临时文件也不会一留下来。进程用open或者creat 创建一个文件,然后调用unlink,当进程终止时候,该文件被删除
我们也可以用remove函数解除对一个文件或者目录的链接。对于文件remove和unlink相同,对于目录remove和rmdir功能相同

除了oldname或newname指向相对路径名时,其他情况这两个函数都是一样的

4.16 函数rename和renameat

文件或者目录可以用rename或renameat函数重命名
除了当oldname或newname指向相对路径名时,其他情况下renameat函数与rename函数功能相同

4.17 符号链接(Symbolic Links)

符号链接是对一个文件的间接指针。引入符号链接是为了避开硬链接的一些限制
(1)硬链接通常要求链接和文件位于一个文件系统中
(2)只有超级用户才能创建指向目录的硬链接
符号链接以及它指向的何种对象没有任何文件系统限制
符号链接一般用于将一个文件或者整个目录的结构移到系统中的另一个位置

4.18 创建和读取符号链接

可以使用symlink或symlinkat函数创建一个符号链接
#include<stdio.h>
int rename(constt chat *oldname, const char *newname);
int renameat(int oldfd, const char *oldname, int newfd, const char *newname);

4.19 文件的时间

4.20 函数futimens, utimensat, utimes

futimens和utimensat函数可以更改一个文件的访问和修改的时间
futimens和utimensat函数包含再POSIX.1中,第三个函数utimes包含在Single UNIXSpecification的XSI扩展中

4.21 函数mkdir, mkdirat和rmdir

用mkdir和mkdirat函数创建目录,用rmdir函数删除目录
#include <sys/stst.h>
int mkdir(const chat *pathname, mode_t mode);
int mkdirat(int fd, const char *pathname, mode_t mode);

rmdir删除目录,但要求一定是空的

4.22 读目录

4.23 函数chdir, fchdir, getcwd 

每个进程都有一个当前工作目录,此目录是搜索所有相对路径名的起点
进程调用chdir或者fchdir函数可以更改当前工作目录
#include<unistd.h>
int chdir(const char *pathname);
int fchdir(int fd);

fchdir函数提供一个便捷的方法,再更换当前工作目录前,先用open打开,保存返回的文件描述符,然后希望回到原目录,是要简单的讲file descriptor传给fchdir
这两个函数分别用pathname和打开的文件描述符来制定新的当前工作目录

因为当前工作目录是进程的一个属性,所以它只影响调用chdir的进程本身,而不影响其他进程
getcwd函数提供保存当前工作路径的功能
char *getcwd (char *buf, size_t size);

4.24 设备特殊文件

4.25 文件访问权限位小结

4.26 小结

本章主要围绕着stat函数,详细介绍了stat结构中的每一个成员
对文件和目录的所有属性已经对文件和目录进行操作的所有函数全面了解,这对UNIX编程很重要

UNIX环境高级编程之第4章:文件和目录相关推荐

  1. UNIX环境高级编程之第4章:文件和文件夹-习题

    4.1 stat函数是尾随符号链接的,所以用stat替换lstat不会显示符号链接的信息 4.2 在一个目录下先再shell中输入umask shell进程再进行创建文件的操作.其权限抖都会被屏蔽 4 ...

  2. unix环境高级编程之 read与write 函数详解

    学习记录:unix环境高级编程之 read 与write  函数详解 备注:本博文非本人所写,本人觉得此文讲的非常地道通俗易懂,所以摘录在此以方便以后再次查看 read函数从打开的设备或文件中读取数据 ...

  3. UNIX环境高级编程源码

    UNIX环境高级编程源码 一.下载源码 利用wget命令下载源码,源码地址http://apuebook.com/src.3e.tar.gz 可以在服务器的根目录下创建文件夹,mkdir 1.mkdi ...

  4. UINX环境高级编程笔记 第3章 文件I/O

    UNIX环境高级编程 第三章 文件I/O 3.1 引言 3.2 文件描述符 3.3 函数open和openat 3.4 函数creat 3.5 函数close 3.6 函数lseek 3.7 函数re ...

  5. 《Unix环境高级编程》Note——第一章基础知识

    文章目录 第一章 Unix基础知识 1.引言 2.Unix体系结构 3.登录 4.文件和目录 5.输入和输出 6.程序和进程 7.出错处理 8.用户标识 9.信号 10.时间值 11.系统调用和库函数 ...

  6. UNIX 环境高级编程总结——第五章 标准I/O 库

    5.1 流和 FILE 对象 对于标准 I/O 库,它们的操作则是围绕流(stream)进行的. 当打开一个流时,标准 I/O 函数 fopen 返回一个指向 FILE 对象的指针. 为了引用一个流, ...

  7. 《UNIX环境高级编程》六系统数据文件和信息读书笔记

    UNIX系统的正常运作需要使用大量与系统有关的数据文件,例如,口令文件/etc/passwd和组文件/etc/group等. 1.口令文件 口令文件的各字段包含在pwd.h>中定义的passwd ...

  8. UNIX环境高级编程(屏幕打印和inet_ntoa输出异常问题)

    一.来回在屏幕和文件之间打印 在网上没找到在屏幕和文件来回打印的方法,翻了下UNIX环境高级编,里面有个freopen用于在一个指定的流上打开一个指定的文件,如果要将标准输出打印到文件,需要调用该函数 ...

  9. (三) 一起学 Unix 环境高级编程 (APUE) 之 文件和目录

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  10. python flask高级编程之restful_('Python Flask高级编程之RESTFul API前后端分离精讲',),全套视频教程学习资料通过百度云网盘下载...

    资源详情 r n t某课网好评度100%的Python Flask高级编程之RESTFul API前后端分离精讲 r n t t t第1章 随便聊聊 r n t t t聊聊Flask与Django,聊 ...

最新文章

  1. 僵尸(bot)程序缓解
  2. 链表问题11——两个单链表相交的系列问题(三):判断两个有环链表是否相交
  3. 【小白学PyTorch】9.tensor数据结构与存储结构
  4. JVM—如何利用虚拟机栈进行函数调用?
  5. java nio epoll_Java NIO 选择器(Selector)的内部实现(poll epoll)
  6. android 动态库 后缀,Android Robolectric加载运行本地So动态库
  7. c语言字符串传给swift,如何把字符串数组从 Swift 传递给 C
  8. 摊上事了?中国卖家对亚马逊发起集体诉讼:3000多账号被封 损失惨重
  9. 基于pyagme用python做接小球游戏
  10. Python3.7入门什么Bug?Bug最基本的调试Debug
  11. iQOO 10系列来袭 OriginOS原系统强化手机体验
  12. 毕业生自传--(宝岛海南“三月游”)
  13. win10重启电脑Java环境变量丢失问题
  14. 纸壳CMS可视化建站系统搭建多语言网站
  15. 浙师大 计算机科学技术导论,计算机科学技术导论
  16. omap3530支持gpu模块
  17. C语言程序设计A重点,【艾学笔记】复习重点之C语言程序设计
  18. 心田花开:中学生心理状态分析
  19. P3088 [USACO13NOV]CROWDED COWS S
  20. imx6ul linux读取DS18B20温度

热门文章

  1. Linux让Apache支持中文URL图片/文件名
  2. Oracle分页总汇
  3. 再谈new functionName
  4. linux 安装apache
  5. install java 7 or 8 on ubuntu14
  6. 蓝桥练习 之 单词个数统计
  7. CSS3常用功能 旋转等
  8. [学习笔记] vim使用大全 [转]
  9. 如何制造万能版的Ghost版Windows?[转]
  10. 【转】SQL Server联机丛书:存储过程及其创建