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