133965Sjdp/* Extended support for using signal values.
233965Sjdp   Written by Fred Fish.  fnf@cygnus.com
333965Sjdp   This file is in the public domain.  */
433965Sjdp
5218822Sdim#include "config.h"
633965Sjdp#include "ansidecl.h"
733965Sjdp#include "libiberty.h"
833965Sjdp
933965Sjdp/* We need to declare sys_siglist, because even if the system provides
1033965Sjdp   it we can't assume that it is declared in <signal.h> (for example,
1133965Sjdp   SunOS provides sys_siglist, but it does not declare it in any
12218822Sdim   header file).  However, we can't declare sys_siglist portably,
1333965Sjdp   because on some systems it is declared with const and on some
1433965Sjdp   systems it is declared without const.  If we were using autoconf,
1533965Sjdp   we could work out the right declaration.  Until, then we just
1633965Sjdp   ignore any declaration in the system header files, and always
1733965Sjdp   declare it ourselves.  With luck, this will always work.  */
1833965Sjdp#define sys_siglist no_such_symbol
1989857Sobrien#define sys_nsig sys_nsig__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
4189857Sobrien#undef sys_nsig
4233965Sjdp
4333965Sjdp#ifndef NULL
44218822Sdim#  define NULL (void *) 0
4533965Sjdp#endif
4633965Sjdp
4733965Sjdp#ifndef MAX
4833965Sjdp#  define MAX(a,b) ((a) > (b) ? (a) : (b))
4933965Sjdp#endif
5033965Sjdp
51218822Sdimstatic void init_signal_tables (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{
6589857Sobrien  const int value;		/* The numeric value from <signal.h> */
6689857Sobrien  const char *const name;	/* The equivalent symbolic value */
6760484Sobrien#ifndef HAVE_SYS_SIGLIST
6889857Sobrien  const char *const 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
287218822Sdiminit_signal_tables (void)
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
34889857Sobrien@deftypefn Extension int signo_max (void)
34933965Sjdp
35089857SobrienReturns the maximum signal value for which a corresponding symbolic
35189857Sobrienname or message is available.  Note that in the case where we use the
35289857Sobrien@code{sys_siglist} supplied by the system, it is possible for there to
35389857Sobrienbe more symbolic names than messages, or vice versa.  In fact, the
35489857Sobrienmanual page for @code{psignal(3b)} explicitly warns that one should
35589857Sobriencheck the size of the table (@code{NSIG}) before indexing it, since
35689857Sobriennew signal codes may be added to the system before they are added to
35789857Sobrienthe table.  Thus @code{NSIG} might be smaller than value implied by
35889857Sobrienthe largest signo value defined in @code{<signal.h>}.
35933965Sjdp
36089857SobrienWe return the maximum value that can be used to obtain a meaningful
36189857Sobriensymbolic name or message.
36233965Sjdp
36389857Sobrien@end deftypefn
36433965Sjdp
36533965Sjdp*/
36633965Sjdp
36733965Sjdpint
368218822Sdimsigno_max (void)
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
38389857Sobrien@deftypefn Supplemental {const char *} strsignal (int @var{signo})
38433965Sjdp
38589857SobrienMaps an signal number to an signal message string, the contents of
38689857Sobrienwhich are implementation defined.  On systems which have the external
38789857Sobrienvariable @code{sys_siglist}, these strings will be the same as the
38889857Sobrienones used by @code{psignal()}.
38933965Sjdp
39089857SobrienIf the supplied signal number is within the valid range of indices for
39189857Sobrienthe @code{sys_siglist}, but no message is available for the particular
39289857Sobriensignal number, then returns the string @samp{Signal @var{num}}, where
39389857Sobrien@var{num} is the signal number.
39433965Sjdp
39589857SobrienIf the supplied signal number is not a valid index into
39689857Sobrien@code{sys_siglist}, returns @code{NULL}.
39733965Sjdp
39889857SobrienThe returned string is only guaranteed to be valid only until the next
39989857Sobriencall to @code{strsignal}.
40033965Sjdp
40189857Sobrien@end deftypefn
40233965Sjdp
40333965Sjdp*/
40433965Sjdp
40560484Sobrien#ifndef HAVE_STRSIGNAL
40633965Sjdp
40733965Sjdpconst char *
408218822Sdimstrsignal (int signo)
40933965Sjdp{
41033965Sjdp  const char *msg;
41133965Sjdp  static char buf[32];
41233965Sjdp
41360484Sobrien#ifndef HAVE_SYS_SIGLIST
41433965Sjdp
41533965Sjdp  if (signal_names == NULL)
41633965Sjdp    {
41733965Sjdp      init_signal_tables ();
41833965Sjdp    }
41933965Sjdp
42033965Sjdp#endif
42133965Sjdp
42233965Sjdp  if ((signo < 0) || (signo >= sys_nsig))
42333965Sjdp    {
42433965Sjdp      /* Out of range, just return NULL */
42533965Sjdp      msg = NULL;
42633965Sjdp    }
42733965Sjdp  else if ((sys_siglist == NULL) || (sys_siglist[signo] == NULL))
42833965Sjdp    {
42933965Sjdp      /* In range, but no sys_siglist or no entry at this index. */
43033965Sjdp      sprintf (buf, "Signal %d", signo);
43133965Sjdp      msg = (const char *) buf;
43233965Sjdp    }
43333965Sjdp  else
43433965Sjdp    {
43533965Sjdp      /* In range, and a valid message.  Just return the message. */
43633965Sjdp      msg = (const char *) sys_siglist[signo];
43733965Sjdp    }
43833965Sjdp
43933965Sjdp  return (msg);
44033965Sjdp}
44133965Sjdp
44260484Sobrien#endif /* ! HAVE_STRSIGNAL */
44333965Sjdp
44433965Sjdp/*
44533965Sjdp
44689857Sobrien@deftypefn Extension {const char*} strsigno (int @var{signo})
44733965Sjdp
44889857SobrienGiven an signal number, returns a pointer to a string containing the
44989857Sobriensymbolic name of that signal number, as found in @code{<signal.h>}.
45033965Sjdp
45189857SobrienIf the supplied signal number is within the valid range of indices for
45289857Sobriensymbolic names, but no name is available for the particular signal
45389857Sobriennumber, then returns the string @samp{Signal @var{num}}, where
45489857Sobrien@var{num} is the signal number.
45533965Sjdp
45689857SobrienIf the supplied signal number is not within the range of valid
45789857Sobrienindices, then returns @code{NULL}.
45833965Sjdp
45989857SobrienThe contents of the location pointed to are only guaranteed to be
46089857Sobrienvalid until the next call to @code{strsigno}.
46133965Sjdp
46289857Sobrien@end deftypefn
46333965Sjdp
46433965Sjdp*/
46533965Sjdp
46633965Sjdpconst char *
467218822Sdimstrsigno (int signo)
46833965Sjdp{
46933965Sjdp  const char *name;
47033965Sjdp  static char buf[32];
47133965Sjdp
47233965Sjdp  if (signal_names == NULL)
47333965Sjdp    {
47433965Sjdp      init_signal_tables ();
47533965Sjdp    }
47633965Sjdp
47733965Sjdp  if ((signo < 0) || (signo >= num_signal_names))
47833965Sjdp    {
47933965Sjdp      /* Out of range, just return NULL */
48033965Sjdp      name = NULL;
48133965Sjdp    }
48233965Sjdp  else if ((signal_names == NULL) || (signal_names[signo] == NULL))
48333965Sjdp    {
48433965Sjdp      /* In range, but no signal_names or no entry at this index. */
48533965Sjdp      sprintf (buf, "Signal %d", signo);
48633965Sjdp      name = (const char *) buf;
48733965Sjdp    }
48833965Sjdp  else
48933965Sjdp    {
49033965Sjdp      /* In range, and a valid name.  Just return the name. */
49133965Sjdp      name = signal_names[signo];
49233965Sjdp    }
49333965Sjdp
49433965Sjdp  return (name);
49533965Sjdp}
49633965Sjdp
49733965Sjdp
49833965Sjdp/*
49933965Sjdp
50089857Sobrien@deftypefn Extension int strtosigno (const char *@var{name})
50133965Sjdp
50289857SobrienGiven the symbolic name of a signal, map it to a signal number.  If no
50389857Sobrientranslation is found, returns 0.
50433965Sjdp
50589857Sobrien@end deftypefn
50633965Sjdp
50733965Sjdp*/
50833965Sjdp
50933965Sjdpint
510218822Sdimstrtosigno (const char *name)
51133965Sjdp{
51233965Sjdp  int signo = 0;
51333965Sjdp
51433965Sjdp  if (name != NULL)
51533965Sjdp    {
51633965Sjdp      if (signal_names == NULL)
51733965Sjdp	{
51833965Sjdp	  init_signal_tables ();
51933965Sjdp	}
52033965Sjdp      for (signo = 0; signo < num_signal_names; signo++)
52133965Sjdp	{
52233965Sjdp	  if ((signal_names[signo] != NULL) &&
52333965Sjdp	      (strcmp (name, signal_names[signo]) == 0))
52433965Sjdp	    {
52533965Sjdp	      break;
52633965Sjdp	    }
52733965Sjdp	}
52833965Sjdp      if (signo == num_signal_names)
52933965Sjdp	{
53033965Sjdp	  signo = 0;
53133965Sjdp	}
53233965Sjdp    }
53333965Sjdp  return (signo);
53433965Sjdp}
53533965Sjdp
53633965Sjdp
53733965Sjdp/*
53833965Sjdp
539218822Sdim@deftypefn Supplemental void psignal (int @var{signo}, char *@var{message})
54033965Sjdp
54189857SobrienPrint @var{message} to the standard error, followed by a colon,
54289857Sobrienfollowed by the description of the signal specified by @var{signo},
54389857Sobrienfollowed by a newline.
54433965Sjdp
54589857Sobrien@end deftypefn
54633965Sjdp
54733965Sjdp*/
54833965Sjdp
54960484Sobrien#ifndef HAVE_PSIGNAL
55033965Sjdp
55133965Sjdpvoid
552218822Sdimpsignal (int signo, char *message)
55333965Sjdp{
55433965Sjdp  if (signal_names == NULL)
55533965Sjdp    {
55633965Sjdp      init_signal_tables ();
55733965Sjdp    }
55833965Sjdp  if ((signo <= 0) || (signo >= sys_nsig))
55933965Sjdp    {
56033965Sjdp      fprintf (stderr, "%s: unknown signal\n", message);
56133965Sjdp    }
56233965Sjdp  else
56333965Sjdp    {
56433965Sjdp      fprintf (stderr, "%s: %s\n", message, sys_siglist[signo]);
56533965Sjdp    }
56633965Sjdp}
56733965Sjdp
56860484Sobrien#endif	/* ! HAVE_PSIGNAL */
56933965Sjdp
57033965Sjdp
57133965Sjdp/* A simple little main that does nothing but print all the signal translations
57233965Sjdp   if MAIN is defined and this file is compiled and linked. */
57333965Sjdp
57433965Sjdp#ifdef MAIN
57533965Sjdp
57633965Sjdp#include <stdio.h>
57733965Sjdp
57833965Sjdpint
579218822Sdimmain (void)
58033965Sjdp{
58133965Sjdp  int signo;
58233965Sjdp  int maxsigno;
58333965Sjdp  const char *name;
58433965Sjdp  const char *msg;
58533965Sjdp
58633965Sjdp  maxsigno = signo_max ();
58733965Sjdp  printf ("%d entries in names table.\n", num_signal_names);
58833965Sjdp  printf ("%d entries in messages table.\n", sys_nsig);
58933965Sjdp  printf ("%d is max useful index.\n", maxsigno);
59033965Sjdp
59133965Sjdp  /* Keep printing values until we get to the end of *both* tables, not
59233965Sjdp     *either* table.  Note that knowing the maximum useful index does *not*
59333965Sjdp     relieve us of the responsibility of testing the return pointer for
59433965Sjdp     NULL. */
59533965Sjdp
59633965Sjdp  for (signo = 0; signo <= maxsigno; signo++)
59733965Sjdp    {
59833965Sjdp      name = strsigno (signo);
59933965Sjdp      name = (name == NULL) ? "<NULL>" : name;
60033965Sjdp      msg = strsignal (signo);
60133965Sjdp      msg = (msg == NULL) ? "<NULL>" : msg;
60233965Sjdp      printf ("%-4d%-18s%s\n", signo, name, msg);
60333965Sjdp    }
60433965Sjdp
60533965Sjdp  return 0;
60633965Sjdp}
60733965Sjdp
60833965Sjdp#endif
609