在我们的例子中,如果open失败了,只是笼统的打印出“打开文件失败了”,但是并没有提示具体出错的原因,没有详细的出错原因提示,遇到比较难排查的错误原因时,很难排查出具体的函数错误。 open失败,如何具体打印出详细的出错信息呢?我们在这里就说明errno的作用了。
函数调用出错时,Linux系统使用错误编号(整形数)来标记具体出错的原因,每个函数有很多错误号,每个错误号代表了一种错误,产生这个错误时,会自动的将错误号赋值给errno这个全局变量。
errno是Linux系统定义的全局变量,可以直接使用。
错误号和errno全局变量都被定义在了errno.h头文件,使用errno时需要包含这个头文件。
man errno,就可以查到errno.h头文件。
那么我们知道了文件在打开的时候有这些具体原因,但是我们如何具体打印出来呢?
我们加入了头文件,并且在读取文件的时候不存在errno.txt的文件进行测试,平且打印出来错误号:
执行结果为:
打开错误,错误号为2
如果没有包含头文件 #include
使用errno时,编译提示‘errno’ undeclare的错误,表示找不到errno全局变量。
例如:
就会出现找不到errno全局变量。
错误号确实标记了具体的出错原因,但是我们并不知道这个错误号,具体到底代表的是什么错误。
perror函数可以自动将“错误号”换成对应的文字信息,并打印出来,方便我们理解。
perror是一个C库函数,不是一个系统函数。
我们详细看一下描述的这一部分:
Perror这个函数,不仅仅用于打印系统函数调用的错误,并且用于打印库函数错误。
使用演示:
使用的时候只是在之前演示的错误码里面加入了perror 的使用。
执行结果为:
结果直接提示文件不存在
我们可以看到编译运行之后会直接打印出来错误号,并且perror会直接打印出来出错的原因。
调用perror函数时,它会自动去一张对照表,将errno中保存的错误号,换成具体的文字信息并打印出来,我们就能知道函数的具体错误原因了。
man open,可以查看open函数,都有哪些错误号
我们通过 man 2 open 来查询open函数的错误号:
每个错误号代表了一种函数可能的出错情况,比如:
EACCES:不允许你访问文件而出错。
Liunx为了让错误号能够见名识意,都给这些整形的错误号定义了对应的宏名,这些宏定义都被定义在了error.h头文件中。
man perror这个函数,也可以看到这个头文件。
使用 man 2 open 查看到这写错误号及详细原因说明:
我们所说的错误号这里并没有直接体现,这下宏定义的背后对应的就是整型编号的错误号,只是为了好识别所以定义为宏。
我们在这里提示:错误号不需要记住,使用perror函数,它可以自动翻译,我们这里说明错误号,只是希望理解错误号,在之后的博客中会出现,我们会用到。
使用char *strerror(int errnum);
返回一个字符串,我们可以讲字符串表示的错误进行打印,也可以把字符串保存到文件。
参数
errno
#include
#include
#include
#include
#include
#include
#include
int main()
{
int fd = open("log",O_RDONLY);
if(fd == -1)
{
perror("open");
//使用perror打印出错原因
printf("open:%s\n",strerror(errno));
//使用strerror打印错误原因
printf("open failed\n");
}
else
{
printf("open success file descriptor : %d\n",fd);
}
close(fd);
return 0;
}