Linux系统编程之错误处理:perror,strerror和errno

news/2024/11/20 4:21:17/

转自:http://www.linuxidc.com/Linux/2013-07/87238.htm

1,在系统编程中错误通常通过函数返回值来表示,并通过特殊变量errno来描述。

errno这个全局变量在<errno.h>头文件中声明如下:extern int errno;

errno是一个由POSIX和ISO C标准定义的符号,看(用)起来就好像是一个整形变量。当系统调用或库函数发生错误的时候,比如以只读方式打开一个不存在的文件时,它的值将会被改变,根据errno值的不同,我们就可以知道自己的程序发生了什么错误,然后进行相应的处理。

为什么,要强调errno看起来好像是一个整形变量呢?因为有的标准(如ISO C)只规定了errno的作用,而没有规定它的实现方式,它可能被定义成一个变量,也有可能被定义成一个宏,这个具体要看编译器自己的实现。早些时候,POSIX.1曾把errno定义成extern int errno这种形式,但现在这种方式比较少见了。因为以这种形式来实现errno,在多线程环境下errno变量是被多个线程共享的,这样可能线程A发生某些错误改变了errno的值,线程B虽然没有发生任何错误,但是当它检测errno的值的时候,线程B会以为自己发生了错误。所以现在errno在Linux中被实现成extern int * __errno_location(void): #define errno (*__errno_location()),这样每个线程都有自己的errno,不会再发生混乱了。

关于errno有三点需要特别注意:

1、如果系统调用或库函数正确执行的话,errno的值是不会被清零(置0,注意这里是不会被清零,不是不会被改变)的,假若执行函数A的时候发生了错误errno被改变,接下来直接执行函数B,如果函数B正确执行的话,errno还保留函数A发生错误时被设置的值。所以,在利用errno之前,最好先对函数的返回值进行判断,看是否发生了错误,返回值错误再利用errno判断时哪里发生了错误。所以如果一个函数无法从返回值上判断正误,而只能通过errno来判断出错,那你在调用它之前必须手动将errno清零

2、系统调用或库函数正确执行,并不保证errno的值不会被改变!

3、任何错误号(即发生错误时errno的取值)都是非0的。

综上所述,当需要用errno来判断函数是否正确执行的时候,最好先将errno清零,函数执行结束时,通过其返回值判断函数是否正确执行,若没有正确执行,再根据errno判断时哪里发生了错误。

2. 错误处理函数

  • perror
  • strerror

perror和strerror函数都是用来打印错误提示信息的,它们的原型分别是:

#include <stdio.h>

void perror(const char *s);

它先打印s指向的字符串,然后输出当前errno值所对应的错误提示信息,例如当前errno若为12,调用perror("ABC"),会输出"ABC: Cannot allocate memory"。

测试程序:

#include <stdio.h>
#include <unistd.h>int main(void)
{int fd = 10;int ret;ret = close(fd);if(ret == -1)perror("close error");return 0;
}

测试结果:

QQ20130709205904_thumb1

#include <string.h>

char *strerror(int errnum);

它返回errnum的值所对应的错误提示信息,例如errnum等于12的话,它就会返回"Cannot allocate memory"。

测试程序:

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>int main(void)
{int fd = 10;int ret;ret = close(fd);if(ret == -1)fprintf(stderr, "close error with msg is: %s\n",strerror(errno));return 0;
}

测试结果:

QQ20130709210627_thumb3

linux

http://www.ppmy.cn/news/651000.html

相关文章

Linux 获取并分析程序崩溃时的调用堆栈

http://blog.csdn.net/zsf8701/article/details/8812508 下面是一个小例子&#xff0c;说明了程序出现段错误时&#xff0c;如何打印程序的堆栈信息。 [cpp] view plain copy #include<stdio.h> #include<string.h> #include<stdlib.h> #include &l…

ios 架构资料

景总的博客http://blog.csdn.net/justinjing0612 &#xff08;目前任职于天猫国际移动开发CTO&#xff0c;曾就职于平安科技项目经理&#xff0c;对IM和APP性能优化有深刻间接 NSHipster http://nshipster.cn/ Limboy http://feeds.feedbur…

嵌入式Linux使用Busybox init进程启动过程分析

转自&#xff1a; http://blog.csdn.net/shanzhizi/article/details/39082495 一、Busybox Busybo是一个遵循GPLv2协议的开源项目。 Busybox将众多的Linux命令集合进一个很小的可执行程序中&#xff0c;可以用来替换GNU fileutils shellutils等工具集。Busybox中各种命令与相应…

猿题库 iOS 客户端架构设计

转载自&#xff1a; 蓝晨钰的博客 序 猿题库是一个拥有数千万用户的创业公司&#xff0c;从2013年题库项目起步到2015年&#xff0c;团队保持了极高的生产效率&#xff0c;使我们的产品完成了五个大版本和数十个小版本的高速迭代。在如此快速的开发过程中&#xff0c;如何保证…

智能mp5 android系统,新Android智能MP5 蓝晨BM790改版上市

新Android智能MP5 蓝晨BM790改版上市 2011年03月02日 05:01作者&#xff1a;厂商投稿编辑&#xff1a;范源媛文章出处&#xff1a;泡泡网原创 分享 泡泡网MP3频道3月2日 当平板电脑袭卷全球&#xff0c;Android智能平台成为目前MID平板应用系统的第一大派系。蓝晨数码在2011年度…

大像素全景,如何让自己的VR全景变得具有高级感?

一个成功的VR全景作品&#xff0c;如果想要在商业领域上获得一定影响力&#xff0c;那么VR全景本身的质量就是关键&#xff0c;如何让自己的VR全景变得具有高级感呢&#xff1f; 从艺术表达手法上&#xff0c;航拍是对VR全景很好的诠释&#xff0c;通过VR全景航拍&#xff0c;人…

Axure教程—上传文件

本文介绍用Axure制作文件上传效果 预览 预览地址&#xff1a;https://6q4of2.axshare.com 功能 1、点击”文件上传“按钮&#xff0c;显示上传的文件 2、点击”删除“图片&#xff0c;显示提示”是否要删除“&#xff0c;点击”是“&#xff0c;删除数据&#xff0c;点击”否…

当产品进化遇见亿元福利,华帝携手人民日报为消费复苏添了一把火

这个五一黄金周&#xff0c;消费复苏的热火彻底被点燃。统计数据显示&#xff0c;2023年“五一”假期累计超过2.74亿人次出游&#xff0c;消费市场恢复到2019年同期水平。久违的“人间烟火气”再度回归。 除了旅游市场的火爆&#xff0c;同样助燃消费市场的还有全民“厨房焕新…