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