当UNIX函数出错时,常常会返回一个负值,而且整型变量errno通常被设置为含有附加信息的一个值。例如,open函数如成功执行则返回一个非负文件描述符,如出错则返回-1。在open出错时,有大约15种不同的errno值(文件不存在、权限问题等)。某些函数并不返回负值而是使用另一种约定。例如,返回一个指向对象的指针的大多数函数,在出错时,将返回一个null(或NULL)指针。

  文件<errno.h>中定义了符合errno以及可以赋予它的各种常量,这些常量都以字符E开头。另外,UNIX系统手册第2部分的第1页intro(2)列出了所有这些出错常量。在Linux中,出错常量在errno(3)手册页中列出(可以使用命令man 3 errno查看)。

  POSIX和ISO C将errno定义为这样一个符号,它扩展成为一个可修改的整型左值(lvalue)。这可以是包含出错编号的一个整数,或者是一个返回出错编号指针的函数。以前使用的定义是:

extern int error;

  但是在支持线程的环境中,多个线程共享进程地址空间,每个线程都有属于它自己的局部extern以避免一个线程干扰另一个线程。例如,Linux支持多线程存取errno,将其定义为:

extern int *__errno_location(void);
#define errno (*__errno_locatioin())

  对于errno应该知道两条规则:

  (1)如果没有出错,则其值不会被一个例程清除。因此,仅当函数的返回值指明出错时,才检验其值。

  (2)任一函数都不会将errno值设置为0,在<errno.h>中定义的所有常量都不为0。

  C标准定义了两个函数,它们帮助打印出错信息:

#include <string.h>
char *strerror(int errnum);
返回值:指向消息字符串的指针

  此函数将errnum(它通常是errno的值)映射为一个出错信息字符串,并且返回此字符串的指针。

  perror函数基于errno的当前值,在标准出错上产生一条出错消息,然后返回。

#include <stdio.h>
void perror(const char *msg);

  它首先输出由msg指向的字符串,然后是一个冒号,一个空格,接着是对应于errno值的出错信息,最后是一个换行符。

  程序清单1-6 示例strerror和perror

[root@localhost unix_env_advance_prog]# cat prog1-.c
#include "apue.h"
#include <errno.h> int
main(int arg, char *argv[])
{
fprintf(stderr, "EACCES: %s\n", strerror(EACCES));
errno = ENOENT;
perror(argv[]);
exit();
}

  编译后执行此程序:

[root@localhost unix_env_advance_prog]# ./prog1-
EACCES: Permission denied
./prog1-: No such file or directory

  注意:我们将程序名(argv[0],其值是./prog1-6)作为参数传递给perror。这是一个标准的UNIX惯例。使用这种方法,在程序作为管道线的一部分执行时,例如:

prog1 < inputfile | prog2 | prog3 >outputifle

  我们就能分清三个程序中的哪一个产生了一条特定的出错信息。

出错恢复

  可将在<errno.h>中定义的各种出错分成致命性的和非致命性的两类。对于致命性的错误,无法执行恢复动作,最多只能在用户屏幕上打印出一条出错消息,或者将一条出错消息写入日志文件中,然后终止。而对于非致命性的出错,有时可以较妥善地进行处理。大多数非致命性错误在本质上是暂时的,例如资源短缺,当系统中的活动较少时,这种出错很可能不会发生。

  与资源相关的非致命性出错包括EAGAIN、ENFILE、ENOBUFS、ENOLCK、ENOSPC、ENOSR、EWOULDBLOCK,有时ENOMEM也是非致命性出错。当EBUSY指明共享资源正在使用时,也可将它作为非致命性出错处理。当EINTR中断一慢速系统调用时,可将它作为非致命性出错处理。

  对于资源相关的非致命性出错,一般恢复动作是延迟一些时间,然后再试。这种技术可应用于其他情况。例如,假设一个出错表明一个网络连接不再起作用,那么应用程序可以在短时间延迟后重建该连接。某些应用使用指数补偿算法,在每次重复中等待更长时间。

  最后,取决于应用程序的开发者,他可以决定哪些出错是可以恢复的。如若使用一种从错误中恢复的合理策略,那么由于避免了应用程序的异常终止,就能改善应用程序的健壮性。

本篇博文内容摘自《UNIX环境高级编程》(第二版),仅作个人学习记录所用。关于本书可参考:http://www.apuebook.com/

