perror, strerror 显示errno对应的字符串错误信息

114 篇文章 1 订阅

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




  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值