strsignal.c revision 60484
133965Sjdp/* Extended support for using signal values.
233965Sjdp   Written by Fred Fish.  fnf@cygnus.com
333965Sjdp   This file is in the public domain.  */
433965Sjdp
533965Sjdp#include "ansidecl.h"
633965Sjdp#include "libiberty.h"
733965Sjdp
833965Sjdp#include "config.h"
933965Sjdp
1033965Sjdp/* We need to declare sys_siglist, because even if the system provides
1133965Sjdp   it we can't assume that it is declared in <signal.h> (for example,
1233965Sjdp   SunOS provides sys_siglist, but it does not declare it in any
1333965Sjdp   header file).  fHowever, we can't declare sys_siglist portably,
1433965Sjdp   because on some systems it is declared with const and on some
1533965Sjdp   systems it is declared without const.  If we were using autoconf,
1633965Sjdp   we could work out the right declaration.  Until, then we just
1733965Sjdp   ignore any declaration in the system header files, and always
1833965Sjdp   declare it ourselves.  With luck, this will always work.  */
1933965Sjdp#define sys_siglist no_such_symbol
2033965Sjdp
2133965Sjdp#include <stdio.h>
2233965Sjdp#include <signal.h>
2333965Sjdp
2433965Sjdp/*  Routines imported from standard C runtime libraries. */
2533965Sjdp
2633965Sjdp#ifdef __STDC__
2733965Sjdp#include <stddef.h>
2833965Sjdpextern void *malloc (size_t size);				/* 4.10.3.3 */
2933965Sjdpextern void *memset (void *s, int c, size_t n);			/* 4.11.6.1 */
3033965Sjdp#else	/* !__STDC__ */
3133965Sjdpextern char *malloc ();		/* Standard memory allocater */
3233965Sjdpextern char *memset ();
3333965Sjdp#endif	/* __STDC__ */
3433965Sjdp
3533965Sjdp/* Undefine the macro we used to hide the definition of sys_siglist
3633965Sjdp   found in the system header files.  */
3733965Sjdp#undef sys_siglist
3833965Sjdp
3933965Sjdp#ifndef NULL
4033965Sjdp#  ifdef __STDC__
4133965Sjdp#    define NULL (void *) 0
4233965Sjdp#  else
4333965Sjdp#    define NULL 0
4433965Sjdp#  endif
4533965Sjdp#endif
4633965Sjdp
4733965Sjdp#ifndef MAX
4833965Sjdp#  define MAX(a,b) ((a) > (b) ? (a) : (b))
4933965Sjdp#endif
5033965Sjdp
5133965Sjdpstatic void init_signal_tables PARAMS ((void));
5233965Sjdp
5333965Sjdp/* Translation table for signal values.
5433965Sjdp
5533965Sjdp   Note that this table is generally only accessed when it is used at runtime
5633965Sjdp   to initialize signal name and message tables that are indexed by signal
5733965Sjdp   value.
5833965Sjdp
5933965Sjdp   Not all of these signals will exist on all systems.  This table is the only
6033965Sjdp   thing that should have to be updated as new signal numbers are introduced.
6133965Sjdp   It's sort of ugly, but at least its portable. */
6233965Sjdp
6333965Sjdpstruct signal_info
6433965Sjdp{
6533965Sjdp  int value;		/* The numeric value from <signal.h> */
6633965Sjdp  const char *name;	/* The equivalent symbolic value */
6760484Sobrien#ifndef HAVE_SYS_SIGLIST
6833965Sjdp  const char *msg;	/* Short message about this value */
6933965Sjdp#endif
7033965Sjdp};
7133965Sjdp
7260484Sobrien#ifndef HAVE_SYS_SIGLIST
7333965Sjdp#   define ENTRY(value, name, msg)	{value, name, msg}
7433965Sjdp#else
7533965Sjdp#   define ENTRY(value, name, msg)	{value, name}
7633965Sjdp#endif
7733965Sjdp
7833965Sjdpstatic const struct signal_info signal_table[] =
7933965Sjdp{
8033965Sjdp#if defined (SIGHUP)
8133965Sjdp  ENTRY(SIGHUP, "SIGHUP", "Hangup"),
8233965Sjdp#endif
8333965Sjdp#if defined (SIGINT)
8433965Sjdp  ENTRY(SIGINT, "SIGINT", "Interrupt"),
8533965Sjdp#endif
8633965Sjdp#if defined (SIGQUIT)
8733965Sjdp  ENTRY(SIGQUIT, "SIGQUIT", "Quit"),
8833965Sjdp#endif
8933965Sjdp#if defined (SIGILL)
9033965Sjdp  ENTRY(SIGILL, "SIGILL", "Illegal instruction"),
9133965Sjdp#endif
9233965Sjdp#if defined (SIGTRAP)
9333965Sjdp  ENTRY(SIGTRAP, "SIGTRAP", "Trace/breakpoint trap"),
9433965Sjdp#endif
9533965Sjdp/* Put SIGIOT before SIGABRT, so that if SIGIOT==SIGABRT then SIGABRT
9633965Sjdp   overrides SIGIOT.  SIGABRT is in ANSI and POSIX.1, and SIGIOT isn't. */
9733965Sjdp#if defined (SIGIOT)
9833965Sjdp  ENTRY(SIGIOT, "SIGIOT", "IOT trap"),
9933965Sjdp#endif
10033965Sjdp#if defined (SIGABRT)
10133965Sjdp  ENTRY(SIGABRT, "SIGABRT", "Aborted"),
10233965Sjdp#endif
10333965Sjdp#if defined (SIGEMT)
10433965Sjdp  ENTRY(SIGEMT, "SIGEMT", "Emulation trap"),
10533965Sjdp#endif
10633965Sjdp#if defined (SIGFPE)
10733965Sjdp  ENTRY(SIGFPE, "SIGFPE", "Arithmetic exception"),
10833965Sjdp#endif
10933965Sjdp#if defined (SIGKILL)
11033965Sjdp  ENTRY(SIGKILL, "SIGKILL", "Killed"),
11133965Sjdp#endif
11233965Sjdp#if defined (SIGBUS)
11333965Sjdp  ENTRY(SIGBUS, "SIGBUS", "Bus error"),
11433965Sjdp#endif
11533965Sjdp#if defined (SIGSEGV)
11633965Sjdp  ENTRY(SIGSEGV, "SIGSEGV", "Segmentation fault"),
11733965Sjdp#endif
11833965Sjdp#if defined (SIGSYS)
11933965Sjdp  ENTRY(SIGSYS, "SIGSYS", "Bad system call"),
12033965Sjdp#endif
12133965Sjdp#if defined (SIGPIPE)
12233965Sjdp  ENTRY(SIGPIPE, "SIGPIPE", "Broken pipe"),
12333965Sjdp#endif
12433965Sjdp#if defined (SIGALRM)
12533965Sjdp  ENTRY(SIGALRM, "SIGALRM", "Alarm clock"),
12633965Sjdp#endif
12733965Sjdp#if defined (SIGTERM)
12833965Sjdp  ENTRY(SIGTERM, "SIGTERM", "Terminated"),
12933965Sjdp#endif
13033965Sjdp#if defined (SIGUSR1)
13133965Sjdp  ENTRY(SIGUSR1, "SIGUSR1", "User defined signal 1"),
13233965Sjdp#endif
13333965Sjdp#if defined (SIGUSR2)
13433965Sjdp  ENTRY(SIGUSR2, "SIGUSR2", "User defined signal 2"),
13533965Sjdp#endif
13633965Sjdp/* Put SIGCLD before SIGCHLD, so that if SIGCLD==SIGCHLD then SIGCHLD
13733965Sjdp   overrides SIGCLD.  SIGCHLD is in POXIX.1 */
13833965Sjdp#if defined (SIGCLD)
13933965Sjdp  ENTRY(SIGCLD, "SIGCLD", "Child status changed"),
14033965Sjdp#endif
14133965Sjdp#if defined (SIGCHLD)
14233965Sjdp  ENTRY(SIGCHLD, "SIGCHLD", "Child status changed"),
14333965Sjdp#endif
14433965Sjdp#if defined (SIGPWR)
14533965Sjdp  ENTRY(SIGPWR, "SIGPWR", "Power fail/restart"),
14633965Sjdp#endif
14733965Sjdp#if defined (SIGWINCH)
14833965Sjdp  ENTRY(SIGWINCH, "SIGWINCH", "Window size changed"),
14933965Sjdp#endif
15033965Sjdp#if defined (SIGURG)
15133965Sjdp  ENTRY(SIGURG, "SIGURG", "Urgent I/O condition"),
15233965Sjdp#endif
15333965Sjdp#if defined (SIGIO)
15433965Sjdp  /* "I/O pending" has also been suggested, but is misleading since the
15533965Sjdp     signal only happens when the process has asked for it, not everytime
15633965Sjdp     I/O is pending. */
15733965Sjdp  ENTRY(SIGIO, "SIGIO", "I/O possible"),
15833965Sjdp#endif
15933965Sjdp#if defined (SIGPOLL)
16033965Sjdp  ENTRY(SIGPOLL, "SIGPOLL", "Pollable event occurred"),
16133965Sjdp#endif
16233965Sjdp#if defined (SIGSTOP)
16333965Sjdp  ENTRY(SIGSTOP, "SIGSTOP", "Stopped (signal)"),
16433965Sjdp#endif
16533965Sjdp#if defined (SIGTSTP)
16633965Sjdp  ENTRY(SIGTSTP, "SIGTSTP", "Stopped (user)"),
16733965Sjdp#endif
16833965Sjdp#if defined (SIGCONT)
16933965Sjdp  ENTRY(SIGCONT, "SIGCONT", "Continued"),
17033965Sjdp#endif
17133965Sjdp#if defined (SIGTTIN)
17233965Sjdp  ENTRY(SIGTTIN, "SIGTTIN", "Stopped (tty input)"),
17333965Sjdp#endif
17433965Sjdp#if defined (SIGTTOU)
17533965Sjdp  ENTRY(SIGTTOU, "SIGTTOU", "Stopped (tty output)"),
17633965Sjdp#endif
17733965Sjdp#if defined (SIGVTALRM)
17833965Sjdp  ENTRY(SIGVTALRM, "SIGVTALRM", "Virtual timer expired"),
17933965Sjdp#endif
18033965Sjdp#if defined (SIGPROF)
18133965Sjdp  ENTRY(SIGPROF, "SIGPROF", "Profiling timer expired"),
18233965Sjdp#endif
18333965Sjdp#if defined (SIGXCPU)
18433965Sjdp  ENTRY(SIGXCPU, "SIGXCPU", "CPU time limit exceeded"),
18533965Sjdp#endif
18633965Sjdp#if defined (SIGXFSZ)
18733965Sjdp  ENTRY(SIGXFSZ, "SIGXFSZ", "File size limit exceeded"),
18833965Sjdp#endif
18933965Sjdp#if defined (SIGWIND)
19033965Sjdp  ENTRY(SIGWIND, "SIGWIND", "SIGWIND"),
19133965Sjdp#endif
19233965Sjdp#if defined (SIGPHONE)
19333965Sjdp  ENTRY(SIGPHONE, "SIGPHONE", "SIGPHONE"),
19433965Sjdp#endif
19533965Sjdp#if defined (SIGLOST)
19633965Sjdp  ENTRY(SIGLOST, "SIGLOST", "Resource lost"),
19733965Sjdp#endif
19833965Sjdp#if defined (SIGWAITING)
19933965Sjdp  ENTRY(SIGWAITING, "SIGWAITING", "Process's LWPs are blocked"),
20033965Sjdp#endif
20133965Sjdp#if defined (SIGLWP)
20233965Sjdp  ENTRY(SIGLWP, "SIGLWP", "Signal LWP"),
20333965Sjdp#endif
20433965Sjdp#if defined (SIGDANGER)
20533965Sjdp  ENTRY(SIGDANGER, "SIGDANGER", "Swap space dangerously low"),
20633965Sjdp#endif
20733965Sjdp#if defined (SIGGRANT)
20833965Sjdp  ENTRY(SIGGRANT, "SIGGRANT", "Monitor mode granted"),
20933965Sjdp#endif
21033965Sjdp#if defined (SIGRETRACT)
21133965Sjdp  ENTRY(SIGRETRACT, "SIGRETRACT", "Need to relinguish monitor mode"),
21233965Sjdp#endif
21333965Sjdp#if defined (SIGMSG)
21433965Sjdp  ENTRY(SIGMSG, "SIGMSG", "Monitor mode data available"),
21533965Sjdp#endif
21633965Sjdp#if defined (SIGSOUND)
21733965Sjdp  ENTRY(SIGSOUND, "SIGSOUND", "Sound completed"),
21833965Sjdp#endif
21933965Sjdp#if defined (SIGSAK)
22033965Sjdp  ENTRY(SIGSAK, "SIGSAK", "Secure attention"),
22133965Sjdp#endif
22233965Sjdp  ENTRY(0, NULL, NULL)
22333965Sjdp};
22433965Sjdp
22533965Sjdp/* Translation table allocated and initialized at runtime.  Indexed by the
22633965Sjdp   signal value to find the equivalent symbolic value. */
22733965Sjdp
22833965Sjdpstatic const char **signal_names;
22933965Sjdpstatic int num_signal_names = 0;
23033965Sjdp
23133965Sjdp/* Translation table allocated and initialized at runtime, if it does not
23233965Sjdp   already exist in the host environment.  Indexed by the signal value to find
23333965Sjdp   the descriptive string.
23433965Sjdp
23533965Sjdp   We don't export it for use in other modules because even though it has the
23633965Sjdp   same name, it differs from other implementations in that it is dynamically
23733965Sjdp   initialized rather than statically initialized. */
23833965Sjdp
23960484Sobrien#ifndef HAVE_SYS_SIGLIST
24033965Sjdp
24133965Sjdpstatic int sys_nsig;
24233965Sjdpstatic const char **sys_siglist;
24333965Sjdp
24433965Sjdp#else
24533965Sjdp
24638889Sjdp#ifdef NSIG
24733965Sjdpstatic int sys_nsig = NSIG;
24838889Sjdp#else
24938889Sjdp#ifdef _NSIG
25038889Sjdpstatic int sys_nsig = _NSIG;
25138889Sjdp#endif
25238889Sjdp#endif
25333965Sjdpextern const char * const sys_siglist[];
25433965Sjdp
25533965Sjdp#endif
25633965Sjdp
25733965Sjdp
25833965Sjdp/*
25933965Sjdp
26033965SjdpNAME
26133965Sjdp
26233965Sjdp	init_signal_tables -- initialize the name and message tables
26333965Sjdp
26433965SjdpSYNOPSIS
26533965Sjdp
26633965Sjdp	static void init_signal_tables ();
26733965Sjdp
26833965SjdpDESCRIPTION
26933965Sjdp
27033965Sjdp	Using the signal_table, which is initialized at compile time, generate
27133965Sjdp	the signal_names and the sys_siglist (if needed) tables, which are
27233965Sjdp	indexed at runtime by a specific signal value.
27333965Sjdp
27433965SjdpBUGS
27533965Sjdp
27633965Sjdp	The initialization of the tables may fail under low memory conditions,
27733965Sjdp	in which case we don't do anything particularly useful, but we don't
27833965Sjdp	bomb either.  Who knows, it might succeed at a later point if we free
27933965Sjdp	some memory in the meantime.  In any case, the other routines know
28033965Sjdp	how to deal with lack of a table after trying to initialize it.  This
28133965Sjdp	may or may not be considered to be a bug, that we don't specifically
28233965Sjdp	warn about this particular failure mode.
28333965Sjdp
28433965Sjdp*/
28533965Sjdp
28633965Sjdpstatic void
28733965Sjdpinit_signal_tables ()
28833965Sjdp{
28933965Sjdp  const struct signal_info *eip;
29033965Sjdp  int nbytes;
29133965Sjdp
29233965Sjdp  /* If we haven't already scanned the signal_table once to find the maximum
29333965Sjdp     signal value, then go find it now. */
29433965Sjdp
29533965Sjdp  if (num_signal_names == 0)
29633965Sjdp    {
29733965Sjdp      for (eip = signal_table; eip -> name != NULL; eip++)
29833965Sjdp	{
29933965Sjdp	  if (eip -> value >= num_signal_names)
30033965Sjdp	    {
30133965Sjdp	      num_signal_names = eip -> value + 1;
30233965Sjdp	    }
30333965Sjdp	}
30433965Sjdp    }
30533965Sjdp
30633965Sjdp  /* Now attempt to allocate the signal_names table, zero it out, and then
30733965Sjdp     initialize it from the statically initialized signal_table. */
30833965Sjdp
30933965Sjdp  if (signal_names == NULL)
31033965Sjdp    {
31133965Sjdp      nbytes = num_signal_names * sizeof (char *);
31233965Sjdp      if ((signal_names = (const char **) malloc (nbytes)) != NULL)
31333965Sjdp	{
31433965Sjdp	  memset (signal_names, 0, nbytes);
31533965Sjdp	  for (eip = signal_table; eip -> name != NULL; eip++)
31633965Sjdp	    {
31733965Sjdp	      signal_names[eip -> value] = eip -> name;
31833965Sjdp	    }
31933965Sjdp	}
32033965Sjdp    }
32133965Sjdp
32260484Sobrien#ifndef HAVE_SYS_SIGLIST
32333965Sjdp
32433965Sjdp  /* Now attempt to allocate the sys_siglist table, zero it out, and then
32533965Sjdp     initialize it from the statically initialized signal_table. */
32633965Sjdp
32733965Sjdp  if (sys_siglist == NULL)
32833965Sjdp    {
32933965Sjdp      nbytes = num_signal_names * sizeof (char *);
33033965Sjdp      if ((sys_siglist = (const char **) malloc (nbytes)) != NULL)
33133965Sjdp	{
33233965Sjdp	  memset (sys_siglist, 0, nbytes);
33333965Sjdp	  sys_nsig = num_signal_names;
33433965Sjdp	  for (eip = signal_table; eip -> name != NULL; eip++)
33533965Sjdp	    {
33633965Sjdp	      sys_siglist[eip -> value] = eip -> msg;
33733965Sjdp	    }
33833965Sjdp	}
33933965Sjdp    }
34033965Sjdp
34133965Sjdp#endif
34233965Sjdp
34333965Sjdp}
34433965Sjdp
34533965Sjdp
34633965Sjdp/*
34733965Sjdp
34833965SjdpNAME
34933965Sjdp
35033965Sjdp	signo_max -- return the max signo value
35133965Sjdp
35233965SjdpSYNOPSIS
35333965Sjdp
35433965Sjdp	int signo_max ();
35533965Sjdp
35633965SjdpDESCRIPTION
35733965Sjdp
35833965Sjdp	Returns the maximum signo value for which a corresponding symbolic
35933965Sjdp	name or message is available.  Note that in the case where
36033965Sjdp	we use the sys_siglist supplied by the system, it is possible for
36133965Sjdp	there to be more symbolic names than messages, or vice versa.
36233965Sjdp	In fact, the manual page for psignal(3b) explicitly warns that one
36333965Sjdp	should check the size of the table (NSIG) before indexing it,
36433965Sjdp	since new signal codes may be added to the system before they are
36533965Sjdp	added to the table.  Thus NSIG might be smaller than value
36633965Sjdp	implied by the largest signo value defined in <signal.h>.
36733965Sjdp
36833965Sjdp	We return the maximum value that can be used to obtain a meaningful
36933965Sjdp	symbolic name or message.
37033965Sjdp
37133965Sjdp*/
37233965Sjdp
37333965Sjdpint
37433965Sjdpsigno_max ()
37533965Sjdp{
37633965Sjdp  int maxsize;
37733965Sjdp
37833965Sjdp  if (signal_names == NULL)
37933965Sjdp    {
38033965Sjdp      init_signal_tables ();
38133965Sjdp    }
38233965Sjdp  maxsize = MAX (sys_nsig, num_signal_names);
38333965Sjdp  return (maxsize - 1);
38433965Sjdp}
38533965Sjdp
38633965Sjdp
38733965Sjdp/*
38833965Sjdp
38933965SjdpNAME
39033965Sjdp
39133965Sjdp	strsignal -- map a signal number to a signal message string
39233965Sjdp
39333965SjdpSYNOPSIS
39433965Sjdp
39533965Sjdp	const char *strsignal (int signo)
39633965Sjdp
39733965SjdpDESCRIPTION
39833965Sjdp
39933965Sjdp	Maps an signal number to an signal message string, the contents of
40033965Sjdp	which are implementation defined.  On systems which have the external
40133965Sjdp	variable sys_siglist, these strings will be the same as the ones used
40233965Sjdp	by psignal().
40333965Sjdp
40433965Sjdp	If the supplied signal number is within the valid range of indices
40533965Sjdp	for the sys_siglist, but no message is available for the particular
40633965Sjdp	signal number, then returns the string "Signal NUM", where NUM is the
40733965Sjdp	signal number.
40833965Sjdp
40933965Sjdp	If the supplied signal number is not a valid index into sys_siglist,
41033965Sjdp	returns NULL.
41133965Sjdp
41233965Sjdp	The returned string is only guaranteed to be valid only until the
41333965Sjdp	next call to strsignal.
41433965Sjdp
41533965Sjdp*/
41633965Sjdp
41760484Sobrien#ifndef HAVE_STRSIGNAL
41833965Sjdp
41933965Sjdpconst char *
42033965Sjdpstrsignal (signo)
42133965Sjdp  int signo;
42233965Sjdp{
42333965Sjdp  const char *msg;
42433965Sjdp  static char buf[32];
42533965Sjdp
42660484Sobrien#ifndef HAVE_SYS_SIGLIST
42733965Sjdp
42833965Sjdp  if (signal_names == NULL)
42933965Sjdp    {
43033965Sjdp      init_signal_tables ();
43133965Sjdp    }
43233965Sjdp
43333965Sjdp#endif
43433965Sjdp
43533965Sjdp  if ((signo < 0) || (signo >= sys_nsig))
43633965Sjdp    {
43733965Sjdp      /* Out of range, just return NULL */
43833965Sjdp      msg = NULL;
43933965Sjdp    }
44033965Sjdp  else if ((sys_siglist == NULL) || (sys_siglist[signo] == NULL))
44133965Sjdp    {
44233965Sjdp      /* In range, but no sys_siglist or no entry at this index. */
44333965Sjdp      sprintf (buf, "Signal %d", signo);
44433965Sjdp      msg = (const char *) buf;
44533965Sjdp    }
44633965Sjdp  else
44733965Sjdp    {
44833965Sjdp      /* In range, and a valid message.  Just return the message. */
44933965Sjdp      msg = (const char *) sys_siglist[signo];
45033965Sjdp    }
45133965Sjdp
45233965Sjdp  return (msg);
45333965Sjdp}
45433965Sjdp
45560484Sobrien#endif /* ! HAVE_STRSIGNAL */
45633965Sjdp
45733965Sjdp/*
45833965Sjdp
45933965SjdpNAME
46033965Sjdp
46133965Sjdp	strsigno -- map an signal number to a symbolic name string
46233965Sjdp
46333965SjdpSYNOPSIS
46433965Sjdp
46533965Sjdp	const char *strsigno (int signo)
46633965Sjdp
46733965SjdpDESCRIPTION
46833965Sjdp
46933965Sjdp	Given an signal number, returns a pointer to a string containing
47033965Sjdp	the symbolic name of that signal number, as found in <signal.h>.
47133965Sjdp
47233965Sjdp	If the supplied signal number is within the valid range of indices
47333965Sjdp	for symbolic names, but no name is available for the particular
47433965Sjdp	signal number, then returns the string "Signal NUM", where NUM is
47533965Sjdp	the signal number.
47633965Sjdp
47733965Sjdp	If the supplied signal number is not within the range of valid
47833965Sjdp	indices, then returns NULL.
47933965Sjdp
48033965SjdpBUGS
48133965Sjdp
48233965Sjdp	The contents of the location pointed to are only guaranteed to be
48333965Sjdp	valid until the next call to strsigno.
48433965Sjdp
48533965Sjdp*/
48633965Sjdp
48733965Sjdpconst char *
48833965Sjdpstrsigno (signo)
48933965Sjdp  int signo;
49033965Sjdp{
49133965Sjdp  const char *name;
49233965Sjdp  static char buf[32];
49333965Sjdp
49433965Sjdp  if (signal_names == NULL)
49533965Sjdp    {
49633965Sjdp      init_signal_tables ();
49733965Sjdp    }
49833965Sjdp
49933965Sjdp  if ((signo < 0) || (signo >= num_signal_names))
50033965Sjdp    {
50133965Sjdp      /* Out of range, just return NULL */
50233965Sjdp      name = NULL;
50333965Sjdp    }
50433965Sjdp  else if ((signal_names == NULL) || (signal_names[signo] == NULL))
50533965Sjdp    {
50633965Sjdp      /* In range, but no signal_names or no entry at this index. */
50733965Sjdp      sprintf (buf, "Signal %d", signo);
50833965Sjdp      name = (const char *) buf;
50933965Sjdp    }
51033965Sjdp  else
51133965Sjdp    {
51233965Sjdp      /* In range, and a valid name.  Just return the name. */
51333965Sjdp      name = signal_names[signo];
51433965Sjdp    }
51533965Sjdp
51633965Sjdp  return (name);
51733965Sjdp}
51833965Sjdp
51933965Sjdp
52033965Sjdp/*
52133965Sjdp
52233965SjdpNAME
52333965Sjdp
52433965Sjdp	strtosigno -- map a symbolic signal name to a numeric value
52533965Sjdp
52633965SjdpSYNOPSIS
52733965Sjdp
52833965Sjdp	int strtosigno (char *name)
52933965Sjdp
53033965SjdpDESCRIPTION
53133965Sjdp
53233965Sjdp	Given the symbolic name of a signal, map it to a signal number.
53333965Sjdp	If no translation is found, returns 0.
53433965Sjdp
53533965Sjdp*/
53633965Sjdp
53733965Sjdpint
53833965Sjdpstrtosigno (name)
53933965Sjdp     const char *name;
54033965Sjdp{
54133965Sjdp  int signo = 0;
54233965Sjdp
54333965Sjdp  if (name != NULL)
54433965Sjdp    {
54533965Sjdp      if (signal_names == NULL)
54633965Sjdp	{
54733965Sjdp	  init_signal_tables ();
54833965Sjdp	}
54933965Sjdp      for (signo = 0; signo < num_signal_names; signo++)
55033965Sjdp	{
55133965Sjdp	  if ((signal_names[signo] != NULL) &&
55233965Sjdp	      (strcmp (name, signal_names[signo]) == 0))
55333965Sjdp	    {
55433965Sjdp	      break;
55533965Sjdp	    }
55633965Sjdp	}
55733965Sjdp      if (signo == num_signal_names)
55833965Sjdp	{
55933965Sjdp	  signo = 0;
56033965Sjdp	}
56133965Sjdp    }
56233965Sjdp  return (signo);
56333965Sjdp}
56433965Sjdp
56533965Sjdp
56633965Sjdp/*
56733965Sjdp
56833965SjdpNAME
56933965Sjdp
57033965Sjdp	psignal -- print message about signal to stderr
57133965Sjdp
57233965SjdpSYNOPSIS
57333965Sjdp
57433965Sjdp	void psignal (unsigned signo, char *message);
57533965Sjdp
57633965SjdpDESCRIPTION
57733965Sjdp
57833965Sjdp	Print to the standard error the message, followed by a colon,
57933965Sjdp	followed by the description of the signal specified by signo,
58033965Sjdp	followed by a newline.
58133965Sjdp*/
58233965Sjdp
58360484Sobrien#ifndef HAVE_PSIGNAL
58433965Sjdp
58533965Sjdpvoid
58633965Sjdppsignal (signo, message)
58733965Sjdp  unsigned signo;
58833965Sjdp  char *message;
58933965Sjdp{
59033965Sjdp  if (signal_names == NULL)
59133965Sjdp    {
59233965Sjdp      init_signal_tables ();
59333965Sjdp    }
59433965Sjdp  if ((signo <= 0) || (signo >= sys_nsig))
59533965Sjdp    {
59633965Sjdp      fprintf (stderr, "%s: unknown signal\n", message);
59733965Sjdp    }
59833965Sjdp  else
59933965Sjdp    {
60033965Sjdp      fprintf (stderr, "%s: %s\n", message, sys_siglist[signo]);
60133965Sjdp    }
60233965Sjdp}
60333965Sjdp
60460484Sobrien#endif	/* ! HAVE_PSIGNAL */
60533965Sjdp
60633965Sjdp
60733965Sjdp/* A simple little main that does nothing but print all the signal translations
60833965Sjdp   if MAIN is defined and this file is compiled and linked. */
60933965Sjdp
61033965Sjdp#ifdef MAIN
61133965Sjdp
61233965Sjdp#include <stdio.h>
61333965Sjdp
61433965Sjdpint
61533965Sjdpmain ()
61633965Sjdp{
61733965Sjdp  int signo;
61833965Sjdp  int maxsigno;
61933965Sjdp  const char *name;
62033965Sjdp  const char *msg;
62133965Sjdp
62233965Sjdp  maxsigno = signo_max ();
62333965Sjdp  printf ("%d entries in names table.\n", num_signal_names);
62433965Sjdp  printf ("%d entries in messages table.\n", sys_nsig);
62533965Sjdp  printf ("%d is max useful index.\n", maxsigno);
62633965Sjdp
62733965Sjdp  /* Keep printing values until we get to the end of *both* tables, not
62833965Sjdp     *either* table.  Note that knowing the maximum useful index does *not*
62933965Sjdp     relieve us of the responsibility of testing the return pointer for
63033965Sjdp     NULL. */
63133965Sjdp
63233965Sjdp  for (signo = 0; signo <= maxsigno; signo++)
63333965Sjdp    {
63433965Sjdp      name = strsigno (signo);
63533965Sjdp      name = (name == NULL) ? "<NULL>" : name;
63633965Sjdp      msg = strsignal (signo);
63733965Sjdp      msg = (msg == NULL) ? "<NULL>" : msg;
63833965Sjdp      printf ("%-4d%-18s%s\n", signo, name, msg);
63933965Sjdp    }
64033965Sjdp
64133965Sjdp  return 0;
64233965Sjdp}
64333965Sjdp
64433965Sjdp#endif
645