偶尔(例如使用strace,gdb等等)人们会发现一个POSIX调用集errno是一个整数值,而一个人想知道编译时间C常数(更准确地是由预处理器定义)来检查它(例如ECHILD)-参见例如等待子进程的pid没有成功。
上面链接的问题中的EG,在10中返回了整数错误号errno。我想从那儿回到琴弦上ECHILD。不给我什么perror或strerror给我什么(“没有子进程”或类似的东西)。
这是这样做的明显方法,该方法不起作用:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int
main (int argc, char **argv)
{
printf ("%s\n", strerror (10));
exit (0);
}
Run Code Online (Sandbox Code Playgroud)
打印输出:
No child processes
Run Code Online (Sandbox Code Playgroud)
不是ECHILD,因此不执行所需的操作。
有什么比手动grep完成更简单的方法/usr/include吗?
您可能认为重复的事物,但并非如此:
如何将UNIX中的errno转换为相应的字符串?-说strerror(很明显)将整数转换为人类可读的字符串,并perror打印出来。我不想那样做。我想打印符号等效项,即可以用来测试的预处理器定义errno。
Linux,将errno转换为name-更接近,但正在寻找API调用。显然,其中没有一个。接受的答案还错误地指出了错误所在errno.h-在我的系统中,错误分散在多个文件之间,使搜索更有趣。如何在C中打印errno的符号名称?类似。
适当的答案可能涉及一些魔术,以预处理的适当部分/usr/include并显示E以适当值开头的任何常数。
您可以直接调用 C 预处理器。对于 GCC 工具链,预处理器可执行文件是cpp.
(编辑:我意识到你特别提到了 POSIX,这个例子是特定于 GCC 的,但也许这是一个开始)
这是我针对您的情况提出的示例:
$ cpp -dM -include /usr/include/errno.h | grep '^#define E' | sed 's/^#define \(E[A-Z0-9]*\)\s*\(.*\)$/\2 \1/g' | sort -n
EAGAIN EWOULDBLOCK
EDEADLK EDEADLOCK
EOPNOTSUPP ENOTSUP
1 EPERM
2 ENOENT
3 ESRCH
4 EINTR
5 EIO
6 ENXIO
7 E2BIG
8 ENOEXEC
9 EBADF
10 ECHILD
11 EAGAIN
12 ENOMEM
13 EACCES
14 EFAULT
15 ENOTBLK
16 EBUSY
17 EEXIST
18 EXDEV
19 ENODEV
20 ENOTDIR
21 EISDIR
22 EINVAL
23 ENFILE
24 EMFILE
25 ENOTTY
26 ETXTBSY
27 EFBIG
28 ENOSPC
29 ESPIPE
30 EROFS
31 EMLINK
32 EPIPE
33 EDOM
34 ERANGE
35 EDEADLK
36 ENAMETOOLONG
37 ENOLCK
38 ENOSYS
39 ENOTEMPTY
40 ELOOP
42 ENOMSG
43 EIDRM
44 ECHRNG
45 EL2NSYNC
46 EL3HLT
47 EL3RST
48 ELNRNG
49 EUNATCH
50 ENOCSI
51 EL2HLT
52 EBADE
53 EBADR
54 EXFULL
55 ENOANO
56 EBADRQC
57 EBADSLT
59 EBFONT
60 ENOSTR
61 ENODATA
62 ETIME
63 ENOSR
64 ENONET
65 ENOPKG
66 EREMOTE
67 ENOLINK
68 EADV
69 ESRMNT
70 ECOMM
71 EPROTO
72 EMULTIHOP
73 EDOTDOT
74 EBADMSG
75 EOVERFLOW
76 ENOTUNIQ
77 EBADFD
78 EREMCHG
79 ELIBACC
80 ELIBBAD
81 ELIBSCN
82 ELIBMAX
83 ELIBEXEC
84 EILSEQ
85 ERESTART
86 ESTRPIPE
87 EUSERS
88 ENOTSOCK
89 EDESTADDRREQ
90 EMSGSIZE
91 EPROTOTYPE
92 ENOPROTOOPT
93 EPROTONOSUPPORT
94 ESOCKTNOSUPPORT
95 EOPNOTSUPP
96 EPFNOSUPPORT
97 EAFNOSUPPORT
98 EADDRINUSE
99 EADDRNOTAVAIL
100 ENETDOWN
101 ENETUNREACH
102 ENETRESET
103 ECONNABORTED
104 ECONNRESET
105 ENOBUFS
106 EISCONN
107 ENOTCONN
108 ESHUTDOWN
109 ETOOMANYREFS
110 ETIMEDOUT
111 ECONNREFUSED
112 EHOSTDOWN
113 EHOSTUNREACH
114 EALREADY
115 EINPROGRESS
116 ESTALE
117 EUCLEAN
118 ENOTNAM
119 ENAVAIL
120 EISNAM
121 EREMOTEIO
122 EDQUOT
123 ENOMEDIUM
124 EMEDIUMTYPE
125 ECANCELED
126 ENOKEY
127 EKEYEXPIRED
128 EKEYREVOKED
129 EKEYREJECTED
130 EOWNERDEAD
131 ENOTRECOVERABLE
132 ERFKILL
133 EHWPOISON
Run Code Online (Sandbox Code Playgroud)
有几点需要注意:
#include-ed(直接或间接)中还有其他宏定义,那么这可能grep '^#define E'不足以errno从cpp命令的输出中过滤掉所需的定义。这绝不是这种方法可能失败的唯一方式。#define EWOULDBLOCK EAGAIN,其中一个Exxxx值被定义为另一个先前定义的值的同义词。有了这些免责声明,应该可以使用这种方法作为脚本的基础(然后你可以选择从你的 Makefile 中调用它)来自动生成一个查找表(例如,errno-lookup.c)并在你的获取任何给定errno值的关联符号的代码。
小智 -1
#ifndef NDEBUG
fprintf(stderr, "Line %d: Error value: %d\n", __LINE__, errno);
#endif
Run Code Online (Sandbox Code Playgroud)
然后在调试器中查找打印值。