2012-02-14 wcdj Happy Valentine's Day !
出错处理
—— 查看 errno,在定位错误信息的时候很有用
当UNIX函数出错时,常常返回一个负值,而且整形变量 errno 通常被设置为含有附加信息的一个值。(注意,不是所有情况都是)
在文件<errno.h>中定义了符号errno以及可以赋予它的各种常量,这些常量都以字符 E 开头。
注意:
(1) 通过 man 3 errno,查看错误常量的具体信息。
(2) The <errno.h> header file defines the integer variable errno, which is set by system calls and some library functions in the event of an error to indicate what went wrong.
(3) 如果调用没有出错,errno的值不会被清除,因此,仅当函数的返回值表明出错时,才应该检验其值。
(4) Valid error numbers are all non-zero; errno is never set to zero by any library function. 任一函数都不会将errno值设置为0,在<errno.h>中定义的所有错误常量都不为0。
(5) errno is defined by the ISO C standard to be a modifiable lvalue of type int, and must not be explicitly declared; errno由系统定义,不可以再重新定义。
(6) errno is thread-local; setting it in one thread does not affect its value in any other thread. 在支持线程的环境中,多个线程共享进程地址空间,每个线程都有属于它自己的局部errno,以避免一个线程干扰另一个线程。
(7) It was common in traditional C to declare errno manually (i.e., extern int errno) instead of including <errno.h>. Do not do this. It will not work with modern versions of hte C library. However, on (very) old Unix systems, there may be no <errno.h> and the declaration is needed. 在现代编译器中,应该显示声明头文件,否则可能会提示找不到 errno 标识。
查看错误码具体信息的简单方法:
方法1:
find /usr/include -name "errno.h" | xargs grep 115 查看错误码信息
方法2:
man perror
perror - explain error codes
例如:
$ perror 2
OS error code 2: No such file or directory
在写程序时,C标准 定义了两个函数,用于打印出错信息:
char *strerror(int errnum); More
void perror(const char *s); More
说明
(1) #include <string.h>,返回指向消息字符串的指针。strerror函数将errnum(通常就是errno值)映射为一个出错信息字符串,并且返回此字符串的指针。(可以用于自己的日志函数)
(2) #include <stdio.h> ,perror函数基于errno的当前值,在标准出错上产生一条出错消息,然后返回。它首先输出由s指向的字符串(用户自己定义的信息),然后是一个冒号,一个空格,接着是对应于errno值的错误信息,最后是一个换行符。(仅用于标准输出)
下面显示errno对应的错误信息:
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void fred(int error_number)
{
fprintf(stderr, "%3d ", error_number);
errno = error_number;
perror("test");
}/*fred()*/
int main(void)
{
int socket1;
int socket2;
int the_error;
struct timeval tv;
for(the_error = 0;
the_error <= 127;
the_error++
)
{
fred(the_error);
}
fprintf(stderr, "==== about to find EDOM\n");
fred(EDOM);
fprintf(stderr, "==== about to do socket stuff\n");
socket1 = socket(AF_INET,
SOCK_STREAM,
IPPROTO_TCP
);
if(socket1 < 0)
{
perror("first socket()");
exit(1);
}
socket2 = socket(AF_INET,
SOCK_STREAM,
IPPROTO_TCP
);
if(socket2 < 0)
{
perror("second socket()");
exit(1);
}
tv.tv_sec = 0;
//tv.tv_usec = 1000000;
tv.tv_usec = 999999;
if(setsockopt(socket1,
SOL_SOCKET,
SO_RCVTIMEO,
&tv,
sizeof(tv)
)
< 0
)
{
perror("first setsockopt()");
}
else
{
fprintf(stderr, "first setsockopt() worked\n");
}
tv.tv_sec = 1;
tv.tv_usec = 0;
if(setsockopt(socket2,
SOL_SOCKET,
SO_RCVTIMEO,
&tv,
sizeof(tv)
)
< 0
)
{
perror("second setsockopt()");
}
else
{
fprintf(stderr, "second setsockopt() worked\n");
}
return 0;
}/*main()*/
output:
0 test: Success
1 test: Operation not permitted
2 test: No such file or directory
3 test: No such process
4 test: Interrupted system call
5 test: Input/output error
6 test: No such device or address
7 test: Argument list too long
8 test: Exec format error
9 test: Bad file descriptor
10 test: No child processes
11 test: Resource temporarily unavailable
12 test: Cannot allocate memory
13 test: Permission denied
14 test: Bad address
15 test: Block device required
16 test: Device or resource busy
17 test: File exists
18 test: Invalid cross-device link
19 test: No such device
20 test: Not a directory
21 test: Is a directory
22 test: Invalid argument
23 test: Too many open files in system
24 test: Too many open files
25 test: Inappropriate ioctl for device
26 test: Text file busy
27 test: File too large
28 test: No space left on device
29 test: Illegal seek
30 test: Read-only file system
31 test: Too many links
32 test: Broken pipe
33 test: Numerical argument out of domain
34 test: Numerical result out of range
35 test: Resource deadlock avoided
36 test: File name too long
37 test: No locks available
38 test: Function not implemented
39 test: Directory not empty
40 test: Too many levels of symbolic links
41 test: Unknown error 41
42 test: No message of desired type
43 test: Identifier removed
44 test: Channel number out of range
45 test: Level 2 not synchronized
46 test: Level 3 halted
47 test: Level 3 reset
48 test: Link number out of range
49 test: Protocol driver not attached
50 test: No CSI structure available
51 test: Level 2 halted
52 test: Invalid exchange
53 test: Invalid request descriptor
54 test: Exchange full
55 test: No anode
56 test: Invalid request code
57 test: Invalid slot
58 test: Unknown error 58
59 test: Bad font file format
60 test: Device not a stream
61 test: No data available
62 test: Timer expired
63 test: Out of streams resources
64 test: Machine is not on the network
65 test: Package not installed
66 test: Object is remote
67 test: Link has been severed
68 test: Advertise error
69 test: Srmount error
70 test: Communication error on send
71 test: Protocol error
72 test: Multihop attempted
73 test: RFS specific error
74 test: Bad message
75 test: Value too large for defined data type
76 test: Name not unique on network
77 test: File descriptor in bad state
78 test: Remote address changed
79 test: Can not access a needed shared library
80 test: Accessing a corrupted shared library
81 test: .lib section in a.out corrupted
82 test: Attempting to link in too many shared libraries
83 test: Cannot exec a shared library directly
84 test: Invalid or incomplete multibyte or wide character
85 test: Interrupted system call should be restarted
86 test: Streams pipe error
87 test: Too many users
88 test: Socket operation on non-socket
89 test: Destination address required
90 test: Message too long
91 test: Protocol wrong type for socket
92 test: Protocol not available
93 test: Protocol not supported
94 test: Socket type not supported
95 test: Operation not supported
96 test: Protocol family not supported
97 test: Address family not supported by protocol
98 test: Address already in use
99 test: Cannot assign requested address
100 test: Network is down
101 test: Network is unreachable
102 test: Network dropped connection on reset
103 test: Software caused connection abort
104 test: Connection reset by peer
105 test: No buffer space available
106 test: Transport endpoint is already connected
107 test: Transport endpoint is not connected
108 test: Cannot send after transport endpoint shutdown
109 test: Too many references: cannot splice
110 test: Connection timed out
111 test: Connection refused
112 test: Host is down
113 test: No route to host
114 test: Operation already in progress
115 test: Operation now in progress
116 test: Stale NFS file handle
117 test: Structure needs cleaning
118 test: Not a XENIX named type file
119 test: No XENIX semaphores available
120 test: Is a named type file
121 test: Remote I/O error
122 test: Disk quota exceeded
123 test: No medium found
124 test: Wrong medium type
125 test: Operation canceled
126 test: Required key not available
127 test: Key has expired
==== about to find EDOM
33 test: Numerical argument out of domain
==== about to do socket stuff
first setsockopt() worked
second setsockopt() worked