如何将UNIX中的errno转换为相应的字符串?

时间:2009-10-10 02:38:50

标签: unix errno

UNIX中是否有任何函数将errno转换为相应的字符串,例如: EIDRM到“EIDRM”。调试以检查这些整数errnos的错误非常烦人。

6 个答案:

答案 0 :(得分:69)

strerror()应该这样做。 http://linux.die.net/man/3/strerror

仅供参考,以便您可以更轻松地找到这些内容:如果您键入man errno(或您正在调查的任何函数),并查看手册页的最底部,您将看到一个列表相关功能。如果你man中的每一个(根据他们的名字猜测哪一个先做),你会经常找到类似问题的答案。

答案 1 :(得分:10)

另一种解决方案可以解决您遇到的问题,但是在Python中而不是C:

>>> import errno
>>> errno.errorcode[errno.EIDRM]
'EIDRM'

答案 2 :(得分:5)

现在有一个与moreutils包一起发布的errno实用程序。

答案 3 :(得分:4)

我不确定这样的enum - 样式名称,但是出于调试和错误报告的目的,您可以使用返回人类可读表示的perror(3)strerror(3) C函数。错误代码。有关更多详细信息,请参阅手册页。

答案 4 :(得分:3)

如果你确实想要EIDRM而不是它的错误字符串:no。但是,在OpenBSD上,

man errno|egrep ' [0-9]+ E[A-Z]+'|sed 's/^ *//'|cut -d' ' -f1,2

打印出一个漂亮的“... \ n89 EIDM \ n ...”表格,您可以将其进一步转换为您希望使用此功能的编程语言的数据结构。

答案 5 :(得分:1)

在UNIX中没有标准功能可以做到这一点。

但是我最近写了the errnoname library,它具有一个errnoname函数,可以完全做到这一点。

strerror(还有strerror_rstrerror_lperror)打印出有关错误原因的“人性化”提示,但其输出是

  • 通常无证,
  • 未标准化
  • 不保证在长度或格式上遵循任何限制,
  • 通常根据语言环境设置而有所不同,并且
  • 并非总是在所有情况下都有意义(例如,它们倾向于为File exists打印EEXIST,即使对于不是文件的错误通常会返回)。

这意味着它们表面上对用户友好,但是

  • 其他代码无法将其可靠地解析(对于自动化,监视,脚本编写,包装程序等而言更糟)
  • 可能会误导极端情况,并且
  • 妨碍技术经验丰富的用户。

具有讽刺意味的是,在所有情况下都不能仅仅通过将errno符号名称用作其错误字符串来防止这些错误-它将在标准的含义之内,尤其是如果它们仅是针对特定的语言环境(例如特殊的C语言环境)执行的。但是我不知道有没有libc。

无论如何,由于我的errnoname是根据“零条款BSD许可证”(0BSD)发行的,该许可证是许可的许可证,或更准确地说是等效于公共域的许可证,因此您可以执行任何操作

为使该答案独立存在,同时仍能满足答案字符的限制,下面是errnoname函数的两个缩写形式。

errnoname中,它们均已实现,但在这里,我将它们的要点分开以使其更具可读性。

笔记夫妇:

  1. 截至8月初,这涵盖了Linux,Darwin(Mac OS X和iOS X),FreeBSD,NetBSD,OpenBSD,DragonflyBSD和几个封闭源Unixes的全部或大部分errno名称2019。

  2. 如果您给它提供一个NULL值(它不知道其名称),它将返回一个errno指针。

变量1:简单,通用,低效

这是一款非常便携和简单的产品,无需担心任何边缘情况。它几乎可以用任何C89或更好的编译器进行编译。 (可能甚至是C ++编译器,随着语言的多样化,这种情况也变得越来越罕见。)此变体不能用现代编译器编译为有效的代码,但应该很好地适合于将来编译器可以轻松实现的优化过程。

#include <errno.h>

char const * errnoname(int errno_)
{
    switch(errno_)
    {
#ifdef E2BIG
        case E2BIG: return "E2BIG";
#endif
#ifdef EACCES
        case EACCES: return "EACCES";
#endif
/*
    repeat for the other 100+ errno names,
    don't forget to handle possible duplicates
    like EAGAIN and EWOULDBLOCK
*/
    }
    return 0;
}

变体2:高效,对大多数系统都有好处

只要系统具有相对较小,正且连续的errno值,该函数的性能就会更高,并且仍然可以安全使用。

只能在对数组实现乱序指定初始化程序的编译器上进行编译(C99或更高版本,到目前为止不包括所有C ++版本。)

#include <errno.h>

char const * errnoname(int errno_)
{
    static char const * const names[] =
    {
#ifdef E2BIG
        [E2BIG] = "E2BIG",
#endif
#ifdef EACCES
        [EACCES] = "EACCES",
#endif
/*
    repeat for the other 100+ errno names,
    don't forget to handle possible duplicates
    like EAGAIN and EWOULDBLOCK
*/
    };
    if(errno_ >= 0 && errno_ < (sizeof(names) / sizeof(*names)))
    {
        return names[errno_];
    }
    return 0;
}