123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- /* vi: set sw=4 ts=4: */
- /*
- * Signal name/number conversion routines.
- *
- * Copyright 2006 Rob Landley <rob@landley.net>
- *
- * Licensed under GPLv2 or later, see file LICENSE in this source tree.
- */
- //config:config FEATURE_RTMINMAX
- //config: bool "Support RTMIN[+n] and RTMAX[-n] signal names"
- //config: default y
- //config: help
- //config: Support RTMIN[+n] and RTMAX[-n] signal names
- //config: in kill, killall etc. This costs ~250 bytes.
- //config:
- //config:config FEATURE_RTMINMAX_USE_LIBC_DEFINITIONS
- //config: bool "Use the definitions of SIGRTMIN/SIGRTMAX provided by libc"
- //config: default y
- //config: depends on FEATURE_RTMINMAX
- //config: help
- //config: Some C libraries reserve a few real-time signals for internal
- //config: use, and adjust the values of SIGRTMIN/SIGRTMAX seen by
- //config: applications accordingly. Saying yes here means that a signal
- //config: name RTMIN+n will be interpreted according to the libc definition
- //config: of SIGRTMIN, and not the raw definition provided by the kernel.
- //config: This behavior matches "kill -l RTMIN+n" from bash.
- #include "libbb.h"
- /* Believe it or not, but some arches have more than 32 SIGs!
- * HPPA: SIGSTKFLT == 36. */
- static const char signals[][7] ALIGN1 = {
- // SUSv3 says kill must support these, and specifies the numerical values,
- // http://www.opengroup.org/onlinepubs/009695399/utilities/kill.html
- // {0, "EXIT"}, {1, "HUP"}, {2, "INT"}, {3, "QUIT"},
- // {6, "ABRT"}, {9, "KILL"}, {14, "ALRM"}, {15, "TERM"}
- // And Posix adds the following:
- // {SIGILL, "ILL"}, {SIGTRAP, "TRAP"}, {SIGFPE, "FPE"}, {SIGUSR1, "USR1"},
- // {SIGSEGV, "SEGV"}, {SIGUSR2, "USR2"}, {SIGPIPE, "PIPE"}, {SIGCHLD, "CHLD"},
- // {SIGCONT, "CONT"}, {SIGSTOP, "STOP"}, {SIGTSTP, "TSTP"}, {SIGTTIN, "TTIN"},
- // {SIGTTOU, "TTOU"}
- [0] = "EXIT",
- #ifdef SIGHUP
- [SIGHUP ] = "HUP",
- #endif
- #ifdef SIGINT
- [SIGINT ] = "INT",
- #endif
- #ifdef SIGQUIT
- [SIGQUIT ] = "QUIT",
- #endif
- #ifdef SIGILL
- [SIGILL ] = "ILL",
- #endif
- #ifdef SIGTRAP
- [SIGTRAP ] = "TRAP",
- #endif
- #ifdef SIGABRT
- [SIGABRT ] = "ABRT",
- #endif
- #ifdef SIGBUS
- [SIGBUS ] = "BUS",
- #endif
- #ifdef SIGFPE
- [SIGFPE ] = "FPE",
- #endif
- #ifdef SIGKILL
- [SIGKILL ] = "KILL",
- #endif
- #ifdef SIGUSR1
- [SIGUSR1 ] = "USR1",
- #endif
- #ifdef SIGSEGV
- [SIGSEGV ] = "SEGV",
- #endif
- #ifdef SIGUSR2
- [SIGUSR2 ] = "USR2",
- #endif
- #ifdef SIGPIPE
- [SIGPIPE ] = "PIPE",
- #endif
- #ifdef SIGALRM
- [SIGALRM ] = "ALRM",
- #endif
- #ifdef SIGTERM
- [SIGTERM ] = "TERM",
- #endif
- #ifdef SIGSTKFLT
- [SIGSTKFLT] = "STKFLT",
- #endif
- #ifdef SIGCHLD
- [SIGCHLD ] = "CHLD",
- #endif
- #ifdef SIGCONT
- [SIGCONT ] = "CONT",
- #endif
- #ifdef SIGSTOP
- [SIGSTOP ] = "STOP",
- #endif
- #ifdef SIGTSTP
- [SIGTSTP ] = "TSTP",
- #endif
- #ifdef SIGTTIN
- [SIGTTIN ] = "TTIN",
- #endif
- #ifdef SIGTTOU
- [SIGTTOU ] = "TTOU",
- #endif
- #ifdef SIGURG
- [SIGURG ] = "URG",
- #endif
- #ifdef SIGXCPU
- [SIGXCPU ] = "XCPU",
- #endif
- #ifdef SIGXFSZ
- [SIGXFSZ ] = "XFSZ",
- #endif
- #ifdef SIGVTALRM
- [SIGVTALRM] = "VTALRM",
- #endif
- #ifdef SIGPROF
- [SIGPROF ] = "PROF",
- #endif
- #ifdef SIGWINCH
- [SIGWINCH ] = "WINCH",
- #endif
- #ifdef SIGPOLL
- [SIGPOLL ] = "POLL",
- #endif
- #ifdef SIGPWR
- [SIGPWR ] = "PWR",
- #endif
- #ifdef SIGSYS
- [SIGSYS ] = "SYS",
- #endif
- #if ENABLE_FEATURE_RTMINMAX && !ENABLE_FEATURE_RTMINMAX_USE_LIBC_DEFINITIONS
- # ifdef __SIGRTMIN
- [__SIGRTMIN] = "RTMIN",
- # endif
- // This makes array about x2 bigger.
- // More compact approach is to special-case SIGRTMAX in print_signames()
- //# ifdef __SIGRTMAX
- // [__SIGRTMAX] = "RTMAX",
- //# endif
- #endif
- };
- // Convert signal name to number.
- int FAST_FUNC get_signum(const char *name)
- {
- unsigned i;
- /* bb_strtou returns UINT_MAX on error. NSIG is smaller
- * than UINT_MAX on any sane Unix. Hence no need
- * to check errno after bb_strtou().
- */
- i = bb_strtou(name, NULL, 10);
- if (i < NSIG) /* for shells, we allow 0 too */
- return i;
- if (strncasecmp(name, "SIG", 3) == 0)
- name += 3;
- for (i = 0; i < ARRAY_SIZE(signals); i++)
- if (strcasecmp(name, signals[i]) == 0)
- return i;
- #if ENABLE_DESKTOP
- # if defined(SIGIOT) || defined(SIGIO)
- /* SIGIO[T] are aliased to other names,
- * thus cannot be stored in the signals[] array.
- * Need special code to recognize them */
- if ((name[0] | 0x20) == 'i' && (name[1] | 0x20) == 'o') {
- # ifdef SIGIO
- if (!name[2])
- return SIGIO;
- # endif
- # ifdef SIGIOT
- if ((name[2] | 0x20) == 't' && !name[3])
- return SIGIOT;
- # endif
- }
- # endif
- #endif
- #if ENABLE_FEATURE_RTMINMAX && defined(SIGRTMIN) && defined(SIGRTMAX)
- {
- # if ENABLE_FEATURE_RTMINMAX_USE_LIBC_DEFINITIONS
- /* Use the libc provided values. */
- unsigned sigrtmin = SIGRTMIN;
- unsigned sigrtmax = SIGRTMAX;
- # else
- /* Use the "raw" SIGRTMIN/MAX. Underscored names, if exist, provide
- * them. If they don't exist, fall back to non-underscored ones: */
- # if !defined(__SIGRTMIN)
- # define __SIGRTMIN SIGRTMIN
- # endif
- # if !defined(__SIGRTMAX)
- # define __SIGRTMAX SIGRTMAX
- # endif
- # define sigrtmin __SIGRTMIN
- # define sigrtmax __SIGRTMAX
- # endif
- if (strncasecmp(name, "RTMIN", 5) == 0) {
- if (!name[5])
- return sigrtmin;
- if (name[5] == '+') {
- i = bb_strtou(name + 6, NULL, 10);
- if (i <= sigrtmax - sigrtmin)
- return sigrtmin + i;
- }
- }
- else if (strncasecmp(name, "RTMAX", 5) == 0) {
- if (!name[5])
- return sigrtmax;
- if (name[5] == '-') {
- i = bb_strtou(name + 6, NULL, 10);
- if (i <= sigrtmax - sigrtmin)
- return sigrtmax - i;
- }
- }
- # undef sigrtmin
- # undef sigrtmax
- }
- #endif
- return -1;
- }
- // Convert signal number to name
- const char* FAST_FUNC get_signame(int number)
- {
- if ((unsigned)number < ARRAY_SIZE(signals)) {
- if (signals[number][0]) /* if it's not an empty str */
- return signals[number];
- }
- return itoa(number);
- }
- // Print the whole signal list
- void FAST_FUNC print_signames(void)
- {
- unsigned signo;
- for (signo = 1; signo < ARRAY_SIZE(signals); signo++) {
- const char *name = signals[signo];
- if (name[0])
- printf("%2u) %s\n", signo, name);
- }
- #if ENABLE_FEATURE_RTMINMAX
- # if ENABLE_FEATURE_RTMINMAX_USE_LIBC_DEFINITIONS
- # if defined(SIGRTMIN) && defined(SIGRTMAX)
- printf("%2u) %s\n", SIGRTMIN, "RTMIN");
- printf("%2u) %s\n", SIGRTMAX, "RTMAX");
- # endif
- # else
- // __SIGRTMIN is included in signals[] array.
- # ifdef __SIGRTMAX
- printf("%2u) %s\n", __SIGRTMAX, "RTMAX");
- # endif
- # endif
- #endif
- }
|