busybox/libbb/u_signal_names.c
<<
>>
Prefs
   1/* vi: set sw=4 ts=4: */
   2/*
   3 * Signal name/number conversion routines.
   4 *
   5 * Copyright 2006 Rob Landley <rob@landley.net>
   6 *
   7 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
   8 */
   9
  10//config:config FEATURE_RTMINMAX
  11//config:       bool "Support RTMIN[+n] and RTMAX[-n] signal names"
  12//config:       default y
  13//config:       help
  14//config:         Support RTMIN[+n] and RTMAX[-n] signal names
  15//config:         in kill, killall etc. This costs ~250 bytes.
  16
  17#include "libbb.h"
  18
  19/* Believe it or not, but some arches have more than 32 SIGs!
  20 * HPPA: SIGSTKFLT == 36. */
  21
  22static const char signals[][7] = {
  23        // SUSv3 says kill must support these, and specifies the numerical values,
  24        // http://www.opengroup.org/onlinepubs/009695399/utilities/kill.html
  25        // {0, "EXIT"}, {1, "HUP"}, {2, "INT"}, {3, "QUIT"},
  26        // {6, "ABRT"}, {9, "KILL"}, {14, "ALRM"}, {15, "TERM"}
  27        // And Posix adds the following:
  28        // {SIGILL, "ILL"}, {SIGTRAP, "TRAP"}, {SIGFPE, "FPE"}, {SIGUSR1, "USR1"},
  29        // {SIGSEGV, "SEGV"}, {SIGUSR2, "USR2"}, {SIGPIPE, "PIPE"}, {SIGCHLD, "CHLD"},
  30        // {SIGCONT, "CONT"}, {SIGSTOP, "STOP"}, {SIGTSTP, "TSTP"}, {SIGTTIN, "TTIN"},
  31        // {SIGTTOU, "TTOU"}
  32
  33        [0] = "EXIT",
  34#ifdef SIGHUP
  35        [SIGHUP   ] = "HUP",
  36#endif
  37#ifdef SIGINT
  38        [SIGINT   ] = "INT",
  39#endif
  40#ifdef SIGQUIT
  41        [SIGQUIT  ] = "QUIT",
  42#endif
  43#ifdef SIGILL
  44        [SIGILL   ] = "ILL",
  45#endif
  46#ifdef SIGTRAP
  47        [SIGTRAP  ] = "TRAP",
  48#endif
  49#ifdef SIGABRT
  50        [SIGABRT  ] = "ABRT",
  51#endif
  52#ifdef SIGBUS
  53        [SIGBUS   ] = "BUS",
  54#endif
  55#ifdef SIGFPE
  56        [SIGFPE   ] = "FPE",
  57#endif
  58#ifdef SIGKILL
  59        [SIGKILL  ] = "KILL",
  60#endif
  61#ifdef SIGUSR1
  62        [SIGUSR1  ] = "USR1",
  63#endif
  64#ifdef SIGSEGV
  65        [SIGSEGV  ] = "SEGV",
  66#endif
  67#ifdef SIGUSR2
  68        [SIGUSR2  ] = "USR2",
  69#endif
  70#ifdef SIGPIPE
  71        [SIGPIPE  ] = "PIPE",
  72#endif
  73#ifdef SIGALRM
  74        [SIGALRM  ] = "ALRM",
  75#endif
  76#ifdef SIGTERM
  77        [SIGTERM  ] = "TERM",
  78#endif
  79#ifdef SIGSTKFLT
  80        [SIGSTKFLT] = "STKFLT",
  81#endif
  82#ifdef SIGCHLD
  83        [SIGCHLD  ] = "CHLD",
  84#endif
  85#ifdef SIGCONT
  86        [SIGCONT  ] = "CONT",
  87#endif
  88#ifdef SIGSTOP
  89        [SIGSTOP  ] = "STOP",
  90#endif
  91#ifdef SIGTSTP
  92        [SIGTSTP  ] = "TSTP",
  93#endif
  94#ifdef SIGTTIN
  95        [SIGTTIN  ] = "TTIN",
  96#endif
  97#ifdef SIGTTOU
  98        [SIGTTOU  ] = "TTOU",
  99#endif
 100#ifdef SIGURG
 101        [SIGURG   ] = "URG",
 102#endif
 103#ifdef SIGXCPU
 104        [SIGXCPU  ] = "XCPU",
 105#endif
 106#ifdef SIGXFSZ
 107        [SIGXFSZ  ] = "XFSZ",
 108#endif
 109#ifdef SIGVTALRM
 110        [SIGVTALRM] = "VTALRM",
 111#endif
 112#ifdef SIGPROF
 113        [SIGPROF  ] = "PROF",
 114#endif
 115#ifdef SIGWINCH
 116        [SIGWINCH ] = "WINCH",
 117#endif
 118#ifdef SIGPOLL
 119        [SIGPOLL  ] = "POLL",
 120#endif
 121#ifdef SIGPWR
 122        [SIGPWR   ] = "PWR",
 123#endif
 124#ifdef SIGSYS
 125        [SIGSYS   ] = "SYS",
 126#endif
 127#if ENABLE_FEATURE_RTMINMAX
 128# ifdef __SIGRTMIN
 129        [__SIGRTMIN] = "RTMIN",
 130# endif
 131// This makes array about x2 bigger.
 132// More compact approach is to special-case SIGRTMAX in print_signames()
 133//# ifdef __SIGRTMAX
 134//      [__SIGRTMAX] = "RTMAX",
 135//# endif
 136#endif
 137};
 138
 139// Convert signal name to number.
 140
 141int FAST_FUNC get_signum(const char *name)
 142{
 143        unsigned i;
 144
 145        i = bb_strtou(name, NULL, 10);
 146        if (!errno)
 147                return i;
 148        if (strncasecmp(name, "SIG", 3) == 0)
 149                name += 3;
 150        for (i = 0; i < ARRAY_SIZE(signals); i++)
 151                if (strcasecmp(name, signals[i]) == 0)
 152                        return i;
 153
 154#if ENABLE_DESKTOP
 155# if defined(SIGIOT) || defined(SIGIO)
 156        /* SIGIO[T] are aliased to other names,
 157         * thus cannot be stored in the signals[] array.
 158         * Need special code to recognize them */
 159        if ((name[0] | 0x20) == 'i' && (name[1] | 0x20) == 'o') {
 160#  ifdef SIGIO
 161                if (!name[2])
 162                        return SIGIO;
 163#  endif
 164#  ifdef SIGIOT
 165                if ((name[2] | 0x20) == 't' && !name[3])
 166                        return SIGIOT;
 167#  endif
 168        }
 169# endif
 170#endif
 171
 172#if ENABLE_FEATURE_RTMINMAX
 173# if defined(SIGRTMIN) && defined(SIGRTMAX)
 174/* libc may use some rt sigs for pthreads and therefore "remap" SIGRTMIN/MAX,
 175 * but we want to use "raw" SIGRTMIN/MAX. Underscored names, if exist, provide
 176 * them. If they don't exist, fall back to non-underscored ones: */
 177#  if !defined(__SIGRTMIN)
 178#   define __SIGRTMIN SIGRTMIN
 179#  endif
 180#  if !defined(__SIGRTMAX)
 181#   define __SIGRTMAX SIGRTMAX
 182#  endif
 183        if (strncasecmp(name, "RTMIN", 5) == 0) {
 184                if (!name[5])
 185                        return __SIGRTMIN;
 186                if (name[5] == '+') {
 187                        i = bb_strtou(name + 6, NULL, 10);
 188                        if (!errno && i <= __SIGRTMAX - __SIGRTMIN)
 189                                return __SIGRTMIN + i;
 190                }
 191        }
 192        else if (strncasecmp(name, "RTMAX", 5) == 0) {
 193                if (!name[5])
 194                        return __SIGRTMAX;
 195                if (name[5] == '-') {
 196                        i = bb_strtou(name + 6, NULL, 10);
 197                        if (!errno && i <= __SIGRTMAX - __SIGRTMIN)
 198                                return __SIGRTMAX - i;
 199                }
 200        }
 201# endif
 202#endif
 203
 204        return -1;
 205}
 206
 207// Convert signal number to name
 208
 209const char* FAST_FUNC get_signame(int number)
 210{
 211        if ((unsigned)number < ARRAY_SIZE(signals)) {
 212                if (signals[number][0]) /* if it's not an empty str */
 213                        return signals[number];
 214        }
 215
 216        return itoa(number);
 217}
 218
 219
 220// Print the whole signal list
 221
 222void FAST_FUNC print_signames(void)
 223{
 224        unsigned signo;
 225
 226        for (signo = 1; signo < ARRAY_SIZE(signals); signo++) {
 227                const char *name = signals[signo];
 228                if (name[0])
 229                        printf("%2u) %s\n", signo, name);
 230        }
 231#if ENABLE_FEATURE_RTMINMAX
 232# ifdef __SIGRTMAX
 233        printf("%2u) %s\n", __SIGRTMAX, "RTMAX");
 234# endif
 235#endif
 236}
 237