errno
很多函数失败返回-1 并设置 errno,errno是啥
errno = “最近一次系统调用失败的原因编号(整数)”
每个线程私有。
这个编号只有在出错的时候才会更新,平时读的都是上一次的。
查询errno:
man 3 errno
errno -l使用方法1:只打印编号
int fd = open("test.txt", O_RDONLY);
if (fd == -1) {
printf(“errno=%d\n”, errno);
}
使用方法2:打印错误原因
printf(“%s\n”, strerror(errno));
输出:
No such file or directory
使用方法3:打印错误原因
perror(“open”);
输出:
open: No such file or directory
errno 表:

系统调用
open
#include <fcntl.h>
int open(const char pathname, int flags, …
/ mode_t mode */ );
成功:文件描述符
失败:-1 并设置 errno
flags:进程打算如何访问这个文件。
以下三个访问模式,三选一,必选。
O_RDONLY:只读
O_WRONLY:只写
O_RDWR:读写
拓展标志选项:
:
:
:
:
:
:
:
:
:
:
:
mode:当打开一个不存在的文件时,指定新文件的访问权限位。

close
#include <unistd.h>
int close(int fd);
参数:
close:文件描述符
返回值:
成功:0
失败:-1 并设置 errno
read
#include <unistd.h>
ssize_t read(int fd, void buf[.count], size_t count);
参数:
fd:文件描述符
buf:缓冲区
count:要读取多少字节
返回值:
成功:读取到的数据的字节数,(读文件时 0 表示到达文件尾了没有可读的了)
失败:-1 并设置 errno,常见错误:EAGAIN(EWOULDBLOCK)、EBADF、EFAULT、EINTR、EINVAL、EIO、EISDIR
write
#include <unistd.h>
ssize_t write(int fd, const void buf[.count], size_t count);
参数:
fd:文件描述符
buf:数据缓冲区
count:要写入多少字节
返回值:
成功:返回成功写入的字节数
失败:-1 并设置 errno
lseek
调整文件读写指针的位置。
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
参数:
offset:
whence:
SEEK_SET:
SEEK_CUR:
SEEK_END:
SEEK_DATA:
SEEK_HOLE:
返回值:
成功:返回
失败:设置 errno,返回
C语言库函数
#include <stdio.h>
FILE *fopen(const char *restrict pathname, const char *restrict mode);
FILE *fdopen(int fd, const char *mode);
FILE *freopen(const char *restrict pathname, const char *restrict mode,
FILE restrict stream);
参数:
返回值:
成功:
失败:-1 并设置 errno
高级知识 - Linux 文件管理原理
内核使用3个数据结构来表示打开的文件
(1)v-node 表(v-node table)
Linux将打开文件的属性信息保存在索引节点对象(inode object,又称为v-node)中。
文件属性信息包括文件名、文件大小、访问权限、修改时间等。
(2)文件表(file table)
Linux将打开文件的信息保存在文件对象(file object)中,即 file 结构。
(3)描述符表(descriptor table)
每一个进程都有一个文件描述符表。
该表为 struct file fd_array[NR_OPEN_DEFAULT],索引号即 open 函数的返回值,称为描述符 descriptor。
之后的文件操作都使用该文件描述符来定位文件对象file,进一步通过v-node对象来获取文件属性。
文件描述符
标准输入输出
文件打开过程
内核中文件I/O数据结构共享原理
参数:
返回值:
成功:
失败:-1 并设置 errno
参数:
返回值:
成功:
失败:-1 并设置 errno
参数:
返回值:
成功:
失败:-1 并设置 errno
参数:
返回值:
成功:
失败:-1 并设置 errno