第八章 使用系统调用进行文件操作
8.1系统调用
在操作系统中,进程以两种不同的模式运行,即内核模式和用户模式,简称Kmode和 Umode。在Umode中,进程的权限非常有限。它不能执行任何需要特殊权限的操作。特殊权限的操作必须在Kmode下执行。系统调用(简称syscall)是一种允许进程进入Kmode以执行Umode不允许操作的机制。复刻子进程、修改执行映像,甚至是终止等操作都必须在内核中执行。
8.2 使用系统调用进行文件操作
系统调用必须由程序发出。它们的用法就像普通函数调用一样。每个系统调用都是一个库函数,它汇集系统调用参数,并最终向操作系统内核发出一个系统调用。
int syscall(int a,int b,int c,int d);
第一个参数a是系统调用编号,b、c、d是对应内核函数的参数。内核的系统调用处理程序根据系统调用编号将调用路由到一个相应的内核函数。当进程结束执行内核函数时,会返回到用户模式,并得到所需的结果。返回值≥0表示成功,-1表示失败。如果失败,errno变量(在errno.h中)会记录错误编号,它们会被映射到描述错误原因的字符串。
简单的系统调用
access | 检查对某个文件的权限 | int access(char *pathname, int mode); |
---|---|---|
chdir | 更改目录 | int chdir(const char *path); |
chmod | 更改某个文件的权限 | int chmod(char *path, mode_t mode); |
chown | 更改文件所有人 | int chown(char *name, int uid, int gid); |
chroot | 将(逻辑)根目录更改为路径名 | int chroot(char *pathname); |
getcwd | 获取CWD的绝对路径名 | char *getcwd(char *buf, int size); |
mkdir | 创建目录 | int mkdir(char *pathname, mode_t mode); |
rmdir | 移除目录(必须为空) | int rmdir(char *pathname); |
link | 将新文件名硬链接到旧文件名 | int link(char *oldpath, char *newpath); |
unlink | 减少文件的链接数;如果链接数达到0,则删除文件 | int unlink(char *pathname); |
symlink | 为文件创建一个符号链接 | int symlink(char *oldpath, char *newpath); |
rename | 更改文件名称 | int rename(char *oldpath,char *newpath); |
utime | 更改文件的访问和修改时间 | int utime(char *pathname, struct utimebuf *time) |
mount | 将文件系统添加到挂载点目录上 | int mount(char *specialfile,char *mountDir); |
mknod | 创建特殊文件 | int mknod(char *path,int mode, int device); |
8.3 常用的系统调用
stat | 获取文件状态信息 |
---|---|
open | 打开一个文件进行读、写、追加 |
close | 关闭打开的文件描述符 |
read | 读取打开的文件描述符 |
write | 写入打开的文件描述符 |
lseek | 重新定位文件描述符的读/写偏移量 |
dup | 将文件描述符复制到可用的最小描述符编号中 |
dup2 | 将oldfd复制到newfd中,如果newfd已打开,先将其关闭 |
link | 将新文件硬链接到旧文件 |
unlink | 取消某个文件的链接;如果文件链接数为0,则删除文件 |
symlink | 创建一个符号链接 |
readlink | 读取符号链接文件的内容 |
8.4 链接文件
Linux允许使用不同的路径名来表示同一个文件,这些文件叫LINK文件。链接有两种类型:硬链接和软链接
-
硬链接
命令ln oldpath newpath创建从newpath到oldpath的硬链接。硬链接文件会共享文件系统中相同的文件表示数据结构(索引节点)。文件链接数会记录链接到同一索引节点的硬链接数量。硬链接仅适用于非目录文件。否则,它可能会在文件系统名称空间中创建循环。 -
软链接
命令ln -s oldpath newpath 创建从newpath到oldpath的软链接或符号链接。newpath是LNK类型的普通文件,包含oldpath字符串。软链接适用于任何文件,包括目录。软链接在以下情况下非常有用。
通过一个较短的名称来访问一个经常使用的较长路径名称。
将标准动态库名称链接到实际版本的动态库。
8.5 stat系统调用
stat/lstat/fstat系统调用可将一个文件的信息返回。stat按文件名统计指向文件,并在缓冲区中填写stat信息。
-
read()系统调用
read()将n个字节从打开的文件描述符读入用户空间中的buf[]。返回值是实际读取的字节数,如果read()失败,会返回-1。 -
write()系统调用
write()将n个字节从用户空间中的buf[]写入文件描述符,必须打开该文件描述符进行写、读写或追加。返回值是实际写入的字节数,通常等于n个字节,如果write()失败,则为-1。
实践部分