2 * Copyright 1998-2003 by Albert Cahalan; all rights resered.
3 * This file may be used subject to the terms and conditions of the
4 * GNU Library General Public License Version 2, or any later version
5 * at your option, as published by the Free Software Foundation.
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU Library General Public License for more details.
19 * SIGSYS is required by Unix98.
20 * SIGEMT is part of SysV, BSD, and ancient UNIX tradition.
22 * They are provided by these Linux ports: alpha, mips, sparc, and sparc64.
23 * You get SIGSTKFLT and SIGUNUSED instead on i386, m68k, ppc, and arm.
24 * (this is a Linux & libc bug -- both must be fixed)
26 * Total garbage: SIGIO SIGINFO SIGIOT SIGLOST SIGCLD
27 * (popular ones are handled as aliases)
28 * Nearly garbage: SIGSTKFLT SIGUNUSED (nothing else to fill slots)
31 /* Linux 2.3.29 replaces SIGUNUSED with the standard SIGSYS signal */
33 # warning Standards require that <signal.h> define SIGSYS
34 # define SIGSYS SIGUNUSED
37 /* If we see both, it is likely SIGSTKFLT (junk) was replaced. */
43 # warning Standards require that <signal.h> define SIGRTMIN; assuming 32
47 /* It seems the SPARC libc does not know the kernel supports SIGPWR. */
49 # warning Your header files lack SIGPWR. (assuming it is number 29)
53 typedef struct mapstruct {
59 static const mapstruct sigtable[] = {
60 {"ABRT", SIGABRT}, /* IOT */
63 {"CHLD", SIGCHLD}, /* CLD */
74 {"POLL", SIGPOLL}, /* IO */
80 {"STKFLT", SIGSTKFLT},
83 {"SYS", SIGSYS}, /* UNUSED */
92 {"VTALRM", SIGVTALRM},
98 static const int number_of_signals = sizeof(sigtable)/sizeof(mapstruct);
100 static int compare_signal_names(const void *a, const void *b){
101 return strcasecmp( ((const mapstruct*)a)->name, ((const mapstruct*)b)->name );
104 /* return -1 on failure */
105 int signal_name_to_number(const char *restrict name){
110 if(!strncasecmp(name,"SIG",3)) name += 3;
112 if(!strcasecmp(name,"CLD")) return SIGCHLD;
113 if(!strcasecmp(name,"IO")) return SIGPOLL;
114 if(!strcasecmp(name,"IOT")) return SIGABRT;
116 /* search the table */
118 const mapstruct ms = {name,0};
119 const mapstruct *restrict const ptr = bsearch(
126 if(ptr) return ptr->num;
129 if(!strcasecmp(name,"RTMIN")) return SIGRTMIN;
130 if(!strcasecmp(name,"EXIT")) return 0;
131 if(!strcasecmp(name,"NULL")) return 0;
134 if(!strncasecmp(name,"RTMIN+",6)){
139 /* not found, so try as a number */
142 val = strtol(name,&endp,10);
143 if(*endp || endp==name) return -1; /* not valid */
145 if(val+SIGRTMIN>127) return -1; /* not valid */
149 const char *signal_number_to_name(int signo){
151 int n = number_of_signals;
152 signo &= 0x7f; /* need to process exit values too */
154 if(sigtable[n].num==signo) return sigtable[n].name;
156 if(signo == SIGRTMIN) return "RTMIN";
157 if(signo) sprintf(buf, "RTMIN+%d", signo-SIGRTMIN);
158 else strcpy(buf,"0"); /* AIX has NULL; Solaris has EXIT */
162 int print_given_signals(int argc, const char *restrict const *restrict argv, int max_line){
163 char buf[1280]; /* 128 signals, "RTMIN+xx" is largest */
164 int ret = 0; /* to be used as exit code by caller */
165 int place = 0; /* position on this line */
167 if(argc > 128) return 1;
170 const char *restrict const txt = *argv;
171 if(*txt >= '0' && *txt <= '9'){
174 val = strtol(txt,&endp,10);
176 fprintf(stderr, "Signal \"%s\" not known.\n", txt);
180 amt = sprintf(tmpbuf, "%s", signal_number_to_name(val));
183 sno = signal_name_to_number(txt);
185 fprintf(stderr, "Signal \"%s\" not known.\n", txt);
189 amt = sprintf(tmpbuf, "%d", sno);
197 if(amt+place+1 > max_line){
203 sprintf(buf+place, " %s", tmpbuf);
208 if(place) printf("%s\n", buf);
212 void pretty_print_signals(void){
214 while(++i <= number_of_signals){
216 n = printf("%2d %s", i, signal_number_to_name(i));
217 if(i%7) printf(" \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + n);
220 if((i-1)%7) printf("\n");
223 void unix_print_signals(void){
226 while(++i <= number_of_signals){
227 if(i-1) printf("%c", (pos>73)?(pos=0,'\n'):(pos++,' ') );
228 pos += printf("%s", signal_number_to_name(i));
234 static int init_signal_list(void) __attribute__((constructor));
235 static int init_signal_list(void){
236 if(number_of_signals != 31){
237 fprintf(stderr, "WARNING: %d signals -- adjust and recompile.\n", number_of_signals);