关于errno的后事妥善处理

在这里插入图片描述

前言

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

文件==<errno.h>==中定义了符号errno以及可以赋予的各个常量,这些常量都以字符E开头。例如,若errno等于常量EACESS,这表示产生了权限问题(例如,没有打开所要求文件的足够权限)。
POSIX和ISO C将errno定义为这一一个符号,它扩展成为一个可以修改的整型左值。这可以是包含出错编号的一个整数,或是一个返回出错编号指针的函数。以前使用的定义是:
extern int errno;

但是在支持线程的环境中,多个线程共享进程地址空间,每个线程都有属于自己的局部errno以避免一个线程干扰另一个线程。

对于errno应当知道两条规则。第一条规则:如果没有出错,则其值不会被一个例程清除。因此,仅当函数返回指明出错时,才检验其值。第二条:任何一个函数都不会将errno值设置为0,在<errno.h>中定义的所有常量都不为0。

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

#include <string.h>
char *strerror(int errnum);

  
 
  • 1
  • 2

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

perror函数基于errno的当前值,在标准错误上产生一条出错信息,

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

  
 
  • 1
  • 2
  • 3

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

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

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

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

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

栗子

对于中断的read、write系 统调用,POSIX.I的语 义在该标准的2001版有所改变。对于如何处理已read、write部分数据量的相应系统调用,早期版本允许实现进行选择。如若read系统调用已接收并传送数据至应用程序缓冲区,但尚未接收到应用程序请求的全部数据,此时被中断、操作系统可以认为该系统调用失败、并将errno设置为EINTR;另一种处理方式是允许该系统调用成功返回,返回已接收到的部分数据量。与此类似,如若write巳传输了应用程序缓冲区中的部分数据,然后被中断,操作系统可以认为该系统调用失败,并将ermo设置为EINTR;另一种处理方式是允许该系统调用成功返回,返回已写的部分数据量。历史上,从系统V派生的实现,将这种系统调用视为失败,而BSD派生的实现则处理为部分成功返回。POSIX.1 标准的2001版采用BSD风格的语义。

假定一个读操作,它被中断,我们要恢复它:

again:
if(n= read(fd, buf, BUFSIZE)) < 0)
	if (errno == EINTR)
		goto again;/* just an interrupted system call * /
/* handle other errors */


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

errno表

其实看不看这个表意义不大,但是有的人他就是想看,那我就贴一份吧。

查看系统中所有的errno所代表的含义,可以采用如下的代码:

/* Function: obtain the errno string
*   char *strerror(int errno)
*/

#include <stdio.h>
#include <string.h> //for strerror()
//#include <errno.h>
int main()
{ int tmp = 0; for(tmp = 0; tmp <=256; tmp++) { printf("errno: %2d\t%s\n",tmp,strerror(tmp)); } return 0;
}

输出信息如下:

