Backport the :end-of-capability fix
[emacs.git] / lib / sig2str.c
blob0966dd525ae4df1b526b722277f098703ea4ea8e
1 /* sig2str.c -- convert between signal names and numbers
3 Copyright (C) 2002, 2004, 2006, 2009-2015 Free Software Foundation,
4 Inc.
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 /* Written by Paul Eggert. */
21 #include <config.h>
23 #include <limits.h>
24 #include <signal.h>
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <string.h>
29 #include "sig2str.h"
31 #ifndef SIGRTMIN
32 # define SIGRTMIN 0
33 # undef SIGRTMAX
34 #endif
35 #ifndef SIGRTMAX
36 # define SIGRTMAX (SIGRTMIN - 1)
37 #endif
39 #define NUMNAME(name) { SIG##name, #name }
41 /* Signal names and numbers. Put the preferred name first. */
42 static struct numname { int num; char const name[8]; } numname_table[] =
44 /* Signals required by POSIX 1003.1-2001 base, listed in
45 traditional numeric order where possible. */
46 #ifdef SIGHUP
47 NUMNAME (HUP),
48 #endif
49 #ifdef SIGINT
50 NUMNAME (INT),
51 #endif
52 #ifdef SIGQUIT
53 NUMNAME (QUIT),
54 #endif
55 #ifdef SIGILL
56 NUMNAME (ILL),
57 #endif
58 #ifdef SIGTRAP
59 NUMNAME (TRAP),
60 #endif
61 #ifdef SIGABRT
62 NUMNAME (ABRT),
63 #endif
64 #ifdef SIGFPE
65 NUMNAME (FPE),
66 #endif
67 #ifdef SIGKILL
68 NUMNAME (KILL),
69 #endif
70 #ifdef SIGSEGV
71 NUMNAME (SEGV),
72 #endif
73 /* On Haiku, SIGSEGV == SIGBUS, but we prefer SIGSEGV to match
74 strsignal.c output, so SIGBUS must be listed second. */
75 #ifdef SIGBUS
76 NUMNAME (BUS),
77 #endif
78 #ifdef SIGPIPE
79 NUMNAME (PIPE),
80 #endif
81 #ifdef SIGALRM
82 NUMNAME (ALRM),
83 #endif
84 #ifdef SIGTERM
85 NUMNAME (TERM),
86 #endif
87 #ifdef SIGUSR1
88 NUMNAME (USR1),
89 #endif
90 #ifdef SIGUSR2
91 NUMNAME (USR2),
92 #endif
93 #ifdef SIGCHLD
94 NUMNAME (CHLD),
95 #endif
96 #ifdef SIGURG
97 NUMNAME (URG),
98 #endif
99 #ifdef SIGSTOP
100 NUMNAME (STOP),
101 #endif
102 #ifdef SIGTSTP
103 NUMNAME (TSTP),
104 #endif
105 #ifdef SIGCONT
106 NUMNAME (CONT),
107 #endif
108 #ifdef SIGTTIN
109 NUMNAME (TTIN),
110 #endif
111 #ifdef SIGTTOU
112 NUMNAME (TTOU),
113 #endif
115 /* Signals required by POSIX 1003.1-2001 with the XSI extension. */
116 #ifdef SIGSYS
117 NUMNAME (SYS),
118 #endif
119 #ifdef SIGPOLL
120 NUMNAME (POLL),
121 #endif
122 #ifdef SIGVTALRM
123 NUMNAME (VTALRM),
124 #endif
125 #ifdef SIGPROF
126 NUMNAME (PROF),
127 #endif
128 #ifdef SIGXCPU
129 NUMNAME (XCPU),
130 #endif
131 #ifdef SIGXFSZ
132 NUMNAME (XFSZ),
133 #endif
135 /* Unix Version 7. */
136 #ifdef SIGIOT
137 NUMNAME (IOT), /* Older name for ABRT. */
138 #endif
139 #ifdef SIGEMT
140 NUMNAME (EMT),
141 #endif
143 /* USG Unix. */
144 #ifdef SIGPHONE
145 NUMNAME (PHONE),
146 #endif
147 #ifdef SIGWIND
148 NUMNAME (WIND),
149 #endif
151 /* Unix System V. */
152 #ifdef SIGCLD
153 NUMNAME (CLD),
154 #endif
155 #ifdef SIGPWR
156 NUMNAME (PWR),
157 #endif
159 /* GNU/Linux 2.2 and Solaris 8. */
160 #ifdef SIGCANCEL
161 NUMNAME (CANCEL),
162 #endif
163 #ifdef SIGLWP
164 NUMNAME (LWP),
165 #endif
166 #ifdef SIGWAITING
167 NUMNAME (WAITING),
168 #endif
169 #ifdef SIGFREEZE
170 NUMNAME (FREEZE),
171 #endif
172 #ifdef SIGTHAW
173 NUMNAME (THAW),
174 #endif
175 #ifdef SIGLOST
176 NUMNAME (LOST),
177 #endif
178 #ifdef SIGWINCH
179 NUMNAME (WINCH),
180 #endif
182 /* GNU/Linux 2.2. */
183 #ifdef SIGINFO
184 NUMNAME (INFO),
185 #endif
186 #ifdef SIGIO
187 NUMNAME (IO),
188 #endif
189 #ifdef SIGSTKFLT
190 NUMNAME (STKFLT),
191 #endif
193 /* AIX 5L. */
194 #ifdef SIGDANGER
195 NUMNAME (DANGER),
196 #endif
197 #ifdef SIGGRANT
198 NUMNAME (GRANT),
199 #endif
200 #ifdef SIGMIGRATE
201 NUMNAME (MIGRATE),
202 #endif
203 #ifdef SIGMSG
204 NUMNAME (MSG),
205 #endif
206 #ifdef SIGPRE
207 NUMNAME (PRE),
208 #endif
209 #ifdef SIGRETRACT
210 NUMNAME (RETRACT),
211 #endif
212 #ifdef SIGSAK
213 NUMNAME (SAK),
214 #endif
215 #ifdef SIGSOUND
216 NUMNAME (SOUND),
217 #endif
219 /* Older AIX versions. */
220 #ifdef SIGALRM1
221 NUMNAME (ALRM1), /* unknown; taken from Bash 2.05 */
222 #endif
223 #ifdef SIGKAP
224 NUMNAME (KAP), /* Older name for SIGGRANT. */
225 #endif
226 #ifdef SIGVIRT
227 NUMNAME (VIRT), /* unknown; taken from Bash 2.05 */
228 #endif
229 #ifdef SIGWINDOW
230 NUMNAME (WINDOW), /* Older name for SIGWINCH. */
231 #endif
233 /* BeOS */
234 #ifdef SIGKILLTHR
235 NUMNAME (KILLTHR),
236 #endif
238 /* Older HP-UX versions. */
239 #ifdef SIGDIL
240 NUMNAME (DIL),
241 #endif
243 /* Korn shell and Bash, of uncertain vintage. */
244 { 0, "EXIT" }
247 #define NUMNAME_ENTRIES (sizeof numname_table / sizeof numname_table[0])
249 /* ISDIGIT differs from isdigit, as follows:
250 - Its arg may be any int or unsigned int; it need not be an unsigned char
251 or EOF.
252 - It's typically faster.
253 POSIX says that only '0' through '9' are digits. Prefer ISDIGIT to
254 isdigit unless it's important to use the locale's definition
255 of "digit" even when the host does not conform to POSIX. */
256 #define ISDIGIT(c) ((unsigned int) (c) - '0' <= 9)
258 /* Convert the signal name SIGNAME to a signal number. Return the
259 signal number if successful, -1 otherwise. */
261 static int
262 str2signum (char const *signame)
264 if (ISDIGIT (*signame))
266 char *endp;
267 long int n = strtol (signame, &endp, 10);
268 if (! *endp && n <= SIGNUM_BOUND)
269 return n;
271 else
273 unsigned int i;
274 for (i = 0; i < NUMNAME_ENTRIES; i++)
275 if (strcmp (numname_table[i].name, signame) == 0)
276 return numname_table[i].num;
279 char *endp;
280 int rtmin = SIGRTMIN;
281 int rtmax = SIGRTMAX;
283 if (0 < rtmin && strncmp (signame, "RTMIN", 5) == 0)
285 long int n = strtol (signame + 5, &endp, 10);
286 if (! *endp && 0 <= n && n <= rtmax - rtmin)
287 return rtmin + n;
289 else if (0 < rtmax && strncmp (signame, "RTMAX", 5) == 0)
291 long int n = strtol (signame + 5, &endp, 10);
292 if (! *endp && rtmin - rtmax <= n && n <= 0)
293 return rtmax + n;
298 return -1;
301 /* Convert the signal name SIGNAME to the signal number *SIGNUM.
302 Return 0 if successful, -1 otherwise. */
305 str2sig (char const *signame, int *signum)
307 *signum = str2signum (signame);
308 return *signum < 0 ? -1 : 0;
311 /* Convert SIGNUM to a signal name in SIGNAME. SIGNAME must point to
312 a buffer of at least SIG2STR_MAX bytes. Return 0 if successful, -1
313 otherwise. */
316 sig2str (int signum, char *signame)
318 unsigned int i;
319 for (i = 0; i < NUMNAME_ENTRIES; i++)
320 if (numname_table[i].num == signum)
322 strcpy (signame, numname_table[i].name);
323 return 0;
327 int rtmin = SIGRTMIN;
328 int rtmax = SIGRTMAX;
329 int base, delta;
331 if (! (rtmin <= signum && signum <= rtmax))
332 return -1;
334 if (signum <= rtmin + (rtmax - rtmin) / 2)
336 strcpy (signame, "RTMIN");
337 base = rtmin;
339 else
341 strcpy (signame, "RTMAX");
342 base = rtmax;
345 delta = signum - base;
346 if (delta != 0)
347 sprintf (signame + 5, "%+d", delta);
348 return 0;