xref: /openbsd-src/gnu/lib/libiberty/src/strsignal.c (revision c404a2006c955289d4e7aa31e6e6f26d6da180a3)
100bf4279Sespie /* Extended support for using signal values.
200bf4279Sespie    Written by Fred Fish.  fnf@cygnus.com
300bf4279Sespie    This file is in the public domain.  */
400bf4279Sespie 
5150b7e42Smiod #include "config.h"
600bf4279Sespie #include "ansidecl.h"
700bf4279Sespie #include "libiberty.h"
800bf4279Sespie 
900bf4279Sespie /* We need to declare sys_siglist, because even if the system provides
1000bf4279Sespie    it we can't assume that it is declared in <signal.h> (for example,
1100bf4279Sespie    SunOS provides sys_siglist, but it does not declare it in any
1200bf4279Sespie    header file).  fHowever, we can't declare sys_siglist portably,
1300bf4279Sespie    because on some systems it is declared with const and on some
1400bf4279Sespie    systems it is declared without const.  If we were using autoconf,
1500bf4279Sespie    we could work out the right declaration.  Until, then we just
1600bf4279Sespie    ignore any declaration in the system header files, and always
1700bf4279Sespie    declare it ourselves.  With luck, this will always work.  */
1800bf4279Sespie #define sys_siglist no_such_symbol
1937c53322Sespie #define sys_nsig sys_nsig__no_such_symbol
2000bf4279Sespie 
2100bf4279Sespie #include <stdio.h>
2200bf4279Sespie #include <signal.h>
2300bf4279Sespie 
2400bf4279Sespie /*  Routines imported from standard C runtime libraries. */
2500bf4279Sespie 
26f5dd06f4Sespie #ifdef HAVE_STDLIB_H
27f5dd06f4Sespie #include <stdlib.h>
28f5dd06f4Sespie #else
29f5dd06f4Sespie extern PTR malloc ();
30f5dd06f4Sespie #endif
31f5dd06f4Sespie 
32f5dd06f4Sespie #ifdef HAVE_STRING_H
33f5dd06f4Sespie #include <string.h>
34f5dd06f4Sespie #else
35f5dd06f4Sespie extern PTR memset ();
36f5dd06f4Sespie #endif
3700bf4279Sespie 
3800bf4279Sespie /* Undefine the macro we used to hide the definition of sys_siglist
3900bf4279Sespie    found in the system header files.  */
4000bf4279Sespie #undef sys_siglist
4137c53322Sespie #undef sys_nsig
4200bf4279Sespie 
4300bf4279Sespie #ifndef NULL
4400bf4279Sespie #  define NULL (void *) 0
4500bf4279Sespie #endif
4600bf4279Sespie 
4700bf4279Sespie #ifndef MAX
4800bf4279Sespie #  define MAX(a,b) ((a) > (b) ? (a) : (b))
4900bf4279Sespie #endif
5000bf4279Sespie 
51150b7e42Smiod static void init_signal_tables (void);
5200bf4279Sespie 
5300bf4279Sespie /* Translation table for signal values.
5400bf4279Sespie 
5500bf4279Sespie    Note that this table is generally only accessed when it is used at runtime
5600bf4279Sespie    to initialize signal name and message tables that are indexed by signal
5700bf4279Sespie    value.
5800bf4279Sespie 
5900bf4279Sespie    Not all of these signals will exist on all systems.  This table is the only
6000bf4279Sespie    thing that should have to be updated as new signal numbers are introduced.
6100bf4279Sespie    It's sort of ugly, but at least its portable. */
6200bf4279Sespie 
6300bf4279Sespie struct signal_info
6400bf4279Sespie {
6537c53322Sespie   const int value;		/* The numeric value from <signal.h> */
6637c53322Sespie   const char *const name;	/* The equivalent symbolic value */
6700bf4279Sespie #ifndef HAVE_SYS_SIGLIST
6837c53322Sespie   const char *const msg;	/* Short message about this value */
6900bf4279Sespie #endif
7000bf4279Sespie };
7100bf4279Sespie 
7200bf4279Sespie #ifndef HAVE_SYS_SIGLIST
7300bf4279Sespie #   define ENTRY(value, name, msg)	{value, name, msg}
7400bf4279Sespie #else
7500bf4279Sespie #   define ENTRY(value, name, msg)	{value, name}
7600bf4279Sespie #endif
7700bf4279Sespie 
7800bf4279Sespie static const struct signal_info signal_table[] =
7900bf4279Sespie {
8000bf4279Sespie #if defined (SIGHUP)
8100bf4279Sespie   ENTRY(SIGHUP, "SIGHUP", "Hangup"),
8200bf4279Sespie #endif
8300bf4279Sespie #if defined (SIGINT)
8400bf4279Sespie   ENTRY(SIGINT, "SIGINT", "Interrupt"),
8500bf4279Sespie #endif
8600bf4279Sespie #if defined (SIGQUIT)
8700bf4279Sespie   ENTRY(SIGQUIT, "SIGQUIT", "Quit"),
8800bf4279Sespie #endif
8900bf4279Sespie #if defined (SIGILL)
9000bf4279Sespie   ENTRY(SIGILL, "SIGILL", "Illegal instruction"),
9100bf4279Sespie #endif
9200bf4279Sespie #if defined (SIGTRAP)
9300bf4279Sespie   ENTRY(SIGTRAP, "SIGTRAP", "Trace/breakpoint trap"),
9400bf4279Sespie #endif
9500bf4279Sespie /* Put SIGIOT before SIGABRT, so that if SIGIOT==SIGABRT then SIGABRT
9600bf4279Sespie    overrides SIGIOT.  SIGABRT is in ANSI and POSIX.1, and SIGIOT isn't. */
9700bf4279Sespie #if defined (SIGIOT)
9800bf4279Sespie   ENTRY(SIGIOT, "SIGIOT", "IOT trap"),
9900bf4279Sespie #endif
10000bf4279Sespie #if defined (SIGABRT)
10100bf4279Sespie   ENTRY(SIGABRT, "SIGABRT", "Aborted"),
10200bf4279Sespie #endif
10300bf4279Sespie #if defined (SIGEMT)
10400bf4279Sespie   ENTRY(SIGEMT, "SIGEMT", "Emulation trap"),
10500bf4279Sespie #endif
10600bf4279Sespie #if defined (SIGFPE)
10700bf4279Sespie   ENTRY(SIGFPE, "SIGFPE", "Arithmetic exception"),
10800bf4279Sespie #endif
10900bf4279Sespie #if defined (SIGKILL)
11000bf4279Sespie   ENTRY(SIGKILL, "SIGKILL", "Killed"),
11100bf4279Sespie #endif
11200bf4279Sespie #if defined (SIGBUS)
11300bf4279Sespie   ENTRY(SIGBUS, "SIGBUS", "Bus error"),
11400bf4279Sespie #endif
11500bf4279Sespie #if defined (SIGSEGV)
11600bf4279Sespie   ENTRY(SIGSEGV, "SIGSEGV", "Segmentation fault"),
11700bf4279Sespie #endif
11800bf4279Sespie #if defined (SIGSYS)
11900bf4279Sespie   ENTRY(SIGSYS, "SIGSYS", "Bad system call"),
12000bf4279Sespie #endif
12100bf4279Sespie #if defined (SIGPIPE)
12200bf4279Sespie   ENTRY(SIGPIPE, "SIGPIPE", "Broken pipe"),
12300bf4279Sespie #endif
12400bf4279Sespie #if defined (SIGALRM)
12500bf4279Sespie   ENTRY(SIGALRM, "SIGALRM", "Alarm clock"),
12600bf4279Sespie #endif
12700bf4279Sespie #if defined (SIGTERM)
12800bf4279Sespie   ENTRY(SIGTERM, "SIGTERM", "Terminated"),
12900bf4279Sespie #endif
13000bf4279Sespie #if defined (SIGUSR1)
13100bf4279Sespie   ENTRY(SIGUSR1, "SIGUSR1", "User defined signal 1"),
13200bf4279Sespie #endif
13300bf4279Sespie #if defined (SIGUSR2)
13400bf4279Sespie   ENTRY(SIGUSR2, "SIGUSR2", "User defined signal 2"),
13500bf4279Sespie #endif
13600bf4279Sespie /* Put SIGCLD before SIGCHLD, so that if SIGCLD==SIGCHLD then SIGCHLD
13700bf4279Sespie    overrides SIGCLD.  SIGCHLD is in POXIX.1 */
13800bf4279Sespie #if defined (SIGCLD)
13900bf4279Sespie   ENTRY(SIGCLD, "SIGCLD", "Child status changed"),
14000bf4279Sespie #endif
14100bf4279Sespie #if defined (SIGCHLD)
14200bf4279Sespie   ENTRY(SIGCHLD, "SIGCHLD", "Child status changed"),
14300bf4279Sespie #endif
14400bf4279Sespie #if defined (SIGPWR)
14500bf4279Sespie   ENTRY(SIGPWR, "SIGPWR", "Power fail/restart"),
14600bf4279Sespie #endif
14700bf4279Sespie #if defined (SIGWINCH)
14800bf4279Sespie   ENTRY(SIGWINCH, "SIGWINCH", "Window size changed"),
14900bf4279Sespie #endif
15000bf4279Sespie #if defined (SIGURG)
15100bf4279Sespie   ENTRY(SIGURG, "SIGURG", "Urgent I/O condition"),
15200bf4279Sespie #endif
15300bf4279Sespie #if defined (SIGIO)
15400bf4279Sespie   /* "I/O pending" has also been suggested, but is misleading since the
15500bf4279Sespie      signal only happens when the process has asked for it, not everytime
15600bf4279Sespie      I/O is pending. */
15700bf4279Sespie   ENTRY(SIGIO, "SIGIO", "I/O possible"),
15800bf4279Sespie #endif
15900bf4279Sespie #if defined (SIGPOLL)
16000bf4279Sespie   ENTRY(SIGPOLL, "SIGPOLL", "Pollable event occurred"),
16100bf4279Sespie #endif
16200bf4279Sespie #if defined (SIGSTOP)
16300bf4279Sespie   ENTRY(SIGSTOP, "SIGSTOP", "Stopped (signal)"),
16400bf4279Sespie #endif
16500bf4279Sespie #if defined (SIGTSTP)
16600bf4279Sespie   ENTRY(SIGTSTP, "SIGTSTP", "Stopped (user)"),
16700bf4279Sespie #endif
16800bf4279Sespie #if defined (SIGCONT)
16900bf4279Sespie   ENTRY(SIGCONT, "SIGCONT", "Continued"),
17000bf4279Sespie #endif
17100bf4279Sespie #if defined (SIGTTIN)
17200bf4279Sespie   ENTRY(SIGTTIN, "SIGTTIN", "Stopped (tty input)"),
17300bf4279Sespie #endif
17400bf4279Sespie #if defined (SIGTTOU)
17500bf4279Sespie   ENTRY(SIGTTOU, "SIGTTOU", "Stopped (tty output)"),
17600bf4279Sespie #endif
17700bf4279Sespie #if defined (SIGVTALRM)
17800bf4279Sespie   ENTRY(SIGVTALRM, "SIGVTALRM", "Virtual timer expired"),
17900bf4279Sespie #endif
18000bf4279Sespie #if defined (SIGPROF)
18100bf4279Sespie   ENTRY(SIGPROF, "SIGPROF", "Profiling timer expired"),
18200bf4279Sespie #endif
18300bf4279Sespie #if defined (SIGXCPU)
18400bf4279Sespie   ENTRY(SIGXCPU, "SIGXCPU", "CPU time limit exceeded"),
18500bf4279Sespie #endif
18600bf4279Sespie #if defined (SIGXFSZ)
18700bf4279Sespie   ENTRY(SIGXFSZ, "SIGXFSZ", "File size limit exceeded"),
18800bf4279Sespie #endif
18900bf4279Sespie #if defined (SIGWIND)
19000bf4279Sespie   ENTRY(SIGWIND, "SIGWIND", "SIGWIND"),
19100bf4279Sespie #endif
19200bf4279Sespie #if defined (SIGPHONE)
19300bf4279Sespie   ENTRY(SIGPHONE, "SIGPHONE", "SIGPHONE"),
19400bf4279Sespie #endif
19500bf4279Sespie #if defined (SIGLOST)
19600bf4279Sespie   ENTRY(SIGLOST, "SIGLOST", "Resource lost"),
19700bf4279Sespie #endif
19800bf4279Sespie #if defined (SIGWAITING)
19900bf4279Sespie   ENTRY(SIGWAITING, "SIGWAITING", "Process's LWPs are blocked"),
20000bf4279Sespie #endif
20100bf4279Sespie #if defined (SIGLWP)
20200bf4279Sespie   ENTRY(SIGLWP, "SIGLWP", "Signal LWP"),
20300bf4279Sespie #endif
20400bf4279Sespie #if defined (SIGDANGER)
20500bf4279Sespie   ENTRY(SIGDANGER, "SIGDANGER", "Swap space dangerously low"),
20600bf4279Sespie #endif
20700bf4279Sespie #if defined (SIGGRANT)
20800bf4279Sespie   ENTRY(SIGGRANT, "SIGGRANT", "Monitor mode granted"),
20900bf4279Sespie #endif
21000bf4279Sespie #if defined (SIGRETRACT)
21100bf4279Sespie   ENTRY(SIGRETRACT, "SIGRETRACT", "Need to relinguish monitor mode"),
21200bf4279Sespie #endif
21300bf4279Sespie #if defined (SIGMSG)
21400bf4279Sespie   ENTRY(SIGMSG, "SIGMSG", "Monitor mode data available"),
21500bf4279Sespie #endif
21600bf4279Sespie #if defined (SIGSOUND)
21700bf4279Sespie   ENTRY(SIGSOUND, "SIGSOUND", "Sound completed"),
21800bf4279Sespie #endif
21900bf4279Sespie #if defined (SIGSAK)
22000bf4279Sespie   ENTRY(SIGSAK, "SIGSAK", "Secure attention"),
22100bf4279Sespie #endif
22200bf4279Sespie   ENTRY(0, NULL, NULL)
22300bf4279Sespie };
22400bf4279Sespie 
22500bf4279Sespie /* Translation table allocated and initialized at runtime.  Indexed by the
22600bf4279Sespie    signal value to find the equivalent symbolic value. */
22700bf4279Sespie 
22800bf4279Sespie static const char **signal_names;
22900bf4279Sespie static int num_signal_names = 0;
23000bf4279Sespie 
23100bf4279Sespie /* Translation table allocated and initialized at runtime, if it does not
23200bf4279Sespie    already exist in the host environment.  Indexed by the signal value to find
23300bf4279Sespie    the descriptive string.
23400bf4279Sespie 
23500bf4279Sespie    We don't export it for use in other modules because even though it has the
23600bf4279Sespie    same name, it differs from other implementations in that it is dynamically
23700bf4279Sespie    initialized rather than statically initialized. */
23800bf4279Sespie 
23900bf4279Sespie #ifndef HAVE_SYS_SIGLIST
24000bf4279Sespie 
24100bf4279Sespie static int sys_nsig;
24200bf4279Sespie static const char **sys_siglist;
24300bf4279Sespie 
24400bf4279Sespie #else
24500bf4279Sespie 
24600bf4279Sespie #ifdef NSIG
24700bf4279Sespie static int sys_nsig = NSIG;
24800bf4279Sespie #else
24900bf4279Sespie #ifdef _NSIG
25000bf4279Sespie static int sys_nsig = _NSIG;
25100bf4279Sespie #endif
25200bf4279Sespie #endif
25300bf4279Sespie extern const char * const sys_siglist[];
25400bf4279Sespie 
25500bf4279Sespie #endif
25600bf4279Sespie 
25700bf4279Sespie 
25800bf4279Sespie /*
25900bf4279Sespie 
26000bf4279Sespie NAME
26100bf4279Sespie 
26200bf4279Sespie 	init_signal_tables -- initialize the name and message tables
26300bf4279Sespie 
26400bf4279Sespie SYNOPSIS
26500bf4279Sespie 
26600bf4279Sespie 	static void init_signal_tables ();
26700bf4279Sespie 
26800bf4279Sespie DESCRIPTION
26900bf4279Sespie 
27000bf4279Sespie 	Using the signal_table, which is initialized at compile time, generate
27100bf4279Sespie 	the signal_names and the sys_siglist (if needed) tables, which are
27200bf4279Sespie 	indexed at runtime by a specific signal value.
27300bf4279Sespie 
27400bf4279Sespie BUGS
27500bf4279Sespie 
27600bf4279Sespie 	The initialization of the tables may fail under low memory conditions,
27700bf4279Sespie 	in which case we don't do anything particularly useful, but we don't
27800bf4279Sespie 	bomb either.  Who knows, it might succeed at a later point if we free
27900bf4279Sespie 	some memory in the meantime.  In any case, the other routines know
28000bf4279Sespie 	how to deal with lack of a table after trying to initialize it.  This
28100bf4279Sespie 	may or may not be considered to be a bug, that we don't specifically
28200bf4279Sespie 	warn about this particular failure mode.
28300bf4279Sespie 
28400bf4279Sespie */
28500bf4279Sespie 
28600bf4279Sespie static void
init_signal_tables(void)287150b7e42Smiod init_signal_tables (void)
28800bf4279Sespie {
28900bf4279Sespie   const struct signal_info *eip;
29000bf4279Sespie   int nbytes;
29100bf4279Sespie 
29200bf4279Sespie   /* If we haven't already scanned the signal_table once to find the maximum
29300bf4279Sespie      signal value, then go find it now. */
29400bf4279Sespie 
29500bf4279Sespie   if (num_signal_names == 0)
29600bf4279Sespie     {
29700bf4279Sespie       for (eip = signal_table; eip -> name != NULL; eip++)
29800bf4279Sespie 	{
29900bf4279Sespie 	  if (eip -> value >= num_signal_names)
30000bf4279Sespie 	    {
30100bf4279Sespie 	      num_signal_names = eip -> value + 1;
30200bf4279Sespie 	    }
30300bf4279Sespie 	}
30400bf4279Sespie     }
30500bf4279Sespie 
30600bf4279Sespie   /* Now attempt to allocate the signal_names table, zero it out, and then
30700bf4279Sespie      initialize it from the statically initialized signal_table. */
30800bf4279Sespie 
30900bf4279Sespie   if (signal_names == NULL)
31000bf4279Sespie     {
31100bf4279Sespie       nbytes = num_signal_names * sizeof (char *);
31200bf4279Sespie       if ((signal_names = (const char **) malloc (nbytes)) != NULL)
31300bf4279Sespie 	{
31400bf4279Sespie 	  memset (signal_names, 0, nbytes);
31500bf4279Sespie 	  for (eip = signal_table; eip -> name != NULL; eip++)
31600bf4279Sespie 	    {
31700bf4279Sespie 	      signal_names[eip -> value] = eip -> name;
31800bf4279Sespie 	    }
31900bf4279Sespie 	}
32000bf4279Sespie     }
32100bf4279Sespie 
32200bf4279Sespie #ifndef HAVE_SYS_SIGLIST
32300bf4279Sespie 
32400bf4279Sespie   /* Now attempt to allocate the sys_siglist table, zero it out, and then
32500bf4279Sespie      initialize it from the statically initialized signal_table. */
32600bf4279Sespie 
32700bf4279Sespie   if (sys_siglist == NULL)
32800bf4279Sespie     {
32900bf4279Sespie       nbytes = num_signal_names * sizeof (char *);
33000bf4279Sespie       if ((sys_siglist = (const char **) malloc (nbytes)) != NULL)
33100bf4279Sespie 	{
33200bf4279Sespie 	  memset (sys_siglist, 0, nbytes);
33300bf4279Sespie 	  sys_nsig = num_signal_names;
33400bf4279Sespie 	  for (eip = signal_table; eip -> name != NULL; eip++)
33500bf4279Sespie 	    {
33600bf4279Sespie 	      sys_siglist[eip -> value] = eip -> msg;
33700bf4279Sespie 	    }
33800bf4279Sespie 	}
33900bf4279Sespie     }
34000bf4279Sespie 
34100bf4279Sespie #endif
34200bf4279Sespie 
34300bf4279Sespie }
34400bf4279Sespie 
34500bf4279Sespie 
34600bf4279Sespie /*
34700bf4279Sespie 
34837c53322Sespie @deftypefn Extension int signo_max (void)
34900bf4279Sespie 
35037c53322Sespie Returns the maximum signal value for which a corresponding symbolic
35137c53322Sespie name or message is available.  Note that in the case where we use the
35237c53322Sespie @code{sys_siglist} supplied by the system, it is possible for there to
35337c53322Sespie be more symbolic names than messages, or vice versa.  In fact, the
35437c53322Sespie manual page for @code{psignal(3b)} explicitly warns that one should
35537c53322Sespie check the size of the table (@code{NSIG}) before indexing it, since
35637c53322Sespie new signal codes may be added to the system before they are added to
35737c53322Sespie the table.  Thus @code{NSIG} might be smaller than value implied by
35837c53322Sespie the largest signo value defined in @code{<signal.h>}.
35900bf4279Sespie 
36000bf4279Sespie We return the maximum value that can be used to obtain a meaningful
36100bf4279Sespie symbolic name or message.
36200bf4279Sespie 
36337c53322Sespie @end deftypefn
36437c53322Sespie 
36500bf4279Sespie */
36600bf4279Sespie 
36700bf4279Sespie int
signo_max(void)368150b7e42Smiod signo_max (void)
36900bf4279Sespie {
37000bf4279Sespie   int maxsize;
37100bf4279Sespie 
37200bf4279Sespie   if (signal_names == NULL)
37300bf4279Sespie     {
37400bf4279Sespie       init_signal_tables ();
37500bf4279Sespie     }
37600bf4279Sespie   maxsize = MAX (sys_nsig, num_signal_names);
37700bf4279Sespie   return (maxsize - 1);
37800bf4279Sespie }
37900bf4279Sespie 
38000bf4279Sespie 
38100bf4279Sespie /*
38200bf4279Sespie 
38337c53322Sespie @deftypefn Supplemental {const char *} strsignal (int @var{signo})
38400bf4279Sespie 
38500bf4279Sespie Maps an signal number to an signal message string, the contents of
38600bf4279Sespie which are implementation defined.  On systems which have the external
38737c53322Sespie variable @code{sys_siglist}, these strings will be the same as the
38837c53322Sespie ones used by @code{psignal()}.
38900bf4279Sespie 
39037c53322Sespie If the supplied signal number is within the valid range of indices for
39137c53322Sespie the @code{sys_siglist}, but no message is available for the particular
39237c53322Sespie signal number, then returns the string @samp{Signal @var{num}}, where
39337c53322Sespie @var{num} is the signal number.
39400bf4279Sespie 
39537c53322Sespie If the supplied signal number is not a valid index into
39637c53322Sespie @code{sys_siglist}, returns @code{NULL}.
39700bf4279Sespie 
39837c53322Sespie The returned string is only guaranteed to be valid only until the next
39937c53322Sespie call to @code{strsignal}.
40037c53322Sespie 
40137c53322Sespie @end deftypefn
40200bf4279Sespie 
40300bf4279Sespie */
40400bf4279Sespie 
40500bf4279Sespie #ifndef HAVE_STRSIGNAL
40600bf4279Sespie 
40700bf4279Sespie const char *
strsignal(int signo)408150b7e42Smiod strsignal (int signo)
40900bf4279Sespie {
41000bf4279Sespie   const char *msg;
41100bf4279Sespie   static char buf[32];
41200bf4279Sespie 
41300bf4279Sespie #ifndef HAVE_SYS_SIGLIST
41400bf4279Sespie 
41500bf4279Sespie   if (signal_names == NULL)
41600bf4279Sespie     {
41700bf4279Sespie       init_signal_tables ();
41800bf4279Sespie     }
41900bf4279Sespie 
42000bf4279Sespie #endif
42100bf4279Sespie 
42200bf4279Sespie   if ((signo < 0) || (signo >= sys_nsig))
42300bf4279Sespie     {
42400bf4279Sespie       /* Out of range, just return NULL */
42500bf4279Sespie       msg = NULL;
42600bf4279Sespie     }
42700bf4279Sespie   else if ((sys_siglist == NULL) || (sys_siglist[signo] == NULL))
42800bf4279Sespie     {
42900bf4279Sespie       /* In range, but no sys_siglist or no entry at this index. */
430*c404a200Smiod       snprintf (buf, sizeof buf, "Signal %d", signo);
43100bf4279Sespie       msg = (const char *) buf;
43200bf4279Sespie     }
43300bf4279Sespie   else
43400bf4279Sespie     {
43500bf4279Sespie       /* In range, and a valid message.  Just return the message. */
43600bf4279Sespie       msg = (const char *) sys_siglist[signo];
43700bf4279Sespie     }
43800bf4279Sespie 
43900bf4279Sespie   return (msg);
44000bf4279Sespie }
44100bf4279Sespie 
44200bf4279Sespie #endif /* ! HAVE_STRSIGNAL */
44300bf4279Sespie 
44400bf4279Sespie /*
44500bf4279Sespie 
44637c53322Sespie @deftypefn Extension {const char*} strsigno (int @var{signo})
44700bf4279Sespie 
44837c53322Sespie Given an signal number, returns a pointer to a string containing the
44937c53322Sespie symbolic name of that signal number, as found in @code{<signal.h>}.
45000bf4279Sespie 
45137c53322Sespie If the supplied signal number is within the valid range of indices for
45237c53322Sespie symbolic names, but no name is available for the particular signal
45337c53322Sespie number, then returns the string @samp{Signal @var{num}}, where
45437c53322Sespie @var{num} is the signal number.
45500bf4279Sespie 
45600bf4279Sespie If the supplied signal number is not within the range of valid
45737c53322Sespie indices, then returns @code{NULL}.
45800bf4279Sespie 
45900bf4279Sespie The contents of the location pointed to are only guaranteed to be
46037c53322Sespie valid until the next call to @code{strsigno}.
46137c53322Sespie 
46237c53322Sespie @end deftypefn
46300bf4279Sespie 
46400bf4279Sespie */
46500bf4279Sespie 
46600bf4279Sespie const char *
strsigno(int signo)467150b7e42Smiod strsigno (int signo)
46800bf4279Sespie {
46900bf4279Sespie   const char *name;
47000bf4279Sespie   static char buf[32];
47100bf4279Sespie 
47200bf4279Sespie   if (signal_names == NULL)
47300bf4279Sespie     {
47400bf4279Sespie       init_signal_tables ();
47500bf4279Sespie     }
47600bf4279Sespie 
47700bf4279Sespie   if ((signo < 0) || (signo >= num_signal_names))
47800bf4279Sespie     {
47900bf4279Sespie       /* Out of range, just return NULL */
48000bf4279Sespie       name = NULL;
48100bf4279Sespie     }
48200bf4279Sespie   else if ((signal_names == NULL) || (signal_names[signo] == NULL))
48300bf4279Sespie     {
48400bf4279Sespie       /* In range, but no signal_names or no entry at this index. */
485*c404a200Smiod       snprintf (buf, sizeof buf, "Signal %d", signo);
48600bf4279Sespie       name = (const char *) buf;
48700bf4279Sespie     }
48800bf4279Sespie   else
48900bf4279Sespie     {
49000bf4279Sespie       /* In range, and a valid name.  Just return the name. */
49100bf4279Sespie       name = signal_names[signo];
49200bf4279Sespie     }
49300bf4279Sespie 
49400bf4279Sespie   return (name);
49500bf4279Sespie }
49600bf4279Sespie 
49700bf4279Sespie 
49800bf4279Sespie /*
49900bf4279Sespie 
50037c53322Sespie @deftypefn Extension int strtosigno (const char *@var{name})
50100bf4279Sespie 
50237c53322Sespie Given the symbolic name of a signal, map it to a signal number.  If no
50337c53322Sespie translation is found, returns 0.
50400bf4279Sespie 
50537c53322Sespie @end deftypefn
50600bf4279Sespie 
50700bf4279Sespie */
50800bf4279Sespie 
50900bf4279Sespie int
strtosigno(const char * name)510150b7e42Smiod strtosigno (const char *name)
51100bf4279Sespie {
51200bf4279Sespie   int signo = 0;
51300bf4279Sespie 
51400bf4279Sespie   if (name != NULL)
51500bf4279Sespie     {
51600bf4279Sespie       if (signal_names == NULL)
51700bf4279Sespie 	{
51800bf4279Sespie 	  init_signal_tables ();
51900bf4279Sespie 	}
52000bf4279Sespie       for (signo = 0; signo < num_signal_names; signo++)
52100bf4279Sespie 	{
52200bf4279Sespie 	  if ((signal_names[signo] != NULL) &&
52300bf4279Sespie 	      (strcmp (name, signal_names[signo]) == 0))
52400bf4279Sespie 	    {
52500bf4279Sespie 	      break;
52600bf4279Sespie 	    }
52700bf4279Sespie 	}
52800bf4279Sespie       if (signo == num_signal_names)
52900bf4279Sespie 	{
53000bf4279Sespie 	  signo = 0;
53100bf4279Sespie 	}
53200bf4279Sespie     }
53300bf4279Sespie   return (signo);
53400bf4279Sespie }
53500bf4279Sespie 
53600bf4279Sespie 
53700bf4279Sespie /*
53800bf4279Sespie 
53937c53322Sespie @deftypefn Supplemental void psignal (unsigned @var{signo}, char *@var{message})
54000bf4279Sespie 
54137c53322Sespie Print @var{message} to the standard error, followed by a colon,
54237c53322Sespie followed by the description of the signal specified by @var{signo},
54300bf4279Sespie followed by a newline.
54437c53322Sespie 
54537c53322Sespie @end deftypefn
54637c53322Sespie 
54700bf4279Sespie */
54800bf4279Sespie 
54900bf4279Sespie #ifndef HAVE_PSIGNAL
55000bf4279Sespie 
55100bf4279Sespie void
psignal(unsigned signo,char * message)552150b7e42Smiod psignal (unsigned signo, char *message)
55300bf4279Sespie {
55400bf4279Sespie   if (signal_names == NULL)
55500bf4279Sespie     {
55600bf4279Sespie       init_signal_tables ();
55700bf4279Sespie     }
55800bf4279Sespie   if ((signo <= 0) || (signo >= sys_nsig))
55900bf4279Sespie     {
56000bf4279Sespie       fprintf (stderr, "%s: unknown signal\n", message);
56100bf4279Sespie     }
56200bf4279Sespie   else
56300bf4279Sespie     {
56400bf4279Sespie       fprintf (stderr, "%s: %s\n", message, sys_siglist[signo]);
56500bf4279Sespie     }
56600bf4279Sespie }
56700bf4279Sespie 
56800bf4279Sespie #endif	/* ! HAVE_PSIGNAL */
56900bf4279Sespie 
57000bf4279Sespie 
57100bf4279Sespie /* A simple little main that does nothing but print all the signal translations
57200bf4279Sespie    if MAIN is defined and this file is compiled and linked. */
57300bf4279Sespie 
57400bf4279Sespie #ifdef MAIN
57500bf4279Sespie 
57600bf4279Sespie #include <stdio.h>
57700bf4279Sespie 
57800bf4279Sespie int
main(void)579150b7e42Smiod main (void)
58000bf4279Sespie {
58100bf4279Sespie   int signo;
58200bf4279Sespie   int maxsigno;
58300bf4279Sespie   const char *name;
58400bf4279Sespie   const char *msg;
58500bf4279Sespie 
58600bf4279Sespie   maxsigno = signo_max ();
58700bf4279Sespie   printf ("%d entries in names table.\n", num_signal_names);
58800bf4279Sespie   printf ("%d entries in messages table.\n", sys_nsig);
58900bf4279Sespie   printf ("%d is max useful index.\n", maxsigno);
59000bf4279Sespie 
59100bf4279Sespie   /* Keep printing values until we get to the end of *both* tables, not
59200bf4279Sespie      *either* table.  Note that knowing the maximum useful index does *not*
59300bf4279Sespie      relieve us of the responsibility of testing the return pointer for
59400bf4279Sespie      NULL. */
59500bf4279Sespie 
59600bf4279Sespie   for (signo = 0; signo <= maxsigno; signo++)
59700bf4279Sespie     {
59800bf4279Sespie       name = strsigno (signo);
59900bf4279Sespie       name = (name == NULL) ? "<NULL>" : name;
60000bf4279Sespie       msg = strsignal (signo);
60100bf4279Sespie       msg = (msg == NULL) ? "<NULL>" : msg;
60200bf4279Sespie       printf ("%-4d%-18s%s\n", signo, name, msg);
60300bf4279Sespie     }
60400bf4279Sespie 
60500bf4279Sespie   return 0;
60600bf4279Sespie }
60700bf4279Sespie 
60800bf4279Sespie #endif
609