More removal of "#if 0" content.
[oweals/busybox.git] / libbb / u_signal_names.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * Utility routines.
4  *
5  * Copyright (C) many different people.
6  * If you wrote this, please acknowledge your work.
7  *
8  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
9  */
10
11 #include <signal.h>
12 #include <ctype.h>
13 #include <string.h>
14 #include <strings.h>
15 #include <stdlib.h>
16 #include <stdio.h>
17
18 #include "libbb.h"
19
20 struct signal_name {
21         const char *name;
22         int number;
23 };
24
25 static const struct signal_name signames[] = {
26         /* POSIX signals */
27         { "EXIT",       0 },            /* 0 */
28         { "HUP",        SIGHUP },       /* 1 */
29         { "INT",        SIGINT },       /* 2 */
30         { "QUIT",       SIGQUIT },      /* 3 */
31         { "ILL",        SIGILL },       /* 4 */
32         { "ABRT",       SIGABRT },      /* 6 */
33         { "FPE",        SIGFPE },       /* 8 */
34         { "KILL",       SIGKILL },      /* 9 */
35         { "SEGV",       SIGSEGV },      /* 11 */
36         { "PIPE",       SIGPIPE },      /* 13 */
37         { "ALRM",       SIGALRM },      /* 14 */
38         { "TERM",       SIGTERM },      /* 15 */
39         { "USR1",       SIGUSR1 },      /* 10 (arm,i386,m68k,ppc), 30 (alpha,sparc*), 16 (mips) */
40         { "USR2",       SIGUSR2 },      /* 12 (arm,i386,m68k,ppc), 31 (alpha,sparc*), 17 (mips) */
41         { "CHLD",       SIGCHLD },      /* 17 (arm,i386,m68k,ppc), 20 (alpha,sparc*), 18 (mips) */
42         { "CONT",       SIGCONT },      /* 18 (arm,i386,m68k,ppc), 19 (alpha,sparc*), 25 (mips) */
43         { "STOP",       SIGSTOP },      /* 19 (arm,i386,m68k,ppc), 17 (alpha,sparc*), 23 (mips) */
44         { "TSTP",       SIGTSTP },      /* 20 (arm,i386,m68k,ppc), 18 (alpha,sparc*), 24 (mips) */
45         { "TTIN",       SIGTTIN },      /* 21 (arm,i386,m68k,ppc,alpha,sparc*), 26 (mips) */
46         { "TTOU",       SIGTTOU },      /* 22 (arm,i386,m68k,ppc,alpha,sparc*), 27 (mips) */
47         /* Miscellaneous other signals */
48 #ifdef SIGTRAP
49         { "TRAP",       SIGTRAP },      /* 5 */
50 #endif
51 #ifdef SIGIOT
52         { "IOT",        SIGIOT },       /* 6, same as SIGABRT */
53 #endif
54 #ifdef SIGEMT
55         { "EMT",        SIGEMT },       /* 7 (mips,alpha,sparc*) */
56 #endif
57 #ifdef SIGBUS
58         { "BUS",        SIGBUS },       /* 7 (arm,i386,m68k,ppc), 10 (mips,alpha,sparc*) */
59 #endif
60 #ifdef SIGSYS
61         { "SYS",        SIGSYS },       /* 12 (mips,alpha,sparc*) */
62 #endif
63 #ifdef SIGSTKFLT
64         { "STKFLT",     SIGSTKFLT },    /* 16 (arm,i386,m68k,ppc) */
65 #endif
66 #ifdef SIGURG
67         { "URG",        SIGURG },       /* 23 (arm,i386,m68k,ppc), 16 (alpha,sparc*), 21 (mips) */
68 #endif
69 #ifdef SIGIO
70         { "IO",         SIGIO },        /* 29 (arm,i386,m68k,ppc), 23 (alpha,sparc*), 22 (mips) */
71 #endif
72 #ifdef SIGPOLL
73         { "POLL",       SIGPOLL },      /* same as SIGIO */
74 #endif
75 #ifdef SIGCLD
76         { "CLD",        SIGCLD },       /* same as SIGCHLD (mips) */
77 #endif
78 #ifdef SIGXCPU
79         { "XCPU",       SIGXCPU },      /* 24 (arm,i386,m68k,ppc,alpha,sparc*), 30 (mips) */
80 #endif
81 #ifdef SIGXFSZ
82         { "XFSZ",       SIGXFSZ },      /* 25 (arm,i386,m68k,ppc,alpha,sparc*), 31 (mips) */
83 #endif
84 #ifdef SIGVTALRM
85         { "VTALRM",     SIGVTALRM },    /* 26 (arm,i386,m68k,ppc,alpha,sparc*), 28 (mips) */
86 #endif
87 #ifdef SIGPROF
88         { "PROF",       SIGPROF },      /* 27 (arm,i386,m68k,ppc,alpha,sparc*), 29 (mips) */
89 #endif
90 #ifdef SIGPWR
91         { "PWR",        SIGPWR },       /* 30 (arm,i386,m68k,ppc), 29 (alpha,sparc*), 19 (mips) */
92 #endif
93 #ifdef SIGINFO
94         { "INFO",       SIGINFO },      /* 29 (alpha) */
95 #endif
96 #ifdef SIGLOST
97         { "LOST",       SIGLOST },      /* 29 (arm,i386,m68k,ppc,sparc*) */
98 #endif
99 #ifdef SIGWINCH
100         { "WINCH",      SIGWINCH },     /* 28 (arm,i386,m68k,ppc,alpha,sparc*), 20 (mips) */
101 #endif
102 #ifdef SIGUNUSED
103         { "UNUSED",     SIGUNUSED },    /* 31 (arm,i386,m68k,ppc) */
104 #endif
105         {0, 0}
106 };
107
108 /*
109         if str_sig == NULL returned signal name [*signo],
110         if str_sig != NULL - set *signo from signal_name,
111                 findings with digit number or with or without SIG-prefix name
112
113         if startnum=0 flag for support finding zero signal,
114                 but str_sig="0" always found, (hmm - standart or realize?)
115         if startnum<0 returned reverse signal_number  <-> signal_name
116         if found error - returned NULL
117
118 */
119
120 const char *
121 u_signal_names(const char *str_sig, int *signo, int startnum)
122 {
123         static char retstr[16];
124         const struct signal_name *s = signames;
125         static const char prefix[] = "SIG";
126         const char *sptr;
127
128         if(startnum)
129                 s++;
130         if(str_sig==NULL) {
131                 while (s->name != 0) {
132                         if(s->number == *signo)
133                                 break;
134                         s++;
135                 }
136         } else {
137                 if (isdigit(((unsigned char)*str_sig))) {
138                         char *endp;
139                         long int sn = strtol(str_sig, &endp, 10);
140                         /* test correct and overflow */
141                         if(*endp == 0 && sn >= 0 && sn < NSIG) {
142                                 *signo = (int)sn;
143                                 /* test for unnamed */
144                                 sptr = u_signal_names(0, signo, 0);
145                                 if(sptr==NULL)
146                                         return NULL;
147                                 if(sn!=0)
148                                         sptr += 3;
149                                 return sptr;
150                         }
151                 } else {
152                         sptr = str_sig;
153                         while (s->name != 0) {
154                                 if (strcasecmp(s->name, sptr) == 0) {
155                                         *signo = s->number;
156                                         if(startnum<0) {
157                                                 sprintf(retstr, "%d", *signo);
158                                                 return retstr;
159                                         }
160                                         break;
161                                 }
162                                 if(s!=signames && sptr == str_sig &&
163                                                 strncasecmp(sptr, prefix, 3) == 0) {
164                                         sptr += 3;      /* strlen(prefix) */
165                                         continue;
166                                 }
167                                 sptr = str_sig;
168                                 s++;
169                         }
170                 }
171         }
172         if(s->name==0)
173                 return NULL;
174         if(s!=signames)
175                 strcpy(retstr, prefix);
176          else
177                 retstr[0] = 0;
178         return strcat(retstr, s->name);
179 }