Other System Calls for Managing Files
还有一些其他的系统调用,能够对这些底层的文件描述符进行操作,这些系统调用允许程序控制文件如何使用以及返回相关的状态信息。
lseek
lseek系统调用对文件描述符fildes的读写指针进行设置,也就是说,我们可以通过它来设置下一个读写操作所发生的位置。我们可以设置指针到文件中一个绝对位置,或者将它设置为相对于当前位置或文件末尾的某个相对位置。
lseek系统调用的语法结构:
#include <sys/types.h>
off_t lseek(int fildes, off_t offset, int whence);
参数offset被用来指定具体的位置,而参数whence则用来指定如何使用offset。whence可以取下列值之一:
SEEK_SET | offset是一个绝对位置 |
SEEK_CUR | offset是一个相对于当前位置的位置 |
SEEK_END | offset是一个相对于文件末尾的位置 |
lseek返回从文件头到文件指针被设置处的字节偏移值,若失败则返回-1。被用来为参数offset进行搜索运算的类型off_t,它是一个与具体实现有关的整数类型,被定义在文件sys/types.h中。
fstat, stat, and lstat
fstat系统调用返回与一个打开的文件描述符相关联的文件的状态信息,该信息将被写入到一个buf结构中,之后此结构的地址将作为一个参数被传递。
下面是语法结构:
#include <sys/stat.h>
#include <sys/types.h>
int fstat(int fildes, struct stat *buf);
int stat(const char *path, struct stat *buf);
int lstat(const char *path, struct stat *buf);
注:sys/types.h的包含是可选的,不过我们推荐在使用系统调用时使用它,因为有些系统调用在使用标准类型时采用的是别名方式,而这种方式可能在以后会改变。
相关函数stat和lstat返回的是指定文件的状态信息,它们得到结果相同。除非该文件是一个符号链接,lstat返回链接本身的信息,而stat则返回该链接所指向的文件的信息。
stat结构的成员在不同的类UNIX系统上都有所不同,不过一般包括下面表格所示的内容:
stat Member | Description |
st_mode | 文件权限以及文件类型信息 |
st_ino | 与文件相关联的inode |
st_dev | 文件所在的设备 |
st_uid | 文件属主的uid号 |
st_gid | 文件属主的gid号 |
st_atime | 文件最后一次访问的时间 |
st_ctime | 文件权限、属主、组以或内容最后一次改变的时间 |
st_mtime | 文件内容最后一个修改的时间 |
st_nlink | 到此文件的硬链接的数量 |
stat结构所返回的st_mode标志还有一些相关联的宏,它们被定义在头文件sys/stat.h中。这些宏包括访问权限和文件类型标志的名称以及一些用于帮助测试的特定类型和权限的掩码。
同前面所描述的open系统调用的权限标志一样,文件类型标志包括:
S_IFBLK | 文件是一个特殊块设备 |
S_IFDIR | 文件是一个目录 |
S_IFCHR | 文件是一个特殊字符设备 |
S_IFIFO | 文件是一个FIFO(管道) |
S_IFREG | 文件是一个普通文件 |
S_IFLNK | 文件是一个符号链接 |
用来解释st_mode标志的掩码包括:
S_IFMT | 文件类型 |
S_IFWXU | 文件属主的读、写、执行权限 |
S_IFWXG | 文件属组的读、写、执行权限 |
S_IFWXO | 其他用户的读、写、执行权限 |
还有一些定义的宏,用来帮助确定文件类型。这些宏只是对经过适当掩码处理的模式标志同恰当的设备类型标志进行比较,他们包括:
S_ISBLK | 测试是否是特殊的块设备文件 |
S_ISCHR | 测试是否是特殊的字符设备文件 |
S_ISDIR | 测试是否是目录 |
S_ISFIFO | 测试是否是FIFO |
S_ISREG | 测试是否是一般文件 |
S_ISLNK | 测试是否是符号链接 |
举例说明,测试一个文件不是目录,且文件属主只拥有执行的权限,而没有其他权限,我们可以如下测试:
mode_t modes;
stat("filename", &statbuf);
modes = statbuf.st_mode;
if(!S_ISDIR(modes) && (modes & S_IRWXU) == S_IXUSR)
....
dup and dup2
dup系统调用提供了一种复制文件描述符的方法,给出两个或多个不同的描述符来访问相同的文件。这可以被用到读写操作在文件的不同位置。dup系统调用复制了文件描述符fildes,之后返回一个新的描述符。dup2系统调用实际上是复制一个文件描述符到另一个指定的描述符。
下面是语法结构:
int dup(int fildes);
int dup2(int fildes, int fildes2);
这些调用在你通过通道进行多进程通信时会十分有用,我们会在以后对dup系统调用进行更深入的讨论。