如何从号码中快速获取信号名称?
有strsignal()
,但我只想要名称,例如SIGUSR1
换句话说,如果我们有像宏
SIGUSR1 -> 12
我们有什么喜欢的吗?
12 -> SIGUSR1
?
答案 0 :(得分:15)
我的strsignal(3)
手册页说您可以直接从sys_signame
数组中获取名称。这是我编写的一个简单的示例程序来测试它:
#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
void upcase(char *s)
{
while (*s)
{
*s = toupper(*s);
s++;
}
}
int main(void)
{
for (int sig = 1; sig < NSIG; sig++)
{
char *str = strdup(sys_signame[sig]);
if (!str)
return -1;
upcase(str);
printf("%2d -> SIG%s\n", sig, str);
free(str);
}
return 0;
}
我认为这个程序产生了你正在寻找的输出:
$ ./example
1 -> SIGHUP
2 -> SIGINT
3 -> SIGQUIT
4 -> SIGILL
5 -> SIGTRAP
6 -> SIGABRT
7 -> SIGEMT
8 -> SIGFPE
9 -> SIGKILL
10 -> SIGBUS
11 -> SIGSEGV
12 -> SIGSYS
13 -> SIGPIPE
14 -> SIGALRM
15 -> SIGTERM
16 -> SIGURG
17 -> SIGSTOP
18 -> SIGTSTP
19 -> SIGCONT
20 -> SIGCHLD
21 -> SIGTTIN
22 -> SIGTTOU
23 -> SIGIO
24 -> SIGXCPU
25 -> SIGXFSZ
26 -> SIGVTALRM
27 -> SIGPROF
28 -> SIGWINCH
29 -> SIGINFO
30 -> SIGUSR1
31 -> SIGUSR2
答案 1 :(得分:1)
正如 Jens Gustedt 多年前在评论中指出的那样,sys_signame 和 sys_siglist 不可移植。
由于此问题被标记为 [unix]
,因此您可以最方便地 #ifdef
以自己的方式映射特定于您的环境的名称和数值。类似的东西:
//
// const char * signame(int s)
//
// return the name of the given signal number as a string,
// or NULL if the number is unrecognized.
//
#define _POSIX_C_SOURCE 200809L
#include <signal.h>
#define SIGNAMEANDNUM(s) { #s, s }
static struct {
const char *name,
int value,
} known_signals[] = {
SIGNAMEANDNUM(SIGABRT), // get the POSIX signals
SIGNAMEANDNUM(SIGALRM),
SIGNAMEANDNUM(SIGBUS),
SIGNAMEANDNUM(SIGCHLD),
/* ... */
SIGNAMEANDNUM(SIGXFSZ),
#ifdef SIGUNUSUAL // get nonstandard signals
SIGNAMEANDNUM(SIGUNUSUAL),
#endif
/* ... */
};
const char *
signame(int s) {
const char *name = NULL;
for (int i = 0; i < sizeof(known_signals)/sizeof(*known_signals); i++) {
if (s == known_signals[i].value) {
name = known_signals[i].name;
break;
}
}
return name;
}
当然,这需要对您的平台有一些先验知识。
答案 2 :(得分:1)
glib 2.32(于 2020 年 8 月 5 日发布)引入了函数 sigabbrev_np(int)
。从那个版本开始,您也不能再使用 sys_siglist[]
。
来自man strsignal
:
sigabbrev_np()
函数返回信号的缩写名称 sig。例如,给定值 SIGINT
,它返回字符串 "INT"
。
[...]
sigdescr_np() 和 sigdabbrev_np() 首次出现在 glibc 2.32 中。
从 2.32 版开始,glibc 不再导出 sys_siglist 符号。
已添加函数 sigabbrev_np
和 sigdescr_np
。 sigabbrev_np
返回缩写的信号名称(例如,"HUP"
代表 SIGHUP
)[...] 两个函数都为无效信号编号返回 NULL。
应该使用它们代替 sys_siglist
或 sys_sigabbrev
,并且它们都是线程和异步信号安全的。这些函数是 GNU 扩展。
答案 3 :(得分:0)
在Ubuntu 16.04和MIPS上测试了以下代码,并且工作正常。
#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
extern const char * const sys_siglist[];
void upcase(char *s)
{
while (*s)
{
*s = toupper(*s);
s++;
}
}
int main(void)
{
int sig;
/*
NSIG returns number of signals available in a system
and it may vary according to platforms;Found on Ubuntu-16.04 it return 65
where as in MIPS it is 31; Found in both the platforms it leads to core dump
after signal 31 so limiting scanning of signal till 31 instead of using NSIG
*/
for (sig = 1; sig < 32; sig++)
{
char *str = strdup(sys_siglist[sig]);
if (!str)
return -1;
upcase(str);
printf("%2d -> SIG%s\n", sig, str);
free(str);
}
return 0;
}
上述代码在Ubuntu-16.04(Intel x86_64 GNU / Linux)上的输出:
1 -> SIGHANGUP
2 -> SIGINTERRUPT
3 -> SIGQUIT
4 -> SIGILLEGAL INSTRUCTION
5 -> SIGTRACE/BREAKPOINT TRAP
6 -> SIGABORTED
7 -> SIGBUS ERROR
8 -> SIGFLOATING POINT EXCEPTION
9 -> SIGKILLED
10 -> SIGUSER DEFINED SIGNAL 1
11 -> SIGSEGMENTATION FAULT
12 -> SIGUSER DEFINED SIGNAL 2
13 -> SIGBROKEN PIPE
14 -> SIGALARM CLOCK
15 -> SIGTERMINATED
16 -> SIGSTACK FAULT
17 -> SIGCHILD EXITED
18 -> SIGCONTINUED
19 -> SIGSTOPPED (SIGNAL)
20 -> SIGSTOPPED
21 -> SIGSTOPPED (TTY INPUT)
22 -> SIGSTOPPED (TTY OUTPUT)
23 -> SIGURGENT I/O CONDITION
24 -> SIGCPU TIME LIMIT EXCEEDED
25 -> SIGFILE SIZE LIMIT EXCEEDED
26 -> SIGVIRTUAL TIMER EXPIRED
27 -> SIGPROFILING TIMER EXPIRED
28 -> SIGWINDOW CHANGED
29 -> SIGI/O POSSIBLE
30 -> SIGPOWER FAILURE
31 -> SIGBAD SYSTEM CALL
上述代码在busybox(MIPS,Cavium)上的输出:
1 -> SIGHANGUP
2 -> SIGINTERRUPT
3 -> SIGQUIT
4 -> SIGILLEGAL INSTRUCTION
5 -> SIGTRACE/BREAKPOINT TRAP
6 -> SIGABORTED
7 -> SIGEMT TRAP
8 -> SIGFLOATING POINT EXCEPTION
9 -> SIGKILLED
10 -> SIGBUS ERROR
11 -> SIGSEGMENTATION FAULT
12 -> SIGBAD SYSTEM CALL
13 -> SIGBROKEN PIPE
14 -> SIGALARM CLOCK
15 -> SIGTERMINATED
16 -> SIGUSER DEFINED SIGNAL 1
17 -> SIGUSER DEFINED SIGNAL 2
18 -> SIGCHILD EXITED
19 -> SIGPOWER FAILURE
20 -> SIGWINDOW CHANGED
21 -> SIGURGENT I/O CONDITION
22 -> SIGI/O POSSIBLE
23 -> SIGSTOPPED (SIGNAL)
24 -> SIGSTOPPED
25 -> SIGCONTINUED
26 -> SIGSTOPPED (TTY INPUT)
27 -> SIGSTOPPED (TTY OUTPUT)
28 -> SIGVIRTUAL TIMER EXPIRED
29 -> SIGPROFILING TIMER EXPIRED
30 -> SIGCPU TIME LIMIT EXCEEDED
31 -> SIGFILE SIZE LIMIT EXCEEDED
答案 4 :(得分:-1)
可能是,您可以声明一个全局数组,就像这样
char *signame[]={"INVALID", "SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGTRAP", "SIGABRT", "SIGBUS", "SIGFPE", "SIGKILL", "SIGUSR1", "SIGSEGV", "SIGUSR2", "SIGPIPE", "SIGALRM", "SIGTERM", "SIGSTKFLT", "SIGCHLD", "SIGCONT", "SIGSTOP", "SIGTSTP", "SIGTTIN", "SIGTTOU", "SIGURG", "SIGXCPU", "SIGXFSZ", "SIGVTALRM", "SIGPROF", "SIGWINCH", "SIGPOLL", "SIGPWR", "SIGSYS", NULL};
可以用它在信号处理程序中打印信号名称,如
void sig_handler(int signum){
printf("Received signal : %s\n", signame[signum]);
}