Unix环境高级编程——第四章 目录和文件

    技术2022-06-10  48

    第四章 文件和目录 #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);         stat函数返回pathname文件有关的信息结构,lstat返回符号链接有关信息,而不是符号链接应用的文件 Unix中一切皆为对象,文件信息结构如下: struct stat { mode_t st_mode;//文件类型,模式字 ino_t st_ino;//i节点号 dev_t st_dev;//设备号(文件系统) dev_t st_rdev;//特殊文件设备号,SUS XSI扩展 nlink_t st_nlink;//i节点连接计数,硬链接 uid_t st_uid;//文件所有者ID gid_t st_gid;//文件组所有者ID off_t st_size;//文件大小(字节) time_t st_atime;//最后访问时间 time_t st_mtime;//最后修改时间 time_t st_ctime;//文件状态最后访问时间 time_t st_blksize;//SUS XSI扩展 time_t st_blocks;//SUS XSI扩展 } 文件类型:ls命令 测试宏;POSIX.1允许将IPC对象(如消息队列,信号量)表示为文件,但是Linux,FreeBSD,Solaris,MacOS都不将这些对象表示为文件。 1)普通文件 -  S_ISREG(stat.st_mode) 2)目录文件 d  S_ISDIR() 3)块文件 b    S_ISCHR()  这种文件提供对设备(如磁盘)带缓冲的访问,每次访问以固定长度为单位进行。 4)字符文件 c  S_ISBLK()  提供对设备不带缓冲的访问,访问长度可变。 5)FIFO f     S_ISFIFO()  命名管道(named pipe),用于IPC 6)套接字 s    S_ISSOCK() 7)符号链接 l  S_ISLNK() 重要问题(用户和组) 弄清楚的概念, 与进程相关联的ID 1) 实际用户ID   登录时取自口令文件/etc/passwd 2)实际组ID    登录时取自口令文件/etc/passwd 3)有效用户ID 4)有效组ID 5)附加组ID 6)保存的设置用户ID 在执行程序是包含了有效用户ID和有效组ID的副本,setuid函数 7)保存的设置组ID         通常有效用户ID等于实际用户ID,有效组ID等于实际组ID。但是当执行一个文件程序(可执行文件)时,文件模式自的两位:设置用户ID位, 设置组ID位。当他们设置时,其含义是,当执行此文件时,将进程的有效用户ID(有效组ID)设置为文件所有者的用户ID(组ID)。 运行设置用户ID程序的进程通常得到额外的权限。 文件访问权限(九位) 文件所有者owner/user 文件所有者所在的组成员group 其他成员other owner:S_IRUSR S_IWUSR S_IXUSR group:S_IRGRP S_IWGRP S_IXGRP other:S_IROTH S_IWOTH S_IXOTH 目录的执行权限位常被称为搜索位:要打开文件a,则包含a的目录用户都必须具有可执行权限。 目录的读权限和执行权限. 注意: 打开文件权限位(O_RDONLY,O_WRONLY,O_RDWR) 对文件指定O_TRUNC标志,文件必须具有写权限 在目录中创建文件,该目录必须具有写权限和执行权限 使用open或creat创建新文件时,新文件的用户ID为进程的有效用户ID;新文件的组ID可以是进程的有效组ID,可以使他所在目录的组ID。 当open打开文件时,内核以进程的有效用户ID和有效组ID为基础执行其访问权限测试。 #include <unistd.h> int access(const char *pathname, int mode);//按照实际用户ID和实际组ID进行访问权限测试。 mode的值: R_OK:测试读权限 W_OK:测试写权限 X_OK:测试执行权限 F_OK:测试文件是否存在 #include <sys/stat.h> mode_t umask(mode_t cmask);--设置文件模式创建屏蔽字,返回以前的值,无出错返回 文件模式创建屏蔽字,与每个进程相关联。cmask是9个常量的按位或。 文件模式创建屏蔽字为1的位,文件的mode相应位关闭。 #include <sys/stat.h> int chmod(const char *pathname, mode_t mode);//更改现有文件的访问权限 int fchmod(int fd, mode_t mode); mode_t的位(除了文件访问权限位9位,以外还有六位) S_IRWXU    用户读写执行 S_IRWXG    组读写执行 S_IRRWXO   其它读写执行 S_ISUID    执行时设置用户ID S_ISGID    执行时设置组ID S_ISVTX    保存正文(站住位) /* 改变文件的用户ID和组ID */ #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 lchown(const char *pathname, uid_t owner, gid_t group); /* 文件截短,将文件截断为length */ #include <unistd.h> int truncate(const char *pathname, off_t length); int truncate(int fd, off_t length); 文件空洞,由所设置的偏移量超过文件尾端,并写了某些数据后造成的。du命令,查看文件占用的磁盘块数。 下面是个重要问题!——文件系统 Unix文件系统(Unix file system),BSD快速文件系统         磁盘0号扇区称为主引导记录(Master Boot Record,MBR),MBR的结尾是分区表(给出每个分区的起始地址和结束地址)。 表中的一个分区被标记为活动分区。计算机被引导时,BIOS读入并执行MBR,MBR确定活动分区,读入其第一个块,称为引 导块并执行。引导块中的程序将装载该分区的操作系统,保留引导块,可以保证以后可以安装操作系统。 超级块,保存文件系统重要参数。 文件系统空闲块,位图形式或指针列表 分区(引导块,超级块,文件系统空闲块,其它) 一个磁盘分成几个分区,每个分区包含一个文件系统。文件系统格式: 自举块(引导块) 超级块 柱面组0 柱面组1 ... 柱面组n i节点,包含了大多数与文件有关的信息:文件类型,文件访问权限位,文件长度,指向该文件所占用的数据块的指针。 目录项,存放文件名和i节点编号。 每个文件系统对它们的i节点进行编号,目录项中的i节点指向同一文件系统中相应的i节点,不能使一个目录项指向另一个文件系统的i节点。 ln命令不能跨越文件系统。 普通文件链接计数和目录文件的链接计数 mkdir test 当前目录 .  链接计数2 任何一个页目录(不含任何子目录和文件的目录)的链接计数总是2  test/. ; test/.. 上级目录 .. 链接计数3 不解释 ../. ; ../.. ; ../test 创建指向现有文件的链接(硬链接) #include <unistd.h> int link(const char *path, const char *newpath); int unlink(const char *pathname);//删除一个现有的目录项 int remove(const char *pathname);//对文件unlink,对于目录与rmdir POSIX.1 允许实现支持跨文件系统的链接,但是多实现要求六个路径名在同一文件系统中。 如果实现支持创建指向一个目录的硬链接,也仅限于root用户。理由是可能在文件系统中形成循环,而大多数处理文件系统的 程序都不能处理这种情况,很多文件系统实现不允许目录硬链接。 为了避开硬链接的限制,引入符号链接。(文件系统限制,目录限制) 每个文件保持有时间 st_atime:文件数据的最后访问时间 st_mtime:文件数据的最后修改时间 st_ctime:i节点状态的最后更改状态 i节点状态(文件的访问权限,用户ID,链接数) #include <utime.h> int utime(const char *pathname, const struct utimbuf *times);//改变一个文件的访问和修改时间 struct utimbuf { time_t actime;//访问时间 time_t modtime;//修改时间 }

    最新回复(0)