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