1 /* Extended support for using signal values. 2 Copyright (C) 1992 Free Software Foundation, Inc. 3 Written by Fred Fish. fnf@cygnus.com 4 5 This file is part of the libiberty library. 6 Libiberty is free software; you can redistribute it and/or 7 modify it under the terms of the GNU Library General Public 8 License as published by the Free Software Foundation; either 9 version 2 of the License, or (at your option) any later version. 10 11 Libiberty is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 Library General Public License for more details. 15 16 You should have received a copy of the GNU Library General Public 17 License along with libiberty; see the file COPYING.LIB. If 18 not, write to the Free Software Foundation, Inc., 675 Mass Ave, 19 Cambridge, MA 02139, USA. */ 20 21 #include "config.h" 22 23 #include <stdio.h> 24 #include <signal.h> 25 26 /* Routines imported from standard C runtime libraries. */ 27 28 #ifdef __STDC__ 29 #include <stddef.h> 30 extern void *malloc (size_t size); /* 4.10.3.3 */ 31 extern void *memset (void *s, int c, size_t n); /* 4.11.6.1 */ 32 #else /* !__STDC__ */ 33 extern char *malloc (); /* Standard memory allocater */ 34 extern char *memset (); 35 #endif /* __STDC__ */ 36 37 #ifndef NULL 38 # ifdef __STDC__ 39 # define NULL (void *) 0 40 # else 41 # define NULL 0 42 # endif 43 #endif 44 45 #ifndef MAX 46 # define MAX(a,b) ((a) > (b) ? (a) : (b)) 47 #endif 48 49 /* Translation table for signal values. 50 51 Note that this table is generally only accessed when it is used at runtime 52 to initialize signal name and message tables that are indexed by signal 53 value. 54 55 Not all of these signals will exist on all systems. This table is the only 56 thing that should have to be updated as new signal numbers are introduced. 57 It's sort of ugly, but at least its portable. */ 58 59 static struct signal_info 60 { 61 int value; /* The numeric value from <signal.h> */ 62 char *name; /* The equivalent symbolic value */ 63 char *msg; /* Short message about this value */ 64 } signal_table[] = 65 { 66 #if defined (SIGHUP) 67 SIGHUP, "SIGHUP", "Hangup", 68 #endif 69 #if defined (SIGINT) 70 SIGINT, "SIGINT", "Interrupt", 71 #endif 72 #if defined (SIGQUIT) 73 SIGQUIT, "SIGQUIT", "Quit", 74 #endif 75 #if defined (SIGILL) 76 SIGILL, "SIGILL", "Illegal instruction", 77 #endif 78 #if defined (SIGTRAP) 79 SIGTRAP, "SIGTRAP", "Trace/breakpoint trap", 80 #endif 81 /* Put SIGIOT before SIGABRT, so that if SIGIOT==SIGABRT then SIGABRT 82 overrides SIGIOT. SIGABRT is in ANSI and POSIX.1, and SIGIOT isn't. */ 83 #if defined (SIGIOT) 84 SIGIOT, "SIGIOT", "IOT trap", 85 #endif 86 #if defined (SIGABRT) 87 SIGABRT, "SIGABRT", "Aborted", 88 #endif 89 #if defined (SIGEMT) 90 SIGEMT, "SIGEMT", "Emulation trap", 91 #endif 92 #if defined (SIGFPE) 93 SIGFPE, "SIGFPE", "Arithmetic exception", 94 #endif 95 #if defined (SIGKILL) 96 SIGKILL, "SIGKILL", "Killed", 97 #endif 98 #if defined (SIGBUS) 99 SIGBUS, "SIGBUS", "Bus error", 100 #endif 101 #if defined (SIGSEGV) 102 SIGSEGV, "SIGSEGV", "Segmentation fault", 103 #endif 104 #if defined (SIGSYS) 105 SIGSYS, "SIGSYS", "Bad system call", 106 #endif 107 #if defined (SIGPIPE) 108 SIGPIPE, "SIGPIPE", "Broken pipe", 109 #endif 110 #if defined (SIGALRM) 111 SIGALRM, "SIGALRM", "Alarm clock", 112 #endif 113 #if defined (SIGTERM) 114 SIGTERM, "SIGTERM", "Terminated", 115 #endif 116 #if defined (SIGUSR1) 117 SIGUSR1, "SIGUSR1", "User defined signal 1", 118 #endif 119 #if defined (SIGUSR2) 120 SIGUSR2, "SIGUSR2", "User defined signal 2", 121 #endif 122 /* Put SIGCLD before SIGCHLD, so that if SIGCLD==SIGCHLD then SIGCHLD 123 overrides SIGCLD. SIGCHLD is in POXIX.1 */ 124 #if defined (SIGCLD) 125 SIGCLD, "SIGCLD", "Child status changed", 126 #endif 127 #if defined (SIGCHLD) 128 SIGCHLD, "SIGCHLD", "Child status changed", 129 #endif 130 #if defined (SIGPWR) 131 SIGPWR, "SIGPWR", "Power fail/restart", 132 #endif 133 #if defined (SIGWINCH) 134 SIGWINCH, "SIGWINCH", "Window size changed", 135 #endif 136 #if defined (SIGURG) 137 SIGURG, "SIGURG", "Urgent I/O condition", 138 #endif 139 #if defined (SIGIO) 140 /* "I/O pending has also been suggested, but is misleading since the 141 signal only happens when the process has asked for it, not everytime 142 I/O is pending. */ 143 SIGIO, "SIGIO", "I/O possible", 144 #endif 145 #if defined (SIGPOLL) 146 SIGPOLL, "SIGPOLL", "Pollable event occurred", 147 #endif 148 #if defined (SIGSTOP) 149 SIGSTOP, "SIGSTOP", "Stopped (signal)", 150 #endif 151 #if defined (SIGTSTP) 152 SIGTSTP, "SIGTSTP", "Stopped (user)", 153 #endif 154 #if defined (SIGCONT) 155 SIGCONT, "SIGCONT", "Continued", 156 #endif 157 #if defined (SIGTTIN) 158 SIGTTIN, "SIGTTIN", "Stopped (tty input)", 159 #endif 160 #if defined (SIGTTOU) 161 SIGTTOU, "SIGTTOU", "Stopped (tty output)", 162 #endif 163 #if defined (SIGVTALRM) 164 SIGVTALRM, "SIGVTALRM", "Virtual timer expired", 165 #endif 166 #if defined (SIGPROF) 167 SIGPROF, "SIGPROF", "Profiling timer expired", 168 #endif 169 #if defined (SIGXCPU) 170 SIGXCPU, "SIGXCPU", "CPU time limit exceeded", 171 #endif 172 #if defined (SIGXFSZ) 173 SIGXFSZ, "SIGXFSZ", "File size limit exceeded", 174 #endif 175 #if defined (SIGWIND) 176 SIGWIND, "SIGWIND", "SIGWIND", 177 #endif 178 #if defined (SIGPHONE) 179 SIGPHONE, "SIGPHONE", "SIGPHONE", 180 #endif 181 #if defined (SIGLOST) 182 SIGLOST, "SIGLOST", "Resource lost", 183 #endif 184 #if defined (SIGWAITING) 185 SIGWAITING, "SIGWAITING", "Process's LWPs are blocked", 186 #endif 187 #if defined (SIGLWP) 188 SIGLWP, "SIGLWP", "Signal LWP", 189 #endif 190 0, NULL, NULL 191 }; 192 193 /* Translation table allocated and initialized at runtime. Indexed by the 194 signal value to find the equivalent symbolic value. */ 195 196 static char **signal_names; 197 static int num_signal_names = 0; 198 199 /* Translation table allocated and initialized at runtime, if it does not 200 already exist in the host environment. Indexed by the signal value to find 201 the descriptive string. 202 203 We don't export it for use in other modules because even though it has the 204 same name, it differs from other implementations in that it is dynamically 205 initialized rather than statically initialized. */ 206 207 #ifdef NEED_sys_siglist 208 209 static int sys_nsig; 210 static char **sys_siglist; 211 212 #else 213 214 static int sys_nsig = NSIG; 215 #ifdef __STDC__ 216 extern const char * const sys_siglist[]; 217 #else 218 extern char *sys_siglist[]; 219 #endif 220 #endif 221 222 223 /* 224 225 NAME 226 227 init_signal_tables -- initialize the name and message tables 228 229 SYNOPSIS 230 231 static void init_signal_tables (); 232 233 DESCRIPTION 234 235 Using the signal_table, which is initialized at compile time, generate 236 the signal_names and the sys_siglist (if needed) tables, which are 237 indexed at runtime by a specific signal value. 238 239 BUGS 240 241 The initialization of the tables may fail under low memory conditions, 242 in which case we don't do anything particularly useful, but we don't 243 bomb either. Who knows, it might succeed at a later point if we free 244 some memory in the meantime. In any case, the other routines know 245 how to deal with lack of a table after trying to initialize it. This 246 may or may not be considered to be a bug, that we don't specifically 247 warn about this particular failure mode. 248 249 */ 250 251 static void 252 init_signal_tables () 253 { 254 struct signal_info *eip; 255 int nbytes; 256 257 /* If we haven't already scanned the signal_table once to find the maximum 258 signal value, then go find it now. */ 259 260 if (num_signal_names == 0) 261 { 262 for (eip = signal_table; eip -> name != NULL; eip++) 263 { 264 if (eip -> value >= num_signal_names) 265 { 266 num_signal_names = eip -> value + 1; 267 } 268 } 269 } 270 271 /* Now attempt to allocate the signal_names table, zero it out, and then 272 initialize it from the statically initialized signal_table. */ 273 274 if (signal_names == NULL) 275 { 276 nbytes = num_signal_names * sizeof (char *); 277 if ((signal_names = (char **) malloc (nbytes)) != NULL) 278 { 279 memset (signal_names, 0, nbytes); 280 for (eip = signal_table; eip -> name != NULL; eip++) 281 { 282 signal_names[eip -> value] = eip -> name; 283 } 284 } 285 } 286 287 #ifdef NEED_sys_siglist 288 289 /* Now attempt to allocate the sys_siglist table, zero it out, and then 290 initialize it from the statically initialized signal_table. */ 291 292 if (sys_siglist == NULL) 293 { 294 nbytes = num_signal_names * sizeof (char *); 295 if ((sys_siglist = (char **) malloc (nbytes)) != NULL) 296 { 297 memset (sys_siglist, 0, nbytes); 298 sys_nsig = num_signal_names; 299 for (eip = signal_table; eip -> name != NULL; eip++) 300 { 301 sys_siglist[eip -> value] = eip -> msg; 302 } 303 } 304 } 305 306 #endif 307 308 } 309 310 311 /* 312 313 NAME 314 315 signo_max -- return the max signo value 316 317 SYNOPSIS 318 319 int signo_max (); 320 321 DESCRIPTION 322 323 Returns the maximum signo value for which a corresponding symbolic 324 name or message is available. Note that in the case where 325 we use the sys_siglist supplied by the system, it is possible for 326 there to be more symbolic names than messages, or vice versa. 327 In fact, the manual page for psignal(3b) explicitly warns that one 328 should check the size of the table (NSIG) before indexing it, 329 since new signal codes may be added to the system before they are 330 added to the table. Thus NSIG might be smaller than value 331 implied by the largest signo value defined in <signal.h>. 332 333 We return the maximum value that can be used to obtain a meaningful 334 symbolic name or message. 335 336 */ 337 338 int 339 signo_max () 340 { 341 int maxsize; 342 343 if (signal_names == NULL) 344 { 345 init_signal_tables (); 346 } 347 maxsize = MAX (sys_nsig, num_signal_names); 348 return (maxsize - 1); 349 } 350 351 352 /* 353 354 NAME 355 356 strsignal -- map a signal number to a signal message string 357 358 SYNOPSIS 359 360 char *strsignal (int signo) 361 362 DESCRIPTION 363 364 Maps an signal number to an signal message string, the contents of 365 which are implementation defined. On systems which have the external 366 variable sys_siglist, these strings will be the same as the ones used 367 by psignal(). 368 369 If the supplied signal number is within the valid range of indices 370 for the sys_siglist, but no message is available for the particular 371 signal number, then returns the string "Signal NUM", where NUM is the 372 signal number. 373 374 If the supplied signal number is not a valid index into sys_siglist, 375 returns NULL. 376 377 The returned string is only guaranteed to be valid only until the 378 next call to strsignal. 379 380 */ 381 382 char * 383 strsignal (signo) 384 int signo; 385 { 386 char *msg; 387 static char buf[32]; 388 389 #ifdef NEED_sys_siglist 390 391 if (signal_names == NULL) 392 { 393 init_signal_tables (); 394 } 395 396 #endif 397 398 if ((signo < 0) || (signo >= sys_nsig)) 399 { 400 /* Out of range, just return NULL */ 401 msg = NULL; 402 } 403 else if ((sys_siglist == NULL) || (sys_siglist[signo] == NULL)) 404 { 405 /* In range, but no sys_siglist or no entry at this index. */ 406 sprintf (buf, "Signal %d", signo); 407 msg = buf; 408 } 409 else 410 { 411 /* In range, and a valid message. Just return the message. */ 412 msg = (char*)sys_siglist[signo]; 413 } 414 415 return (msg); 416 } 417 418 419 /* 420 421 NAME 422 423 strsigno -- map an signal number to a symbolic name string 424 425 SYNOPSIS 426 427 char *strsigno (int signo) 428 429 DESCRIPTION 430 431 Given an signal number, returns a pointer to a string containing 432 the symbolic name of that signal number, as found in <signal.h>. 433 434 If the supplied signal number is within the valid range of indices 435 for symbolic names, but no name is available for the particular 436 signal number, then returns the string "Signal NUM", where NUM is 437 the signal number. 438 439 If the supplied signal number is not within the range of valid 440 indices, then returns NULL. 441 442 BUGS 443 444 The contents of the location pointed to are only guaranteed to be 445 valid until the next call to strsigno. 446 447 */ 448 449 char * 450 strsigno (signo) 451 int signo; 452 { 453 char *name; 454 static char buf[32]; 455 456 if (signal_names == NULL) 457 { 458 init_signal_tables (); 459 } 460 461 if ((signo < 0) || (signo >= num_signal_names)) 462 { 463 /* Out of range, just return NULL */ 464 name = NULL; 465 } 466 else if ((signal_names == NULL) || (signal_names[signo] == NULL)) 467 { 468 /* In range, but no signal_names or no entry at this index. */ 469 sprintf (buf, "Signal %d", signo); 470 name = buf; 471 } 472 else 473 { 474 /* In range, and a valid name. Just return the name. */ 475 name = signal_names[signo]; 476 } 477 478 return (name); 479 } 480 481 482 /* 483 484 NAME 485 486 strtosigno -- map a symbolic signal name to a numeric value 487 488 SYNOPSIS 489 490 int strtosigno (char *name) 491 492 DESCRIPTION 493 494 Given the symbolic name of a signal, map it to a signal number. 495 If no translation is found, returns 0. 496 497 */ 498 499 int 500 strtosigno (name) 501 char *name; 502 { 503 int signo = 0; 504 505 if (name != NULL) 506 { 507 if (signal_names == NULL) 508 { 509 init_signal_tables (); 510 } 511 for (signo = 0; signo < num_signal_names; signo++) 512 { 513 if ((signal_names[signo] != NULL) && 514 (strcmp (name, signal_names[signo]) == 0)) 515 { 516 break; 517 } 518 } 519 if (signo == num_signal_names) 520 { 521 signo = 0; 522 } 523 } 524 return (signo); 525 } 526 527 528 /* 529 530 NAME 531 532 psignal -- print message about signal to stderr 533 534 SYNOPSIS 535 536 void psignal (unsigned signo, char *message); 537 538 DESCRIPTION 539 540 Print to the standard error the message, followed by a colon, 541 followed by the description of the signal specified by signo, 542 followed by a newline. 543 */ 544 545 #ifdef NEED_psignal 546 547 void 548 psignal (signo, message) 549 unsigned signo; 550 char *message; 551 { 552 if (signal_names == NULL) 553 { 554 init_signal_tables (); 555 } 556 if ((signo <= 0) || (signo >= sys_nsig)) 557 { 558 fprintf (stderr, "%s: unknown signal\n", message); 559 } 560 else 561 { 562 fprintf (stderr, "%s: %s\n", message, sys_siglist[signo]); 563 } 564 } 565 566 #endif /* NEED_psignal */ 567 568 569 /* A simple little main that does nothing but print all the signal translations 570 if MAIN is defined and this file is compiled and linked. */ 571 572 #ifdef MAIN 573 574 main () 575 { 576 int signo; 577 int maxsigno; 578 char *name; 579 char *msg; 580 char *strsigno (); 581 char *strsignal (); 582 583 maxsigno = signo_max (); 584 printf ("%d entries in names table.\n", num_signal_names); 585 printf ("%d entries in messages table.\n", sys_nsig); 586 printf ("%d is max useful index.\n", maxsigno); 587 588 /* Keep printing values until we get to the end of *both* tables, not 589 *either* table. Note that knowing the maximum useful index does *not* 590 relieve us of the responsibility of testing the return pointer for 591 NULL. */ 592 593 for (signo = 0; signo <= maxsigno; signo++) 594 { 595 name = strsigno (signo); 596 name = (name == NULL) ? "<NULL>" : name; 597 msg = strsignal (signo); 598 msg = (msg == NULL) ? "<NULL>" : msg; 599 printf ("%-4d%-18s%s\n", signo, name, msg); 600 } 601 } 602 603 #endif 604