1/* signames.c -- Create an array of signal names. */
2
3/* Copyright (C) 2006 Free Software Foundation, Inc.
4
5   This file is part of GNU Bash, the Bourne Again SHell.
6
7   Bash is free software; you can redistribute it and/or modify it under
8   the terms of the GNU General Public License as published by the Free
9   Software Foundation; either version 2, or (at your option) any later
10   version.
11
12   Bash is distributed in the hope that it will be useful, but WITHOUT ANY
13   WARRANTY; without even the implied warranty of MERCHANTABILITY or
14   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15   for more details.
16
17   You should have received a copy of the GNU General Public License along
18   with Bash; see the file COPYING.  If not, write to the Free Software
19   Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
20
21#include <config.h>
22
23#include <stdio.h>
24
25#include <sys/types.h>
26#include <signal.h>
27
28#if defined (HAVE_STDLIB_H)
29#  include <stdlib.h>
30#else
31#  include "ansi_stdlib.h"
32#endif /* HAVE_STDLIB_H */
33
34#if !defined (NSIG)
35#  define NSIG 64
36#endif
37
38/*
39 * Special traps:
40 *	EXIT == 0
41 *	DEBUG == NSIG
42 *	ERR == NSIG+1
43 *	RETURN == NSIG+2
44 */
45#define LASTSIG NSIG+2
46
47char *signal_names[2 * (LASTSIG)];
48
49#define signal_names_size (sizeof(signal_names)/sizeof(signal_names[0]))
50
51/* AIX 4.3 defines SIGRTMIN and SIGRTMAX as 888 and 999 respectively.
52   I don't want to allocate so much unused space for the intervening signal
53   numbers, so we just punt if SIGRTMAX is past the bounds of the
54   signal_names array (handled in configure). */
55#if defined (SIGRTMAX) && defined (UNUSABLE_RT_SIGNALS)
56#  undef SIGRTMAX
57#  undef SIGRTMIN
58#endif
59
60#if defined (SIGRTMAX) || defined (SIGRTMIN)
61#  define RTLEN 14
62#  define RTLIM 256
63#endif
64
65#if defined (BUILDTOOL)
66extern char *progname;
67#endif
68
69void
70initialize_signames ()
71{
72  register int i;
73#if defined (SIGRTMAX) || defined (SIGRTMIN)
74  int rtmin, rtmax, rtcnt;
75#endif
76
77  for (i = 1; i < signal_names_size; i++)
78    signal_names[i] = (char *)NULL;
79
80  /* `signal' 0 is what we do on exit. */
81  signal_names[0] = "EXIT";
82
83  /* Place signal names which can be aliases for more common signal
84     names first.  This allows (for example) SIGABRT to overwrite SIGLOST. */
85
86  /* POSIX 1003.1b-1993 real time signals, but take care of incomplete
87     implementations. Acoording to the standard, both, SIGRTMIN and
88     SIGRTMAX must be defined, SIGRTMIN must be stricly less than
89     SIGRTMAX, and the difference must be at least 7, that is, there
90     must be at least eight distinct real time signals. */
91
92  /* The generated signal names are SIGRTMIN, SIGRTMIN+1, ...,
93     SIGRTMIN+x, SIGRTMAX-x, ..., SIGRTMAX-1, SIGRTMAX. If the number
94     of RT signals is odd, there is an extra SIGRTMIN+(x+1).
95     These names are the ones used by ksh and /usr/xpg4/bin/sh on SunOS5. */
96
97#if defined (SIGRTMIN)
98  rtmin = SIGRTMIN;
99  signal_names[rtmin] = "SIGRTMIN";
100#endif
101
102#if defined (SIGRTMAX)
103  rtmax = SIGRTMAX;
104  signal_names[rtmax] = "SIGRTMAX";
105#endif
106
107#if defined (SIGRTMAX) && defined (SIGRTMIN)
108  if (rtmax > rtmin)
109    {
110      rtcnt = (rtmax - rtmin - 1) / 2;
111      /* croak if there are too many RT signals */
112      if (rtcnt >= RTLIM/2)
113	{
114	  rtcnt = RTLIM/2-1;
115#ifdef BUILDTOOL
116	  fprintf(stderr, "%s: error: more than %d real time signals, fix `%s'\n",
117		  progname, RTLIM, progname);
118#endif
119	}
120
121      for (i = 1; i <= rtcnt; i++)
122	{
123	  signal_names[rtmin+i] = (char *)malloc(RTLEN);
124	  if (signal_names[rtmin+i])
125	    sprintf (signal_names[rtmin+i], "SIGRTMIN+%d", i);
126	  signal_names[rtmax-i] = (char *)malloc(RTLEN);
127	  if (signal_names[rtmax-i])
128	    sprintf (signal_names[rtmax-i], "SIGRTMAX-%d", i);
129	}
130
131      if (rtcnt < RTLIM/2-1 && rtcnt != (rtmax-rtmin)/2)
132	{
133	  /* Need an extra RTMIN signal */
134	  signal_names[rtmin+rtcnt+1] = (char *)malloc(RTLEN);
135	  if (signal_names[rtmin+rtcnt+1])
136	    sprintf (signal_names[rtmin+rtcnt+1], "SIGRTMIN+%d", rtcnt+1);
137	}
138    }
139#endif /* SIGRTMIN && SIGRTMAX */
140
141#if defined (SIGLOST)	/* resource lost (eg, record-lock lost) */
142  signal_names[SIGLOST] = "SIGLOST";
143#endif
144
145/* AIX */
146#if defined (SIGMSG)	/* HFT input data pending */
147  signal_names[SIGMSG] = "SIGMSG";
148#endif
149
150#if defined (SIGDANGER)	/* system crash imminent */
151  signal_names[SIGDANGER] = "SIGDANGER";
152#endif
153
154#if defined (SIGMIGRATE) /* migrate process to another CPU */
155  signal_names[SIGMIGRATE] = "SIGMIGRATE";
156#endif
157
158#if defined (SIGPRE)	/* programming error */
159  signal_names[SIGPRE] = "SIGPRE";
160#endif
161
162#if defined (SIGVIRT)	/* AIX virtual time alarm */
163  signal_names[SIGVIRT] = "SIGVIRT";
164#endif
165
166#if defined (SIGALRM1)	/* m:n condition variables */
167  signal_names[SIGALRM1] = "SIGALRM1";
168#endif
169
170#if defined (SIGWAITING)	/* m:n scheduling */
171  signal_names[SIGWAITING] = "SIGWAITING";
172#endif
173
174#if defined (SIGGRANT)	/* HFT monitor mode granted */
175  signal_names[SIGGRANT] = "SIGGRANT";
176#endif
177
178#if defined (SIGKAP)	/* keep alive poll from native keyboard */
179  signal_names[SIGKAP] = "SIGKAP";
180#endif
181
182#if defined (SIGRETRACT) /* HFT monitor mode retracted */
183  signal_names[SIGRETRACT] = "SIGRETRACT";
184#endif
185
186#if defined (SIGSOUND)	/* HFT sound sequence has completed */
187  signal_names[SIGSOUND] = "SIGSOUND";
188#endif
189
190#if defined (SIGSAK)	/* Secure Attention Key */
191  signal_names[SIGSAK] = "SIGSAK";
192#endif
193
194/* SunOS5 */
195#if defined (SIGLWP)	/* special signal used by thread library */
196  signal_names[SIGLWP] = "SIGLWP";
197#endif
198
199#if defined (SIGFREEZE)	/* special signal used by CPR */
200  signal_names[SIGFREEZE] = "SIGFREEZE";
201#endif
202
203#if defined (SIGTHAW)	/* special signal used by CPR */
204  signal_names[SIGTHAW] = "SIGTHAW";
205#endif
206
207#if defined (SIGCANCEL)	/* thread cancellation signal used by libthread */
208  signal_names[SIGCANCEL] = "SIGCANCEL";
209#endif
210
211#if defined (SIGXRES)	/* resource control exceeded */
212  signal_names[SIGXRES] = "SIGXRES";
213#endif
214
215/* HP-UX */
216#if defined (SIGDIL)	/* DIL signal (?) */
217  signal_names[SIGDIL] = "SIGDIL";
218#endif
219
220/* System V */
221#if defined (SIGCLD)	/* Like SIGCHLD.  */
222  signal_names[SIGCLD] = "SIGCLD";
223#endif
224
225#if defined (SIGPWR)	/* power state indication */
226  signal_names[SIGPWR] = "SIGPWR";
227#endif
228
229#if defined (SIGPOLL)	/* Pollable event (for streams)  */
230  signal_names[SIGPOLL] = "SIGPOLL";
231#endif
232
233/* Unknown */
234#if defined (SIGWINDOW)
235  signal_names[SIGWINDOW] = "SIGWINDOW";
236#endif
237
238/* Linux */
239#if defined (SIGSTKFLT)
240  signal_names[SIGSTKFLT] = "SIGSTKFLT";
241#endif
242
243/* FreeBSD */
244#if defined (SIGTHR)	/* thread interrupt */
245  signal_names[SIGTHR] = "SIGTHR";
246#endif
247
248/* Common */
249#if defined (SIGHUP)	/* hangup */
250  signal_names[SIGHUP] = "SIGHUP";
251#endif
252
253#if defined (SIGINT)	/* interrupt */
254  signal_names[SIGINT] = "SIGINT";
255#endif
256
257#if defined (SIGQUIT)	/* quit */
258  signal_names[SIGQUIT] = "SIGQUIT";
259#endif
260
261#if defined (SIGILL)	/* illegal instruction (not reset when caught) */
262  signal_names[SIGILL] = "SIGILL";
263#endif
264
265#if defined (SIGTRAP)	/* trace trap (not reset when caught) */
266  signal_names[SIGTRAP] = "SIGTRAP";
267#endif
268
269#if defined (SIGIOT)	/* IOT instruction */
270  signal_names[SIGIOT] = "SIGIOT";
271#endif
272
273#if defined (SIGABRT)	/* Cause current process to dump core. */
274  signal_names[SIGABRT] = "SIGABRT";
275#endif
276
277#if defined (SIGEMT)	/* EMT instruction */
278  signal_names[SIGEMT] = "SIGEMT";
279#endif
280
281#if defined (SIGFPE)	/* floating point exception */
282  signal_names[SIGFPE] = "SIGFPE";
283#endif
284
285#if defined (SIGKILL)	/* kill (cannot be caught or ignored) */
286  signal_names[SIGKILL] = "SIGKILL";
287#endif
288
289#if defined (SIGBUS)	/* bus error */
290  signal_names[SIGBUS] = "SIGBUS";
291#endif
292
293#if defined (SIGSEGV)	/* segmentation violation */
294  signal_names[SIGSEGV] = "SIGSEGV";
295#endif
296
297#if defined (SIGSYS)	/* bad argument to system call */
298  signal_names[SIGSYS] = "SIGSYS";
299#endif
300
301#if defined (SIGPIPE)	/* write on a pipe with no one to read it */
302  signal_names[SIGPIPE] = "SIGPIPE";
303#endif
304
305#if defined (SIGALRM)	/* alarm clock */
306  signal_names[SIGALRM] = "SIGALRM";
307#endif
308
309#if defined (SIGTERM)	/* software termination signal from kill */
310  signal_names[SIGTERM] = "SIGTERM";
311#endif
312
313#if defined (SIGURG)	/* urgent condition on IO channel */
314  signal_names[SIGURG] = "SIGURG";
315#endif
316
317#if defined (SIGSTOP)	/* sendable stop signal not from tty */
318  signal_names[SIGSTOP] = "SIGSTOP";
319#endif
320
321#if defined (SIGTSTP)	/* stop signal from tty */
322  signal_names[SIGTSTP] = "SIGTSTP";
323#endif
324
325#if defined (SIGCONT)	/* continue a stopped process */
326  signal_names[SIGCONT] = "SIGCONT";
327#endif
328
329#if defined (SIGCHLD)	/* to parent on child stop or exit */
330  signal_names[SIGCHLD] = "SIGCHLD";
331#endif
332
333#if defined (SIGTTIN)	/* to readers pgrp upon background tty read */
334  signal_names[SIGTTIN] = "SIGTTIN";
335#endif
336
337#if defined (SIGTTOU)	/* like TTIN for output if (tp->t_local&LTOSTOP) */
338  signal_names[SIGTTOU] = "SIGTTOU";
339#endif
340
341#if defined (SIGIO)	/* input/output possible signal */
342  signal_names[SIGIO] = "SIGIO";
343#endif
344
345#if defined (SIGXCPU)	/* exceeded CPU time limit */
346  signal_names[SIGXCPU] = "SIGXCPU";
347#endif
348
349#if defined (SIGXFSZ)	/* exceeded file size limit */
350  signal_names[SIGXFSZ] = "SIGXFSZ";
351#endif
352
353#if defined (SIGVTALRM)	/* virtual time alarm */
354  signal_names[SIGVTALRM] = "SIGVTALRM";
355#endif
356
357#if defined (SIGPROF)	/* profiling time alarm */
358  signal_names[SIGPROF] = "SIGPROF";
359#endif
360
361#if defined (SIGWINCH)	/* window changed */
362  signal_names[SIGWINCH] = "SIGWINCH";
363#endif
364
365/* 4.4 BSD */
366#if defined (SIGINFO) && !defined (_SEQUENT_)	/* information request */
367  signal_names[SIGINFO] = "SIGINFO";
368#endif
369
370#if defined (SIGUSR1)	/* user defined signal 1 */
371  signal_names[SIGUSR1] = "SIGUSR1";
372#endif
373
374#if defined (SIGUSR2)	/* user defined signal 2 */
375  signal_names[SIGUSR2] = "SIGUSR2";
376#endif
377
378#if defined (SIGKILLTHR)	/* BeOS: Kill Thread */
379  signal_names[SIGKILLTHR] = "SIGKILLTHR";
380#endif
381
382  for (i = 0; i < NSIG; i++)
383    if (signal_names[i] == (char *)NULL)
384      {
385	signal_names[i] = (char *)malloc (18);
386	if (signal_names[i])
387	  sprintf (signal_names[i], "SIGJUNK(%d)", i);
388      }
389
390  signal_names[NSIG] = "DEBUG";
391  signal_names[NSIG+1] = "ERR";
392  signal_names[NSIG+2] = "RETURN";
393}
394