errno:  0 Success
errno:  1 Operation not permitted
errno:  2 No such file or directory
errno:  3 No such process
errno:  4 Interrupted system call
errno:  5 Input/output error
errno:  6 No such device or address
errno:  7 Argument list too long
errno:  8 Exec format error
errno:  9 Bad file descriptor
errno: 10 No child processes
errno: 11 Resource temporarily unavailable
errno: 12 Cannot allocate memory
errno: 13 Permission denied
errno: 14 Bad address
errno: 15 Block device required
errno: 16 Device or resource busy
errno: 17 File exists
errno: 18 Invalid cross-device link
errno: 19 No such device
errno: 20 Not a directory
errno: 21 Is a directory
errno: 22 Invalid argument
errno: 23 Too many open files in system
errno: 24 Too many open files
errno: 25 Inappropriate ioctl for device
errno: 26 Text file busy
errno: 27 File too large
errno: 28 No space left on device
errno: 29 Illegal seek
errno: 30 Read-only file system
errno: 31 Too many links
errno: 32 Broken pipe
errno: 33 Numerical argument out of domain
errno: 34 Numerical result out of range
errno: 35 Resource deadlock avoided
errno: 36 File name too long
errno: 37 No locks available
errno: 38 Function not implemented
errno: 39 Directory not empty
errno: 40 Too many levels of symbolic links
errno: 41 Unknown error 41
errno: 42 No message of desired type
errno: 43 Identifier removed
errno: 44 Channel number out of range
errno: 45 Level 2 not synchronized
errno: 46 Level 3 halted
errno: 47 Level 3 reset
errno: 48 Link number out of range
errno: 49 Protocol driver not attached
errno: 50 No CSI structure available
errno: 51 Level 2 halted
errno: 52 Invalid exchange
errno: 53 Invalid request descriptor
errno: 54 Exchange full
errno: 55 No anode
errno: 56 Invalid request code
errno: 57 Invalid slot
errno: 58 Unknown error 58
errno: 59 Bad font file format
errno: 60 Device not a stream
errno: 61 No data available
errno: 62 Timer expired
errno: 63 Out of streams resources
errno: 64 Machine is not on the network
errno: 65 Package not installed
errno: 66 Object is remote
errno: 67 Link has been severed
errno: 68 Advertise error
errno: 69 Srmount error
errno: 70 Communication error on send
errno: 71 Protocol error
errno: 72 Multihop attempted
errno: 73 RFS specific error
errno: 74 Bad message
errno: 75 Value too large for defined data type
errno: 76 Name not unique on network
errno: 77 File descriptor in bad state
errno: 78 Remote address changed
errno: 79 Can not access a needed shared library
errno: 80 Accessing a corrupted shared library
errno: 81 .lib section in a.out corrupted
errno: 82 Attempting to link in too many shared libraries
errno: 83 Cannot exec a shared library directly
errno: 84 Invalid or incomplete multibyte or wide character
errno: 85 Interrupted system call should be restarted
errno: 86 Streams pipe error
errno: 87 Too many users
errno: 88 Socket operation on non-socket
errno: 89 Destination address required
errno: 90 Message too long
errno: 91 Protocol wrong type for socket
errno: 92 Protocol not available
errno: 93 Protocol not supported
errno: 94 Socket type not supported
errno: 95 Operation not supported
errno: 96 Protocol family not supported
errno: 97 Address family not supported by protocol
errno: 98 Address already in use
errno: 99 Cannot assign requested address
errno: 100 Network is down
errno: 101 Network is unreachable
errno: 102 Network dropped connection on reset
errno: 103 Software caused connection abort
errno: 104 Connection reset by peer
errno: 105 No buffer space available
errno: 106 Transport endpoint is already connected
errno: 107 Transport endpoint is not connected
errno: 108 Cannot send after transport endpoint shutdown
errno: 109 Too many references: cannot splice
errno: 110 Connection timed out
errno: 111 Connection refused
errno: 112 Host is down
errno: 113 No route to host
errno: 114 Operation already in progress
errno: 115 Operation now in progress
errno: 116 Stale file handle
errno: 117 Structure needs cleaning
errno: 118 Not a XENIX named type file
errno: 119 No XENIX semaphores available
errno: 120 Is a named type file
errno: 121 Remote I/O error
errno: 122 Disk quota exceeded
errno: 123 No medium found
errno: 124 Wrong medium type
errno: 125 Operation canceled
errno: 126 Required key not available
errno: 127 Key has expired
errno: 128 Key has been revoked
errno: 129 Key was rejected by service
errno: 130 Owner died
errno: 131 State not recoverable
errno: 132 Operation not possible due to RF-kill
errno: 133 Memory page has hardware error
errno: 134~255  unknown error!

Linux中,在头文件 /usr/include/asm-generic/errno-base.h 对基础常用errno进行了宏定义:

#ifndef _ASM_GENERIC_ERRNO_BASE_H
#define _ASM_GENERIC_ERRNO_BASE_H

