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