strsignal.c revision 33965
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 */
6733965Sjdp#ifdef NEED_sys_siglist
6833965Sjdp  const char *msg;	/* Short message about this value */
6933965Sjdp#endif
7033965Sjdp};
7133965Sjdp
7233965Sjdp#ifdef NEED_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
23933965Sjdp#ifdef NEED_sys_siglist
24033965Sjdp
24133965Sjdpstatic int sys_nsig;
24233965Sjdpstatic const char **sys_siglist;
24333965Sjdp
24433965Sjdp#else
24533965Sjdp
24633965Sjdpstatic int sys_nsig = NSIG;
24733965Sjdpextern const char * const sys_siglist[];
24833965Sjdp
24933965Sjdp#endif
25033965Sjdp
25133965Sjdp
25233965Sjdp/*
25333965Sjdp
25433965SjdpNAME
25533965Sjdp
25633965Sjdp	init_signal_tables -- initialize the name and message tables
25733965Sjdp
25833965SjdpSYNOPSIS
25933965Sjdp
26033965Sjdp	static void init_signal_tables ();
26133965Sjdp
26233965SjdpDESCRIPTION
26333965Sjdp
26433965Sjdp	Using the signal_table, which is initialized at compile time, generate
26533965Sjdp	the signal_names and the sys_siglist (if needed) tables, which are
26633965Sjdp	indexed at runtime by a specific signal value.
26733965Sjdp
26833965SjdpBUGS
26933965Sjdp
27033965Sjdp	The initialization of the tables may fail under low memory conditions,
27133965Sjdp	in which case we don't do anything particularly useful, but we don't
27233965Sjdp	bomb either.  Who knows, it might succeed at a later point if we free
27333965Sjdp	some memory in the meantime.  In any case, the other routines know
27433965Sjdp	how to deal with lack of a table after trying to initialize it.  This
27533965Sjdp	may or may not be considered to be a bug, that we don't specifically
27633965Sjdp	warn about this particular failure mode.
27733965Sjdp
27833965Sjdp*/
27933965Sjdp
28033965Sjdpstatic void
28133965Sjdpinit_signal_tables ()
28233965Sjdp{
28333965Sjdp  const struct signal_info *eip;
28433965Sjdp  int nbytes;
28533965Sjdp
28633965Sjdp  /* If we haven't already scanned the signal_table once to find the maximum
28733965Sjdp     signal value, then go find it now. */
28833965Sjdp
28933965Sjdp  if (num_signal_names == 0)
29033965Sjdp    {
29133965Sjdp      for (eip = signal_table; eip -> name != NULL; eip++)
29233965Sjdp	{
29333965Sjdp	  if (eip -> value >= num_signal_names)
29433965Sjdp	    {
29533965Sjdp	      num_signal_names = eip -> value + 1;
29633965Sjdp	    }
29733965Sjdp	}
29833965Sjdp    }
29933965Sjdp
30033965Sjdp  /* Now attempt to allocate the signal_names table, zero it out, and then
30133965Sjdp     initialize it from the statically initialized signal_table. */
30233965Sjdp
30333965Sjdp  if (signal_names == NULL)
30433965Sjdp    {
30533965Sjdp      nbytes = num_signal_names * sizeof (char *);
30633965Sjdp      if ((signal_names = (const char **) malloc (nbytes)) != NULL)
30733965Sjdp	{
30833965Sjdp	  memset (signal_names, 0, nbytes);
30933965Sjdp	  for (eip = signal_table; eip -> name != NULL; eip++)
31033965Sjdp	    {
31133965Sjdp	      signal_names[eip -> value] = eip -> name;
31233965Sjdp	    }
31333965Sjdp	}
31433965Sjdp    }
31533965Sjdp
31633965Sjdp#ifdef NEED_sys_siglist
31733965Sjdp
31833965Sjdp  /* Now attempt to allocate the sys_siglist table, zero it out, and then
31933965Sjdp     initialize it from the statically initialized signal_table. */
32033965Sjdp
32133965Sjdp  if (sys_siglist == NULL)
32233965Sjdp    {
32333965Sjdp      nbytes = num_signal_names * sizeof (char *);
32433965Sjdp      if ((sys_siglist = (const char **) malloc (nbytes)) != NULL)
32533965Sjdp	{
32633965Sjdp	  memset (sys_siglist, 0, nbytes);
32733965Sjdp	  sys_nsig = num_signal_names;
32833965Sjdp	  for (eip = signal_table; eip -> name != NULL; eip++)
32933965Sjdp	    {
33033965Sjdp	      sys_siglist[eip -> value] = eip -> msg;
33133965Sjdp	    }
33233965Sjdp	}
33333965Sjdp    }
33433965Sjdp
33533965Sjdp#endif
33633965Sjdp
33733965Sjdp}
33833965Sjdp
33933965Sjdp
34033965Sjdp/*
34133965Sjdp
34233965SjdpNAME
34333965Sjdp
34433965Sjdp	signo_max -- return the max signo value
34533965Sjdp
34633965SjdpSYNOPSIS
34733965Sjdp
34833965Sjdp	int signo_max ();
34933965Sjdp
35033965SjdpDESCRIPTION
35133965Sjdp
35233965Sjdp	Returns the maximum signo value for which a corresponding symbolic
35333965Sjdp	name or message is available.  Note that in the case where
35433965Sjdp	we use the sys_siglist supplied by the system, it is possible for
35533965Sjdp	there to be more symbolic names than messages, or vice versa.
35633965Sjdp	In fact, the manual page for psignal(3b) explicitly warns that one
35733965Sjdp	should check the size of the table (NSIG) before indexing it,
35833965Sjdp	since new signal codes may be added to the system before they are
35933965Sjdp	added to the table.  Thus NSIG might be smaller than value
36033965Sjdp	implied by the largest signo value defined in <signal.h>.
36133965Sjdp
36233965Sjdp	We return the maximum value that can be used to obtain a meaningful
36333965Sjdp	symbolic name or message.
36433965Sjdp
36533965Sjdp*/
36633965Sjdp
36733965Sjdpint
36833965Sjdpsigno_max ()
36933965Sjdp{
37033965Sjdp  int maxsize;
37133965Sjdp
37233965Sjdp  if (signal_names == NULL)
37333965Sjdp    {
37433965Sjdp      init_signal_tables ();
37533965Sjdp    }
37633965Sjdp  maxsize = MAX (sys_nsig, num_signal_names);
37733965Sjdp  return (maxsize - 1);
37833965Sjdp}
37933965Sjdp
38033965Sjdp
38133965Sjdp/*
38233965Sjdp
38333965SjdpNAME
38433965Sjdp
38533965Sjdp	strsignal -- map a signal number to a signal message string
38633965Sjdp
38733965SjdpSYNOPSIS
38833965Sjdp
38933965Sjdp	const char *strsignal (int signo)
39033965Sjdp
39133965SjdpDESCRIPTION
39233965Sjdp
39333965Sjdp	Maps an signal number to an signal message string, the contents of
39433965Sjdp	which are implementation defined.  On systems which have the external
39533965Sjdp	variable sys_siglist, these strings will be the same as the ones used
39633965Sjdp	by psignal().
39733965Sjdp
39833965Sjdp	If the supplied signal number is within the valid range of indices
39933965Sjdp	for the sys_siglist, but no message is available for the particular
40033965Sjdp	signal number, then returns the string "Signal NUM", where NUM is the
40133965Sjdp	signal number.
40233965Sjdp
40333965Sjdp	If the supplied signal number is not a valid index into sys_siglist,
40433965Sjdp	returns NULL.
40533965Sjdp
40633965Sjdp	The returned string is only guaranteed to be valid only until the
40733965Sjdp	next call to strsignal.
40833965Sjdp
40933965Sjdp*/
41033965Sjdp
41133965Sjdp#ifdef NEED_strsignal
41233965Sjdp
41333965Sjdpconst char *
41433965Sjdpstrsignal (signo)
41533965Sjdp  int signo;
41633965Sjdp{
41733965Sjdp  const char *msg;
41833965Sjdp  static char buf[32];
41933965Sjdp
42033965Sjdp#ifdef NEED_sys_siglist
42133965Sjdp
42233965Sjdp  if (signal_names == NULL)
42333965Sjdp    {
42433965Sjdp      init_signal_tables ();
42533965Sjdp    }
42633965Sjdp
42733965Sjdp#endif
42833965Sjdp
42933965Sjdp  if ((signo < 0) || (signo >= sys_nsig))
43033965Sjdp    {
43133965Sjdp      /* Out of range, just return NULL */
43233965Sjdp      msg = NULL;
43333965Sjdp    }
43433965Sjdp  else if ((sys_siglist == NULL) || (sys_siglist[signo] == NULL))
43533965Sjdp    {
43633965Sjdp      /* In range, but no sys_siglist or no entry at this index. */
43733965Sjdp      sprintf (buf, "Signal %d", signo);
43833965Sjdp      msg = (const char *) buf;
43933965Sjdp    }
44033965Sjdp  else
44133965Sjdp    {
44233965Sjdp      /* In range, and a valid message.  Just return the message. */
44333965Sjdp      msg = (const char *) sys_siglist[signo];
44433965Sjdp    }
44533965Sjdp
44633965Sjdp  return (msg);
44733965Sjdp}
44833965Sjdp
44933965Sjdp#endif /* NEED_strsignal */
45033965Sjdp
45133965Sjdp/*
45233965Sjdp
45333965SjdpNAME
45433965Sjdp
45533965Sjdp	strsigno -- map an signal number to a symbolic name string
45633965Sjdp
45733965SjdpSYNOPSIS
45833965Sjdp
45933965Sjdp	const char *strsigno (int signo)
46033965Sjdp
46133965SjdpDESCRIPTION
46233965Sjdp
46333965Sjdp	Given an signal number, returns a pointer to a string containing
46433965Sjdp	the symbolic name of that signal number, as found in <signal.h>.
46533965Sjdp
46633965Sjdp	If the supplied signal number is within the valid range of indices
46733965Sjdp	for symbolic names, but no name is available for the particular
46833965Sjdp	signal number, then returns the string "Signal NUM", where NUM is
46933965Sjdp	the signal number.
47033965Sjdp
47133965Sjdp	If the supplied signal number is not within the range of valid
47233965Sjdp	indices, then returns NULL.
47333965Sjdp
47433965SjdpBUGS
47533965Sjdp
47633965Sjdp	The contents of the location pointed to are only guaranteed to be
47733965Sjdp	valid until the next call to strsigno.
47833965Sjdp
47933965Sjdp*/
48033965Sjdp
48133965Sjdpconst char *
48233965Sjdpstrsigno (signo)
48333965Sjdp  int signo;
48433965Sjdp{
48533965Sjdp  const char *name;
48633965Sjdp  static char buf[32];
48733965Sjdp
48833965Sjdp  if (signal_names == NULL)
48933965Sjdp    {
49033965Sjdp      init_signal_tables ();
49133965Sjdp    }
49233965Sjdp
49333965Sjdp  if ((signo < 0) || (signo >= num_signal_names))
49433965Sjdp    {
49533965Sjdp      /* Out of range, just return NULL */
49633965Sjdp      name = NULL;
49733965Sjdp    }
49833965Sjdp  else if ((signal_names == NULL) || (signal_names[signo] == NULL))
49933965Sjdp    {
50033965Sjdp      /* In range, but no signal_names or no entry at this index. */
50133965Sjdp      sprintf (buf, "Signal %d", signo);
50233965Sjdp      name = (const char *) buf;
50333965Sjdp    }
50433965Sjdp  else
50533965Sjdp    {
50633965Sjdp      /* In range, and a valid name.  Just return the name. */
50733965Sjdp      name = signal_names[signo];
50833965Sjdp    }
50933965Sjdp
51033965Sjdp  return (name);
51133965Sjdp}
51233965Sjdp
51333965Sjdp
51433965Sjdp/*
51533965Sjdp
51633965SjdpNAME
51733965Sjdp
51833965Sjdp	strtosigno -- map a symbolic signal name to a numeric value
51933965Sjdp
52033965SjdpSYNOPSIS
52133965Sjdp
52233965Sjdp	int strtosigno (char *name)
52333965Sjdp
52433965SjdpDESCRIPTION
52533965Sjdp
52633965Sjdp	Given the symbolic name of a signal, map it to a signal number.
52733965Sjdp	If no translation is found, returns 0.
52833965Sjdp
52933965Sjdp*/
53033965Sjdp
53133965Sjdpint
53233965Sjdpstrtosigno (name)
53333965Sjdp     const char *name;
53433965Sjdp{
53533965Sjdp  int signo = 0;
53633965Sjdp
53733965Sjdp  if (name != NULL)
53833965Sjdp    {
53933965Sjdp      if (signal_names == NULL)
54033965Sjdp	{
54133965Sjdp	  init_signal_tables ();
54233965Sjdp	}
54333965Sjdp      for (signo = 0; signo < num_signal_names; signo++)
54433965Sjdp	{
54533965Sjdp	  if ((signal_names[signo] != NULL) &&
54633965Sjdp	      (strcmp (name, signal_names[signo]) == 0))
54733965Sjdp	    {
54833965Sjdp	      break;
54933965Sjdp	    }
55033965Sjdp	}
55133965Sjdp      if (signo == num_signal_names)
55233965Sjdp	{
55333965Sjdp	  signo = 0;
55433965Sjdp	}
55533965Sjdp    }
55633965Sjdp  return (signo);
55733965Sjdp}
55833965Sjdp
55933965Sjdp
56033965Sjdp/*
56133965Sjdp
56233965SjdpNAME
56333965Sjdp
56433965Sjdp	psignal -- print message about signal to stderr
56533965Sjdp
56633965SjdpSYNOPSIS
56733965Sjdp
56833965Sjdp	void psignal (unsigned signo, char *message);
56933965Sjdp
57033965SjdpDESCRIPTION
57133965Sjdp
57233965Sjdp	Print to the standard error the message, followed by a colon,
57333965Sjdp	followed by the description of the signal specified by signo,
57433965Sjdp	followed by a newline.
57533965Sjdp*/
57633965Sjdp
57733965Sjdp#ifdef NEED_psignal
57833965Sjdp
57933965Sjdpvoid
58033965Sjdppsignal (signo, message)
58133965Sjdp  unsigned signo;
58233965Sjdp  char *message;
58333965Sjdp{
58433965Sjdp  if (signal_names == NULL)
58533965Sjdp    {
58633965Sjdp      init_signal_tables ();
58733965Sjdp    }
58833965Sjdp  if ((signo <= 0) || (signo >= sys_nsig))
58933965Sjdp    {
59033965Sjdp      fprintf (stderr, "%s: unknown signal\n", message);
59133965Sjdp    }
59233965Sjdp  else
59333965Sjdp    {
59433965Sjdp      fprintf (stderr, "%s: %s\n", message, sys_siglist[signo]);
59533965Sjdp    }
59633965Sjdp}
59733965Sjdp
59833965Sjdp#endif	/* NEED_psignal */
59933965Sjdp
60033965Sjdp
60133965Sjdp/* A simple little main that does nothing but print all the signal translations
60233965Sjdp   if MAIN is defined and this file is compiled and linked. */
60333965Sjdp
60433965Sjdp#ifdef MAIN
60533965Sjdp
60633965Sjdp#include <stdio.h>
60733965Sjdp
60833965Sjdpint
60933965Sjdpmain ()
61033965Sjdp{
61133965Sjdp  int signo;
61233965Sjdp  int maxsigno;
61333965Sjdp  const char *name;
61433965Sjdp  const char *msg;
61533965Sjdp
61633965Sjdp  maxsigno = signo_max ();
61733965Sjdp  printf ("%d entries in names table.\n", num_signal_names);
61833965Sjdp  printf ("%d entries in messages table.\n", sys_nsig);
61933965Sjdp  printf ("%d is max useful index.\n", maxsigno);
62033965Sjdp
62133965Sjdp  /* Keep printing values until we get to the end of *both* tables, not
62233965Sjdp     *either* table.  Note that knowing the maximum useful index does *not*
62333965Sjdp     relieve us of the responsibility of testing the return pointer for
62433965Sjdp     NULL. */
62533965Sjdp
62633965Sjdp  for (signo = 0; signo <= maxsigno; signo++)
62733965Sjdp    {
62833965Sjdp      name = strsigno (signo);
62933965Sjdp      name = (name == NULL) ? "<NULL>" : name;
63033965Sjdp      msg = strsignal (signo);
63133965Sjdp      msg = (msg == NULL) ? "<NULL>" : msg;
63233965Sjdp      printf ("%-4d%-18s%s\n", signo, name, msg);
63333965Sjdp    }
63433965Sjdp
63533965Sjdp  return 0;
63633965Sjdp}
63733965Sjdp
63833965Sjdp#endif
639