BSD 4_4_Lite1 release
[unix-history] / usr / src / contrib / gdb-4.7.LBL / libiberty / strsignal.c
CommitLineData
7742285c
C
1/* Extended support for using signal values.
2 Copyright (C) 1992 Free Software Foundation, Inc.
3 Written by Fred Fish. fnf@cygnus.com
4
5This file is part of the libiberty library.
6Libiberty is free software; you can redistribute it and/or
7modify it under the terms of the GNU Library General Public
8License as published by the Free Software Foundation; either
9version 2 of the License, or (at your option) any later version.
10
11Libiberty is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14Library General Public License for more details.
15
16You should have received a copy of the GNU Library General Public
17License along with libiberty; see the file COPYING.LIB. If
18not, write to the Free Software Foundation, Inc., 675 Mass Ave,
19Cambridge, 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>
30extern void *malloc (size_t size); /* 4.10.3.3 */
31extern void *memset (void *s, int c, size_t n); /* 4.11.6.1 */
32#else /* !__STDC__ */
33extern char *malloc (); /* Standard memory allocater */
34extern 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
59static 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
196static char **signal_names;
197static 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
209static int sys_nsig;
210static char **sys_siglist;
211
212#else
213
214static int sys_nsig = NSIG;
215#ifdef __STDC__
216#ifdef notdef
217extern const char * const sys_siglist[];
218#endif
219#else
220extern char *sys_siglist[];
221#endif
222#endif
223
224
225/*
226
227NAME
228
229 init_signal_tables -- initialize the name and message tables
230
231SYNOPSIS
232
233 static void init_signal_tables ();
234
235DESCRIPTION
236
237 Using the signal_table, which is initialized at compile time, generate
238 the signal_names and the sys_siglist (if needed) tables, which are
239 indexed at runtime by a specific signal value.
240
241BUGS
242
243 The initialization of the tables may fail under low memory conditions,
244 in which case we don't do anything particularly useful, but we don't
245 bomb either. Who knows, it might succeed at a later point if we free
246 some memory in the meantime. In any case, the other routines know
247 how to deal with lack of a table after trying to initialize it. This
248 may or may not be considered to be a bug, that we don't specifically
249 warn about this particular failure mode.
250
251*/
252
253static void
254init_signal_tables ()
255{
256 struct signal_info *eip;
257 int nbytes;
258
259 /* If we haven't already scanned the signal_table once to find the maximum
260 signal value, then go find it now. */
261
262 if (num_signal_names == 0)
263 {
264 for (eip = signal_table; eip -> name != NULL; eip++)
265 {
266 if (eip -> value >= num_signal_names)
267 {
268 num_signal_names = eip -> value + 1;
269 }
270 }
271 }
272
273 /* Now attempt to allocate the signal_names table, zero it out, and then
274 initialize it from the statically initialized signal_table. */
275
276 if (signal_names == NULL)
277 {
278 nbytes = num_signal_names * sizeof (char *);
279 if ((signal_names = (char **) malloc (nbytes)) != NULL)
280 {
281 memset (signal_names, 0, nbytes);
282 for (eip = signal_table; eip -> name != NULL; eip++)
283 {
284 signal_names[eip -> value] = eip -> name;
285 }
286 }
287 }
288
289#ifdef NEED_sys_siglist
290
291 /* Now attempt to allocate the sys_siglist table, zero it out, and then
292 initialize it from the statically initialized signal_table. */
293
294 if (sys_siglist == NULL)
295 {
296 nbytes = num_signal_names * sizeof (char *);
297 if ((sys_siglist = (char **) malloc (nbytes)) != NULL)
298 {
299 memset (sys_siglist, 0, nbytes);
300 sys_nsig = num_signal_names;
301 for (eip = signal_table; eip -> name != NULL; eip++)
302 {
303 sys_siglist[eip -> value] = eip -> msg;
304 }
305 }
306 }
307
308#endif
309
310}
311
312
313/*
314
315NAME
316
317 signo_max -- return the max signo value
318
319SYNOPSIS
320
321 int signo_max ();
322
323DESCRIPTION
324
325 Returns the maximum signo value for which a corresponding symbolic
326 name or message is available. Note that in the case where
327 we use the sys_siglist supplied by the system, it is possible for
328 there to be more symbolic names than messages, or vice versa.
329 In fact, the manual page for psignal(3b) explicitly warns that one
330 should check the size of the table (NSIG) before indexing it,
331 since new signal codes may be added to the system before they are
332 added to the table. Thus NSIG might be smaller than value
333 implied by the largest signo value defined in <signal.h>.
334
335 We return the maximum value that can be used to obtain a meaningful
336 symbolic name or message.
337
338*/
339
340int
341signo_max ()
342{
343 int maxsize;
344
345 if (signal_names == NULL)
346 {
347 init_signal_tables ();
348 }
349 maxsize = MAX (sys_nsig, num_signal_names);
350 return (maxsize - 1);
351}
352
353
354/*
355
356NAME
357
358 strsignal -- map a signal number to a signal message string
359
360SYNOPSIS
361
362 char *strsignal (int signo)
363
364DESCRIPTION
365
366 Maps an signal number to an signal message string, the contents of
367 which are implementation defined. On systems which have the external
368 variable sys_siglist, these strings will be the same as the ones used
369 by psignal().
370
371 If the supplied signal number is within the valid range of indices
372 for the sys_siglist, but no message is available for the particular
373 signal number, then returns the string "Signal NUM", where NUM is the
374 signal number.
375
376 If the supplied signal number is not a valid index into sys_siglist,
377 returns NULL.
378
379 The returned string is only guaranteed to be valid only until the
380 next call to strsignal.
381
382*/
383
384char *
385strsignal (signo)
386 int signo;
387{
388 char *msg;
389 static char buf[32];
390
391#ifdef NEED_sys_siglist
392
393 if (signal_names == NULL)
394 {
395 init_signal_tables ();
396 }
397
398#endif
399
400 if ((signo < 0) || (signo >= sys_nsig))
401 {
402 /* Out of range, just return NULL */
403 msg = NULL;
404 }
405 else if ((sys_siglist == NULL) || (sys_siglist[signo] == NULL))
406 {
407 /* In range, but no sys_siglist or no entry at this index. */
408 sprintf (buf, "Signal %d", signo);
409 msg = buf;
410 }
411 else
412 {
413 /* In range, and a valid message. Just return the message. */
414 msg = (char*)sys_siglist[signo];
415 }
416
417 return (msg);
418}
419
420
421/*
422
423NAME
424
425 strsigno -- map an signal number to a symbolic name string
426
427SYNOPSIS
428
429 char *strsigno (int signo)
430
431DESCRIPTION
432
433 Given an signal number, returns a pointer to a string containing
434 the symbolic name of that signal number, as found in <signal.h>.
435
436 If the supplied signal number is within the valid range of indices
437 for symbolic names, but no name is available for the particular
438 signal number, then returns the string "Signal NUM", where NUM is
439 the signal number.
440
441 If the supplied signal number is not within the range of valid
442 indices, then returns NULL.
443
444BUGS
445
446 The contents of the location pointed to are only guaranteed to be
447 valid until the next call to strsigno.
448
449*/
450
451char *
452strsigno (signo)
453 int signo;
454{
455 char *name;
456 static char buf[32];
457
458 if (signal_names == NULL)
459 {
460 init_signal_tables ();
461 }
462
463 if ((signo < 0) || (signo >= num_signal_names))
464 {
465 /* Out of range, just return NULL */
466 name = NULL;
467 }
468 else if ((signal_names == NULL) || (signal_names[signo] == NULL))
469 {
470 /* In range, but no signal_names or no entry at this index. */
471 sprintf (buf, "Signal %d", signo);
472 name = buf;
473 }
474 else
475 {
476 /* In range, and a valid name. Just return the name. */
477 name = signal_names[signo];
478 }
479
480 return (name);
481}
482
483
484/*
485
486NAME
487
488 strtosigno -- map a symbolic signal name to a numeric value
489
490SYNOPSIS
491
492 int strtosigno (char *name)
493
494DESCRIPTION
495
496 Given the symbolic name of a signal, map it to a signal number.
497 If no translation is found, returns 0.
498
499*/
500
501int
502strtosigno (name)
503 char *name;
504{
505 int signo = 0;
506
507 if (name != NULL)
508 {
509 if (signal_names == NULL)
510 {
511 init_signal_tables ();
512 }
513 for (signo = 0; signo < num_signal_names; signo++)
514 {
515 if ((signal_names[signo] != NULL) &&
516 (strcmp (name, signal_names[signo]) == 0))
517 {
518 break;
519 }
520 }
521 if (signo == num_signal_names)
522 {
523 signo = 0;
524 }
525 }
526 return (signo);
527}
528
529
530/*
531
532NAME
533
534 psignal -- print message about signal to stderr
535
536SYNOPSIS
537
538 void psignal (unsigned signo, char *message);
539
540DESCRIPTION
541
542 Print to the standard error the message, followed by a colon,
543 followed by the description of the signal specified by signo,
544 followed by a newline.
545*/
546
547#ifdef NEED_psignal
548
549void
550psignal (signo, message)
551 unsigned signo;
552 char *message;
553{
554 if (signal_names == NULL)
555 {
556 init_signal_tables ();
557 }
558 if ((signo <= 0) || (signo >= sys_nsig))
559 {
560 fprintf (stderr, "%s: unknown signal\n", message);
561 }
562 else
563 {
564 fprintf (stderr, "%s: %s\n", message, sys_siglist[signo]);
565 }
566}
567
568#endif /* NEED_psignal */
569
570
571/* A simple little main that does nothing but print all the signal translations
572 if MAIN is defined and this file is compiled and linked. */
573
574#ifdef MAIN
575
576main ()
577{
578 int signo;
579 int maxsigno;
580 char *name;
581 char *msg;
582 char *strsigno ();
583 char *strsignal ();
584
585 maxsigno = signo_max ();
586 printf ("%d entries in names table.\n", num_signal_names);
587 printf ("%d entries in messages table.\n", sys_nsig);
588 printf ("%d is max useful index.\n", maxsigno);
589
590 /* Keep printing values until we get to the end of *both* tables, not
591 *either* table. Note that knowing the maximum useful index does *not*
592 relieve us of the responsibility of testing the return pointer for
593 NULL. */
594
595 for (signo = 0; signo <= maxsigno; signo++)
596 {
597 name = strsigno (signo);
598 name = (name == NULL) ? "<NULL>" : name;
599 msg = strsignal (signo);
600 msg = (msg == NULL) ? "<NULL>" : msg;
601 printf ("%-4d%-18s%s\n", signo, name, msg);
602 }
603}
604
605#endif