blob: b49714f2a6473989060dcf93ebb4f3c53475c980
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 | |
22 | static const char signals[][7] ALIGN1 = { |
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 | |
141 | int 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 | |
209 | const 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 | |
222 | void 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 |