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