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