#define EPERM 1  /* Operation not permitted */
#define ENOENT 2  /* No such file or directory */
#define ESRCH 3  /* No such process */
#define EINTR 4  /* Interrupted system call */
#define EIO 5  /* I/O error */
#define ENXIO 6  /* No such device or address */
#define E2BIG 7  /* Argument list too long */
#define ENOEXEC 8  /* Exec format error */
#define EBADF 9  /* Bad file number */
#define ECHILD 10  /* No child processes */
#define EAGAIN 11  /* Try again */
#define ENOMEM 12  /* Out of memory */
#define EACCES 13  /* Permission denied */
#define EFAULT 14  /* Bad address */
#define ENOTBLK 15  /* Block device required */
#define EBUSY 16  /* Device or resource busy */
#define EEXIST 17  /* File exists */
#define EXDEV 18  /* Cross-device link */
#define ENODEV 19  /* No such device */
#define ENOTDIR 20  /* Not a directory */
#define EISDIR 21  /* Is a directory */
#define EINVAL 22  /* Invalid argument */
#define ENFILE 23  /* File table overflow */
#define EMFILE 24  /* Too many open files */
#define ENOTTY 25  /* Not a typewriter */
#define ETXTBSY 26  /* Text file busy */
#define EFBIG 27  /* File too large */
#define ENOSPC 28  /* No space left on device */
#define ESPIPE 29  /* Illegal seek */
#define EROFS 30  /* Read-only file system */
#define EMLINK 31  /* Too many links */
#define EPIPE 32  /* Broken pipe */
#define EDOM 33  /* Math argument out of domain of func */
#define ERANGE 34  /* Math result not representable */

#endif/usr/include/asm-asm-generic/errno.h 中,对剩余的errno做了宏定义:

#ifndef _ASM_GENERIC_ERRNO_H
#define _ASM_GENERIC_ERRNO_H

#include <asm-generic/errno-base.h>

#define EDEADLK 35  /* Resource deadlock would occur */
#define ENAMETOOLONG 36  /* File name too long */
#define ENOLCK 37  /* No record locks available */
#define ENOSYS 38  /* Function not implemented */
#define ENOTEMPTY   39  /* Directory not empty */
#define ELOOP 40  /* Too many symbolic links encountered */
#define EWOULDBLOCK EAGAIN  /* Operation would block */
#define ENOMSG 42  /* No message of desired type */
#define EIDRM 43  /* Identifier removed */
#define ECHRNG 44  /* Channel number out of range */
#define EL2NSYNC 45  /* Level 2 not synchronized */
#define EL3HLT 46  /* Level 3 halted */
#define EL3RST 47  /* Level 3 reset */
#define ELNRNG 48  /* Link number out of range */
#define EUNATCH 49  /* Protocol driver not attached */
#define ENOCSI 50  /* No CSI structure available */
#define EL2HLT 51  /* Level 2 halted */
#define EBADE 52  /* Invalid exchange */
#define EBADR 53  /* Invalid request descriptor */
#define EXFULL 54  /* Exchange full */
#define ENOANO 55  /* No anode */
#define EBADRQC 56  /* Invalid request code */
#define EBADSLT 57  /* Invalid slot */

#define EDEADLOCK   EDEADLK

#define EBFONT 59  /* Bad font file format */
#define ENOSTR 60  /* Device not a stream */
#define ENODATA 61  /* No data available */
#define ETIME 62  /* Timer expired */
#define ENOSR 63  /* Out of streams resources */
#define ENONET 64  /* Machine is not on the network */
#define ENOPKG 65  /* Package not installed */
#define EREMOTE 66  /* Object is remote */
#define ENOLINK 67  /* Link has been severed */
#define EADV 68  /* Advertise error */
#define ESRMNT 69  /* Srmount error */
#define ECOMM 70  /* Communication error on send */
#define EPROTO 71  /* Protocol error */
#define EMULTIHOP   72  /* Multihop attempted */
#define EDOTDOT 73  /* RFS specific error */
#define EBADMSG 74  /* Not a data message */
#define EOVERFLOW   75  /* Value too large for defined data type */
#define ENOTUNIQ 76  /* Name not unique on network */
#define EBADFD 77  /* File descriptor in bad state */
#define EREMCHG 78  /* Remote address changed */
#define ELIBACC 79  /* Can not access a needed shared library */
#define ELIBBAD 80  /* Accessing a corrupted shared library */
#define ELIBSCN 81  /* .lib section in a.out corrupted */
#define ELIBMAX 82  /* Attempting to link in too many shared libraries */

