偶尔(例如使用strace
,gdb
等)发现POSIX调用将errno
设置为整数值,并且想知道编译时间C常量(更准确地说是-processor define)检查它(例如ECHILD
) - 参见eg waitpid for child process not succeeding
在上述链接问题中,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);
}
打印输出:
No child processes
不是ECHILD
,因此没有做到要求。
除了手动grep
到/usr/include
之外,还有更简单的方法吗?
你可能认为重复但不是:
How to convert errno in UNIX to corresponding string? - 说strerror
(显然)将整数转换为人类可读的字符串,perror
打印出来。我不想那样做。我想打印符号等效项,即可用于测试errno
的预处理器定义。
Linux, convert errno to name - 更接近,但正在寻找API调用。显然没有其中之一。接受的答案也错误地指出错误在errno.h
中 - 在我的系统中,它们分布在多个文件中,使搜索更有趣。 How can I print the symbolic name of an errno in C?类似。
适当的答案可能需要一些魔法来预处理/usr/include
的适当部分,并以E
开头显示任何具有适当值的常量。
答案 0 :(得分:4)
您可以直接调用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
有几点需要注意:
#include
- ed(直接或间接)中,那么grep '^#define E'
可能不是足以从errno
命令的输出中过滤出所需的cpp
定义。而这绝不是这种方法可能失败的唯一方式。#define EWOULDBLOCK EAGAIN
,其中一个Exxxx
值被定义为另一个先前定义的值的同义词。将这些免责声明排除在外,应该可以使用此方法作为脚本的基础(然后您可以选择从Makefile中调用)以自动生成查找表(例如,{{1} })并在代码中引用此表以获取任何给定errno-lookup.c
值的关联符号。
答案 1 :(得分:2)
我最近写了一个the errnoname
library,它具有一个errnoname
函数,可以完成此操作。
因此,您可以从问题#include "errnoname.h"
中获取示例程序,只需将strerror
替换为errnoname
,然后用errnoname.c
进行编译/链接。
正如其他答案所表明的那样,errnoname
函数本身并没有什么困难或复杂之处,手工实现以确保包括所有errno
名称真的很繁琐,并且所有的小箱子都可以处理。
示例:
EWOULDBLOCK
等于EAGAIN
之类的对,在某些系统上具有相同的值,在其他系统上具有不同的值,并且errno
的名称根本不能保证是连续的(因此,为什么我建议将其实现为switch语句而不是数组),因为在某些罕见的或将来的系统中,它可能是一个非常非常低效的大型数组,其中包含很多未使用的条目(即使它可以编译)。无论如何,由于它是根据“零条款BSD许可证”(0BSD)发行的,该许可证是许可的许可证,或更准确地说是等效于公共域的许可证,因此您可以使用它进行任何操作。
下面是我库中函数的直接复制粘贴,因此该答案可以单独使用。几个注意事项:
从开始之初,它涵盖了我可以在Linux,Darwin(Mac OS X和iOS X),FreeBSD,NetBSD,OpenBSD,DragonflyBSD和几个封闭源Unixes上找到的所有errno
名称。 2019年8月。
如果您给它提供一个NULL
值(它不知道其名称),它将返回一个errno
指针。
#include <errno.h>
char const * errnoname(int errno_)
{
switch(errno_)
{
#ifdef E2BIG
case E2BIG: return "E2BIG";
#endif
#ifdef EACCES
case EACCES: return "EACCES";
#endif
#ifdef EADDRINUSE
case EADDRINUSE: return "EADDRINUSE";
#endif
#ifdef EADDRNOTAVAIL
case EADDRNOTAVAIL: return "EADDRNOTAVAIL";
#endif
#ifdef EADI
case EADI: return "EADI";
#endif
#ifdef EADV
case EADV: return "EADV";
#endif
#ifdef EAFNOSUPPORT
case EAFNOSUPPORT: return "EAFNOSUPPORT";
#endif
#ifdef EAGAIN
case EAGAIN: return "EAGAIN";
#endif
#ifdef EAIO
case EAIO: return "EAIO";
#endif
#ifdef EALIGN
case EALIGN: return "EALIGN";
#endif
#ifdef EALREADY
case EALREADY: return "EALREADY";
#endif
#ifdef EASYNC
case EASYNC: return "EASYNC";
#endif
#ifdef EAUTH
case EAUTH: return "EAUTH";
#endif
#ifdef EBADARCH
case EBADARCH: return "EBADARCH";
#endif
#ifdef EBADE
case EBADE: return "EBADE";
#endif
#ifdef EBADEXEC
case EBADEXEC: return "EBADEXEC";
#endif
#ifdef EBADF
case EBADF: return "EBADF";
#endif
#ifdef EBADFD
case EBADFD: return "EBADFD";
#endif
#ifdef EBADMACHO
case EBADMACHO: return "EBADMACHO";
#endif
#ifdef EBADMSG
case EBADMSG: return "EBADMSG";
#endif
#ifdef EBADR
case EBADR: return "EBADR";
#endif
#ifdef EBADRPC
case EBADRPC: return "EBADRPC";
#endif
#ifdef EBADRQC
case EBADRQC: return "EBADRQC";
#endif
#ifdef EBADSLT
case EBADSLT: return "EBADSLT";
#endif
#ifdef EBADVER
case EBADVER: return "EBADVER";
#endif
#ifdef EBFONT
case EBFONT: return "EBFONT";
#endif
#ifdef EBUSY
case EBUSY: return "EBUSY";
#endif
#ifdef ECANCELED
case ECANCELED: return "ECANCELED";
#endif
#if defined(ECANCELLED) && (!defined(ECANCELED) || ECANCELLED != ECANCELED)
case ECANCELLED: return "ECANCELLED";
#endif
#ifdef ECAPMODE
case ECAPMODE: return "ECAPMODE";
#endif
#ifdef ECHILD
case ECHILD: return "ECHILD";
#endif
#ifdef ECHRNG
case ECHRNG: return "ECHRNG";
#endif
#ifdef ECKPT
case ECKPT: return "ECKPT";
#endif
#ifdef ECLONEME
case ECLONEME: return "ECLONEME";
#endif
#ifdef ECOMM
case ECOMM: return "ECOMM";
#endif
#ifdef ECONFIG
case ECONFIG: return "ECONFIG";
#endif
#ifdef ECONNABORTED
case ECONNABORTED: return "ECONNABORTED";
#endif
#ifdef ECONNREFUSED
case ECONNREFUSED: return "ECONNREFUSED";
#endif
#ifdef ECONNRESET
case ECONNRESET: return "ECONNRESET";
#endif
#ifdef ECORRUPT
case ECORRUPT: return "ECORRUPT";
#endif
#ifdef ECVCERORR
case ECVCERORR: return "ECVCERORR";
#endif
#ifdef ECVPERORR
case ECVPERORR: return "ECVPERORR";
#endif
#ifdef EDEADLK
case EDEADLK: return "EDEADLK";
#endif
#if defined(EDEADLOCK) && (!defined(EDEADLK) || EDEADLOCK != EDEADLK)
case EDEADLOCK: return "EDEADLOCK";
#endif
#ifdef EDESTADDREQ
case EDESTADDREQ: return "EDESTADDREQ";
#endif
#ifdef EDESTADDRREQ
case EDESTADDRREQ: return "EDESTADDRREQ";
#endif
#ifdef EDEVERR
case EDEVERR: return "EDEVERR";
#endif
#ifdef EDIRIOCTL
case EDIRIOCTL: return "EDIRIOCTL";
#endif
#ifdef EDIRTY
case EDIRTY: return "EDIRTY";
#endif
#ifdef EDIST
case EDIST: return "EDIST";
#endif
#ifdef EDOM
case EDOM: return "EDOM";
#endif
#ifdef EDOOFUS
case EDOOFUS: return "EDOOFUS";
#endif
#ifdef EDOTDOT
case EDOTDOT: return "EDOTDOT";
#endif
#ifdef EDQUOT
case EDQUOT: return "EDQUOT";
#endif
#ifdef EDUPFD
case EDUPFD: return "EDUPFD";
#endif
#ifdef EDUPPKG
case EDUPPKG: return "EDUPPKG";
#endif
#ifdef EEXIST
case EEXIST: return "EEXIST";
#endif
#ifdef EFAIL
case EFAIL: return "EFAIL";
#endif
#ifdef EFAULT
case EFAULT: return "EFAULT";
#endif
#ifdef EFBIG
case EFBIG: return "EFBIG";
#endif
#ifdef EFORMAT
case EFORMAT: return "EFORMAT";
#endif
#ifdef EFSCORRUPTED
case EFSCORRUPTED: return "EFSCORRUPTED";
#endif
#ifdef EFTYPE
case EFTYPE: return "EFTYPE";
#endif
#ifdef EHOSTDOWN
case EHOSTDOWN: return "EHOSTDOWN";
#endif
#ifdef EHOSTUNREACH
case EHOSTUNREACH: return "EHOSTUNREACH";
#endif
#ifdef EHWPOISON
case EHWPOISON: return "EHWPOISON";
#endif
#ifdef EIDRM
case EIDRM: return "EIDRM";
#endif
#ifdef EILSEQ
case EILSEQ: return "EILSEQ";
#endif
#ifdef EINIT
case EINIT: return "EINIT";
#endif
#ifdef EINPROG
case EINPROG: return "EINPROG";
#endif
#ifdef EINPROGRESS
case EINPROGRESS: return "EINPROGRESS";
#endif
#ifdef EINTEGRITY
case EINTEGRITY: return "EINTEGRITY";
#endif
#ifdef EINTR
case EINTR: return "EINTR";
#endif
#ifdef EINVAL
case EINVAL: return "EINVAL";
#endif
#ifdef EIO
case EIO: return "EIO";
#endif
#ifdef EIPSEC
case EIPSEC: return "EIPSEC";
#endif
#ifdef EISCONN
case EISCONN: return "EISCONN";
#endif
#ifdef EISDIR
case EISDIR: return "EISDIR";
#endif
#ifdef EISNAM
case EISNAM: return "EISNAM";
#endif
#ifdef EJUSTRETURN
case EJUSTRETURN: return "EJUSTRETURN";
#endif
#ifdef EKEEPLOOKING
case EKEEPLOOKING: return "EKEEPLOOKING";
#endif
#ifdef EKEYEXPIRED
case EKEYEXPIRED: return "EKEYEXPIRED";
#endif
#ifdef EKEYREJECTED
case EKEYREJECTED: return "EKEYREJECTED";
#endif
#ifdef EKEYREVOKED
case EKEYREVOKED: return "EKEYREVOKED";
#endif
#ifdef EL2HLT
case EL2HLT: return "EL2HLT";
#endif
#ifdef EL2NSYNC
case EL2NSYNC: return "EL2NSYNC";
#endif
#ifdef EL3HLT
case EL3HLT: return "EL3HLT";
#endif
#ifdef EL3RST
case EL3RST: return "EL3RST";
#endif
#ifdef ELIBACC
case ELIBACC: return "ELIBACC";
#endif
#ifdef ELIBBAD
case ELIBBAD: return "ELIBBAD";
#endif
#ifdef ELIBEXEC
case ELIBEXEC: return "ELIBEXEC";
#endif
#ifdef ELIBMAX
case ELIBMAX: return "ELIBMAX";
#endif
#ifdef ELIBSCN
case ELIBSCN: return "ELIBSCN";
#endif
#ifdef ELNRNG
case ELNRNG: return "ELNRNG";
#endif
#ifdef ELOCKUNMAPPED
case ELOCKUNMAPPED: return "ELOCKUNMAPPED";
#endif
#ifdef ELOOP
case ELOOP: return "ELOOP";
#endif
#ifdef EMEDIA
case EMEDIA: return "EMEDIA";
#endif
#ifdef EMEDIUMTYPE
case EMEDIUMTYPE: return "EMEDIUMTYPE";
#endif
#ifdef EMFILE
case EMFILE: return "EMFILE";
#endif
#ifdef EMLINK
case EMLINK: return "EMLINK";
#endif
#ifdef EMOUNTEXIT
case EMOUNTEXIT: return "EMOUNTEXIT";
#endif
#ifdef EMOVEFD
case EMOVEFD: return "EMOVEFD";
#endif
#ifdef EMSGSIZE
case EMSGSIZE: return "EMSGSIZE";
#endif
#ifdef EMTIMERS
case EMTIMERS: return "EMTIMERS";
#endif
#ifdef EMULTIHOP
case EMULTIHOP: return "EMULTIHOP";
#endif
#ifdef ENAMETOOLONG
case ENAMETOOLONG: return "ENAMETOOLONG";
#endif
#ifdef ENAVAIL
case ENAVAIL: return "ENAVAIL";
#endif
#ifdef ENEEDAUTH
case ENEEDAUTH: return "ENEEDAUTH";
#endif
#ifdef ENETDOWN
case ENETDOWN: return "ENETDOWN";
#endif
#ifdef ENETRESET
case ENETRESET: return "ENETRESET";
#endif
#ifdef ENETUNREACH
case ENETUNREACH: return "ENETUNREACH";
#endif
#ifdef ENFILE
case ENFILE: return "ENFILE";
#endif
#ifdef ENFSREMOTE
case ENFSREMOTE: return "ENFSREMOTE";
#endif
#ifdef ENOANO
case ENOANO: return "ENOANO";
#endif
#ifdef ENOATTR
case ENOATTR: return "ENOATTR";
#endif
#ifdef ENOBUFS
case ENOBUFS: return "ENOBUFS";
#endif
#ifdef ENOCONNECT
case ENOCONNECT: return "ENOCONNECT";
#endif
#ifdef ENOCSI
case ENOCSI: return "ENOCSI";
#endif
#ifdef ENODATA
case ENODATA: return "ENODATA";
#endif
#ifdef ENODEV
case ENODEV: return "ENODEV";
#endif
#ifdef ENOENT
case ENOENT: return "ENOENT";
#endif
#ifdef ENOEXEC
case ENOEXEC: return "ENOEXEC";
#endif
#ifdef ENOIOCTL
case ENOIOCTL: return "ENOIOCTL";
#endif
#ifdef ENOKEY
case ENOKEY: return "ENOKEY";
#endif
#ifdef ENOLCK
case ENOLCK: return "ENOLCK";
#endif
#ifdef ENOLINK
case ENOLINK: return "ENOLINK";
#endif
#ifdef ENOLOAD
case ENOLOAD: return "ENOLOAD";
#endif
#ifdef ENOMATCH
case ENOMATCH: return "ENOMATCH";
#endif
#ifdef ENOMEDIUM
case ENOMEDIUM: return "ENOMEDIUM";
#endif
#ifdef ENOMEM
case ENOMEM: return "ENOMEM";
#endif
#ifdef ENOMSG
case ENOMSG: return "ENOMSG";
#endif
#ifdef ENONET
case ENONET: return "ENONET";
#endif
#ifdef ENOPKG
case ENOPKG: return "ENOPKG";
#endif
#ifdef ENOPOLICY
case ENOPOLICY: return "ENOPOLICY";
#endif
#ifdef ENOPROTOOPT
case ENOPROTOOPT: return "ENOPROTOOPT";
#endif
#ifdef ENOREG
case ENOREG: return "ENOREG";
#endif
#ifdef ENOSPC
case ENOSPC: return "ENOSPC";
#endif
#ifdef ENOSR
case ENOSR: return "ENOSR";
#endif
#ifdef ENOSTR
case ENOSTR: return "ENOSTR";
#endif
#ifdef ENOSYM
case ENOSYM: return "ENOSYM";
#endif
#ifdef ENOSYS
case ENOSYS: return "ENOSYS";
#endif
#ifdef ENOTACTIVE
case ENOTACTIVE: return "ENOTACTIVE";
#endif
#ifdef ENOTBLK
case ENOTBLK: return "ENOTBLK";
#endif
#ifdef ENOTCAPABLE
case ENOTCAPABLE: return "ENOTCAPABLE";
#endif
#ifdef ENOTCONN
case ENOTCONN: return "ENOTCONN";
#endif
#ifdef ENOTDIR
case ENOTDIR: return "ENOTDIR";
#endif
#ifdef ENOTEMPTY
case ENOTEMPTY: return "ENOTEMPTY";
#endif
#ifdef ENOTNAM
case ENOTNAM: return "ENOTNAM";
#endif
#ifdef ENOTREADY
case ENOTREADY: return "ENOTREADY";
#endif
#ifdef ENOTRECOVERABLE
case ENOTRECOVERABLE: return "ENOTRECOVERABLE";
#endif
#ifdef ENOTRUST
case ENOTRUST: return "ENOTRUST";
#endif
#ifdef ENOTSOCK
case ENOTSOCK: return "ENOTSOCK";
#endif
#ifdef ENOTSUP
case ENOTSUP: return "ENOTSUP";
#endif
#ifdef ENOTTY
case ENOTTY: return "ENOTTY";
#endif
#ifdef ENOTUNIQ
case ENOTUNIQ: return "ENOTUNIQ";
#endif
#ifdef ENOUNLD
case ENOUNLD: return "ENOUNLD";
#endif
#ifdef ENOUNREG
case ENOUNREG: return "ENOUNREG";
#endif
#ifdef ENXIO
case ENXIO: return "ENXIO";
#endif
#ifdef EOPCOMPLETE
case EOPCOMPLETE: return "EOPCOMPLETE";
#endif
#if defined(EOPNOTSUPP) && (!defined(ENOTSUP) || EOPNOTSUPP != ENOTSUP)
case EOPNOTSUPP: return "EOPNOTSUPP";
#endif
#ifdef EOVERFLOW
case EOVERFLOW: return "EOVERFLOW";
#endif
#ifdef EOWNERDEAD
case EOWNERDEAD: return "EOWNERDEAD";
#endif
#ifdef EPASSTHROUGH
case EPASSTHROUGH: return "EPASSTHROUGH";
#endif
#ifdef EPATHREMOTE
case EPATHREMOTE: return "EPATHREMOTE";
#endif
#ifdef EPERM
case EPERM: return "EPERM";
#endif
#ifdef EPFNOSUPPORT
case EPFNOSUPPORT: return "EPFNOSUPPORT";
#endif
#ifdef EPIPE
case EPIPE: return "EPIPE";
#endif
#ifdef EPOWERF
case EPOWERF: return "EPOWERF";
#endif
#ifdef EPROCLIM
case EPROCLIM: return "EPROCLIM";
#endif
#ifdef EPROCUNAVAIL
case EPROCUNAVAIL: return "EPROCUNAVAIL";
#endif
#ifdef EPROGMISMATCH
case EPROGMISMATCH: return "EPROGMISMATCH";
#endif
#ifdef EPROGUNAVAIL
case EPROGUNAVAIL: return "EPROGUNAVAIL";
#endif
#ifdef EPROTO
case EPROTO: return "EPROTO";
#endif
#ifdef EPROTONOSUPPORT
case EPROTONOSUPPORT: return "EPROTONOSUPPORT";
#endif
#ifdef EPROTOTYPE
case EPROTOTYPE: return "EPROTOTYPE";
#endif
#ifdef EPWROFF
case EPWROFF: return "EPWROFF";
#endif
#ifdef EQFULL
case EQFULL: return "EQFULL";
#endif
#ifdef EQSUSPENDED
case EQSUSPENDED: return "EQSUSPENDED";
#endif
#ifdef ERANGE
case ERANGE: return "ERANGE";
#endif
#ifdef ERECYCLE
case ERECYCLE: return "ERECYCLE";
#endif
#ifdef EREDRIVEOPEN
case EREDRIVEOPEN: return "EREDRIVEOPEN";
#endif
#ifdef EREFUSED
case EREFUSED: return "EREFUSED";
#endif
#ifdef ERELOC
case ERELOC: return "ERELOC";
#endif
#ifdef ERELOCATED
case ERELOCATED: return "ERELOCATED";
#endif
#ifdef ERELOOKUP
case ERELOOKUP: return "ERELOOKUP";
#endif
#ifdef EREMCHG
case EREMCHG: return "EREMCHG";
#endif
#ifdef EREMDEV
case EREMDEV: return "EREMDEV";
#endif
#ifdef EREMOTE
case EREMOTE: return "EREMOTE";
#endif
#ifdef EREMOTEIO
case EREMOTEIO: return "EREMOTEIO";
#endif
#ifdef EREMOTERELEASE
case EREMOTERELEASE: return "EREMOTERELEASE";
#endif
#ifdef ERESTART
case ERESTART: return "ERESTART";
#endif
#ifdef ERFKILL
case ERFKILL: return "ERFKILL";
#endif
#ifdef EROFS
case EROFS: return "EROFS";
#endif
#ifdef ERPCMISMATCH
case ERPCMISMATCH: return "ERPCMISMATCH";
#endif
#ifdef ESAD
case ESAD: return "ESAD";
#endif
#ifdef ESHLIBVERS
case ESHLIBVERS: return "ESHLIBVERS";
#endif
#ifdef ESHUTDOWN
case ESHUTDOWN: return "ESHUTDOWN";
#endif
#ifdef ESOCKTNOSUPPORT
case ESOCKTNOSUPPORT: return "ESOCKTNOSUPPORT";
#endif
#ifdef ESOFT
case ESOFT: return "ESOFT";
#endif
#ifdef ESPIPE
case ESPIPE: return "ESPIPE";
#endif
#ifdef ESRCH
case ESRCH: return "ESRCH";
#endif
#ifdef ESRMNT
case ESRMNT: return "ESRMNT";
#endif
#ifdef ESTALE
case ESTALE: return "ESTALE";
#endif
#ifdef ESTART
case ESTART: return "ESTART";
#endif
#ifdef ESTRPIPE
case ESTRPIPE: return "ESTRPIPE";
#endif
#ifdef ESYSERROR
case ESYSERROR: return "ESYSERROR";
#endif
#ifdef ETIME
case ETIME: return "ETIME";
#endif
#ifdef ETIMEDOUT
case ETIMEDOUT: return "ETIMEDOUT";
#endif
#ifdef ETOOMANYREFS
case ETOOMANYREFS: return "ETOOMANYREFS";
#endif
#ifdef ETXTBSY
case ETXTBSY: return "ETXTBSY";
#endif
#ifdef EUCLEAN
case EUCLEAN: return "EUCLEAN";
#endif
#ifdef EUNATCH
case EUNATCH: return "EUNATCH";
#endif
#ifdef EUSERS
case EUSERS: return "EUSERS";
#endif
#ifdef EVERSION
case EVERSION: return "EVERSION";
#endif
#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || EWOULDBLOCK != EAGAIN)
case EWOULDBLOCK: return "EWOULDBLOCK";
#endif
#ifdef EWRONGFS
case EWRONGFS: return "EWRONGFS";
#endif
#ifdef EWRPROTECT
case EWRPROTECT: return "EWRPROTECT";
#endif
#ifdef EXDEV
case EXDEV: return "EXDEV";
#endif
#ifdef EXFULL
case EXFULL: return "EXFULL";
#endif
}
return 0;
}
答案 2 :(得分:1)
这是一个似乎这样做的perl技巧:
#!/usr/bin/perl -w
use strict;
no strict "refs";
use POSIX qw(:errno_h);
my $code = shift;
my $ns = \%{'POSIX::'};
foreach (keys %$ns) {
print "$_\n" if /^E(?!XPORT)/ && (${$ns->{$_}}||-1) == $code;
}
答案 3 :(得分:1)
EFOO
中定义的<errno.h>
常量集(直接或间接)及其值,因系统而异。通常不止一个EFOO
常数;例如,在我的系统上,EAGAIN
和EWOULDBLOCK
的值均为11
。因此,对于给定的数字EFOO
值,不一定有唯一的errno
符号。
我收集了来自各种系统的160个E*
符号的列表。它既不是决定性的,也不是详尽无遗的。您可以编写一个脚本,将列表作为输入,并生成一个C源程序,用于打印每个符号的数值。对于每个符号,程序将包含以下内容:
#ifdef E2BIG
printf("E2BIG %d\n", E2BIG);
#endif
从那里,您可以生成一个C函数,该函数将相应的符号作为字符串返回,或者如果没有这样的符号则返回"?"
之类的符号。
我知道这是一个不完整的答案,但这是一个很好的起点。我稍后可能会实施更完整的解决方案。如果是这样,我可能会将其创建为Github项目并通过链接更新此答案。
以下是清单:
E2BIG EACCES EADDRINUSE EADDRNOTAVAIL EADV EAFNOSUPPORT EAGAIN
EALREADY EBADCOOKIE EBADE EBADF EBADFD EBADHANDLE EBADMSG EBADR EBADRQC
EBADSLT EBADTYPE EBFONT EBUSY ECANCELED ECANCELLED ECHILD ECHRNG ECOMM
ECONNABORTED ECONNREFUSED ECONNRESET EDEADLK EDEADLOCK EDESTADDRREQ
EDOM EDOTDOT EDQUOT EEXIST EFAULT EFBIG EHOSTDOWN EHOSTUNREACH EHWPOISON
EIDRM EILSEQ EINIT EINPROGRESS EINTR EINVAL EIO EIOCBQUEUED EIOCBRETRY
EISCONN EISDIR EISNAM EJUKEBOX EKEYEXPIRED EKEYREJECTED EKEYREVOKED
EL2HLT EL2NSYNC EL3HLT EL3RST ELIBACC ELIBBAD ELIBEXEC ELIBMAX ELIBSCN
ELNRNG ELOCKUNMAPPED ELOOP EMAXERRNO EMEDIUMTYPE EMFILE EMLINK EMSGSIZE
EMULTIHOP ENAMETOOLONG ENAVAIL ENETDOWN ENETRESET ENETUNREACH ENFILE
ENOANO ENOBUFS ENOCSI ENODATA ENODEV ENOENT ENOEXEC ENOIOCTLCMD ENOKEY
ENOLCK ENOLINK ENOMEDIUM ENOMEM ENOMSG ENONET ENOPKG ENOPROTOOPT ENOSPC
ENOSR ENOSTR ENOSYM ENOSYS ENOTACTIVE ENOTBLK ENOTCONN ENOTDIR ENOTEMPTY
ENOTNAM ENOTRECOVERABLE ENOTSOCK ENOTSUP ENOTSUPP ENOTSYNC ENOTTY
ENOTUNIQ ENXIO EOPNOTSUPP EOVERFLOW EOWNERDEAD EPERM EPFNOSUPPORT EPIPE
EPROCLIM EPROTO EPROTONOSUPPORT EPROTOTYPE ERANGE EREFUSED EREMCHG EREMDEV
EREMOTE EREMOTEIO EREMOTERELEASE ERESTART ERESTARTNOHAND ERESTARTNOINTR
ERESTARTSYS ERESTART_RESTARTBLOCK ERFKILL EROFS ERREMOTE ESERVERFAULT
ESHUTDOWN ESOCKTNOSUPPORT ESPIPE ESRCH ESRMNT ESTALE ESTRPIPE ETIME
ETIMEDOUT ETOOMANYREFS ETOOSMALL ETXTBSY EUCLEAN EUNATCH EUSERS
EWOULDBLOCK EXDEV EXFULL
答案 4 :(得分:1)
这是我自己的答案,基于其他人的组合加上一些perl
:
#!/usr/bin/perl
use strict;
use warnings;
die "Syntax: error ERRORNUM" unless ($#ARGV==0);
open (my $p, "cpp -dM /usr/include/errno.h |") || die ("Cannot preprocess headers: $!");
while (<$p>)
{
chomp;
print "$1\n" if /^#define (E\w+) (\d+)/ && $2==$ARGV[0];
}
close ($p);
用法示例:
$ ./error 10
ECHILD
我确定通过一些错误处理可以改善它。
答案 5 :(得分:0)
strerror()
函数通常(总是?)在返回的消息中的某处提供该常量的名称。这是一个黑客攻击,但是对于以“E”开头的第一组连续大写字母,你可以这样做......
答案 6 :(得分:0)
编辑在问题中的拼写错误被删除之后无关紧要的部分。
如标题中所述,谈论POSIX,你应该完成你问题中提到的errno.h
头文件。
查看标准以查看应在那里定义的宏的完整列表。 (http://pubs.opengroup.org/onlinepubs/9699919799/)
使用gcc,您应该能够在使用gcc -dM -E /usr/include/errno.h
包含errno.h之后获取所有宏定义的列表,而不是手动从那里开始搜索包含树。
使用启发式或多或少的所有以字母E
开头的宏定义都应该是错误代码,您可以使用grep,awk或您选择的工具进一步缩小列表范围。
gcc -dM -E /usr/include/errno.h | awk '$2 ~ /^E/ {print $3 "\t" $2}'
是我正在尝试的版本,同时取消了这一行。
与此同时,正如评论部分 abligh 中所提到的那样gcc -dM -E /usr/include/errno.h | egrep "^#define E" | cut -c 9- | sort -n -k 2
也应该提供已排序的列表。
答案 7 :(得分:0)
Perl上个赛季是如此,这是一种现在可以更轻松地用Python实现的方法!它还具有errno
模块,该模块随时具有称为errno.errorcode
>>> import errno
>>> errno.errorcode[10]
'ECHILD'
从命令行:
python -c 'import errno; print(errno.errorcode[10])'
或者将其放在独立脚本中:
#!/usr/bin/python
import errno, sys
for i in sys.argv[1:]:
code = int(i)
print('{0:8d} - {1}'.format(code, errno.errorcode.get(code, '<unknown>')))
然后errno.py 10 20 30 666
将打印
10 - ECHILD
20 - ENOTDIR
30 - EROFS
666 - <unknown>
答案 8 :(得分:0)
至少在Ubuntu上有一个名为moreutils
的软件包,其中包含由Lars Wirzenius编写的名为errno
的程序,它将完成您想要的操作:
% errno 10 20 30 666
ECHILD 10 No child processes
ENOTDIR 20 Not a directory
EROFS 30 Read-only file system
我针对Python程序测试了该程序,它至少映射了Python中可用的所有错误。但是我的Python只有130个代码。 errno
产生134。在134中,这3个是重复项,因此反向映射不是唯一的。 Python errno
模块中缺少但在errno
中可用的一个是EHWPOISON 133 Memory page has hardware error
。
答案 9 :(得分:-1)
#ifndef NDEBUG
fprintf(stderr, "Line %d: Error value: %d\n", __LINE__, errno);
#endif
然后在调试器中查找打印值。
答案 10 :(得分:-1)
您可以使用符号本身来编写错误符号表。显然,这要求您包含定义要考虑的常量的所有标题。
从man page of errno
复制并粘贴常量列表。
如果在下面的实现中不知道符号,则会写入通用宏,例如ERROR_161
。如果您知道生成代码的系统调用,请查找其文档并手动包含可能的错误代码。这样你就可以随着时间的推移建立一个代码库。 (我同意它并不是很优雅。)
代码由宏创建,并存储为带有指定初始化程序的字符串的静态数组。数组大小由最大索引确定。
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
// ... more sys includes as appropriate ...
#define ERRNAME(X) [X] = #X
static const char *errname[] = {
ERRNAME(E2BIG),
ERRNAME(EACCES),
ERRNAME(EADDRINUSE),
ERRNAME(EADDRNOTAVAIL),
ERRNAME(EAFNOSUPPORT),
ERRNAME(EAGAIN),
// ... more symbols ...
};
const char *errsym(int e)
{
static char buf[20];
if (e >= 0 && e < (sizeof(errname) / sizeof(*errname))) {
if (errname[e]) return errname[e];
}
snprintf(buf, sizeof(buf), "ERROR_%u", (unsigned int) e);
return buf;
}