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