UNIX环境编程学习笔记(1):——出错处理errno
lienhua34
2014 年 8 月 24 日
1. errno变量
文件 <errno.h> 中定义了符号 errno 以及可以赋予它的各种常量,这些常量都是以字符 E 开头。例如,若 errno 等于常量 EACCES,表示产生了权限问题(例如,没有打开所要求文件的足够权限)。
当 UNIX 函数出错时,常常返回一个负值,而且将整型变量 errno 设置成含有附加信息的各个常量。例如,open 函数如果成功执行则返回一个非负文件描述符,如出错则返回 -1。在 open 出错时,有大约 15 种不同的errno 值(文件不存在、权限问题等)。
对于 errno 应该知道两条规则。
规则一:如果没有出错,则errno的值不会被一个例程清除。
因此,仅当函数的返回值指明出错时,才校验 errno 的值。
规则二:任一函数都不会将errno的值设置为0,在<errno.h>中定义的所有常量都不为0.
出错标志 errno 是一个整型数值,这个对于用户提示不够有好。C 标准定义了两个函数,用于帮助打印出错信息。
#include <string.h>
char *strerror(int errnum);
返回值:指向消息字符串的指针
此函数将 errnum(它通常就是 errno 值)映射为一个出错信息字符串,并且返回此字符串的指针。
perror 函数基于 errno 的当前值,在标准出错上产生一条出错信息,然后返回。
#include <stdio.h>
void perror(const char *msg);
它首先输出由 msg 指向的字符串,然后是一个冒号,一个空格,接着是对应于 errno 值的出错信息,最后是一个换行符。
例子:
下面代码展示了这两个出错函数的使用方法。
#include <string.h> #include <stdio.h> #include <errno.h> #include <stdlib.h> int main(int argc, char *argv[]) {fprintf(stderr, "EACCES: %s\n", strerror(EACCES));errno = ENOENT;perror(argv[0]);exit(0); }
编译该程序,生成errno_demo,然后执行它。
lienhua34:demo$ gcc -o errno_demo errno_demo.c lienhua34:demo$ ./errno_demo EACCES: Permission denied ./errno_demo: No such file or directory
2. 打印所有错误信息
C 标准库定义了sys_nerr 用于记录错误信息总个数,下面程序通过循环来打印所有信息。
#include <string.h> #include <stdio.h> #include <errno.h> #include <stdlib.h> int main(int argc, char *argv[]) {int idx = 0;for (idx = 0; idx < sys_nerr; idx++) {printf("Error #%3d: %s\n", idx, strerror(idx));}exit(0); }
编译该程序,生成print_err,然后执行它。
lienhua34:demo$ gcc -o print_err print_err.c lienhua34:demo$ ./print_err Error # 0: Success Error # 1: Operation not permitted Error # 2: No such file or directory Error # 3: No such process Error # 4: Interrupted system call ... Error #133: Unknown error 133 Error #134: Unknown error 134 lienhua34:demo$
3. 多线程扩展
在支持线程的环境中,多个线程共享进程地址空间,每个线程都有属于它自己的局部 errno 以避免一个线程干扰另一个线程。
函数 strerror() 不是线程安全的。因为该函数将 errnum 对应的字符串保存在一个静态的缓冲区中,然后将该缓冲区的指针返回。另一个线程调用 strerror() 就会重新设置静态缓冲区的内容。
4. 出错恢复
可将 <errno.h> 中定义的各种出错分成致命性的和非致命性的两类。对于致命性的错误,无法执行恢复动作,最多只能在用户屏幕上打印出一条出错信息,或者将一条出错信息写入日志文件,然后终止。而对于非致命性的错误,有时可以较妥善地进行处理。
UNIX环境编程学习笔记(1):——出错处理errno相关推荐
- UNIX环境编程学习笔记(19)——进程管理之fork 函数的深入学习
在"进程控制三部曲"中,我们学习到了 fork 是三部曲的第一部,用于创建一个新进程.但是关于 fork 的更深入的一些的东西我们还没有涉及到,例如,fork 创建的新进程与调用进 ...
- UNIX环境编程学习笔记(21)——进程管理之获取进程终止状态的 wait 和 waitpid 函数...
lienhua34 2014-10-12 当一个进程正常或者异常终止时,内核就向其父进程发送 SIGCHLD信号.父进程可以选择忽略该信号,或者提供一个该信号发生时即被调用的函数(信号处理程序).对于 ...
- UNIX环境编程学习笔记(6)——文件I/O之判断文件类型
lienhua34 2014-09-01 1 文件类型 我们平时最常接触的文件类型有普通文件(regular file)和目录(di-rectory file),但是 UNIX 系统提供了多种文件类型 ...
- UNIX环境编程学习笔记(25)——信号处理进阶学习之 sigaction 函数
lienhua34 2014-11-05 sigaction 函数跟 signal 函数一样,用于设置信号处理函数.此函数是用于取代 UNIX 早期版本使用的 signal 函数.UNIX 早期版本的 ...
- UNIX环境编程学习笔记(11)——文件I/O之文件时间以及 utime 函数
lienhua34 2014-09-16 1 文件的时间 每个文件都有三个时间字段,如表 1 所示. 表 1: 文件的三个时间字段 说明 字段 st_atime 文件数据的最后访问时间 st_mtim ...
- 5w字总结 Unix系统编程学习笔记(面试向)(Unix环境高级编程/Unix环境程序设计)
文章目录 一.计算 C语言的数据表示与处理 计算 C语言的基本运算操作 内存表和符号表 类型转换 函数类型的分析 指令 复合指令 句法 函数 函数激活(Activation Record) 函数激活定 ...
- UNIX网络编程学习笔记(代码超详细解析)(持续更新)
1. 其他函数准备 1. TCP 回射服务器程序: str_echo 函数 #include "unp.h"void str_echo(int sockfd) {ssize_t n ...
- 2021版!万字UNIX网络编程学习笔记(套接字篇)
目录 1.一个简单的时间获取服务器的程序 2.套接字篇 2.1 套接字简介 2.2 套接字中常用的函数 2.3 基本TCP套接字编程 2.3.1.socket函数 2.3.2 connect函数 2. ...
- Unix网络编程学习笔记之第11章 名字与地址转换
一. 域名系统(DNS) 1. 简介 DNS主要用于主机名和IP地址之间的映射. 主机名可以是简单的名字ljm,也可以是全限定域名ljm.localdomainbaidu.com等. 2.资源记录 D ...
最新文章
- Microbiome:人类肠道和病原菌的可移动抗性组驱动环境中抗生素抗性增长
- php轮播代码生成器,最简单的Banner轮播左右切换效果代码及实现思路(附带源码)...
- 核函数K(kernel function)
- Node.js 0.8.21 稳定版发布
- linux检测文件名编码,Linux下查看文件编码,文件或文件名编码格式转换 | 缥缈的云...
- 初识Mysql(part6)--我需要知道的4条Mysql语句之利用通配符过滤
- winform TopMost
- 阿里P8亲自讲解!java分布式需要学什么技术
- windows xp 下的putty不能使用小键盘的问题
- eslint vscode 自动格式化_使用 VSCode 的必备三大神器,这才是开发 Vue 的真香解决方案...
- 帝国CMS7.5仿hao123漫画网站模板动态版
- 用计算机模拟宇宙,计算机中的宇宙
- java map用二叉树_HashMap
- java 反射 动态_java实现反射,动态配置
- 关于安装centOS精简版ifconfig无效的问题
- OC_内存管理(二)对象复制、循环引用问题、自动释放池
- jmeter录制脚本(针对谷歌)
- Arduino开发遥控小车(二)基于nRF24L01无线模块实现数据发送和接收
- 常用文件密码破解工具
- 红烧茄子做法--小黄讲解