linux系统编程之错误处理:perror,strerror和errno
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 = ;
int ret;
ret = close(fd);
if(ret == -)
perror("close error");
return ;
}
测试结果:

#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 = ;
int ret;
ret = close(fd);
if(ret == -)
fprintf(stderr, "close error with msg is: %s\n",strerror(errno));
return ;
}
测试结果:

注:本文参考http://blog.csdn.net/yandianxun/article/details/6676248
linux系统编程之错误处理:perror,strerror和errno的更多相关文章
- linux系统编程之错误处理
在linux系统编程中,当系统调用出现错误时,有一个整型变量会被设置,这个整型变量就是errno,这个变量的定义在/usr/include/errno.h文件中 #ifndef _ERRNO_H /* ...
- linux系统编程之错误处理机制
在讲解liunx错误处理机制之前我们先来看一段代码: #include<sys/types.h> #include<sys/stat.h> #include<fcntl. ...
- Linux系统编程@进程通信(一)
进程间通信概述 需要进程通信的原因: 数据传输 资源共享 通知事件 进程控制 Linux进程间通信(IPC)发展由来 Unix进程间通信 基于System V进程间通信(System V:UNIX系统 ...
- Linux系统编程【转】
转自:https://blog.csdn.net/majiakun1/article/details/8558308 一.Linux系统编程概论 1.1 系统编程基石 syscall: libc:标准 ...
- linux系统编程之文件与io(一)
经过了漫长的学习,C语言相关的的基础知识算是告一段落了,这也是尝试用写博客的形式来学习c语言,回过头来看,虽说可能写的内容有些比较简单,但是个人感觉是有史起来学习最踏实的一次,因为里面的每个实验都是自 ...
- Linux C 程序 文件操作(Linux系统编程)(14)
文件操作(Linux系统编程) 创建一个目录时,系统会自动创建两个目录.和.. C语言实现权限控制函数 #include<stdio.h> #include<stdlib.h> ...
- linux系统编程之文件与io(五)
上一节中已经学习了文件描述符的复制,复制方法有三种,其中最后一种fcntl还并未使用到,关于这个函数,不光只有复制文件描述符的功能,还有其它一些用法,本节就对其进行一一剖析: fcntl常用操作: 这 ...
- Linux 系统编程 学习:02-进程间通信1:Unix IPC(1)管道
Linux 系统编程 学习:02-进程间通信1:Unix IPC(1)管道 背景 上一讲我们介绍了创建子进程的方式.我们都知道,创建子进程是为了与父进程协作(或者是为了执行新的程序,参考 Linux ...
- Linux 系统编程 学习:03-进程间通信1:Unix IPC(2)信号
Linux 系统编程 学习:03-进程间通信1:Unix IPC(2)信号 背景 上一讲我们介绍了Unix IPC中的2种管道. 回顾一下上一讲的介绍,IPC的方式通常有: Unix IPC包括:管道 ...
随机推荐
- 兼容IE7、IE8、IE9的input type="number"插件
IE11版本好像才兼容input type="number",但是现在Win7版本操作系统下,很多人的IE版本都是IE7/8/9,所以为了体验就自己写了一个小插件,支持设置最大值. ...
- Redis的简介
Redis 简介 Redis 是一个高性能的key-value数据库.支持复杂的数据结构,支持持久化,支持主从集群,支持高可用,支持较大的value存储... Redis是一个nosql,非关系型数据 ...
- DFT
离散傅里叶变换(Discrete Fourier Transform,缩写为DFT),是傅里叶变换在时域和频域上都呈离散的形式, 将信号的时域采样变换为其DTFT的频域采样.在形式上,变换两端(时域和 ...
- Spring框架的JDBC模板技术概述
1. Spring框架中提供了很多持久层的模板类来简化编程,使用模板类编写程序会变的简单 2. 提供了JDBC模板,Spring框架提供的 * JdbcTemplate类 3. Spring框架可以整 ...
- C#中发送邮件,包含Html代码 CDO.Message
C#代码: /// <summary> /// 发送邮件 /// </summary> /// <param name="context">&l ...
- php调用C#写的dll包
1.转到需要注册的dll路径下 2.输入regasm命令+文件名 3问题解决
- sklearn 算法大全
http://scikit-learn.org/stable/tutorial/machine_learning_map/
- 2018.09.08 NOIP模拟eat(贪心)
签到水题啊... 这题完全跟图论没有关系. 显然如果确定了哪些点会被选之后顺序已经不重要了.于是我们给点按权值排序贪心从大向小选. 我们要求的显然就是∑i(a[i]−(n−i))" role ...
- 2018.08.09洛谷P3959 宝藏(随机化贪心)
传送门 回想起了自己赛场上乱搜的20分. 好吧现在也就是写了一个随机化贪心就水过去了,不得不说随机化贪心大法好. 代码: #include<bits/stdc++.h> using nam ...
- 第七章 介词(La préposition )
法语中的介词是将两个同类或非同类的词连接在一起,把一个句中成分同另一个句子成分联系起来,并表明两者之间关系的词类.介词是一种无词性变化的词类. ★介词的形式 ()简单形式的介词,如: ()复合形式的介 ...