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