|
在程序执行过程中,当判断到某个函数执行失败时,通常会调用return退出程序。在Linux系统下对常见的错误做了一个编号,每一个编号都代表着每一种不同的错误类型,当函数执行发生错误的时候,操作系统会将这个错误所对应的编号赋值给errno变量,每一个进程(程序)都维护了自己的errno变量,它是程序中的全局变量,该变量用于存储就近发生的函数执行错误编号,也就意味着下一次的错误码会覆盖上一次的错误码。 所以由此可知道,当程序中调用函数发生错误的时候,操作系统内部会通过设置程序的 errno变量来告知调用者究竟发生了什么错误。 errno本质上是一个int类型的变量,用于存储错误编号,但是需要注意的是,并不是执行所有的系统调用或C库函数出错时,操作系统都会设置errno。通过man手册可以查到,譬如以open函数为例,执行"man 2 open"打开open函数的帮助信息,找到函数返回值描述段,如下所示,当函数返回错误时会设置errno: RETURN VALUE open(), openat(), and creat() return the new file descriptor (a nonnegative integer), or -1 if an error occurred (in which case, errno is set appropriately). 示例: #include #include int main() { printf("errno1=%dn", errno); fopen("errno", "r"); printf("errno2=%dn", errno); return 0; } 编译运行并查看测试结果 errno1=0 errno2=2 此处errno2=2,由于open函数打开了一个不存在的文件,errno的错误码则为ENOENT(文件不存在),对应的int数值就是2。关于errno的更多错误宏的定义,可以阅读/usr/include/asm-generic/errno-base.h /usr/include/asm-generic/errno.h $ cat /usr/include/asm-generic/errno-base.h /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_GENERIC_ERRNO_BASE_H #define _ASM_GENERIC_ERRNO_BASE_H
#define EPERM 1 /* Operation not permitted */ #define ENOENT 2 /* No such file or directory */ #define ESRCH 3 /* No such process */ #define EINTR 4 /* Interrupted system call */ #define EIO 5 /* I/O error */ #define ENXIO 6 /* No such device or address */ #define E2BIG 7 /* Argument list too long */ ...... 由于errno仅返回数值,还需查阅错误宏定义才能知道具体错误原因,由此引入以下两个标准c库函数。 perror 用于在发生系统调用错误时输出有关错误信息的描述。当一个系统调用或库函数发生错误时,通常会将全局变量errno设置为一个特定的错误码。perror函数读取errno的值,并根据这个值生成相应的错误描述。然后,将错误描述与传入的字符串参数拼接,并输出到标准错误流。 1.头文件 #include 2.函数原型 void perror(const char *str); 3.参数 str:表示一个指向常量字符的指针,用于提供上下文信息。在输出错误消息时,这个字符串将作为错误消息的前缀(可以主动的去描述这个错误信息的内容)。 4.返回值 无。 5.示例 #include int main() { FILE *fp = fopen("perror", "r"); //打开一个不存在的文件perror if (!fp) { perror("perror test"); return -1; } fclose(fp); return 0; } 6.编译运行并查看测试结果 perror test: No such file or directory //报错提示没有这个文件 strerror 用于生成描述错误代码的字符串。 1.头文件 #include 2.函数原型 char *strerror(int errnum); 3.参数 errnum:错误标号,通常用errno。 4.返回值 会返回一个指向描述该错误的字符串的指针。 5.示例 #include #include #include int main() { FILE *fp = fopen("strerror", "r"); if (!fp) { fprintf(stdout, "strerror test: %sn", strerror(errno)); return -1; } fclose(fp); return 0; } 6.编译运行并查看测试结果 strerror test: No such file or directory
|