#define ELIBEXEC 83  /* Cannot exec a shared library directly */
#define EILSEQ 84  /* Illegal byte sequence */
#define ERESTART 85  /* Interrupted system call should be restarted */
#define ESTRPIPE 86  /* Streams pipe error */
#define EUSERS 87  /* Too many users */
#define ENOTSOCK 88  /* Socket operation on non-socket */
#define EDESTADDRREQ 89  /* Destination address required */
#define EMSGSIZE 90  /* Message too long */
#define EPROTOTYPE  91  /* Protocol wrong type for socket */
#define ENOPROTOOPT 92  /* Protocol not available */
#define EPROTONOSUPPORT 93  /* Protocol not supported */
#define ESOCKTNOSUPPORT 94  /* Socket type not supported */
#define EOPNOTSUPP  95  /* Operation not supported on transport endpoint */
#define EPFNOSUPPORT 96  /* Protocol family not supported */
#define EAFNOSUPPORT 97  /* Address family not supported by protocol */
#define EADDRINUSE  98  /* Address already in use */
#define EADDRNOTAVAIL   99  /* Cannot assign requested address */
#define ENETDOWN 100 /* Network is down */
#define ENETUNREACH 101 /* Network is unreachable */
#define ENETRESET   102 /* Network dropped connection because of reset */
#define ECONNABORTED 103 /* Software caused connection abort */
#define ECONNRESET  104 /* Connection reset by peer */
#define ENOBUFS 105 /* No buffer space available */
#define EISCONN 106 /* Transport endpoint is already connected */
#define ENOTCONN 107 /* Transport endpoint is not connected */
#define ESHUTDOWN   108 /* Cannot send after transport endpoint shutdown */
#define ETOOMANYREFS 109 /* Too many references: cannot splice */
#define ETIMEDOUT   110 /* Connection timed out */
#define ECONNREFUSED 111 /* Connection refused */
#define EHOSTDOWN   112 /* Host is down */
#define EHOSTUNREACH 113 /* No route to host */
#define EALREADY 114 /* Operation already in progress */
#define EINPROGRESS 115 /* Operation now in progress */
#define ESTALE 116 /* Stale file handle */
#define EUCLEAN 117 /* Structure needs cleaning */
#define ENOTNAM 118 /* Not a XENIX named type file */
#define ENAVAIL 119 /* No XENIX semaphores available */
#define EISNAM 120 /* Is a named type file */
#define EREMOTEIO   121 /* Remote I/O error */
#define EDQUOT 122 /* Quota exceeded */

#define ENOMEDIUM   123 /* No medium found */
#define EMEDIUMTYPE 124 /* Wrong medium type */
#define ECANCELED   125 /* Operation Canceled */
#define ENOKEY 126 /* Required key not available */
#define EKEYEXPIRED 127 /* Key has expired */
#define EKEYREVOKED 128 /* Key has been revoked */
#define EKEYREJECTED 129 /* Key was rejected by service */

/* for robust mutexes */
#define EOWNERDEAD  130 /* Owner died */
#define ENOTRECOVERABLE 131 /* State not recoverable */

#define ERFKILL 132 /* Operation not possible due to RF-kill */

#define EHWPOISON   133 /* Memory page has hardware error */

#endif

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315

文章来源: lion-wu.blog.csdn.net,作者:看,未来,版权归原作者所有,如需转载,请联系作者。

原文链接:lion-wu.blog.csdn.net/article/details/106684671

(完)