内核是如何处理系统调用
- 每个系统调用被赋予了一个系统调用号
- 在i386平台上,执行一个系统调用是通过int 0X80指令完成的
- eax存放系统的调用号
- ebx,ecx,edx,esi,edi存储系统调用的参数,对于超过5个参数的系统调用,用一个寄存器指向用户空间存储所有的系统调用的参数
错误的处理
-
在系统调用中错误通常通过函数返回值来表示,并且通过特殊变量errno 来描述。
-
errno 这个全家变量在<errno.h>的头文件中声明:
extern int errno
-
错误处理函数 , 可以通过man进行查看
- perror
- strerror 存在于 <string.h>头文件中
perror函数和strerror 函数
1 /* ************************************************************************
2 > File Name: t0.c
3 > Author: sansuitaibai
4 > email: [email protected]
5 > Created Time: 2022年09月15日 19时16分21秒 CST
6 > Description:
7 ************************************************************************/
8 #include<unistd.h>
9 #include<string.h>
10 #include<stdio.h>
11 #include<errno.h>
12
13 int main(){
14
15 int ret = 0;
16 ret = close(10);
17 if(ret == -1){
18 perror("close with: ");
19
20 }
21 if(ret == -1){
22 fprintf(stderr, "closr whith : %s\n", strerror(errno));
23 }
24 printf("EINTR = %s \n", strerror(EINTR));
25 return 0;
26
27 }
28
- perror 函数直接将errno 这个全局变量进行输出,不需要我们的转换
- strerror函数直接将错误码对应的的字符串转换过来(需包含<string.h>)
结果:
errno这个全局变量里面存放的就是对应错误码,每个错误码对应不同的信息。如下:
错误码:
错误码 | 含义 |
---|---|
E2BIG | 参数太长 |
EACCESS | 权限不足 |
EAGAIN | 重试 |
EBADF | 错误的文件描述符 |
EBUYS | 设备或资源忙 |
ECHILD | 无子进程 |
EDOM | 数学参数不在函数域内 |
EEXIST | 文件已经存在 |
EFAULT | 地址错误 |
EFBIG | 文件太大 |
EINTR | 系统调用中断 |
什么是I/O
- 在输入和输出是主存和外部设备之间拷贝数据的过程
- 设备->内存(输入操作)
- 内存-> 设备 (输出操作)
- 高级I/O
- ANSI C提供的标准I/O库称为高级I/O,通常也称为带缓冲的I/O
- 低级I/O
- 通常也称为不带缓冲的I/O
文件描述符
-
对于Linux而言,所有的对设备或文件的操作都是通过文件描述符进行的。
-
当打开一个或者创建一个文件时候,内核向进程返回一个文件描述符(非负整数)。后续对文件的操作只需要通过该文件描述符,内核记录有关这个打开文件的信息。
-
当一个进程启动时,默认打开了3个文件,标准输入,标准输出,标准错误三个文件描述符。对应描述符
- 0(STDIN_FILENO) : 文件指针 stdin
- 1(STDOUT_FILENO) : 文件指针 stdout
- 2(STDERR_FILENO) : 文件指针 stderr
这些常量定义在<unistd.h>头文件中。
文件描述符与文件指针的转换
-
int fileno(FILE *stream);
将文件指针转换为文件描述符。
-
FILE *fdopen(int fd, const char *mode);
将文件描述符转换为文件指针。
例子:stdin stdout stderr文件指针
/* ************************************************************************
2 > File Name: t0.c
3 > Author: sansuitaibai
4 > email: [email protected]
5 > Created Time: 2022年09月15日 19时16分21秒 CST
6 > Description:
7 ************************************************************************/
8 #include<unistd.h>
9 #include<string.h>
10 #include<stdio.h>
11 #include<errno.h>
12
13 int main(){
14
15 printf("fileno(stdin) = %d \n", fileno(stdin));
16 printf("fileno(stdout) = %d \n", fileno(stdout));
17 printf("fileno(stderr) = %d \n", fileno(stderr));
18
19 return 0;
20 }
21
结果: