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