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