Wie kann ich den Signalnamen schnell von seiner Nummer erhalten? Es gibt strsignal()
aber ich möchte nur den Namen, zB SIGUSR1
Mit anderen Worten, wenn wir Makros mögen
SIGUSR1 -> 12
haben wir sowas
12 -> SIGUSR1
?
Wie kann ich den Signalnamen schnell von seiner Nummer erhalten? Es gibt strsignal()
aber ich möchte nur den Namen, zB SIGUSR1
Mit anderen Worten, wenn wir Makros mögen
SIGUSR1 -> 12
haben wir sowas
12 -> SIGUSR1
?
Karl Norum
Mein strsignal(3)
Manpage sagt, dass Sie die Namen direkt von der erhalten können sys_signame
Reihe. Hier ist ein einfaches Beispielprogramm, das ich geschrieben habe, um es zu testen:
#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;
}
Ich denke, dieses Programm erzeugt die Ausgabe, die Sie suchen:
$ ./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
Nur strsignal
scheint von POSIX definiert zu sein, wie es scheint, Array-Deklarationen sys_signame
scheint eine Erweiterung zu sein.
– Jens Gustedt
12. Mai 2013 um 20:53 Uhr
Dies ist also vielleicht eine Antwort auf das Problem, das das OP hat, wenn es OS X verwendet, aber keine Antwort auf die Frage, wie sie formuliert ist.
– Jens Gustedt
13. Mai 2013 um 6:24 Uhr
⁺¹, aber beachten Sie, dass der Array-Name wahrscheinlich geändert wurde – es ist sys_siglist.
– Hallo Engel
16. Oktober 2018 um 14:10 Uhr
Socowi
glib 2.32 (veröffentlicht am 05.08.2020) hat die Funktion eingeführt sigabbrev_np(int)
. Seit dieser Version können Sie nicht verwenden sys_siglist[]
auch nicht mehr.
Aus man strsignal
:
Das
sigabbrev_np()
Die Funktion gibt den abgekürzten Namen des Signals zurück, sig. Zum Beispiel den Wert gegebenSIGINT
es gibt die Zeichenfolge zurück"INT"
.
[…]sigdescr_np() und sigdabbrev_np() tauchten erstmals in glibc 2.32 auf. Ab Version 2.32 wird das sys_siglist-Symbol nicht mehr von glibc exportiert.
Und von der Versionshinweise:
Die Funktionen
sigabbrev_np
undsigdescr_np
wurde hinzugefügt. Dassigabbrev_np
gibt den abgekürzten Signalnamen zurück (zB"HUP"
zumSIGHUP
) […] beide Funktionen geben NULL für eine ungültige Signalnummer zurück.Sie sollten stattdessen verwendet werden
sys_siglist
odersys_sigabbrev
und sie sind sowohl thread- als auch asynchronsignalsicher. Diese Funktionen sind GNU-Erweiterungen.
Getestet unter Code auf Ubuntu 16.04 und MIPS und es funktioniert gut.
#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;
}
Die Ausgabe des obigen Codes auf 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
Die Ausgabe des obigen Codes auf 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
aber es gibt kein SIGHANGUP oder SIGINTERRUPT, sie sind SIGHUP und SIGINT. Die mit Leerzeichen sind noch offensichtlicher falsch. Das einzige, was hier richtig ist, ist SIGQUIT …
– Ilkkachu
13. Oktober 2021 um 17:41 Uhr
Pilkrähe
Wie Jens Gustedt vor Jahren in Kommentaren betonte, sys_signname und sys_siglist sind nicht tragbar.
Da diese Frage markiert ist [unix]
können Sie am portabelsten #ifdef
Ihren Weg zu einer für Ihre Umgebung spezifischen Zuordnung von Namen und numerischen Werten. Etwas wie:
//
// 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;
}
Dazu braucht es einige a priori Kenntnis Ihrer Plattform natürlich.
Möglicherweise können Sie ein globales Array wie folgt deklarieren
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};
und kann es verwenden, um den Signalnamen im Signal-Handler zu drucken, wie z
void sig_handler(int signum){
printf("Received signal : %s\n", signame[signum]);
}
Dies ist eine schlechte Idee, da die meisten Signalnummern von der Implementierung abhängig sind. SIGKILL ist immer 9, aber nicht alle Signale haben solche festen Nummern.
– Dietrich Ep
3. November 2016 um 20:21 Uhr
aber es ist schön, es in einem Signalhandler verwenden zu müssen, da strsignal nicht signalsicher ist
– SRombauten
4. Januar 2018 um 10:24 Uhr
Dies ist eine schlechte Idee, da die meisten Signalnummern von der Implementierung abhängig sind. SIGKILL ist immer 9, aber nicht alle Signale haben solche festen Nummern.
– Dietrich Ep
3. November 2016 um 20:21 Uhr
aber es ist schön, es in einem Signalhandler verwenden zu müssen, da strsignal nicht signalsicher ist
– SRombauten
4. Januar 2018 um 10:24 Uhr
In meinem
/usr/include/sys/signal.h
alle Signalnamen sind einfach#define
d-Konstanten. Das heißt, der Präprozessor hat sie bis zur Ausführung des Compilers bereits durch konstante Integer ersetzt – den symbolischen Namen existiert nicht was das Programm betrifft. Was genau versuchst du hier zu tun?– Karl Norum
12. Mai 2013 um 16:37 Uhr
@CarlNorum, nichts Besonderes, nur ausgefallene Ausgabe. Ich dachte, die tatsächlichen Namen könnten woanders gespeichert werden, damit ich sie bekommen könnte.
– Mike Rolle
12. Mai 2013 um 16:42 Uhr
Wenn Sie “ausgefallene Ausgabe” wollen, ist das nicht genau das Richtige
strsignal
ist für?– Karl Norum
12. Mai 2013 um 16:43 Uhr
Ja, es ist schick, aber nicht so, wie ich es will 🙂 Nur neugierig, überhaupt kein Problem.
– Mike Rolle
12. Mai 2013 um 16:46 Uhr
Mein
strsignal
Manpage sagt, dass Sie die Namen direkt von bekommen könnensys_signame
.– Karl Norum
12. Mai 2013 um 16:48 Uhr