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