1440a403fSchristos /* Extended support for using signal values.
2440a403fSchristos Written by Fred Fish. fnf@cygnus.com
3440a403fSchristos This file is in the public domain. */
4440a403fSchristos
5440a403fSchristos #include "config.h"
6440a403fSchristos #include "ansidecl.h"
7440a403fSchristos #include "libiberty.h"
8440a403fSchristos
9440a403fSchristos /* We need to declare sys_siglist, because even if the system provides
10440a403fSchristos it we can't assume that it is declared in <signal.h> (for example,
11440a403fSchristos SunOS provides sys_siglist, but it does not declare it in any
12440a403fSchristos header file). However, we can't declare sys_siglist portably,
13440a403fSchristos because on some systems it is declared with const and on some
14440a403fSchristos systems it is declared without const. If we were using autoconf,
15440a403fSchristos we could work out the right declaration. Until, then we just
16440a403fSchristos ignore any declaration in the system header files, and always
17440a403fSchristos declare it ourselves. With luck, this will always work. */
18440a403fSchristos #define sys_siglist no_such_symbol
19440a403fSchristos #define sys_nsig sys_nsig__no_such_symbol
20440a403fSchristos
21440a403fSchristos #include <stdio.h>
22440a403fSchristos #include <signal.h>
23440a403fSchristos
24440a403fSchristos /* Routines imported from standard C runtime libraries. */
25440a403fSchristos
26440a403fSchristos #ifdef HAVE_STDLIB_H
27440a403fSchristos #include <stdlib.h>
28440a403fSchristos #else
29440a403fSchristos extern PTR malloc ();
30440a403fSchristos #endif
31440a403fSchristos
32440a403fSchristos #ifdef HAVE_STRING_H
33440a403fSchristos #include <string.h>
34440a403fSchristos #else
35440a403fSchristos extern PTR memset ();
36440a403fSchristos #endif
37440a403fSchristos
38440a403fSchristos /* Undefine the macro we used to hide the definition of sys_siglist
39440a403fSchristos found in the system header files. */
40440a403fSchristos #undef sys_siglist
41440a403fSchristos #undef sys_nsig
42440a403fSchristos
43440a403fSchristos #ifndef NULL
44440a403fSchristos # define NULL (void *) 0
45440a403fSchristos #endif
46440a403fSchristos
47440a403fSchristos #ifndef MAX
48440a403fSchristos # define MAX(a,b) ((a) > (b) ? (a) : (b))
49440a403fSchristos #endif
50440a403fSchristos
51440a403fSchristos static void init_signal_tables (void);
52440a403fSchristos
53440a403fSchristos /* Translation table for signal values.
54440a403fSchristos
55440a403fSchristos Note that this table is generally only accessed when it is used at runtime
56440a403fSchristos to initialize signal name and message tables that are indexed by signal
57440a403fSchristos value.
58440a403fSchristos
59440a403fSchristos Not all of these signals will exist on all systems. This table is the only
60440a403fSchristos thing that should have to be updated as new signal numbers are introduced.
61440a403fSchristos It's sort of ugly, but at least its portable. */
62440a403fSchristos
63440a403fSchristos struct signal_info
64440a403fSchristos {
65440a403fSchristos const int value; /* The numeric value from <signal.h> */
66440a403fSchristos const char *const name; /* The equivalent symbolic value */
67440a403fSchristos #ifndef HAVE_SYS_SIGLIST
68440a403fSchristos const char *const msg; /* Short message about this value */
69440a403fSchristos #endif
70440a403fSchristos };
71440a403fSchristos
72440a403fSchristos #ifndef HAVE_SYS_SIGLIST
73440a403fSchristos # define ENTRY(value, name, msg) {value, name, msg}
74440a403fSchristos #else
75440a403fSchristos # define ENTRY(value, name, msg) {value, name}
76440a403fSchristos #endif
77440a403fSchristos
78440a403fSchristos static const struct signal_info signal_table[] =
79440a403fSchristos {
80440a403fSchristos #if defined (SIGHUP)
81440a403fSchristos ENTRY(SIGHUP, "SIGHUP", "Hangup"),
82440a403fSchristos #endif
83440a403fSchristos #if defined (SIGINT)
84440a403fSchristos ENTRY(SIGINT, "SIGINT", "Interrupt"),
85440a403fSchristos #endif
86440a403fSchristos #if defined (SIGQUIT)
87440a403fSchristos ENTRY(SIGQUIT, "SIGQUIT", "Quit"),
88440a403fSchristos #endif
89440a403fSchristos #if defined (SIGILL)
90440a403fSchristos ENTRY(SIGILL, "SIGILL", "Illegal instruction"),
91440a403fSchristos #endif
92440a403fSchristos #if defined (SIGTRAP)
93440a403fSchristos ENTRY(SIGTRAP, "SIGTRAP", "Trace/breakpoint trap"),
94440a403fSchristos #endif
95440a403fSchristos /* Put SIGIOT before SIGABRT, so that if SIGIOT==SIGABRT then SIGABRT
96440a403fSchristos overrides SIGIOT. SIGABRT is in ANSI and POSIX.1, and SIGIOT isn't. */
97440a403fSchristos #if defined (SIGIOT)
98440a403fSchristos ENTRY(SIGIOT, "SIGIOT", "IOT trap"),
99440a403fSchristos #endif
100440a403fSchristos #if defined (SIGABRT)
101440a403fSchristos ENTRY(SIGABRT, "SIGABRT", "Aborted"),
102440a403fSchristos #endif
103440a403fSchristos #if defined (SIGEMT)
104440a403fSchristos ENTRY(SIGEMT, "SIGEMT", "Emulation trap"),
105440a403fSchristos #endif
106440a403fSchristos #if defined (SIGFPE)
107440a403fSchristos ENTRY(SIGFPE, "SIGFPE", "Arithmetic exception"),
108440a403fSchristos #endif
109440a403fSchristos #if defined (SIGKILL)
110440a403fSchristos ENTRY(SIGKILL, "SIGKILL", "Killed"),
111440a403fSchristos #endif
112440a403fSchristos #if defined (SIGBUS)
113440a403fSchristos ENTRY(SIGBUS, "SIGBUS", "Bus error"),
114440a403fSchristos #endif
115440a403fSchristos #if defined (SIGSEGV)
116440a403fSchristos ENTRY(SIGSEGV, "SIGSEGV", "Segmentation fault"),
117440a403fSchristos #endif
118440a403fSchristos #if defined (SIGSYS)
119440a403fSchristos ENTRY(SIGSYS, "SIGSYS", "Bad system call"),
120440a403fSchristos #endif
121440a403fSchristos #if defined (SIGPIPE)
122440a403fSchristos ENTRY(SIGPIPE, "SIGPIPE", "Broken pipe"),
123440a403fSchristos #endif
124440a403fSchristos #if defined (SIGALRM)
125440a403fSchristos ENTRY(SIGALRM, "SIGALRM", "Alarm clock"),
126440a403fSchristos #endif
127440a403fSchristos #if defined (SIGTERM)
128440a403fSchristos ENTRY(SIGTERM, "SIGTERM", "Terminated"),
129440a403fSchristos #endif
130440a403fSchristos #if defined (SIGUSR1)
131440a403fSchristos ENTRY(SIGUSR1, "SIGUSR1", "User defined signal 1"),
132440a403fSchristos #endif
133440a403fSchristos #if defined (SIGUSR2)
134440a403fSchristos ENTRY(SIGUSR2, "SIGUSR2", "User defined signal 2"),
135440a403fSchristos #endif
136440a403fSchristos /* Put SIGCLD before SIGCHLD, so that if SIGCLD==SIGCHLD then SIGCHLD
137440a403fSchristos overrides SIGCLD. SIGCHLD is in POXIX.1 */
138440a403fSchristos #if defined (SIGCLD)
139440a403fSchristos ENTRY(SIGCLD, "SIGCLD", "Child status changed"),
140440a403fSchristos #endif
141440a403fSchristos #if defined (SIGCHLD)
142440a403fSchristos ENTRY(SIGCHLD, "SIGCHLD", "Child status changed"),
143440a403fSchristos #endif
144440a403fSchristos #if defined (SIGPWR)
145440a403fSchristos ENTRY(SIGPWR, "SIGPWR", "Power fail/restart"),
146440a403fSchristos #endif
147440a403fSchristos #if defined (SIGWINCH)
148440a403fSchristos ENTRY(SIGWINCH, "SIGWINCH", "Window size changed"),
149440a403fSchristos #endif
150440a403fSchristos #if defined (SIGURG)
151440a403fSchristos ENTRY(SIGURG, "SIGURG", "Urgent I/O condition"),
152440a403fSchristos #endif
153440a403fSchristos #if defined (SIGIO)
154440a403fSchristos /* "I/O pending" has also been suggested, but is misleading since the
155440a403fSchristos signal only happens when the process has asked for it, not everytime
156440a403fSchristos I/O is pending. */
157440a403fSchristos ENTRY(SIGIO, "SIGIO", "I/O possible"),
158440a403fSchristos #endif
159440a403fSchristos #if defined (SIGPOLL)
160440a403fSchristos ENTRY(SIGPOLL, "SIGPOLL", "Pollable event occurred"),
161440a403fSchristos #endif
162440a403fSchristos #if defined (SIGSTOP)
163440a403fSchristos ENTRY(SIGSTOP, "SIGSTOP", "Stopped (signal)"),
164440a403fSchristos #endif
165440a403fSchristos #if defined (SIGTSTP)
166440a403fSchristos ENTRY(SIGTSTP, "SIGTSTP", "Stopped (user)"),
167440a403fSchristos #endif
168440a403fSchristos #if defined (SIGCONT)
169440a403fSchristos ENTRY(SIGCONT, "SIGCONT", "Continued"),
170440a403fSchristos #endif
171440a403fSchristos #if defined (SIGTTIN)
172440a403fSchristos ENTRY(SIGTTIN, "SIGTTIN", "Stopped (tty input)"),
173440a403fSchristos #endif
174440a403fSchristos #if defined (SIGTTOU)
175440a403fSchristos ENTRY(SIGTTOU, "SIGTTOU", "Stopped (tty output)"),
176440a403fSchristos #endif
177440a403fSchristos #if defined (SIGVTALRM)
178440a403fSchristos ENTRY(SIGVTALRM, "SIGVTALRM", "Virtual timer expired"),
179440a403fSchristos #endif
180440a403fSchristos #if defined (SIGPROF)
181440a403fSchristos ENTRY(SIGPROF, "SIGPROF", "Profiling timer expired"),
182440a403fSchristos #endif
183440a403fSchristos #if defined (SIGXCPU)
184440a403fSchristos ENTRY(SIGXCPU, "SIGXCPU", "CPU time limit exceeded"),
185440a403fSchristos #endif
186440a403fSchristos #if defined (SIGXFSZ)
187440a403fSchristos ENTRY(SIGXFSZ, "SIGXFSZ", "File size limit exceeded"),
188440a403fSchristos #endif
189440a403fSchristos #if defined (SIGWIND)
190440a403fSchristos ENTRY(SIGWIND, "SIGWIND", "SIGWIND"),
191440a403fSchristos #endif
192440a403fSchristos #if defined (SIGPHONE)
193440a403fSchristos ENTRY(SIGPHONE, "SIGPHONE", "SIGPHONE"),
194440a403fSchristos #endif
195440a403fSchristos #if defined (SIGLOST)
196440a403fSchristos ENTRY(SIGLOST, "SIGLOST", "Resource lost"),
197440a403fSchristos #endif
198440a403fSchristos #if defined (SIGWAITING)
199440a403fSchristos ENTRY(SIGWAITING, "SIGWAITING", "Process's LWPs are blocked"),
200440a403fSchristos #endif
201440a403fSchristos #if defined (SIGLWP)
202440a403fSchristos ENTRY(SIGLWP, "SIGLWP", "Signal LWP"),
203440a403fSchristos #endif
204440a403fSchristos #if defined (SIGDANGER)
205440a403fSchristos ENTRY(SIGDANGER, "SIGDANGER", "Swap space dangerously low"),
206440a403fSchristos #endif
207440a403fSchristos #if defined (SIGGRANT)
208440a403fSchristos ENTRY(SIGGRANT, "SIGGRANT", "Monitor mode granted"),
209440a403fSchristos #endif
210440a403fSchristos #if defined (SIGRETRACT)
211440a403fSchristos ENTRY(SIGRETRACT, "SIGRETRACT", "Need to relinguish monitor mode"),
212440a403fSchristos #endif
213440a403fSchristos #if defined (SIGMSG)
214440a403fSchristos ENTRY(SIGMSG, "SIGMSG", "Monitor mode data available"),
215440a403fSchristos #endif
216440a403fSchristos #if defined (SIGSOUND)
217440a403fSchristos ENTRY(SIGSOUND, "SIGSOUND", "Sound completed"),
218440a403fSchristos #endif
219440a403fSchristos #if defined (SIGSAK)
220440a403fSchristos ENTRY(SIGSAK, "SIGSAK", "Secure attention"),
221440a403fSchristos #endif
222440a403fSchristos ENTRY(0, NULL, NULL)
223440a403fSchristos };
224440a403fSchristos
225440a403fSchristos /* Translation table allocated and initialized at runtime. Indexed by the
226440a403fSchristos signal value to find the equivalent symbolic value. */
227440a403fSchristos
228440a403fSchristos static const char **signal_names;
229440a403fSchristos static int num_signal_names = 0;
230440a403fSchristos
231440a403fSchristos /* Translation table allocated and initialized at runtime, if it does not
232440a403fSchristos already exist in the host environment. Indexed by the signal value to find
233440a403fSchristos the descriptive string.
234440a403fSchristos
235440a403fSchristos We don't export it for use in other modules because even though it has the
236440a403fSchristos same name, it differs from other implementations in that it is dynamically
237440a403fSchristos initialized rather than statically initialized. */
238440a403fSchristos
239440a403fSchristos #ifndef HAVE_SYS_SIGLIST
240440a403fSchristos
241440a403fSchristos static int sys_nsig;
242440a403fSchristos static const char **sys_siglist;
243440a403fSchristos
244440a403fSchristos #else
245440a403fSchristos
246440a403fSchristos #ifdef NSIG
247440a403fSchristos static int sys_nsig = NSIG;
248440a403fSchristos #else
249440a403fSchristos #ifdef _NSIG
250440a403fSchristos static int sys_nsig = _NSIG;
251440a403fSchristos #endif
252440a403fSchristos #endif
253440a403fSchristos extern const char * const sys_siglist[];
254440a403fSchristos
255440a403fSchristos #endif
256440a403fSchristos
257440a403fSchristos
258440a403fSchristos /*
259440a403fSchristos
260440a403fSchristos NAME
261440a403fSchristos
262440a403fSchristos init_signal_tables -- initialize the name and message tables
263440a403fSchristos
264440a403fSchristos SYNOPSIS
265440a403fSchristos
266440a403fSchristos static void init_signal_tables ();
267440a403fSchristos
268440a403fSchristos DESCRIPTION
269440a403fSchristos
270440a403fSchristos Using the signal_table, which is initialized at compile time, generate
271440a403fSchristos the signal_names and the sys_siglist (if needed) tables, which are
272440a403fSchristos indexed at runtime by a specific signal value.
273440a403fSchristos
274440a403fSchristos BUGS
275440a403fSchristos
276440a403fSchristos The initialization of the tables may fail under low memory conditions,
277440a403fSchristos in which case we don't do anything particularly useful, but we don't
278440a403fSchristos bomb either. Who knows, it might succeed at a later point if we free
279440a403fSchristos some memory in the meantime. In any case, the other routines know
280440a403fSchristos how to deal with lack of a table after trying to initialize it. This
281440a403fSchristos may or may not be considered to be a bug, that we don't specifically
282440a403fSchristos warn about this particular failure mode.
283440a403fSchristos
284440a403fSchristos */
285440a403fSchristos
286440a403fSchristos static void
init_signal_tables(void)287440a403fSchristos init_signal_tables (void)
288440a403fSchristos {
289440a403fSchristos const struct signal_info *eip;
290440a403fSchristos int nbytes;
291440a403fSchristos
292440a403fSchristos /* If we haven't already scanned the signal_table once to find the maximum
293440a403fSchristos signal value, then go find it now. */
294440a403fSchristos
295440a403fSchristos if (num_signal_names == 0)
296440a403fSchristos {
297440a403fSchristos for (eip = signal_table; eip -> name != NULL; eip++)
298440a403fSchristos {
299440a403fSchristos if (eip -> value >= num_signal_names)
300440a403fSchristos {
301440a403fSchristos num_signal_names = eip -> value + 1;
302440a403fSchristos }
303440a403fSchristos }
304440a403fSchristos }
305440a403fSchristos
306440a403fSchristos /* Now attempt to allocate the signal_names table, zero it out, and then
307440a403fSchristos initialize it from the statically initialized signal_table. */
308440a403fSchristos
309440a403fSchristos if (signal_names == NULL)
310440a403fSchristos {
311440a403fSchristos nbytes = num_signal_names * sizeof (char *);
312440a403fSchristos if ((signal_names = (const char **) malloc (nbytes)) != NULL)
313440a403fSchristos {
314440a403fSchristos memset (signal_names, 0, nbytes);
315440a403fSchristos for (eip = signal_table; eip -> name != NULL; eip++)
316440a403fSchristos {
317440a403fSchristos signal_names[eip -> value] = eip -> name;
318440a403fSchristos }
319440a403fSchristos }
320440a403fSchristos }
321440a403fSchristos
322440a403fSchristos #ifndef HAVE_SYS_SIGLIST
323440a403fSchristos
324440a403fSchristos /* Now attempt to allocate the sys_siglist table, zero it out, and then
325440a403fSchristos initialize it from the statically initialized signal_table. */
326440a403fSchristos
327440a403fSchristos if (sys_siglist == NULL)
328440a403fSchristos {
329440a403fSchristos nbytes = num_signal_names * sizeof (char *);
330440a403fSchristos if ((sys_siglist = (const char **) malloc (nbytes)) != NULL)
331440a403fSchristos {
332440a403fSchristos memset (sys_siglist, 0, nbytes);
333440a403fSchristos sys_nsig = num_signal_names;
334440a403fSchristos for (eip = signal_table; eip -> name != NULL; eip++)
335440a403fSchristos {
336440a403fSchristos sys_siglist[eip -> value] = eip -> msg;
337440a403fSchristos }
338440a403fSchristos }
339440a403fSchristos }
340440a403fSchristos
341440a403fSchristos #endif
342440a403fSchristos
343440a403fSchristos }
344440a403fSchristos
345440a403fSchristos
346440a403fSchristos /*
347440a403fSchristos
348440a403fSchristos @deftypefn Extension int signo_max (void)
349440a403fSchristos
350440a403fSchristos Returns the maximum signal value for which a corresponding symbolic
351440a403fSchristos name or message is available. Note that in the case where we use the
352440a403fSchristos @code{sys_siglist} supplied by the system, it is possible for there to
353440a403fSchristos be more symbolic names than messages, or vice versa. In fact, the
354440a403fSchristos manual page for @code{psignal(3b)} explicitly warns that one should
355440a403fSchristos check the size of the table (@code{NSIG}) before indexing it, since
356440a403fSchristos new signal codes may be added to the system before they are added to
357440a403fSchristos the table. Thus @code{NSIG} might be smaller than value implied by
358440a403fSchristos the largest signo value defined in @code{<signal.h>}.
359440a403fSchristos
360440a403fSchristos We return the maximum value that can be used to obtain a meaningful
361440a403fSchristos symbolic name or message.
362440a403fSchristos
363440a403fSchristos @end deftypefn
364440a403fSchristos
365440a403fSchristos */
366440a403fSchristos
367440a403fSchristos int
signo_max(void)368440a403fSchristos signo_max (void)
369440a403fSchristos {
370440a403fSchristos int maxsize;
371440a403fSchristos
372440a403fSchristos if (signal_names == NULL)
373440a403fSchristos {
374440a403fSchristos init_signal_tables ();
375440a403fSchristos }
376440a403fSchristos maxsize = MAX (sys_nsig, num_signal_names);
377440a403fSchristos return (maxsize - 1);
378440a403fSchristos }
379440a403fSchristos
380440a403fSchristos
381440a403fSchristos /*
382440a403fSchristos
383440a403fSchristos @deftypefn Supplemental {const char *} strsignal (int @var{signo})
384440a403fSchristos
385440a403fSchristos Maps an signal number to an signal message string, the contents of
386440a403fSchristos which are implementation defined. On systems which have the external
387440a403fSchristos variable @code{sys_siglist}, these strings will be the same as the
388440a403fSchristos ones used by @code{psignal()}.
389440a403fSchristos
390440a403fSchristos If the supplied signal number is within the valid range of indices for
391440a403fSchristos the @code{sys_siglist}, but no message is available for the particular
392440a403fSchristos signal number, then returns the string @samp{Signal @var{num}}, where
393440a403fSchristos @var{num} is the signal number.
394440a403fSchristos
395440a403fSchristos If the supplied signal number is not a valid index into
396440a403fSchristos @code{sys_siglist}, returns @code{NULL}.
397440a403fSchristos
398440a403fSchristos The returned string is only guaranteed to be valid only until the next
399440a403fSchristos call to @code{strsignal}.
400440a403fSchristos
401440a403fSchristos @end deftypefn
402440a403fSchristos
403440a403fSchristos */
404440a403fSchristos
405440a403fSchristos #ifndef HAVE_STRSIGNAL
406440a403fSchristos
407440a403fSchristos char *
strsignal(int signo)408440a403fSchristos strsignal (int signo)
409440a403fSchristos {
410440a403fSchristos char *msg;
411440a403fSchristos static char buf[32];
412440a403fSchristos
413440a403fSchristos #ifndef HAVE_SYS_SIGLIST
414440a403fSchristos
415440a403fSchristos if (signal_names == NULL)
416440a403fSchristos {
417440a403fSchristos init_signal_tables ();
418440a403fSchristos }
419440a403fSchristos
420440a403fSchristos #endif
421440a403fSchristos
422440a403fSchristos if ((signo < 0) || (signo >= sys_nsig))
423440a403fSchristos {
424440a403fSchristos /* Out of range, just return NULL */
425440a403fSchristos msg = NULL;
426440a403fSchristos }
427440a403fSchristos else if ((sys_siglist == NULL) || (sys_siglist[signo] == NULL))
428440a403fSchristos {
429440a403fSchristos /* In range, but no sys_siglist or no entry at this index. */
430440a403fSchristos sprintf (buf, "Signal %d", signo);
431440a403fSchristos msg = buf;
432440a403fSchristos }
433440a403fSchristos else
434440a403fSchristos {
435440a403fSchristos /* In range, and a valid message. Just return the message. We
436440a403fSchristos can safely cast away const, since POSIX says the user must
437440a403fSchristos not modify the result. */
438440a403fSchristos msg = (char *) sys_siglist[signo];
439440a403fSchristos }
440440a403fSchristos
441440a403fSchristos return (msg);
442440a403fSchristos }
443440a403fSchristos
444440a403fSchristos #endif /* ! HAVE_STRSIGNAL */
445440a403fSchristos
446440a403fSchristos /*
447440a403fSchristos
448440a403fSchristos @deftypefn Extension {const char*} strsigno (int @var{signo})
449440a403fSchristos
450440a403fSchristos Given an signal number, returns a pointer to a string containing the
451440a403fSchristos symbolic name of that signal number, as found in @code{<signal.h>}.
452440a403fSchristos
453440a403fSchristos If the supplied signal number is within the valid range of indices for
454440a403fSchristos symbolic names, but no name is available for the particular signal
455440a403fSchristos number, then returns the string @samp{Signal @var{num}}, where
456440a403fSchristos @var{num} is the signal number.
457440a403fSchristos
458440a403fSchristos If the supplied signal number is not within the range of valid
459440a403fSchristos indices, then returns @code{NULL}.
460440a403fSchristos
461440a403fSchristos The contents of the location pointed to are only guaranteed to be
462440a403fSchristos valid until the next call to @code{strsigno}.
463440a403fSchristos
464440a403fSchristos @end deftypefn
465440a403fSchristos
466440a403fSchristos */
467440a403fSchristos
468440a403fSchristos const char *
strsigno(int signo)469440a403fSchristos strsigno (int signo)
470440a403fSchristos {
471440a403fSchristos const char *name;
472440a403fSchristos static char buf[32];
473440a403fSchristos
474440a403fSchristos if (signal_names == NULL)
475440a403fSchristos {
476440a403fSchristos init_signal_tables ();
477440a403fSchristos }
478440a403fSchristos
479440a403fSchristos if ((signo < 0) || (signo >= num_signal_names))
480440a403fSchristos {
481440a403fSchristos /* Out of range, just return NULL */
482440a403fSchristos name = NULL;
483440a403fSchristos }
484440a403fSchristos else if ((signal_names == NULL) || (signal_names[signo] == NULL))
485440a403fSchristos {
486440a403fSchristos /* In range, but no signal_names or no entry at this index. */
487440a403fSchristos sprintf (buf, "Signal %d", signo);
488440a403fSchristos name = (const char *) buf;
489440a403fSchristos }
490440a403fSchristos else
491440a403fSchristos {
492440a403fSchristos /* In range, and a valid name. Just return the name. */
493440a403fSchristos name = signal_names[signo];
494440a403fSchristos }
495440a403fSchristos
496440a403fSchristos return (name);
497440a403fSchristos }
498440a403fSchristos
499440a403fSchristos
500440a403fSchristos /*
501440a403fSchristos
502440a403fSchristos @deftypefn Extension int strtosigno (const char *@var{name})
503440a403fSchristos
504440a403fSchristos Given the symbolic name of a signal, map it to a signal number. If no
505440a403fSchristos translation is found, returns 0.
506440a403fSchristos
507440a403fSchristos @end deftypefn
508440a403fSchristos
509440a403fSchristos */
510440a403fSchristos
511440a403fSchristos int
strtosigno(const char * name)512440a403fSchristos strtosigno (const char *name)
513440a403fSchristos {
514440a403fSchristos int signo = 0;
515440a403fSchristos
516440a403fSchristos if (name != NULL)
517440a403fSchristos {
518440a403fSchristos if (signal_names == NULL)
519440a403fSchristos {
520440a403fSchristos init_signal_tables ();
521440a403fSchristos }
522440a403fSchristos for (signo = 0; signo < num_signal_names; signo++)
523440a403fSchristos {
524440a403fSchristos if ((signal_names[signo] != NULL) &&
525440a403fSchristos (strcmp (name, signal_names[signo]) == 0))
526440a403fSchristos {
527440a403fSchristos break;
528440a403fSchristos }
529440a403fSchristos }
530440a403fSchristos if (signo == num_signal_names)
531440a403fSchristos {
532440a403fSchristos signo = 0;
533440a403fSchristos }
534440a403fSchristos }
535440a403fSchristos return (signo);
536440a403fSchristos }
537440a403fSchristos
538440a403fSchristos
539440a403fSchristos /*
540440a403fSchristos
541440a403fSchristos @deftypefn Supplemental void psignal (int @var{signo}, char *@var{message})
542440a403fSchristos
543440a403fSchristos Print @var{message} to the standard error, followed by a colon,
544440a403fSchristos followed by the description of the signal specified by @var{signo},
545440a403fSchristos followed by a newline.
546440a403fSchristos
547440a403fSchristos @end deftypefn
548440a403fSchristos
549440a403fSchristos */
550440a403fSchristos
551440a403fSchristos #ifndef HAVE_PSIGNAL
552440a403fSchristos
553440a403fSchristos void
psignal(int signo,const char * message)554*b88e3e88Schristos psignal (int signo, const char *message)
555440a403fSchristos {
556440a403fSchristos if (signal_names == NULL)
557440a403fSchristos {
558440a403fSchristos init_signal_tables ();
559440a403fSchristos }
560440a403fSchristos if ((signo <= 0) || (signo >= sys_nsig))
561440a403fSchristos {
562440a403fSchristos fprintf (stderr, "%s: unknown signal\n", message);
563440a403fSchristos }
564440a403fSchristos else
565440a403fSchristos {
566440a403fSchristos fprintf (stderr, "%s: %s\n", message, sys_siglist[signo]);
567440a403fSchristos }
568440a403fSchristos }
569440a403fSchristos
570440a403fSchristos #endif /* ! HAVE_PSIGNAL */
571440a403fSchristos
572440a403fSchristos
573440a403fSchristos /* A simple little main that does nothing but print all the signal translations
574440a403fSchristos if MAIN is defined and this file is compiled and linked. */
575440a403fSchristos
576440a403fSchristos #ifdef MAIN
577440a403fSchristos
578440a403fSchristos #include <stdio.h>
579440a403fSchristos
580440a403fSchristos int
main(void)581440a403fSchristos main (void)
582440a403fSchristos {
583440a403fSchristos int signo;
584440a403fSchristos int maxsigno;
585440a403fSchristos const char *name;
586440a403fSchristos const char *msg;
587440a403fSchristos
588440a403fSchristos maxsigno = signo_max ();
589440a403fSchristos printf ("%d entries in names table.\n", num_signal_names);
590440a403fSchristos printf ("%d entries in messages table.\n", sys_nsig);
591440a403fSchristos printf ("%d is max useful index.\n", maxsigno);
592440a403fSchristos
593440a403fSchristos /* Keep printing values until we get to the end of *both* tables, not
594440a403fSchristos *either* table. Note that knowing the maximum useful index does *not*
595440a403fSchristos relieve us of the responsibility of testing the return pointer for
596440a403fSchristos NULL. */
597440a403fSchristos
598440a403fSchristos for (signo = 0; signo <= maxsigno; signo++)
599440a403fSchristos {
600440a403fSchristos name = strsigno (signo);
601440a403fSchristos name = (name == NULL) ? "<NULL>" : name;
602440a403fSchristos msg = strsignal (signo);
603440a403fSchristos msg = (msg == NULL) ? "<NULL>" : msg;
604440a403fSchristos printf ("%-4d%-18s%s\n", signo, name, msg);
605440a403fSchristos }
606440a403fSchristos
607440a403fSchristos return 0;
608440a403fSchristos }
609440a403fSchristos
610440a403fSchristos #endif
611