strsignal.c revision 1.1 1 1.1 mrg /* Extended support for using signal values.
2 1.1 mrg Written by Fred Fish. fnf (at) cygnus.com
3 1.1 mrg This file is in the public domain. */
4 1.1 mrg
5 1.1 mrg #include "config.h"
6 1.1 mrg #include "ansidecl.h"
7 1.1 mrg #include "libiberty.h"
8 1.1 mrg
9 1.1 mrg /* We need to declare sys_siglist, because even if the system provides
10 1.1 mrg it we can't assume that it is declared in <signal.h> (for example,
11 1.1 mrg SunOS provides sys_siglist, but it does not declare it in any
12 1.1 mrg header file). However, we can't declare sys_siglist portably,
13 1.1 mrg because on some systems it is declared with const and on some
14 1.1 mrg systems it is declared without const. If we were using autoconf,
15 1.1 mrg we could work out the right declaration. Until, then we just
16 1.1 mrg ignore any declaration in the system header files, and always
17 1.1 mrg declare it ourselves. With luck, this will always work. */
18 1.1 mrg #define sys_siglist no_such_symbol
19 1.1 mrg #define sys_nsig sys_nsig__no_such_symbol
20 1.1 mrg
21 1.1 mrg #include <stdio.h>
22 1.1 mrg #include <signal.h>
23 1.1 mrg
24 1.1 mrg /* Routines imported from standard C runtime libraries. */
25 1.1 mrg
26 1.1 mrg #ifdef HAVE_STDLIB_H
27 1.1 mrg #include <stdlib.h>
28 1.1 mrg #else
29 1.1 mrg extern PTR malloc ();
30 1.1 mrg #endif
31 1.1 mrg
32 1.1 mrg #ifdef HAVE_STRING_H
33 1.1 mrg #include <string.h>
34 1.1 mrg #else
35 1.1 mrg extern PTR memset ();
36 1.1 mrg #endif
37 1.1 mrg
38 1.1 mrg /* Undefine the macro we used to hide the definition of sys_siglist
39 1.1 mrg found in the system header files. */
40 1.1 mrg #undef sys_siglist
41 1.1 mrg #undef sys_nsig
42 1.1 mrg
43 1.1 mrg #ifndef NULL
44 1.1 mrg # define NULL (void *) 0
45 1.1 mrg #endif
46 1.1 mrg
47 1.1 mrg #ifndef MAX
48 1.1 mrg # define MAX(a,b) ((a) > (b) ? (a) : (b))
49 1.1 mrg #endif
50 1.1 mrg
51 1.1 mrg static void init_signal_tables (void);
52 1.1 mrg
53 1.1 mrg /* Translation table for signal values.
54 1.1 mrg
55 1.1 mrg Note that this table is generally only accessed when it is used at runtime
56 1.1 mrg to initialize signal name and message tables that are indexed by signal
57 1.1 mrg value.
58 1.1 mrg
59 1.1 mrg Not all of these signals will exist on all systems. This table is the only
60 1.1 mrg thing that should have to be updated as new signal numbers are introduced.
61 1.1 mrg It's sort of ugly, but at least its portable. */
62 1.1 mrg
63 1.1 mrg struct signal_info
64 1.1 mrg {
65 1.1 mrg const int value; /* The numeric value from <signal.h> */
66 1.1 mrg const char *const name; /* The equivalent symbolic value */
67 1.1 mrg #ifndef HAVE_SYS_SIGLIST
68 1.1 mrg const char *const msg; /* Short message about this value */
69 1.1 mrg #endif
70 1.1 mrg };
71 1.1 mrg
72 1.1 mrg #ifndef HAVE_SYS_SIGLIST
73 1.1 mrg # define ENTRY(value, name, msg) {value, name, msg}
74 1.1 mrg #else
75 1.1 mrg # define ENTRY(value, name, msg) {value, name}
76 1.1 mrg #endif
77 1.1 mrg
78 1.1 mrg static const struct signal_info signal_table[] =
79 1.1 mrg {
80 1.1 mrg #if defined (SIGHUP)
81 1.1 mrg ENTRY(SIGHUP, "SIGHUP", "Hangup"),
82 1.1 mrg #endif
83 1.1 mrg #if defined (SIGINT)
84 1.1 mrg ENTRY(SIGINT, "SIGINT", "Interrupt"),
85 1.1 mrg #endif
86 1.1 mrg #if defined (SIGQUIT)
87 1.1 mrg ENTRY(SIGQUIT, "SIGQUIT", "Quit"),
88 1.1 mrg #endif
89 1.1 mrg #if defined (SIGILL)
90 1.1 mrg ENTRY(SIGILL, "SIGILL", "Illegal instruction"),
91 1.1 mrg #endif
92 1.1 mrg #if defined (SIGTRAP)
93 1.1 mrg ENTRY(SIGTRAP, "SIGTRAP", "Trace/breakpoint trap"),
94 1.1 mrg #endif
95 1.1 mrg /* Put SIGIOT before SIGABRT, so that if SIGIOT==SIGABRT then SIGABRT
96 1.1 mrg overrides SIGIOT. SIGABRT is in ANSI and POSIX.1, and SIGIOT isn't. */
97 1.1 mrg #if defined (SIGIOT)
98 1.1 mrg ENTRY(SIGIOT, "SIGIOT", "IOT trap"),
99 1.1 mrg #endif
100 1.1 mrg #if defined (SIGABRT)
101 1.1 mrg ENTRY(SIGABRT, "SIGABRT", "Aborted"),
102 1.1 mrg #endif
103 1.1 mrg #if defined (SIGEMT)
104 1.1 mrg ENTRY(SIGEMT, "SIGEMT", "Emulation trap"),
105 1.1 mrg #endif
106 1.1 mrg #if defined (SIGFPE)
107 1.1 mrg ENTRY(SIGFPE, "SIGFPE", "Arithmetic exception"),
108 1.1 mrg #endif
109 1.1 mrg #if defined (SIGKILL)
110 1.1 mrg ENTRY(SIGKILL, "SIGKILL", "Killed"),
111 1.1 mrg #endif
112 1.1 mrg #if defined (SIGBUS)
113 1.1 mrg ENTRY(SIGBUS, "SIGBUS", "Bus error"),
114 1.1 mrg #endif
115 1.1 mrg #if defined (SIGSEGV)
116 1.1 mrg ENTRY(SIGSEGV, "SIGSEGV", "Segmentation fault"),
117 1.1 mrg #endif
118 1.1 mrg #if defined (SIGSYS)
119 1.1 mrg ENTRY(SIGSYS, "SIGSYS", "Bad system call"),
120 1.1 mrg #endif
121 1.1 mrg #if defined (SIGPIPE)
122 1.1 mrg ENTRY(SIGPIPE, "SIGPIPE", "Broken pipe"),
123 1.1 mrg #endif
124 1.1 mrg #if defined (SIGALRM)
125 1.1 mrg ENTRY(SIGALRM, "SIGALRM", "Alarm clock"),
126 1.1 mrg #endif
127 1.1 mrg #if defined (SIGTERM)
128 1.1 mrg ENTRY(SIGTERM, "SIGTERM", "Terminated"),
129 1.1 mrg #endif
130 1.1 mrg #if defined (SIGUSR1)
131 1.1 mrg ENTRY(SIGUSR1, "SIGUSR1", "User defined signal 1"),
132 1.1 mrg #endif
133 1.1 mrg #if defined (SIGUSR2)
134 1.1 mrg ENTRY(SIGUSR2, "SIGUSR2", "User defined signal 2"),
135 1.1 mrg #endif
136 1.1 mrg /* Put SIGCLD before SIGCHLD, so that if SIGCLD==SIGCHLD then SIGCHLD
137 1.1 mrg overrides SIGCLD. SIGCHLD is in POXIX.1 */
138 1.1 mrg #if defined (SIGCLD)
139 1.1 mrg ENTRY(SIGCLD, "SIGCLD", "Child status changed"),
140 1.1 mrg #endif
141 1.1 mrg #if defined (SIGCHLD)
142 1.1 mrg ENTRY(SIGCHLD, "SIGCHLD", "Child status changed"),
143 1.1 mrg #endif
144 1.1 mrg #if defined (SIGPWR)
145 1.1 mrg ENTRY(SIGPWR, "SIGPWR", "Power fail/restart"),
146 1.1 mrg #endif
147 1.1 mrg #if defined (SIGWINCH)
148 1.1 mrg ENTRY(SIGWINCH, "SIGWINCH", "Window size changed"),
149 1.1 mrg #endif
150 1.1 mrg #if defined (SIGURG)
151 1.1 mrg ENTRY(SIGURG, "SIGURG", "Urgent I/O condition"),
152 1.1 mrg #endif
153 1.1 mrg #if defined (SIGIO)
154 1.1 mrg /* "I/O pending" has also been suggested, but is misleading since the
155 1.1 mrg signal only happens when the process has asked for it, not everytime
156 1.1 mrg I/O is pending. */
157 1.1 mrg ENTRY(SIGIO, "SIGIO", "I/O possible"),
158 1.1 mrg #endif
159 1.1 mrg #if defined (SIGPOLL)
160 1.1 mrg ENTRY(SIGPOLL, "SIGPOLL", "Pollable event occurred"),
161 1.1 mrg #endif
162 1.1 mrg #if defined (SIGSTOP)
163 1.1 mrg ENTRY(SIGSTOP, "SIGSTOP", "Stopped (signal)"),
164 1.1 mrg #endif
165 1.1 mrg #if defined (SIGTSTP)
166 1.1 mrg ENTRY(SIGTSTP, "SIGTSTP", "Stopped (user)"),
167 1.1 mrg #endif
168 1.1 mrg #if defined (SIGCONT)
169 1.1 mrg ENTRY(SIGCONT, "SIGCONT", "Continued"),
170 1.1 mrg #endif
171 1.1 mrg #if defined (SIGTTIN)
172 1.1 mrg ENTRY(SIGTTIN, "SIGTTIN", "Stopped (tty input)"),
173 1.1 mrg #endif
174 1.1 mrg #if defined (SIGTTOU)
175 1.1 mrg ENTRY(SIGTTOU, "SIGTTOU", "Stopped (tty output)"),
176 1.1 mrg #endif
177 1.1 mrg #if defined (SIGVTALRM)
178 1.1 mrg ENTRY(SIGVTALRM, "SIGVTALRM", "Virtual timer expired"),
179 1.1 mrg #endif
180 1.1 mrg #if defined (SIGPROF)
181 1.1 mrg ENTRY(SIGPROF, "SIGPROF", "Profiling timer expired"),
182 1.1 mrg #endif
183 1.1 mrg #if defined (SIGXCPU)
184 1.1 mrg ENTRY(SIGXCPU, "SIGXCPU", "CPU time limit exceeded"),
185 1.1 mrg #endif
186 1.1 mrg #if defined (SIGXFSZ)
187 1.1 mrg ENTRY(SIGXFSZ, "SIGXFSZ", "File size limit exceeded"),
188 1.1 mrg #endif
189 1.1 mrg #if defined (SIGWIND)
190 1.1 mrg ENTRY(SIGWIND, "SIGWIND", "SIGWIND"),
191 1.1 mrg #endif
192 1.1 mrg #if defined (SIGPHONE)
193 1.1 mrg ENTRY(SIGPHONE, "SIGPHONE", "SIGPHONE"),
194 1.1 mrg #endif
195 1.1 mrg #if defined (SIGLOST)
196 1.1 mrg ENTRY(SIGLOST, "SIGLOST", "Resource lost"),
197 1.1 mrg #endif
198 1.1 mrg #if defined (SIGWAITING)
199 1.1 mrg ENTRY(SIGWAITING, "SIGWAITING", "Process's LWPs are blocked"),
200 1.1 mrg #endif
201 1.1 mrg #if defined (SIGLWP)
202 1.1 mrg ENTRY(SIGLWP, "SIGLWP", "Signal LWP"),
203 1.1 mrg #endif
204 1.1 mrg #if defined (SIGDANGER)
205 1.1 mrg ENTRY(SIGDANGER, "SIGDANGER", "Swap space dangerously low"),
206 1.1 mrg #endif
207 1.1 mrg #if defined (SIGGRANT)
208 1.1 mrg ENTRY(SIGGRANT, "SIGGRANT", "Monitor mode granted"),
209 1.1 mrg #endif
210 1.1 mrg #if defined (SIGRETRACT)
211 1.1 mrg ENTRY(SIGRETRACT, "SIGRETRACT", "Need to relinguish monitor mode"),
212 1.1 mrg #endif
213 1.1 mrg #if defined (SIGMSG)
214 1.1 mrg ENTRY(SIGMSG, "SIGMSG", "Monitor mode data available"),
215 1.1 mrg #endif
216 1.1 mrg #if defined (SIGSOUND)
217 1.1 mrg ENTRY(SIGSOUND, "SIGSOUND", "Sound completed"),
218 1.1 mrg #endif
219 1.1 mrg #if defined (SIGSAK)
220 1.1 mrg ENTRY(SIGSAK, "SIGSAK", "Secure attention"),
221 1.1 mrg #endif
222 1.1 mrg ENTRY(0, NULL, NULL)
223 1.1 mrg };
224 1.1 mrg
225 1.1 mrg /* Translation table allocated and initialized at runtime. Indexed by the
226 1.1 mrg signal value to find the equivalent symbolic value. */
227 1.1 mrg
228 1.1 mrg static const char **signal_names;
229 1.1 mrg static int num_signal_names = 0;
230 1.1 mrg
231 1.1 mrg /* Translation table allocated and initialized at runtime, if it does not
232 1.1 mrg already exist in the host environment. Indexed by the signal value to find
233 1.1 mrg the descriptive string.
234 1.1 mrg
235 1.1 mrg We don't export it for use in other modules because even though it has the
236 1.1 mrg same name, it differs from other implementations in that it is dynamically
237 1.1 mrg initialized rather than statically initialized. */
238 1.1 mrg
239 1.1 mrg #ifndef HAVE_SYS_SIGLIST
240 1.1 mrg
241 1.1 mrg static int sys_nsig;
242 1.1 mrg static const char **sys_siglist;
243 1.1 mrg
244 1.1 mrg #else
245 1.1 mrg
246 1.1 mrg #ifdef NSIG
247 1.1 mrg static int sys_nsig = NSIG;
248 1.1 mrg #else
249 1.1 mrg #ifdef _NSIG
250 1.1 mrg static int sys_nsig = _NSIG;
251 1.1 mrg #endif
252 1.1 mrg #endif
253 1.1 mrg extern const char * const sys_siglist[];
254 1.1 mrg
255 1.1 mrg #endif
256 1.1 mrg
257 1.1 mrg
258 1.1 mrg /*
259 1.1 mrg
260 1.1 mrg NAME
261 1.1 mrg
262 1.1 mrg init_signal_tables -- initialize the name and message tables
263 1.1 mrg
264 1.1 mrg SYNOPSIS
265 1.1 mrg
266 1.1 mrg static void init_signal_tables ();
267 1.1 mrg
268 1.1 mrg DESCRIPTION
269 1.1 mrg
270 1.1 mrg Using the signal_table, which is initialized at compile time, generate
271 1.1 mrg the signal_names and the sys_siglist (if needed) tables, which are
272 1.1 mrg indexed at runtime by a specific signal value.
273 1.1 mrg
274 1.1 mrg BUGS
275 1.1 mrg
276 1.1 mrg The initialization of the tables may fail under low memory conditions,
277 1.1 mrg in which case we don't do anything particularly useful, but we don't
278 1.1 mrg bomb either. Who knows, it might succeed at a later point if we free
279 1.1 mrg some memory in the meantime. In any case, the other routines know
280 1.1 mrg how to deal with lack of a table after trying to initialize it. This
281 1.1 mrg may or may not be considered to be a bug, that we don't specifically
282 1.1 mrg warn about this particular failure mode.
283 1.1 mrg
284 1.1 mrg */
285 1.1 mrg
286 1.1 mrg static void
287 1.1 mrg init_signal_tables (void)
288 1.1 mrg {
289 1.1 mrg const struct signal_info *eip;
290 1.1 mrg int nbytes;
291 1.1 mrg
292 1.1 mrg /* If we haven't already scanned the signal_table once to find the maximum
293 1.1 mrg signal value, then go find it now. */
294 1.1 mrg
295 1.1 mrg if (num_signal_names == 0)
296 1.1 mrg {
297 1.1 mrg for (eip = signal_table; eip -> name != NULL; eip++)
298 1.1 mrg {
299 1.1 mrg if (eip -> value >= num_signal_names)
300 1.1 mrg {
301 1.1 mrg num_signal_names = eip -> value + 1;
302 1.1 mrg }
303 1.1 mrg }
304 1.1 mrg }
305 1.1 mrg
306 1.1 mrg /* Now attempt to allocate the signal_names table, zero it out, and then
307 1.1 mrg initialize it from the statically initialized signal_table. */
308 1.1 mrg
309 1.1 mrg if (signal_names == NULL)
310 1.1 mrg {
311 1.1 mrg nbytes = num_signal_names * sizeof (char *);
312 1.1 mrg if ((signal_names = (const char **) malloc (nbytes)) != NULL)
313 1.1 mrg {
314 1.1 mrg memset (signal_names, 0, nbytes);
315 1.1 mrg for (eip = signal_table; eip -> name != NULL; eip++)
316 1.1 mrg {
317 1.1 mrg signal_names[eip -> value] = eip -> name;
318 1.1 mrg }
319 1.1 mrg }
320 1.1 mrg }
321 1.1 mrg
322 1.1 mrg #ifndef HAVE_SYS_SIGLIST
323 1.1 mrg
324 1.1 mrg /* Now attempt to allocate the sys_siglist table, zero it out, and then
325 1.1 mrg initialize it from the statically initialized signal_table. */
326 1.1 mrg
327 1.1 mrg if (sys_siglist == NULL)
328 1.1 mrg {
329 1.1 mrg nbytes = num_signal_names * sizeof (char *);
330 1.1 mrg if ((sys_siglist = (const char **) malloc (nbytes)) != NULL)
331 1.1 mrg {
332 1.1 mrg memset (sys_siglist, 0, nbytes);
333 1.1 mrg sys_nsig = num_signal_names;
334 1.1 mrg for (eip = signal_table; eip -> name != NULL; eip++)
335 1.1 mrg {
336 1.1 mrg sys_siglist[eip -> value] = eip -> msg;
337 1.1 mrg }
338 1.1 mrg }
339 1.1 mrg }
340 1.1 mrg
341 1.1 mrg #endif
342 1.1 mrg
343 1.1 mrg }
344 1.1 mrg
345 1.1 mrg
346 1.1 mrg /*
347 1.1 mrg
348 1.1 mrg @deftypefn Extension int signo_max (void)
349 1.1 mrg
350 1.1 mrg Returns the maximum signal value for which a corresponding symbolic
351 1.1 mrg name or message is available. Note that in the case where we use the
352 1.1 mrg @code{sys_siglist} supplied by the system, it is possible for there to
353 1.1 mrg be more symbolic names than messages, or vice versa. In fact, the
354 1.1 mrg manual page for @code{psignal(3b)} explicitly warns that one should
355 1.1 mrg check the size of the table (@code{NSIG}) before indexing it, since
356 1.1 mrg new signal codes may be added to the system before they are added to
357 1.1 mrg the table. Thus @code{NSIG} might be smaller than value implied by
358 1.1 mrg the largest signo value defined in @code{<signal.h>}.
359 1.1 mrg
360 1.1 mrg We return the maximum value that can be used to obtain a meaningful
361 1.1 mrg symbolic name or message.
362 1.1 mrg
363 1.1 mrg @end deftypefn
364 1.1 mrg
365 1.1 mrg */
366 1.1 mrg
367 1.1 mrg int
368 1.1 mrg signo_max (void)
369 1.1 mrg {
370 1.1 mrg int maxsize;
371 1.1 mrg
372 1.1 mrg if (signal_names == NULL)
373 1.1 mrg {
374 1.1 mrg init_signal_tables ();
375 1.1 mrg }
376 1.1 mrg maxsize = MAX (sys_nsig, num_signal_names);
377 1.1 mrg return (maxsize - 1);
378 1.1 mrg }
379 1.1 mrg
380 1.1 mrg
381 1.1 mrg /*
382 1.1 mrg
383 1.1 mrg @deftypefn Supplemental {const char *} strsignal (int @var{signo})
384 1.1 mrg
385 1.1 mrg Maps an signal number to an signal message string, the contents of
386 1.1 mrg which are implementation defined. On systems which have the external
387 1.1 mrg variable @code{sys_siglist}, these strings will be the same as the
388 1.1 mrg ones used by @code{psignal()}.
389 1.1 mrg
390 1.1 mrg If the supplied signal number is within the valid range of indices for
391 1.1 mrg the @code{sys_siglist}, but no message is available for the particular
392 1.1 mrg signal number, then returns the string @samp{Signal @var{num}}, where
393 1.1 mrg @var{num} is the signal number.
394 1.1 mrg
395 1.1 mrg If the supplied signal number is not a valid index into
396 1.1 mrg @code{sys_siglist}, returns @code{NULL}.
397 1.1 mrg
398 1.1 mrg The returned string is only guaranteed to be valid only until the next
399 1.1 mrg call to @code{strsignal}.
400 1.1 mrg
401 1.1 mrg @end deftypefn
402 1.1 mrg
403 1.1 mrg */
404 1.1 mrg
405 1.1 mrg #ifndef HAVE_STRSIGNAL
406 1.1 mrg
407 1.1 mrg char *
408 1.1 mrg strsignal (int signo)
409 1.1 mrg {
410 1.1 mrg char *msg;
411 1.1 mrg static char buf[32];
412 1.1 mrg
413 1.1 mrg #ifndef HAVE_SYS_SIGLIST
414 1.1 mrg
415 1.1 mrg if (signal_names == NULL)
416 1.1 mrg {
417 1.1 mrg init_signal_tables ();
418 1.1 mrg }
419 1.1 mrg
420 1.1 mrg #endif
421 1.1 mrg
422 1.1 mrg if ((signo < 0) || (signo >= sys_nsig))
423 1.1 mrg {
424 1.1 mrg /* Out of range, just return NULL */
425 1.1 mrg msg = NULL;
426 1.1 mrg }
427 1.1 mrg else if ((sys_siglist == NULL) || (sys_siglist[signo] == NULL))
428 1.1 mrg {
429 1.1 mrg /* In range, but no sys_siglist or no entry at this index. */
430 1.1 mrg sprintf (buf, "Signal %d", signo);
431 1.1 mrg msg = buf;
432 1.1 mrg }
433 1.1 mrg else
434 1.1 mrg {
435 1.1 mrg /* In range, and a valid message. Just return the message. We
436 1.1 mrg can safely cast away const, since POSIX says the user must
437 1.1 mrg not modify the result. */
438 1.1 mrg msg = (char *) sys_siglist[signo];
439 1.1 mrg }
440 1.1 mrg
441 1.1 mrg return (msg);
442 1.1 mrg }
443 1.1 mrg
444 1.1 mrg #endif /* ! HAVE_STRSIGNAL */
445 1.1 mrg
446 1.1 mrg /*
447 1.1 mrg
448 1.1 mrg @deftypefn Extension {const char*} strsigno (int @var{signo})
449 1.1 mrg
450 1.1 mrg Given an signal number, returns a pointer to a string containing the
451 1.1 mrg symbolic name of that signal number, as found in @code{<signal.h>}.
452 1.1 mrg
453 1.1 mrg If the supplied signal number is within the valid range of indices for
454 1.1 mrg symbolic names, but no name is available for the particular signal
455 1.1 mrg number, then returns the string @samp{Signal @var{num}}, where
456 1.1 mrg @var{num} is the signal number.
457 1.1 mrg
458 1.1 mrg If the supplied signal number is not within the range of valid
459 1.1 mrg indices, then returns @code{NULL}.
460 1.1 mrg
461 1.1 mrg The contents of the location pointed to are only guaranteed to be
462 1.1 mrg valid until the next call to @code{strsigno}.
463 1.1 mrg
464 1.1 mrg @end deftypefn
465 1.1 mrg
466 1.1 mrg */
467 1.1 mrg
468 1.1 mrg const char *
469 1.1 mrg strsigno (int signo)
470 1.1 mrg {
471 1.1 mrg const char *name;
472 1.1 mrg static char buf[32];
473 1.1 mrg
474 1.1 mrg if (signal_names == NULL)
475 1.1 mrg {
476 1.1 mrg init_signal_tables ();
477 1.1 mrg }
478 1.1 mrg
479 1.1 mrg if ((signo < 0) || (signo >= num_signal_names))
480 1.1 mrg {
481 1.1 mrg /* Out of range, just return NULL */
482 1.1 mrg name = NULL;
483 1.1 mrg }
484 1.1 mrg else if ((signal_names == NULL) || (signal_names[signo] == NULL))
485 1.1 mrg {
486 1.1 mrg /* In range, but no signal_names or no entry at this index. */
487 1.1 mrg sprintf (buf, "Signal %d", signo);
488 1.1 mrg name = (const char *) buf;
489 1.1 mrg }
490 1.1 mrg else
491 1.1 mrg {
492 1.1 mrg /* In range, and a valid name. Just return the name. */
493 1.1 mrg name = signal_names[signo];
494 1.1 mrg }
495 1.1 mrg
496 1.1 mrg return (name);
497 1.1 mrg }
498 1.1 mrg
499 1.1 mrg
500 1.1 mrg /*
501 1.1 mrg
502 1.1 mrg @deftypefn Extension int strtosigno (const char *@var{name})
503 1.1 mrg
504 1.1 mrg Given the symbolic name of a signal, map it to a signal number. If no
505 1.1 mrg translation is found, returns 0.
506 1.1 mrg
507 1.1 mrg @end deftypefn
508 1.1 mrg
509 1.1 mrg */
510 1.1 mrg
511 1.1 mrg int
512 1.1 mrg strtosigno (const char *name)
513 1.1 mrg {
514 1.1 mrg int signo = 0;
515 1.1 mrg
516 1.1 mrg if (name != NULL)
517 1.1 mrg {
518 1.1 mrg if (signal_names == NULL)
519 1.1 mrg {
520 1.1 mrg init_signal_tables ();
521 1.1 mrg }
522 1.1 mrg for (signo = 0; signo < num_signal_names; signo++)
523 1.1 mrg {
524 1.1 mrg if ((signal_names[signo] != NULL) &&
525 1.1 mrg (strcmp (name, signal_names[signo]) == 0))
526 1.1 mrg {
527 1.1 mrg break;
528 1.1 mrg }
529 1.1 mrg }
530 1.1 mrg if (signo == num_signal_names)
531 1.1 mrg {
532 1.1 mrg signo = 0;
533 1.1 mrg }
534 1.1 mrg }
535 1.1 mrg return (signo);
536 1.1 mrg }
537 1.1 mrg
538 1.1 mrg
539 1.1 mrg /*
540 1.1 mrg
541 1.1 mrg @deftypefn Supplemental void psignal (int @var{signo}, char *@var{message})
542 1.1 mrg
543 1.1 mrg Print @var{message} to the standard error, followed by a colon,
544 1.1 mrg followed by the description of the signal specified by @var{signo},
545 1.1 mrg followed by a newline.
546 1.1 mrg
547 1.1 mrg @end deftypefn
548 1.1 mrg
549 1.1 mrg */
550 1.1 mrg
551 1.1 mrg #ifndef HAVE_PSIGNAL
552 1.1 mrg
553 1.1 mrg void
554 1.1 mrg psignal (int signo, char *message)
555 1.1 mrg {
556 1.1 mrg if (signal_names == NULL)
557 1.1 mrg {
558 1.1 mrg init_signal_tables ();
559 1.1 mrg }
560 1.1 mrg if ((signo <= 0) || (signo >= sys_nsig))
561 1.1 mrg {
562 1.1 mrg fprintf (stderr, "%s: unknown signal\n", message);
563 1.1 mrg }
564 1.1 mrg else
565 1.1 mrg {
566 1.1 mrg fprintf (stderr, "%s: %s\n", message, sys_siglist[signo]);
567 1.1 mrg }
568 1.1 mrg }
569 1.1 mrg
570 1.1 mrg #endif /* ! HAVE_PSIGNAL */
571 1.1 mrg
572 1.1 mrg
573 1.1 mrg /* A simple little main that does nothing but print all the signal translations
574 1.1 mrg if MAIN is defined and this file is compiled and linked. */
575 1.1 mrg
576 1.1 mrg #ifdef MAIN
577 1.1 mrg
578 1.1 mrg #include <stdio.h>
579 1.1 mrg
580 1.1 mrg int
581 1.1 mrg main (void)
582 1.1 mrg {
583 1.1 mrg int signo;
584 1.1 mrg int maxsigno;
585 1.1 mrg const char *name;
586 1.1 mrg const char *msg;
587 1.1 mrg
588 1.1 mrg maxsigno = signo_max ();
589 1.1 mrg printf ("%d entries in names table.\n", num_signal_names);
590 1.1 mrg printf ("%d entries in messages table.\n", sys_nsig);
591 1.1 mrg printf ("%d is max useful index.\n", maxsigno);
592 1.1 mrg
593 1.1 mrg /* Keep printing values until we get to the end of *both* tables, not
594 1.1 mrg *either* table. Note that knowing the maximum useful index does *not*
595 1.1 mrg relieve us of the responsibility of testing the return pointer for
596 1.1 mrg NULL. */
597 1.1 mrg
598 1.1 mrg for (signo = 0; signo <= maxsigno; signo++)
599 1.1 mrg {
600 1.1 mrg name = strsigno (signo);
601 1.1 mrg name = (name == NULL) ? "<NULL>" : name;
602 1.1 mrg msg = strsignal (signo);
603 1.1 mrg msg = (msg == NULL) ? "<NULL>" : msg;
604 1.1 mrg printf ("%-4d%-18s%s\n", signo, name, msg);
605 1.1 mrg }
606 1.1 mrg
607 1.1 mrg return 0;
608 1.1 mrg }
609 1.1 mrg
610 1.1 mrg #endif
611