如何打印C中的错误号的符号名称? [英] How can I print the symbolic name of an errno in C?

查看:168
本文介绍了如何打印C中的错误号的符号名称?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以使用 PERROR()字符串错误()打印属于人类可读的错误消息一个错误号,但如果我的的要打印的符号名称(例如, EAGAIN )的错误号

任何方便的功能或宏这样做呢?

更新:安装的code我结束了写作,基于下面的接受的答案和意见的想法:

 的#include<&文件ctype.h GT;
#包括LT&;&errno.h中GT;
#包括LT&;&stdio.h中GT;INT get_errno_name(字符* BUF,诠释buf_size){
    //使用Linux只呆呆地看着方便,因为不是awk中,
    //匹配()功能。对于POSIX可移植性,使用不同的配方......
    CHAR CMD [] =E =&放大器;&安培;//错误号此处插入(最多位数= 6)
                 回声的#include<&errno.h中GT;' |
                 GCC -dM -E - |//可选,使用$ CC的gcc inead
                 GAWK \\比赛(\\\\ $ 0 / ^#[[:空间:]] *定义[[:空间:]] +
                     (E [[:alnum:]] +)[[:空间:]] + $ E($ | [^ [:alnum:]])/,M)
                     {打印米[1]} \\;
    {
        //将错误号在上面的命令中的Eshell变量。
        INT errno_digit_c =的snprintf(CMD + 2,6,%D,错误号);
        如果(errno_digit_c&所述; 1){
            fprintf中(标准错误,无法字符串化的错误号
                            在get_errno_name()\\ n);
            返回-1;
        }
        //更换插入终止'\\ 0'与空白
        CMD [errno_digit_c + 2] ='';
    }
    FILE * F =的popen(CMD,R);
    如果(F == NULL){
        PERROR(无法popen()完成在get_errno_name());
        返回-1;
    }
    INT read_size = 0,C;
    而((C = GETC(F))!= EOF){
        如果(字符isalnum(c))的{
            BUF [read_size ++] = C;
            如果(read_size +1 GT; buf_size){
                fprintf中(标准错误,读取错误号名称超过字符大
                                缓冲区提供给get_errno_name()\\ n);
                返回-1;
            }
        }
    }
    BUF [read_size ++] ='\\ 0';
    如果(pclose函数(F)== -1){
        PERROR(无法pclose函数()在get_errno_name());
        返回-1;
    }
    返回read_size;
}


解决方案

有没有一个简单的方法来做到这一点。

您可以创建一个程序 - 我已创建了一个,这可能是重新打包为库函数 - 从数字转换为名称。但产生的表是中等硬度。我使用运行编译器(GCC或同等学历)的选项( -H ),列出被包括 / USR包括头一个Perl脚本/include/errno.h ,然后扫描这些文件,寻找名(的#define 加上电子后跟一个大写字母或数字),数字和评论。这个工作在Linux,Mac OS X,Solaris和HP-UX,AIX。它没有特别的琐碎

当心,在 errno.h中在Mac OS X包括 ELAST (名称保留给实现的名称使用),这是人数最多的一个副本(但是从发布的映射修改的版本;它在山狮是105,我相信,但它是在小牛队106)

I can use perror() or strerror() to print the "human readable" error message belonging to an errno, but what if I also want to print the symbolic name (e.g., "EAGAIN") of the errno?

Any convenient function or macro to do that?

update: attaching the code I ended up writing, based on the idea of the accepted answer below and its comments:

#include <ctype.h>
#include <errno.h>
#include <stdio.h>

int get_errno_name(char *buf, int buf_size) {
    // Using the linux-only gawk instead of awk, because of the convenient
    // match() functionality. For Posix portability, use a different recipe...
    char cmd[] = "e=       && " // errno to be inserted here (max digits = 6)
                 "echo '#include <errno.h>' | "
                 "gcc -dM -E - | " // optionally, use $CC inead of gcc
                 "gawk \"match(\\$0, /^#[[:space:]]*define[[:space:]]+"
                     "(E[[:alnum:]]+)[[:space:]]+$e($|[^[:alnum:]])/, m) "
                     "{ print m[1] }\"";
    {
        // Insert the errno as the "e" shell variable in the command above.
        int errno_digit_c = snprintf(cmd + 2, 6, "%d", errno);
        if (errno_digit_c < 1) {
            fprintf(stderr, "Failed to stringify an errno "
                            "in get_errno_name().\n");
            return -1;
        }
        // Replace the inserted terminating '\0' with whitespace
        cmd[errno_digit_c + 2] = ' ';
    }
    FILE *f = popen(cmd, "r");
    if (f == NULL) {
        perror("Failed to popen() in get_errno_name()");
        return -1;
    }
    int read_size = 0, c;
    while ((c = getc(f)) != EOF) {
        if (isalnum(c)) {
            buf[read_size++] = c;
            if (read_size + 1 > buf_size) {
                fprintf(stderr, "Read errno name is larger than the character "
                                "buffer supplied to get_errno_name().\n");
                return -1;
            }
        }
    }
    buf[read_size++] = '\0';
    if (pclose(f) == -1) {
        perror("Failed to pclose() in get_errno_name()");
        return -1;
    }
    return read_size;
}

解决方案

There isn't a simple way to do that.

You can create a program — and I have created one, which could be repackaged as a library function — that converts from number to name. But generating the table is moderately hard. I use a Perl script that runs the compiler (GCC or equivalent) with options (-H) to list the headers that are included by including /usr/include/errno.h, and then scans those files, looking for names (#define plus E followed by an upper-case letter or digit), numbers, and comments. This works on Linux, Mac OS X, Solaris, HP-UX, AIX. It isn't particularly trivial.

Beware, the errno.h on Mac OS X includes a name ELAST (a name reserved for the implementation to use) that is a duplicate of the highest number (but the mapping changes from release to release; it was 105 in Mountain Lion, I believe, but it is 106 in Mavericks).

这篇关于如何打印C中的错误号的符号名称?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