8fb78a301c6f1f0236429a6cc34e0d3918b014f3
[kopensolaris-gnu/glibc.git] / sysdeps / generic / signame.c
1 /* Convert between signal names and numbers.
2    Copyright (C) 1990, 92, 93, 95, 96, 97 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; see the file COPYING.  If not, write to
16 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
17
18 #ifdef HAVE_CONFIG_H
19 #include <config.h>
20 #endif
21
22 #include <stdio.h>
23 #include <sys/types.h>          /* Some systems need this for <signal.h>.  */
24 #include <signal.h>
25
26 #ifdef HAVE_STRING_H
27 #include <string.h>
28 #endif
29
30 /* Some systems declare `sys_siglist in <unistd.h>; if
31    configure defined SYS_SIGLIST_DECLARED, it may expect
32    to find the declaration there.  */
33 #ifdef HAVE_UNISTD_H
34 #include <unistd.h>
35 #endif
36
37
38 /* Some systems do not define NSIG in <signal.h>.  */
39 #ifndef NSIG
40 #ifdef  _NSIG
41 #define NSIG    _NSIG
42 #else
43 #define NSIG    32
44 #endif
45 #endif
46
47 #if !__STDC__
48 #define const
49 #endif
50
51 #include "signame.h"
52
53 #ifndef HAVE_SYS_SIGLIST
54 /* There is too much variation in Sys V signal numbers and names, so
55    we must initialize them at runtime.  */
56
57 static const char undoc[] = "unknown signal";
58
59 const char *sys_siglist[NSIG];
60
61 #else   /* HAVE_SYS_SIGLIST.  */
62
63 #ifndef SYS_SIGLIST_DECLARED
64 extern char *sys_siglist[];
65 #endif  /* Not SYS_SIGLIST_DECLARED.  */
66
67 #endif  /* Not HAVE_SYS_SIGLIST.  */
68
69 /* Table of abbreviations for signals.  Note:  A given number can
70    appear more than once with different abbreviations.  */
71 typedef struct
72   {
73     int number;
74     const char *abbrev;
75   } num_abbrev;
76 static num_abbrev sig_table[NSIG*2];
77 /* Number of elements of sig_table used.  */
78 static int sig_table_nelts = 0;
79
80 /* Enter signal number NUMBER into the tables with ABBREV and NAME.  */
81
82 static void
83 init_sig (number, abbrev, name)
84      int number;
85      const char *abbrev;
86      const char *name;
87 {
88 #ifndef HAVE_SYS_SIGLIST
89   sys_siglist[number] = name;
90 #endif
91   sig_table[sig_table_nelts].number = number;
92   sig_table[sig_table_nelts++].abbrev = abbrev;
93 }
94
95 void
96 signame_init ()
97 {
98 #ifndef HAVE_SYS_SIGLIST
99   int i;
100   /* Initialize signal names.  */
101   for (i = 0; i < NSIG; i++)
102     sys_siglist[i] = undoc;
103 #endif /* !HAVE_SYS_SIGLIST */
104
105   /* Initialize signal names.  */
106 #if defined (SIGHUP)
107   init_sig (SIGHUP, "HUP", "Hangup");
108 #endif
109 #if defined (SIGINT)
110   init_sig (SIGINT, "INT", "Interrupt");
111 #endif
112 #if defined (SIGQUIT)
113   init_sig (SIGQUIT, "QUIT", "Quit");
114 #endif
115 #if defined (SIGILL)
116   init_sig (SIGILL, "ILL", "Illegal Instruction");
117 #endif
118 #if defined (SIGTRAP)
119   init_sig (SIGTRAP, "TRAP", "Trace/breakpoint trap");
120 #endif
121   /* If SIGIOT == SIGABRT, we want to print it as SIGABRT because
122      SIGABRT is in ANSI and POSIX.1 and SIGIOT isn't.  */
123 #if defined (SIGABRT)
124   init_sig (SIGABRT, "ABRT", "Aborted");
125 #endif
126 #if defined (SIGIOT)
127   init_sig (SIGIOT, "IOT", "IOT trap");
128 #endif
129 #if defined (SIGEMT)
130   init_sig (SIGEMT, "EMT", "EMT trap");
131 #endif
132 #if defined (SIGFPE)
133   init_sig (SIGFPE, "FPE", "Floating point exception");
134 #endif
135 #if defined (SIGKILL)
136   init_sig (SIGKILL, "KILL", "Killed");
137 #endif
138 #if defined (SIGBUS)
139   init_sig (SIGBUS, "BUS", "Bus error");
140 #endif
141 #if defined (SIGSEGV)
142   init_sig (SIGSEGV, "SEGV", "Segmentation fault");
143 #endif
144 #if defined (SIGSYS)
145   init_sig (SIGSYS, "SYS", "Bad system call");
146 #endif
147 #if defined (SIGPIPE)
148   init_sig (SIGPIPE, "PIPE", "Broken pipe");
149 #endif
150 #if defined (SIGALRM)
151   init_sig (SIGALRM, "ALRM", "Alarm clock");
152 #endif
153 #if defined (SIGTERM)
154   init_sig (SIGTERM, "TERM", "Terminated");
155 #endif
156 #if defined (SIGUSR1)
157   init_sig (SIGUSR1, "USR1", "User defined signal 1");
158 #endif
159 #if defined (SIGUSR2)
160   init_sig (SIGUSR2, "USR2", "User defined signal 2");
161 #endif
162   /* If SIGCLD == SIGCHLD, we want to print it as SIGCHLD because that
163      is what is in POSIX.1.  */
164 #if defined (SIGCHLD)
165   init_sig (SIGCHLD, "CHLD", "Child exited");
166 #endif
167 #if defined (SIGCLD)
168   init_sig (SIGCLD, "CLD", "Child exited");
169 #endif
170 #if defined (SIGPWR)
171   init_sig (SIGPWR, "PWR", "Power failure");
172 #endif
173 #if defined (SIGTSTP)
174   init_sig (SIGTSTP, "TSTP", "Stopped");
175 #endif
176 #if defined (SIGTTIN)
177   init_sig (SIGTTIN, "TTIN", "Stopped (tty input)");
178 #endif
179 #if defined (SIGTTOU)
180   init_sig (SIGTTOU, "TTOU", "Stopped (tty output)");
181 #endif
182 #if defined (SIGSTOP)
183   init_sig (SIGSTOP, "STOP", "Stopped (signal)");
184 #endif
185 #if defined (SIGXCPU)
186   init_sig (SIGXCPU, "XCPU", "CPU time limit exceeded");
187 #endif
188 #if defined (SIGXFSZ)
189   init_sig (SIGXFSZ, "XFSZ", "File size limit exceeded");
190 #endif
191 #if defined (SIGVTALRM)
192   init_sig (SIGVTALRM, "VTALRM", "Virtual timer expired");
193 #endif
194 #if defined (SIGPROF)
195   init_sig (SIGPROF, "PROF", "Profiling timer expired");
196 #endif
197 #if defined (SIGWINCH)
198   /* "Window size changed" might be more accurate, but even if that
199      is all that it means now, perhaps in the future it will be
200      extended to cover other kinds of window changes.  */
201   init_sig (SIGWINCH, "WINCH", "Window changed");
202 #endif
203 #if defined (SIGCONT)
204   init_sig (SIGCONT, "CONT", "Continued");
205 #endif
206 #if defined (SIGURG)
207   init_sig (SIGURG, "URG", "Urgent I/O condition");
208 #endif
209 #if defined (SIGIO)
210   /* "I/O pending" has also been suggested.  A disadvantage is
211      that signal only happens when the process has
212      asked for it, not everytime I/O is pending.  Another disadvantage
213      is the confusion from giving it a different name than under Unix.  */
214   init_sig (SIGIO, "IO", "I/O possible");
215 #endif
216 #if defined (SIGWIND)
217   init_sig (SIGWIND, "WIND", "SIGWIND");
218 #endif
219 #if defined (SIGPHONE)
220   init_sig (SIGPHONE, "PHONE", "SIGPHONE");
221 #endif
222 #if defined (SIGPOLL)
223   init_sig (SIGPOLL, "POLL", "I/O possible");
224 #endif
225 #if defined (SIGLOST)
226   init_sig (SIGLOST, "LOST", "Resource lost");
227 #endif
228 #if defined (SIGDANGER)
229   init_sig (SIGDANGER, "DANGER", "Danger signal");
230 #endif
231 #if defined (SIGINFO)
232   init_sig (SIGINFO, "INFO", "Information request");
233 #endif
234 #if defined (SIGNOFP)
235   init_sig (SIGNOFP, "NOFP", "Floating point co-processor not available");
236 #endif
237 }
238
239 /* Return the abbreviation for signal NUMBER.  */
240
241 char *
242 sig_abbrev (number)
243      int number;
244 {
245   int i;
246
247   if (sig_table_nelts == 0)
248     signame_init ();
249
250   for (i = 0; i < sig_table_nelts; i++)
251     if (sig_table[i].number == number)
252       return (char *)sig_table[i].abbrev;
253   return NULL;
254 }
255
256 /* Return the signal number for an ABBREV, or -1 if there is no
257    signal by that name.  */
258
259 int
260 sig_number (abbrev)
261      const char *abbrev;
262 {
263   int i;
264
265   if (sig_table_nelts == 0)
266     signame_init ();
267
268   /* Skip over "SIG" if present.  */
269   if (abbrev[0] == 'S' && abbrev[1] == 'I' && abbrev[2] == 'G')
270     abbrev += 3;
271
272   for (i = 0; i < sig_table_nelts; i++)
273     if (abbrev[0] == sig_table[i].abbrev[0]
274         && strcmp (abbrev, sig_table[i].abbrev) == 0)
275       return sig_table[i].number;
276   return -1;
277 }
278
279 #ifndef HAVE_PSIGNAL
280 /* Print to standard error the name of SIGNAL, preceded by MESSAGE and
281    a colon, and followed by a newline.  */
282
283 void
284 psignal (signal, message)
285      int signal;
286      const char *message;
287 {
288   if (signal <= 0 || signal >= NSIG)
289     fprintf (stderr, "%s: unknown signal", message);
290   else
291     fprintf (stderr, "%s: %s\n", message, sys_siglist[signal]);
292 }
293 #endif
294
295 #ifndef HAVE_STRSIGNAL
296 /* Return the string associated with the signal number.  */
297
298 char *
299 strsignal (signal)
300      int signal;
301 {
302   static char buf[] = "Signal 12345678901234567890";
303
304   if (signal > 0 || signal < NSIG)
305     return (char *) sys_siglist[signal];
306
307   sprintf (buf, "Signal %d", signal);
308   return buf;
309 }
310 #endif