1deb979d6Selan /* Extended support for using signal values.
2deb979d6Selan    Copyright (C) 1992 Free Software Foundation, Inc.
3deb979d6Selan    Written by Fred Fish.  fnf@cygnus.com
4deb979d6Selan 
5deb979d6Selan This file is part of the libiberty library.
6deb979d6Selan Libiberty is free software; you can redistribute it and/or
7deb979d6Selan modify it under the terms of the GNU Library General Public
8deb979d6Selan License as published by the Free Software Foundation; either
9deb979d6Selan version 2 of the License, or (at your option) any later version.
10deb979d6Selan 
11deb979d6Selan Libiberty is distributed in the hope that it will be useful,
12deb979d6Selan but WITHOUT ANY WARRANTY; without even the implied warranty of
13deb979d6Selan MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14deb979d6Selan Library General Public License for more details.
15deb979d6Selan 
16deb979d6Selan You should have received a copy of the GNU Library General Public
17deb979d6Selan License along with libiberty; see the file COPYING.LIB.  If
18deb979d6Selan not, write to the Free Software Foundation, Inc., 675 Mass Ave,
19deb979d6Selan Cambridge, MA 02139, USA.  */
20deb979d6Selan 
21deb979d6Selan #include "config.h"
22deb979d6Selan 
23deb979d6Selan #include <stdio.h>
24deb979d6Selan #include <signal.h>
25deb979d6Selan 
26deb979d6Selan /*  Routines imported from standard C runtime libraries. */
27deb979d6Selan 
28deb979d6Selan #ifdef __STDC__
29deb979d6Selan #include <stddef.h>
30deb979d6Selan extern void *malloc (size_t size);				/* 4.10.3.3 */
31deb979d6Selan extern void *memset (void *s, int c, size_t n);			/* 4.11.6.1 */
32deb979d6Selan #else	/* !__STDC__ */
33deb979d6Selan extern char *malloc ();		/* Standard memory allocater */
34deb979d6Selan extern char *memset ();
35deb979d6Selan #endif	/* __STDC__ */
36deb979d6Selan 
37deb979d6Selan #ifndef NULL
38deb979d6Selan #  ifdef __STDC__
39deb979d6Selan #    define NULL (void *) 0
40deb979d6Selan #  else
41deb979d6Selan #    define NULL 0
42deb979d6Selan #  endif
43deb979d6Selan #endif
44deb979d6Selan 
45deb979d6Selan #ifndef MAX
46deb979d6Selan #  define MAX(a,b) ((a) > (b) ? (a) : (b))
47deb979d6Selan #endif
48deb979d6Selan 
49deb979d6Selan /* Translation table for signal values.
50deb979d6Selan 
51deb979d6Selan    Note that this table is generally only accessed when it is used at runtime
52deb979d6Selan    to initialize signal name and message tables that are indexed by signal
53deb979d6Selan    value.
54deb979d6Selan 
55deb979d6Selan    Not all of these signals will exist on all systems.  This table is the only
56deb979d6Selan    thing that should have to be updated as new signal numbers are introduced.
57deb979d6Selan    It's sort of ugly, but at least its portable. */
58deb979d6Selan 
59deb979d6Selan static struct signal_info
60deb979d6Selan {
61deb979d6Selan   int value;		/* The numeric value from <signal.h> */
62deb979d6Selan   char *name;		/* The equivalent symbolic value */
63deb979d6Selan   char *msg;		/* Short message about this value */
64deb979d6Selan } signal_table[] =
65deb979d6Selan {
66deb979d6Selan #if defined (SIGHUP)
67deb979d6Selan   SIGHUP, "SIGHUP", "Hangup",
68deb979d6Selan #endif
69deb979d6Selan #if defined (SIGINT)
70deb979d6Selan   SIGINT, "SIGINT", "Interrupt",
71deb979d6Selan #endif
72deb979d6Selan #if defined (SIGQUIT)
73deb979d6Selan   SIGQUIT, "SIGQUIT", "Quit",
74deb979d6Selan #endif
75deb979d6Selan #if defined (SIGILL)
76deb979d6Selan   SIGILL, "SIGILL", "Illegal instruction",
77deb979d6Selan #endif
78deb979d6Selan #if defined (SIGTRAP)
79deb979d6Selan   SIGTRAP, "SIGTRAP", "Trace/breakpoint trap",
80deb979d6Selan #endif
81deb979d6Selan /* Put SIGIOT before SIGABRT, so that if SIGIOT==SIGABRT then SIGABRT
82deb979d6Selan    overrides SIGIOT.  SIGABRT is in ANSI and POSIX.1, and SIGIOT isn't. */
83deb979d6Selan #if defined (SIGIOT)
84deb979d6Selan   SIGIOT, "SIGIOT", "IOT trap",
85deb979d6Selan #endif
86deb979d6Selan #if defined (SIGABRT)
87deb979d6Selan   SIGABRT, "SIGABRT", "Aborted",
88deb979d6Selan #endif
89deb979d6Selan #if defined (SIGEMT)
90deb979d6Selan   SIGEMT, "SIGEMT", "Emulation trap",
91deb979d6Selan #endif
92deb979d6Selan #if defined (SIGFPE)
93deb979d6Selan   SIGFPE, "SIGFPE", "Arithmetic exception",
94deb979d6Selan #endif
95deb979d6Selan #if defined (SIGKILL)
96deb979d6Selan   SIGKILL, "SIGKILL", "Killed",
97deb979d6Selan #endif
98deb979d6Selan #if defined (SIGBUS)
99deb979d6Selan   SIGBUS, "SIGBUS", "Bus error",
100deb979d6Selan #endif
101deb979d6Selan #if defined (SIGSEGV)
102deb979d6Selan   SIGSEGV, "SIGSEGV", "Segmentation fault",
103deb979d6Selan #endif
104deb979d6Selan #if defined (SIGSYS)
105deb979d6Selan   SIGSYS, "SIGSYS", "Bad system call",
106deb979d6Selan #endif
107deb979d6Selan #if defined (SIGPIPE)
108deb979d6Selan   SIGPIPE, "SIGPIPE", "Broken pipe",
109deb979d6Selan #endif
110deb979d6Selan #if defined (SIGALRM)
111deb979d6Selan   SIGALRM, "SIGALRM", "Alarm clock",
112deb979d6Selan #endif
113deb979d6Selan #if defined (SIGTERM)
114deb979d6Selan   SIGTERM, "SIGTERM", "Terminated",
115deb979d6Selan #endif
116deb979d6Selan #if defined (SIGUSR1)
117deb979d6Selan   SIGUSR1, "SIGUSR1", "User defined signal 1",
118deb979d6Selan #endif
119deb979d6Selan #if defined (SIGUSR2)
120deb979d6Selan   SIGUSR2, "SIGUSR2", "User defined signal 2",
121deb979d6Selan #endif
122deb979d6Selan /* Put SIGCLD before SIGCHLD, so that if SIGCLD==SIGCHLD then SIGCHLD
123deb979d6Selan    overrides SIGCLD.  SIGCHLD is in POXIX.1 */
124deb979d6Selan #if defined (SIGCLD)
125deb979d6Selan   SIGCLD, "SIGCLD", "Child status changed",
126deb979d6Selan #endif
127deb979d6Selan #if defined (SIGCHLD)
128deb979d6Selan   SIGCHLD, "SIGCHLD", "Child status changed",
129deb979d6Selan #endif
130deb979d6Selan #if defined (SIGPWR)
131deb979d6Selan   SIGPWR, "SIGPWR", "Power fail/restart",
132deb979d6Selan #endif
133deb979d6Selan #if defined (SIGWINCH)
134deb979d6Selan   SIGWINCH, "SIGWINCH", "Window size changed",
135deb979d6Selan #endif
136deb979d6Selan #if defined (SIGURG)
137deb979d6Selan   SIGURG, "SIGURG", "Urgent I/O condition",
138deb979d6Selan #endif
139deb979d6Selan #if defined (SIGIO)
140deb979d6Selan   /* "I/O pending has also been suggested, but is misleading since the
141deb979d6Selan      signal only happens when the process has asked for it, not everytime
142deb979d6Selan      I/O is pending. */
143deb979d6Selan   SIGIO, "SIGIO", "I/O possible",
144deb979d6Selan #endif
145deb979d6Selan #if defined (SIGPOLL)
146deb979d6Selan   SIGPOLL, "SIGPOLL", "Pollable event occurred",
147deb979d6Selan #endif
148deb979d6Selan #if defined (SIGSTOP)
149deb979d6Selan   SIGSTOP, "SIGSTOP", "Stopped (signal)",
150deb979d6Selan #endif
151deb979d6Selan #if defined (SIGTSTP)
152deb979d6Selan   SIGTSTP, "SIGTSTP", "Stopped (user)",
153deb979d6Selan #endif
154deb979d6Selan #if defined (SIGCONT)
155deb979d6Selan   SIGCONT, "SIGCONT", "Continued",
156deb979d6Selan #endif
157deb979d6Selan #if defined (SIGTTIN)
158deb979d6Selan   SIGTTIN, "SIGTTIN", "Stopped (tty input)",
159deb979d6Selan #endif
160deb979d6Selan #if defined (SIGTTOU)
161deb979d6Selan   SIGTTOU, "SIGTTOU", "Stopped (tty output)",
162deb979d6Selan #endif
163deb979d6Selan #if defined (SIGVTALRM)
164deb979d6Selan   SIGVTALRM, "SIGVTALRM", "Virtual timer expired",
165deb979d6Selan #endif
166deb979d6Selan #if defined (SIGPROF)
167deb979d6Selan   SIGPROF, "SIGPROF", "Profiling timer expired",
168deb979d6Selan #endif
169deb979d6Selan #if defined (SIGXCPU)
170deb979d6Selan   SIGXCPU, "SIGXCPU", "CPU time limit exceeded",
171deb979d6Selan #endif
172deb979d6Selan #if defined (SIGXFSZ)
173deb979d6Selan   SIGXFSZ, "SIGXFSZ", "File size limit exceeded",
174deb979d6Selan #endif
175deb979d6Selan #if defined (SIGWIND)
176deb979d6Selan   SIGWIND, "SIGWIND", "SIGWIND",
177deb979d6Selan #endif
178deb979d6Selan #if defined (SIGPHONE)
179deb979d6Selan   SIGPHONE, "SIGPHONE", "SIGPHONE",
180deb979d6Selan #endif
181deb979d6Selan #if defined (SIGLOST)
182deb979d6Selan   SIGLOST, "SIGLOST", "Resource lost",
183deb979d6Selan #endif
184deb979d6Selan #if defined (SIGWAITING)
185deb979d6Selan   SIGWAITING, "SIGWAITING", "Process's LWPs are blocked",
186deb979d6Selan #endif
187deb979d6Selan #if defined (SIGLWP)
188deb979d6Selan   SIGLWP, "SIGLWP", "Signal LWP",
189deb979d6Selan #endif
190deb979d6Selan   0, NULL, NULL
191deb979d6Selan };
192deb979d6Selan 
193deb979d6Selan /* Translation table allocated and initialized at runtime.  Indexed by the
194deb979d6Selan    signal value to find the equivalent symbolic value. */
195deb979d6Selan 
196deb979d6Selan static char **signal_names;
197deb979d6Selan static int num_signal_names = 0;
198deb979d6Selan 
199deb979d6Selan /* Translation table allocated and initialized at runtime, if it does not
200deb979d6Selan    already exist in the host environment.  Indexed by the signal value to find
201deb979d6Selan    the descriptive string.
202deb979d6Selan 
203deb979d6Selan    We don't export it for use in other modules because even though it has the
204deb979d6Selan    same name, it differs from other implementations in that it is dynamically
205deb979d6Selan    initialized rather than statically initialized. */
206deb979d6Selan 
207deb979d6Selan #ifdef NEED_sys_siglist
208deb979d6Selan 
209deb979d6Selan static int sys_nsig;
210*e6f010a6Selan #ifdef notdef
211deb979d6Selan static char **sys_siglist;
212*e6f010a6Selan #endif
213deb979d6Selan 
214deb979d6Selan #else
215deb979d6Selan 
216deb979d6Selan static int sys_nsig = NSIG;
217*e6f010a6Selan #ifdef notdef
218deb979d6Selan #ifdef __STDC__
21945b0109eSelan extern char * const sys_siglist[];
220deb979d6Selan #else
221deb979d6Selan extern char *sys_siglist[];
222deb979d6Selan #endif
223deb979d6Selan #endif
2249c318bc5Selan #endif
225deb979d6Selan 
226deb979d6Selan 
227deb979d6Selan /*
228deb979d6Selan 
229deb979d6Selan NAME
230deb979d6Selan 
231deb979d6Selan 	init_signal_tables -- initialize the name and message tables
232deb979d6Selan 
233deb979d6Selan SYNOPSIS
234deb979d6Selan 
235deb979d6Selan 	static void init_signal_tables ();
236deb979d6Selan 
237deb979d6Selan DESCRIPTION
238deb979d6Selan 
239deb979d6Selan 	Using the signal_table, which is initialized at compile time, generate
240deb979d6Selan 	the signal_names and the sys_siglist (if needed) tables, which are
241deb979d6Selan 	indexed at runtime by a specific signal value.
242deb979d6Selan 
243deb979d6Selan BUGS
244deb979d6Selan 
245deb979d6Selan 	The initialization of the tables may fail under low memory conditions,
246deb979d6Selan 	in which case we don't do anything particularly useful, but we don't
247deb979d6Selan 	bomb either.  Who knows, it might succeed at a later point if we free
248deb979d6Selan 	some memory in the meantime.  In any case, the other routines know
249deb979d6Selan 	how to deal with lack of a table after trying to initialize it.  This
250deb979d6Selan 	may or may not be considered to be a bug, that we don't specifically
251deb979d6Selan 	warn about this particular failure mode.
252deb979d6Selan 
253deb979d6Selan */
254deb979d6Selan 
255deb979d6Selan static void
init_signal_tables()256deb979d6Selan init_signal_tables ()
257deb979d6Selan {
258deb979d6Selan   struct signal_info *eip;
259deb979d6Selan   int nbytes;
260deb979d6Selan 
261deb979d6Selan   /* If we haven't already scanned the signal_table once to find the maximum
262deb979d6Selan      signal value, then go find it now. */
263deb979d6Selan 
264deb979d6Selan   if (num_signal_names == 0)
265deb979d6Selan     {
266deb979d6Selan       for (eip = signal_table; eip -> name != NULL; eip++)
267deb979d6Selan 	{
268deb979d6Selan 	  if (eip -> value >= num_signal_names)
269deb979d6Selan 	    {
270deb979d6Selan 	      num_signal_names = eip -> value + 1;
271deb979d6Selan 	    }
272deb979d6Selan 	}
273deb979d6Selan     }
274deb979d6Selan 
275deb979d6Selan   /* Now attempt to allocate the signal_names table, zero it out, and then
276deb979d6Selan      initialize it from the statically initialized signal_table. */
277deb979d6Selan 
278deb979d6Selan   if (signal_names == NULL)
279deb979d6Selan     {
280deb979d6Selan       nbytes = num_signal_names * sizeof (char *);
281deb979d6Selan       if ((signal_names = (char **) malloc (nbytes)) != NULL)
282deb979d6Selan 	{
283deb979d6Selan 	  memset (signal_names, 0, nbytes);
284deb979d6Selan 	  for (eip = signal_table; eip -> name != NULL; eip++)
285deb979d6Selan 	    {
286deb979d6Selan 	      signal_names[eip -> value] = eip -> name;
287deb979d6Selan 	    }
288deb979d6Selan 	}
289deb979d6Selan     }
290deb979d6Selan 
291deb979d6Selan #ifdef NEED_sys_siglist
292deb979d6Selan 
293deb979d6Selan   /* Now attempt to allocate the sys_siglist table, zero it out, and then
294deb979d6Selan      initialize it from the statically initialized signal_table. */
295deb979d6Selan 
296deb979d6Selan   if (sys_siglist == NULL)
297deb979d6Selan     {
298deb979d6Selan       nbytes = num_signal_names * sizeof (char *);
299deb979d6Selan       if ((sys_siglist = (char **) malloc (nbytes)) != NULL)
300deb979d6Selan 	{
301deb979d6Selan 	  memset (sys_siglist, 0, nbytes);
302deb979d6Selan 	  sys_nsig = num_signal_names;
303deb979d6Selan 	  for (eip = signal_table; eip -> name != NULL; eip++)
304deb979d6Selan 	    {
305deb979d6Selan 	      sys_siglist[eip -> value] = eip -> msg;
306deb979d6Selan 	    }
307deb979d6Selan 	}
308deb979d6Selan     }
309deb979d6Selan 
310deb979d6Selan #endif
311deb979d6Selan 
312deb979d6Selan }
313deb979d6Selan 
314deb979d6Selan 
315deb979d6Selan /*
316deb979d6Selan 
317deb979d6Selan NAME
318deb979d6Selan 
319deb979d6Selan 	signo_max -- return the max signo value
320deb979d6Selan 
321deb979d6Selan SYNOPSIS
322deb979d6Selan 
323deb979d6Selan 	int signo_max ();
324deb979d6Selan 
325deb979d6Selan DESCRIPTION
326deb979d6Selan 
327deb979d6Selan 	Returns the maximum signo value for which a corresponding symbolic
328deb979d6Selan 	name or message is available.  Note that in the case where
329deb979d6Selan 	we use the sys_siglist supplied by the system, it is possible for
330deb979d6Selan 	there to be more symbolic names than messages, or vice versa.
331deb979d6Selan 	In fact, the manual page for psignal(3b) explicitly warns that one
332deb979d6Selan 	should check the size of the table (NSIG) before indexing it,
333deb979d6Selan 	since new signal codes may be added to the system before they are
334deb979d6Selan 	added to the table.  Thus NSIG might be smaller than value
335deb979d6Selan 	implied by the largest signo value defined in <signal.h>.
336deb979d6Selan 
337deb979d6Selan 	We return the maximum value that can be used to obtain a meaningful
338deb979d6Selan 	symbolic name or message.
339deb979d6Selan 
340deb979d6Selan */
341deb979d6Selan 
342deb979d6Selan int
signo_max()343deb979d6Selan signo_max ()
344deb979d6Selan {
345deb979d6Selan   int maxsize;
346deb979d6Selan 
347deb979d6Selan   if (signal_names == NULL)
348deb979d6Selan     {
349deb979d6Selan       init_signal_tables ();
350deb979d6Selan     }
351deb979d6Selan   maxsize = MAX (sys_nsig, num_signal_names);
352deb979d6Selan   return (maxsize - 1);
353deb979d6Selan }
354deb979d6Selan 
355deb979d6Selan 
356deb979d6Selan /*
357deb979d6Selan 
358deb979d6Selan NAME
359deb979d6Selan 
360deb979d6Selan 	strsignal -- map a signal number to a signal message string
361deb979d6Selan 
362deb979d6Selan SYNOPSIS
363deb979d6Selan 
364deb979d6Selan 	char *strsignal (int signo)
365deb979d6Selan 
366deb979d6Selan DESCRIPTION
367deb979d6Selan 
368deb979d6Selan 	Maps an signal number to an signal message string, the contents of
369deb979d6Selan 	which are implementation defined.  On systems which have the external
370deb979d6Selan 	variable sys_siglist, these strings will be the same as the ones used
371deb979d6Selan 	by psignal().
372deb979d6Selan 
373deb979d6Selan 	If the supplied signal number is within the valid range of indices
374deb979d6Selan 	for the sys_siglist, but no message is available for the particular
375deb979d6Selan 	signal number, then returns the string "Signal NUM", where NUM is the
376deb979d6Selan 	signal number.
377deb979d6Selan 
378deb979d6Selan 	If the supplied signal number is not a valid index into sys_siglist,
379deb979d6Selan 	returns NULL.
380deb979d6Selan 
381deb979d6Selan 	The returned string is only guaranteed to be valid only until the
382deb979d6Selan 	next call to strsignal.
383deb979d6Selan 
384deb979d6Selan */
385deb979d6Selan 
386deb979d6Selan char *
strsignal(signo)387deb979d6Selan strsignal (signo)
388deb979d6Selan   int signo;
389deb979d6Selan {
390deb979d6Selan   char *msg;
391deb979d6Selan   static char buf[32];
392deb979d6Selan 
393deb979d6Selan #ifdef NEED_sys_siglist
394deb979d6Selan 
395deb979d6Selan   if (signal_names == NULL)
396deb979d6Selan     {
397deb979d6Selan       init_signal_tables ();
398deb979d6Selan     }
399deb979d6Selan 
400deb979d6Selan #endif
401deb979d6Selan 
402deb979d6Selan   if ((signo < 0) || (signo >= sys_nsig))
403deb979d6Selan     {
404deb979d6Selan       /* Out of range, just return NULL */
405deb979d6Selan       msg = NULL;
406deb979d6Selan     }
407deb979d6Selan   else if ((sys_siglist == NULL) || (sys_siglist[signo] == NULL))
408deb979d6Selan     {
409deb979d6Selan       /* In range, but no sys_siglist or no entry at this index. */
410deb979d6Selan       sprintf (buf, "Signal %d", signo);
411deb979d6Selan       msg = buf;
412deb979d6Selan     }
413deb979d6Selan   else
414deb979d6Selan     {
415deb979d6Selan       /* In range, and a valid message.  Just return the message. */
416deb979d6Selan       msg = (char*)sys_siglist[signo];
417deb979d6Selan     }
418deb979d6Selan 
419deb979d6Selan   return (msg);
420deb979d6Selan }
421deb979d6Selan 
422deb979d6Selan 
423deb979d6Selan /*
424deb979d6Selan 
425deb979d6Selan NAME
426deb979d6Selan 
427deb979d6Selan 	strsigno -- map an signal number to a symbolic name string
428deb979d6Selan 
429deb979d6Selan SYNOPSIS
430deb979d6Selan 
431deb979d6Selan 	char *strsigno (int signo)
432deb979d6Selan 
433deb979d6Selan DESCRIPTION
434deb979d6Selan 
435deb979d6Selan 	Given an signal number, returns a pointer to a string containing
436deb979d6Selan 	the symbolic name of that signal number, as found in <signal.h>.
437deb979d6Selan 
438deb979d6Selan 	If the supplied signal number is within the valid range of indices
439deb979d6Selan 	for symbolic names, but no name is available for the particular
440deb979d6Selan 	signal number, then returns the string "Signal NUM", where NUM is
441deb979d6Selan 	the signal number.
442deb979d6Selan 
443deb979d6Selan 	If the supplied signal number is not within the range of valid
444deb979d6Selan 	indices, then returns NULL.
445deb979d6Selan 
446deb979d6Selan BUGS
447deb979d6Selan 
448deb979d6Selan 	The contents of the location pointed to are only guaranteed to be
449deb979d6Selan 	valid until the next call to strsigno.
450deb979d6Selan 
451deb979d6Selan */
452deb979d6Selan 
453deb979d6Selan char *
strsigno(signo)454deb979d6Selan strsigno (signo)
455deb979d6Selan   int signo;
456deb979d6Selan {
457deb979d6Selan   char *name;
458deb979d6Selan   static char buf[32];
459deb979d6Selan 
460deb979d6Selan   if (signal_names == NULL)
461deb979d6Selan     {
462deb979d6Selan       init_signal_tables ();
463deb979d6Selan     }
464deb979d6Selan 
465deb979d6Selan   if ((signo < 0) || (signo >= num_signal_names))
466deb979d6Selan     {
467deb979d6Selan       /* Out of range, just return NULL */
468deb979d6Selan       name = NULL;
469deb979d6Selan     }
470deb979d6Selan   else if ((signal_names == NULL) || (signal_names[signo] == NULL))
471deb979d6Selan     {
472deb979d6Selan       /* In range, but no signal_names or no entry at this index. */
473deb979d6Selan       sprintf (buf, "Signal %d", signo);
474deb979d6Selan       name = buf;
475deb979d6Selan     }
476deb979d6Selan   else
477deb979d6Selan     {
478deb979d6Selan       /* In range, and a valid name.  Just return the name. */
479deb979d6Selan       name = signal_names[signo];
480deb979d6Selan     }
481deb979d6Selan 
482deb979d6Selan   return (name);
483deb979d6Selan }
484deb979d6Selan 
485deb979d6Selan 
486deb979d6Selan /*
487deb979d6Selan 
488deb979d6Selan NAME
489deb979d6Selan 
490deb979d6Selan 	strtosigno -- map a symbolic signal name to a numeric value
491deb979d6Selan 
492deb979d6Selan SYNOPSIS
493deb979d6Selan 
494deb979d6Selan 	int strtosigno (char *name)
495deb979d6Selan 
496deb979d6Selan DESCRIPTION
497deb979d6Selan 
498deb979d6Selan 	Given the symbolic name of a signal, map it to a signal number.
499deb979d6Selan 	If no translation is found, returns 0.
500deb979d6Selan 
501deb979d6Selan */
502deb979d6Selan 
503deb979d6Selan int
strtosigno(name)504deb979d6Selan strtosigno (name)
505deb979d6Selan   char *name;
506deb979d6Selan {
507deb979d6Selan   int signo = 0;
508deb979d6Selan 
509deb979d6Selan   if (name != NULL)
510deb979d6Selan     {
511deb979d6Selan       if (signal_names == NULL)
512deb979d6Selan 	{
513deb979d6Selan 	  init_signal_tables ();
514deb979d6Selan 	}
515deb979d6Selan       for (signo = 0; signo < num_signal_names; signo++)
516deb979d6Selan 	{
517deb979d6Selan 	  if ((signal_names[signo] != NULL) &&
518deb979d6Selan 	      (strcmp (name, signal_names[signo]) == 0))
519deb979d6Selan 	    {
520deb979d6Selan 	      break;
521deb979d6Selan 	    }
522deb979d6Selan 	}
523deb979d6Selan       if (signo == num_signal_names)
524deb979d6Selan 	{
525deb979d6Selan 	  signo = 0;
526deb979d6Selan 	}
527deb979d6Selan     }
528deb979d6Selan   return (signo);
529deb979d6Selan }
530deb979d6Selan 
531deb979d6Selan 
532deb979d6Selan /*
533deb979d6Selan 
534deb979d6Selan NAME
535deb979d6Selan 
536deb979d6Selan 	psignal -- print message about signal to stderr
537deb979d6Selan 
538deb979d6Selan SYNOPSIS
539deb979d6Selan 
540deb979d6Selan 	void psignal (unsigned signo, char *message);
541deb979d6Selan 
542deb979d6Selan DESCRIPTION
543deb979d6Selan 
544deb979d6Selan 	Print to the standard error the message, followed by a colon,
545deb979d6Selan 	followed by the description of the signal specified by signo,
546deb979d6Selan 	followed by a newline.
547deb979d6Selan */
548deb979d6Selan 
549deb979d6Selan #ifdef NEED_psignal
550deb979d6Selan 
551deb979d6Selan void
psignal(signo,message)552deb979d6Selan psignal (signo, message)
553deb979d6Selan   unsigned signo;
554deb979d6Selan   char *message;
555deb979d6Selan {
556deb979d6Selan   if (signal_names == NULL)
557deb979d6Selan     {
558deb979d6Selan       init_signal_tables ();
559deb979d6Selan     }
560deb979d6Selan   if ((signo <= 0) || (signo >= sys_nsig))
561deb979d6Selan     {
562deb979d6Selan       fprintf (stderr, "%s: unknown signal\n", message);
563deb979d6Selan     }
564deb979d6Selan   else
565deb979d6Selan     {
566deb979d6Selan       fprintf (stderr, "%s: %s\n", message, sys_siglist[signo]);
567deb979d6Selan     }
568deb979d6Selan }
569deb979d6Selan 
570deb979d6Selan #endif	/* NEED_psignal */
571deb979d6Selan 
572deb979d6Selan 
573deb979d6Selan /* A simple little main that does nothing but print all the signal translations
574deb979d6Selan    if MAIN is defined and this file is compiled and linked. */
575deb979d6Selan 
576deb979d6Selan #ifdef MAIN
577deb979d6Selan 
main()578deb979d6Selan main ()
579deb979d6Selan {
580deb979d6Selan   int signo;
581deb979d6Selan   int maxsigno;
582deb979d6Selan   char *name;
583deb979d6Selan   char *msg;
584deb979d6Selan   char *strsigno ();
585deb979d6Selan   char *strsignal ();
586deb979d6Selan 
587deb979d6Selan   maxsigno = signo_max ();
588deb979d6Selan   printf ("%d entries in names table.\n", num_signal_names);
589deb979d6Selan   printf ("%d entries in messages table.\n", sys_nsig);
590deb979d6Selan   printf ("%d is max useful index.\n", maxsigno);
591deb979d6Selan 
592deb979d6Selan   /* Keep printing values until we get to the end of *both* tables, not
593deb979d6Selan      *either* table.  Note that knowing the maximum useful index does *not*
594deb979d6Selan      relieve us of the responsibility of testing the return pointer for
595deb979d6Selan      NULL. */
596deb979d6Selan 
597deb979d6Selan   for (signo = 0; signo <= maxsigno; signo++)
598deb979d6Selan     {
599deb979d6Selan       name = strsigno (signo);
600deb979d6Selan       name = (name == NULL) ? "<NULL>" : name;
601deb979d6Selan       msg = strsignal (signo);
602deb979d6Selan       msg = (msg == NULL) ? "<NULL>" : msg;
603deb979d6Selan       printf ("%-4d%-18s%s\n", signo, name, msg);
604deb979d6Selan     }
605deb979d6Selan }
606deb979d6Selan 
607deb979d6Selan #endif
608