![如何将程序的退出状态转换为信号名称](https://linux22.com/image/197008/%E5%A6%82%E4%BD%95%E5%B0%86%E7%A8%8B%E5%BA%8F%E7%9A%84%E9%80%80%E5%87%BA%E7%8A%B6%E6%80%81%E8%BD%AC%E6%8D%A2%E4%B8%BA%E4%BF%A1%E5%8F%B7%E5%90%8D%E7%A7%B0.png)
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+0
、SIGRTMIN+1
等,最多为SIGRTMAX
。
或者,至少如果您使用的是 Linux,请检查手册页获取信号列表。这些数字在不同的体系结构之间进行洗牌,并且存在的信号也略有不同,但您可以从那里获得名称列表。
答案2
如果您有 glibc 2.32 或更高版本,您可以使用sigabbrev_np
:
sigabbrev_np() 函数返回信号的缩写名称 sig。例如,给定值 SIGINT,它返回字符串“INT”。
所以你只需要前置SIG
即可获取SIGINT
.