UNIX基础知识之出错处理的更多相关文章

  1. UNIX环境高级编程--第一章 UNIX基础知识

    第一章 UNIX基础知识 1.2 UNIX体系结构   从严格意义上说,可将操作系统定义为一种软件,它控制计算机硬件资源,提供程序运行环境.我们将这种软件称为内核(kernel),因为 它相对较小,且 ...

  2. 《UNIX环境高级编程》(APUE) 笔记第一章 - UNIX基础知识

    1 - UNIX基础知识 Github 地址 1. 操作系统 可将操作系统定义为一种软件,它控制计算机硬件资源,提供程序运行环境.通常将这种软件称为 内核 (kernel) .( Linux 是 GN ...

  3. 《UNIX环境高级编程》笔记——1.UNIX基础知识

    这一章节侧重一些基本概念和书中用到的一些名词. 一.引言 所有的操作都提供服务,典型的服务包括:执行新程序.打开文件.读写文件.分配存储区以及获得当前时间等. 二.UNIX体系结构 其实linux常见 ...

  4. UNIX环境高级编程 第1章 UNIX基础知识

    所有操作系统都为运行在它之上的程序提供各种服务,典型的服务包括:执行新程序.打开文件.读写文件.分配存储空间.提供时间等. UNIX体系结构 严格来说,操作系统是一种软件,它控制计算机硬件资源,提供程 ...

  5. 第一章:UNIX基础知识

    本章内容主要是为了学习UNIX的基本知识和一些最基本的系统函数. 学习的关键就是跟随者书本敲代码.本节遇到的第一个问题就死本书的apue.h这个文件:一开始没有注意这个文件,盲目的去百度,一番百度之后 ...

  6. UNIX基础知识之程序和进程

    一.程序 程序(program)是存放在磁盘上.处于某个目录中的一个可执行文件.使用6个exec函数中的一个由内核将程序读入存储器,并使其执行. 二.进程和进程ID 程序的执行实例被称为进程(proc ...

  7. apue- chapter 1 UNIX基础知识

    1.C++实现ls命令 #include<dirent.h> #include<stdlib.h> #include<iostream> #include &quo ...

  8. UNIX 基础知识

    登陆       1.登录名            系统在其 口令文件(通常是/etc/passwd文件) 中查看用户名,口令文件中包含了有关用户的信息.       2.shell          ...

  9. APUE(1)----UNIX基础知识

    一.UNIX体系结构 所有操作系统都为他们所运行的程序提供服务,典型的服务包括:执行新程序.打开文件.读文件.分配存储区等.严格意义上来说,操作系统可以定义为一种软件,它控制计算机硬件资源,提供程序运 ...

随机推荐

  1. codeforces 679A Bear and Prime 100 交互

    第一次交互题,记录一下吧 #include <cstdio> #include <iostream> #include <ctime> #include <v ...

  2. [GRYZ2015]工业时代

    试题描述 小FF的第一片矿区已经开始运作了, 他着手开展第二片矿区……小FF的第二片矿区, 也是”NewBe_One“计划的核心部分, 因为在这片矿区里面有全宇宙最稀有的两种矿物,科学家称其为NEW矿 ...

  3. 双nginx(主备、主主)反向代理tomcat实现web端负载均衡

    经过以前做完的产品,受前公司几位前辈技术大拿指点,来自己动手实现并总结一下web端的负载解决方法,高手请略过,个人认知有限,请各位指正错误. 下面是结构图: 我的系统环境是Fedora22(适用rea ...

  4. AtCoder Grand Contest 001

    B - Mysterious Light 题意:从一个正三角形边上一点出发,遇到边和已走过的边则反弹,问最终路径长度 思路:GCD 数据爆long long #pragma comment(linke ...

  5. C字符串和C++中string的区别 &amp;&amp;&amp;&amp;C++中int型与string型互相转换

    在C++中则把字符串封装成了一种数据类型string,可以直接声明变量并进行赋值等字符串操作.以下是C字符串和C++中string的区别:   C字符串 string对象(C++) 所需的头文件名称 ...

  6. json字符串转换为JSONObject和JSONArray

    一.下载json 具体到http://www.json.org/上找java-json下载,并把其放到项目源代码中,这样就可以引用其类对象了 二.具体转化过程 //JSONObject String ...

  7. discuz论坛apache日志hadoop大数据分析项目:清洗数据核心功能解说及代码实现

    discuz论坛apache日志hadoop大数据分析项目:清洗数据核心功能解说及代码实现http://www.aboutyun.com/thread-8637-1-1.html(出处: about云 ...

  8. Distributed Sentence Similarity Base on Word Mover's Distance

    Algorithm: Refrence from one ICML15 paper: Word Mover's Distance. 1. First use Google's word2vec too ...

  9. SCAU 07校赛 10317 Fans of Footbal Teams

    10317 Fans of Footbal Teams 时间限制:1000MS  内存限制:65535K 题型: 编程题   语言: 无限制 Description Two famous footba ...

  10. linux下开发c第一弹--相关环境需求

    我用的是mac,mac和linux一般集成了一定的开发环境,基本上需要gcc.vim.gdb之类的,linux下需要apt-get,mac下homebrew的brew install都可以解决问题.同 ...