如何将程序的退出状态转换为信号名称

如何将程序的退出状态转换为信号名称
pid_t waitpid(pid_t pid, int *status, int options);

例如当status=2时,返回字符串“SIGINT”,当status=11时,返回字符串“SIGSEGV”。是否有一个内置的 c 函数可以接收状态并输出信号名称?

答案1

与 类似strerror(n),有strsignal(n),它给出了详细名称,例如 SIGINT -> “Interrupt”。但这并不是你真正想要的。

Stackoverflow 上的这个答案表明sigabbrev_np()glibc 2.32 中应该可用: https://stackoverflow.com/a/68481682/6372809

预处理器已知信号缩写以及错误号缩写,因此您可以手动构建一个列表,如代码审查中的答案所示:https://codereview.stackexchange.com/a/252825/111089

对代码进行一些处理以减少 #预处理器运算符的重复,该程序将通过数字知道一些信号的名称:

#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#define init_signame(x) [x] = #x

static const char *signames[] = {
    init_signame(SIGINT),
    init_signame(SIGSTOP),
    init_signame(SIGTERM),
    init_signame(SIGKILL),
    init_signame(SIGHUP),
    [0] = ""
};

const char *getsig(int sig) {
    if (sig <= 0 || sig >= sizeof(signames) / sizeof(*signames) || !signames[sig])
        return "UNKN";

    return signames[sig];
}

int main(int argc, char *argv[])
{
    int i = 0;
    if (argc > 1) {
        i = atoi(argv[1]);
    }
    printf("%d = %s = %s\n", i, getsig(i), strsignal(i));
}

它给出例如:

$ ./signame2 1
1 = SIGHUP = Hangup

这里的问题是找出填写表格的所有名称......

为此,一种选择是让编译器转储它知道的定义,例如:

$ gcc -dM -E - <<< '#include <signal.h>' |grep -E '#define SIG[A-Z]+ ' 
#define SIGBUS 7
#define SIGTTIN 21
#define SIGTTOU 22
...

然后使用脚本从中构建一些有用的东西。请注意,还可能存在如下条目:

#define SIGCLD SIGCHLD
#define SIGRTMAX (__libc_current_sigrtmax ())

我不确定实时信号是否在任何地方都有单独的定义,或者它们是否只是SIGRTMIN+0SIGRTMIN+1等,最多为SIGRTMAX

或者,至少如果您使用的是 Linux,请检查手册页获取信号列表。这些数字在不同的体系结构之间进行洗牌,并且存在的信号也略有不同,但您可以从那里获得名称列表。

答案2

如果您有 glibc 2.32 或更高版本,您可以使用sigabbrev_np

sigabbrev_np() 函数返回信号的缩写名称 sig。例如,给定值 SIGINT,它返回字符串“INT”。

所以你只需要前置SIG即可获取SIGINT.

相关内容