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

来源:互联网 发布:js模拟鼠标滚轮 编辑:程序博客网 时间:2024/05/08 10:14
第四章 文件和目录


#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;//修改时间}





原创粉丝点击