133965Sjdp/* Extended support for using signal values. 233965Sjdp Written by Fred Fish. fnf@cygnus.com 333965Sjdp This file is in the public domain. */ 433965Sjdp 5218822Sdim#include "config.h" 633965Sjdp#include "ansidecl.h" 733965Sjdp#include "libiberty.h" 833965Sjdp 933965Sjdp/* We need to declare sys_siglist, because even if the system provides 1033965Sjdp it we can't assume that it is declared in <signal.h> (for example, 1133965Sjdp SunOS provides sys_siglist, but it does not declare it in any 12218822Sdim header file). However, we can't declare sys_siglist portably, 1333965Sjdp because on some systems it is declared with const and on some 1433965Sjdp systems it is declared without const. If we were using autoconf, 1533965Sjdp we could work out the right declaration. Until, then we just 1633965Sjdp ignore any declaration in the system header files, and always 1733965Sjdp declare it ourselves. With luck, this will always work. */ 1833965Sjdp#define sys_siglist no_such_symbol 1989857Sobrien#define sys_nsig sys_nsig__no_such_symbol 2033965Sjdp 2133965Sjdp#include <stdio.h> 2233965Sjdp#include <signal.h> 2333965Sjdp 2433965Sjdp/* Routines imported from standard C runtime libraries. */ 2533965Sjdp 2677298Sobrien#ifdef HAVE_STDLIB_H 2777298Sobrien#include <stdlib.h> 2877298Sobrien#else 2977298Sobrienextern PTR malloc (); 3077298Sobrien#endif 3133965Sjdp 3277298Sobrien#ifdef HAVE_STRING_H 3377298Sobrien#include <string.h> 3477298Sobrien#else 3577298Sobrienextern PTR memset (); 3677298Sobrien#endif 3777298Sobrien 3833965Sjdp/* Undefine the macro we used to hide the definition of sys_siglist 3933965Sjdp found in the system header files. */ 4033965Sjdp#undef sys_siglist 4189857Sobrien#undef sys_nsig 4233965Sjdp 4333965Sjdp#ifndef NULL 44218822Sdim# define NULL (void *) 0 4533965Sjdp#endif 4633965Sjdp 4733965Sjdp#ifndef MAX 4833965Sjdp# define MAX(a,b) ((a) > (b) ? (a) : (b)) 4933965Sjdp#endif 5033965Sjdp 51218822Sdimstatic void init_signal_tables (void); 5233965Sjdp 5333965Sjdp/* Translation table for signal values. 5433965Sjdp 5533965Sjdp Note that this table is generally only accessed when it is used at runtime 5633965Sjdp to initialize signal name and message tables that are indexed by signal 5733965Sjdp value. 5833965Sjdp 5933965Sjdp Not all of these signals will exist on all systems. This table is the only 6033965Sjdp thing that should have to be updated as new signal numbers are introduced. 6133965Sjdp It's sort of ugly, but at least its portable. */ 6233965Sjdp 6333965Sjdpstruct signal_info 6433965Sjdp{ 6589857Sobrien const int value; /* The numeric value from <signal.h> */ 6689857Sobrien const char *const name; /* The equivalent symbolic value */ 6760484Sobrien#ifndef HAVE_SYS_SIGLIST 6889857Sobrien const char *const msg; /* Short message about this value */ 6933965Sjdp#endif 7033965Sjdp}; 7133965Sjdp 7260484Sobrien#ifndef HAVE_SYS_SIGLIST 7333965Sjdp# define ENTRY(value, name, msg) {value, name, msg} 7433965Sjdp#else 7533965Sjdp# define ENTRY(value, name, msg) {value, name} 7633965Sjdp#endif 7733965Sjdp 7833965Sjdpstatic const struct signal_info signal_table[] = 7933965Sjdp{ 8033965Sjdp#if defined (SIGHUP) 8133965Sjdp ENTRY(SIGHUP, "SIGHUP", "Hangup"), 8233965Sjdp#endif 8333965Sjdp#if defined (SIGINT) 8433965Sjdp ENTRY(SIGINT, "SIGINT", "Interrupt"), 8533965Sjdp#endif 8633965Sjdp#if defined (SIGQUIT) 8733965Sjdp ENTRY(SIGQUIT, "SIGQUIT", "Quit"), 8833965Sjdp#endif 8933965Sjdp#if defined (SIGILL) 9033965Sjdp ENTRY(SIGILL, "SIGILL", "Illegal instruction"), 9133965Sjdp#endif 9233965Sjdp#if defined (SIGTRAP) 9333965Sjdp ENTRY(SIGTRAP, "SIGTRAP", "Trace/breakpoint trap"), 9433965Sjdp#endif 9533965Sjdp/* Put SIGIOT before SIGABRT, so that if SIGIOT==SIGABRT then SIGABRT 9633965Sjdp overrides SIGIOT. SIGABRT is in ANSI and POSIX.1, and SIGIOT isn't. */ 9733965Sjdp#if defined (SIGIOT) 9833965Sjdp ENTRY(SIGIOT, "SIGIOT", "IOT trap"), 9933965Sjdp#endif 10033965Sjdp#if defined (SIGABRT) 10133965Sjdp ENTRY(SIGABRT, "SIGABRT", "Aborted"), 10233965Sjdp#endif 10333965Sjdp#if defined (SIGEMT) 10433965Sjdp ENTRY(SIGEMT, "SIGEMT", "Emulation trap"), 10533965Sjdp#endif 10633965Sjdp#if defined (SIGFPE) 10733965Sjdp ENTRY(SIGFPE, "SIGFPE", "Arithmetic exception"), 10833965Sjdp#endif 10933965Sjdp#if defined (SIGKILL) 11033965Sjdp ENTRY(SIGKILL, "SIGKILL", "Killed"), 11133965Sjdp#endif 11233965Sjdp#if defined (SIGBUS) 11333965Sjdp ENTRY(SIGBUS, "SIGBUS", "Bus error"), 11433965Sjdp#endif 11533965Sjdp#if defined (SIGSEGV) 11633965Sjdp ENTRY(SIGSEGV, "SIGSEGV", "Segmentation fault"), 11733965Sjdp#endif 11833965Sjdp#if defined (SIGSYS) 11933965Sjdp ENTRY(SIGSYS, "SIGSYS", "Bad system call"), 12033965Sjdp#endif 12133965Sjdp#if defined (SIGPIPE) 12233965Sjdp ENTRY(SIGPIPE, "SIGPIPE", "Broken pipe"), 12333965Sjdp#endif 12433965Sjdp#if defined (SIGALRM) 12533965Sjdp ENTRY(SIGALRM, "SIGALRM", "Alarm clock"), 12633965Sjdp#endif 12733965Sjdp#if defined (SIGTERM) 12833965Sjdp ENTRY(SIGTERM, "SIGTERM", "Terminated"), 12933965Sjdp#endif 13033965Sjdp#if defined (SIGUSR1) 13133965Sjdp ENTRY(SIGUSR1, "SIGUSR1", "User defined signal 1"), 13233965Sjdp#endif 13333965Sjdp#if defined (SIGUSR2) 13433965Sjdp ENTRY(SIGUSR2, "SIGUSR2", "User defined signal 2"), 13533965Sjdp#endif 13633965Sjdp/* Put SIGCLD before SIGCHLD, so that if SIGCLD==SIGCHLD then SIGCHLD 13733965Sjdp overrides SIGCLD. SIGCHLD is in POXIX.1 */ 13833965Sjdp#if defined (SIGCLD) 13933965Sjdp ENTRY(SIGCLD, "SIGCLD", "Child status changed"), 14033965Sjdp#endif 14133965Sjdp#if defined (SIGCHLD) 14233965Sjdp ENTRY(SIGCHLD, "SIGCHLD", "Child status changed"), 14333965Sjdp#endif 14433965Sjdp#if defined (SIGPWR) 14533965Sjdp ENTRY(SIGPWR, "SIGPWR", "Power fail/restart"), 14633965Sjdp#endif 14733965Sjdp#if defined (SIGWINCH) 14833965Sjdp ENTRY(SIGWINCH, "SIGWINCH", "Window size changed"), 14933965Sjdp#endif 15033965Sjdp#if defined (SIGURG) 15133965Sjdp ENTRY(SIGURG, "SIGURG", "Urgent I/O condition"), 15233965Sjdp#endif 15333965Sjdp#if defined (SIGIO) 15433965Sjdp /* "I/O pending" has also been suggested, but is misleading since the 15533965Sjdp signal only happens when the process has asked for it, not everytime 15633965Sjdp I/O is pending. */ 15733965Sjdp ENTRY(SIGIO, "SIGIO", "I/O possible"), 15833965Sjdp#endif 15933965Sjdp#if defined (SIGPOLL) 16033965Sjdp ENTRY(SIGPOLL, "SIGPOLL", "Pollable event occurred"), 16133965Sjdp#endif 16233965Sjdp#if defined (SIGSTOP) 16333965Sjdp ENTRY(SIGSTOP, "SIGSTOP", "Stopped (signal)"), 16433965Sjdp#endif 16533965Sjdp#if defined (SIGTSTP) 16633965Sjdp ENTRY(SIGTSTP, "SIGTSTP", "Stopped (user)"), 16733965Sjdp#endif 16833965Sjdp#if defined (SIGCONT) 16933965Sjdp ENTRY(SIGCONT, "SIGCONT", "Continued"), 17033965Sjdp#endif 17133965Sjdp#if defined (SIGTTIN) 17233965Sjdp ENTRY(SIGTTIN, "SIGTTIN", "Stopped (tty input)"), 17333965Sjdp#endif 17433965Sjdp#if defined (SIGTTOU) 17533965Sjdp ENTRY(SIGTTOU, "SIGTTOU", "Stopped (tty output)"), 17633965Sjdp#endif 17733965Sjdp#if defined (SIGVTALRM) 17833965Sjdp ENTRY(SIGVTALRM, "SIGVTALRM", "Virtual timer expired"), 17933965Sjdp#endif 18033965Sjdp#if defined (SIGPROF) 18133965Sjdp ENTRY(SIGPROF, "SIGPROF", "Profiling timer expired"), 18233965Sjdp#endif 18333965Sjdp#if defined (SIGXCPU) 18433965Sjdp ENTRY(SIGXCPU, "SIGXCPU", "CPU time limit exceeded"), 18533965Sjdp#endif 18633965Sjdp#if defined (SIGXFSZ) 18733965Sjdp ENTRY(SIGXFSZ, "SIGXFSZ", "File size limit exceeded"), 18833965Sjdp#endif 18933965Sjdp#if defined (SIGWIND) 19033965Sjdp ENTRY(SIGWIND, "SIGWIND", "SIGWIND"), 19133965Sjdp#endif 19233965Sjdp#if defined (SIGPHONE) 19333965Sjdp ENTRY(SIGPHONE, "SIGPHONE", "SIGPHONE"), 19433965Sjdp#endif 19533965Sjdp#if defined (SIGLOST) 19633965Sjdp ENTRY(SIGLOST, "SIGLOST", "Resource lost"), 19733965Sjdp#endif 19833965Sjdp#if defined (SIGWAITING) 19933965Sjdp ENTRY(SIGWAITING, "SIGWAITING", "Process's LWPs are blocked"), 20033965Sjdp#endif 20133965Sjdp#if defined (SIGLWP) 20233965Sjdp ENTRY(SIGLWP, "SIGLWP", "Signal LWP"), 20333965Sjdp#endif 20433965Sjdp#if defined (SIGDANGER) 20533965Sjdp ENTRY(SIGDANGER, "SIGDANGER", "Swap space dangerously low"), 20633965Sjdp#endif 20733965Sjdp#if defined (SIGGRANT) 20833965Sjdp ENTRY(SIGGRANT, "SIGGRANT", "Monitor mode granted"), 20933965Sjdp#endif 21033965Sjdp#if defined (SIGRETRACT) 21133965Sjdp ENTRY(SIGRETRACT, "SIGRETRACT", "Need to relinguish monitor mode"), 21233965Sjdp#endif 21333965Sjdp#if defined (SIGMSG) 21433965Sjdp ENTRY(SIGMSG, "SIGMSG", "Monitor mode data available"), 21533965Sjdp#endif 21633965Sjdp#if defined (SIGSOUND) 21733965Sjdp ENTRY(SIGSOUND, "SIGSOUND", "Sound completed"), 21833965Sjdp#endif 21933965Sjdp#if defined (SIGSAK) 22033965Sjdp ENTRY(SIGSAK, "SIGSAK", "Secure attention"), 22133965Sjdp#endif 22233965Sjdp ENTRY(0, NULL, NULL) 22333965Sjdp}; 22433965Sjdp 22533965Sjdp/* Translation table allocated and initialized at runtime. Indexed by the 22633965Sjdp signal value to find the equivalent symbolic value. */ 22733965Sjdp 22833965Sjdpstatic const char **signal_names; 22933965Sjdpstatic int num_signal_names = 0; 23033965Sjdp 23133965Sjdp/* Translation table allocated and initialized at runtime, if it does not 23233965Sjdp already exist in the host environment. Indexed by the signal value to find 23333965Sjdp the descriptive string. 23433965Sjdp 23533965Sjdp We don't export it for use in other modules because even though it has the 23633965Sjdp same name, it differs from other implementations in that it is dynamically 23733965Sjdp initialized rather than statically initialized. */ 23833965Sjdp 23960484Sobrien#ifndef HAVE_SYS_SIGLIST 24033965Sjdp 24133965Sjdpstatic int sys_nsig; 24233965Sjdpstatic const char **sys_siglist; 24333965Sjdp 24433965Sjdp#else 24533965Sjdp 24638889Sjdp#ifdef NSIG 24733965Sjdpstatic int sys_nsig = NSIG; 24838889Sjdp#else 24938889Sjdp#ifdef _NSIG 25038889Sjdpstatic int sys_nsig = _NSIG; 25138889Sjdp#endif 25238889Sjdp#endif 25333965Sjdpextern const char * const sys_siglist[]; 25433965Sjdp 25533965Sjdp#endif 25633965Sjdp 25733965Sjdp 25833965Sjdp/* 25933965Sjdp 26033965SjdpNAME 26133965Sjdp 26233965Sjdp init_signal_tables -- initialize the name and message tables 26333965Sjdp 26433965SjdpSYNOPSIS 26533965Sjdp 26633965Sjdp static void init_signal_tables (); 26733965Sjdp 26833965SjdpDESCRIPTION 26933965Sjdp 27033965Sjdp Using the signal_table, which is initialized at compile time, generate 27133965Sjdp the signal_names and the sys_siglist (if needed) tables, which are 27233965Sjdp indexed at runtime by a specific signal value. 27333965Sjdp 27433965SjdpBUGS 27533965Sjdp 27633965Sjdp The initialization of the tables may fail under low memory conditions, 27733965Sjdp in which case we don't do anything particularly useful, but we don't 27833965Sjdp bomb either. Who knows, it might succeed at a later point if we free 27933965Sjdp some memory in the meantime. In any case, the other routines know 28033965Sjdp how to deal with lack of a table after trying to initialize it. This 28133965Sjdp may or may not be considered to be a bug, that we don't specifically 28233965Sjdp warn about this particular failure mode. 28333965Sjdp 28433965Sjdp*/ 28533965Sjdp 28633965Sjdpstatic void 287218822Sdiminit_signal_tables (void) 28833965Sjdp{ 28933965Sjdp const struct signal_info *eip; 29033965Sjdp int nbytes; 29133965Sjdp 29233965Sjdp /* If we haven't already scanned the signal_table once to find the maximum 29333965Sjdp signal value, then go find it now. */ 29433965Sjdp 29533965Sjdp if (num_signal_names == 0) 29633965Sjdp { 29733965Sjdp for (eip = signal_table; eip -> name != NULL; eip++) 29833965Sjdp { 29933965Sjdp if (eip -> value >= num_signal_names) 30033965Sjdp { 30133965Sjdp num_signal_names = eip -> value + 1; 30233965Sjdp } 30333965Sjdp } 30433965Sjdp } 30533965Sjdp 30633965Sjdp /* Now attempt to allocate the signal_names table, zero it out, and then 30733965Sjdp initialize it from the statically initialized signal_table. */ 30833965Sjdp 30933965Sjdp if (signal_names == NULL) 31033965Sjdp { 31133965Sjdp nbytes = num_signal_names * sizeof (char *); 31233965Sjdp if ((signal_names = (const char **) malloc (nbytes)) != NULL) 31333965Sjdp { 31433965Sjdp memset (signal_names, 0, nbytes); 31533965Sjdp for (eip = signal_table; eip -> name != NULL; eip++) 31633965Sjdp { 31733965Sjdp signal_names[eip -> value] = eip -> name; 31833965Sjdp } 31933965Sjdp } 32033965Sjdp } 32133965Sjdp 32260484Sobrien#ifndef HAVE_SYS_SIGLIST 32333965Sjdp 32433965Sjdp /* Now attempt to allocate the sys_siglist table, zero it out, and then 32533965Sjdp initialize it from the statically initialized signal_table. */ 32633965Sjdp 32733965Sjdp if (sys_siglist == NULL) 32833965Sjdp { 32933965Sjdp nbytes = num_signal_names * sizeof (char *); 33033965Sjdp if ((sys_siglist = (const char **) malloc (nbytes)) != NULL) 33133965Sjdp { 33233965Sjdp memset (sys_siglist, 0, nbytes); 33333965Sjdp sys_nsig = num_signal_names; 33433965Sjdp for (eip = signal_table; eip -> name != NULL; eip++) 33533965Sjdp { 33633965Sjdp sys_siglist[eip -> value] = eip -> msg; 33733965Sjdp } 33833965Sjdp } 33933965Sjdp } 34033965Sjdp 34133965Sjdp#endif 34233965Sjdp 34333965Sjdp} 34433965Sjdp 34533965Sjdp 34633965Sjdp/* 34733965Sjdp 34889857Sobrien@deftypefn Extension int signo_max (void) 34933965Sjdp 35089857SobrienReturns the maximum signal value for which a corresponding symbolic 35189857Sobrienname or message is available. Note that in the case where we use the 35289857Sobrien@code{sys_siglist} supplied by the system, it is possible for there to 35389857Sobrienbe more symbolic names than messages, or vice versa. In fact, the 35489857Sobrienmanual page for @code{psignal(3b)} explicitly warns that one should 35589857Sobriencheck the size of the table (@code{NSIG}) before indexing it, since 35689857Sobriennew signal codes may be added to the system before they are added to 35789857Sobrienthe table. Thus @code{NSIG} might be smaller than value implied by 35889857Sobrienthe largest signo value defined in @code{<signal.h>}. 35933965Sjdp 36089857SobrienWe return the maximum value that can be used to obtain a meaningful 36189857Sobriensymbolic name or message. 36233965Sjdp 36389857Sobrien@end deftypefn 36433965Sjdp 36533965Sjdp*/ 36633965Sjdp 36733965Sjdpint 368218822Sdimsigno_max (void) 36933965Sjdp{ 37033965Sjdp int maxsize; 37133965Sjdp 37233965Sjdp if (signal_names == NULL) 37333965Sjdp { 37433965Sjdp init_signal_tables (); 37533965Sjdp } 37633965Sjdp maxsize = MAX (sys_nsig, num_signal_names); 37733965Sjdp return (maxsize - 1); 37833965Sjdp} 37933965Sjdp 38033965Sjdp 38133965Sjdp/* 38233965Sjdp 38389857Sobrien@deftypefn Supplemental {const char *} strsignal (int @var{signo}) 38433965Sjdp 38589857SobrienMaps an signal number to an signal message string, the contents of 38689857Sobrienwhich are implementation defined. On systems which have the external 38789857Sobrienvariable @code{sys_siglist}, these strings will be the same as the 38889857Sobrienones used by @code{psignal()}. 38933965Sjdp 39089857SobrienIf the supplied signal number is within the valid range of indices for 39189857Sobrienthe @code{sys_siglist}, but no message is available for the particular 39289857Sobriensignal number, then returns the string @samp{Signal @var{num}}, where 39389857Sobrien@var{num} is the signal number. 39433965Sjdp 39589857SobrienIf the supplied signal number is not a valid index into 39689857Sobrien@code{sys_siglist}, returns @code{NULL}. 39733965Sjdp 39889857SobrienThe returned string is only guaranteed to be valid only until the next 39989857Sobriencall to @code{strsignal}. 40033965Sjdp 40189857Sobrien@end deftypefn 40233965Sjdp 40333965Sjdp*/ 40433965Sjdp 40560484Sobrien#ifndef HAVE_STRSIGNAL 40633965Sjdp 40733965Sjdpconst char * 408218822Sdimstrsignal (int signo) 40933965Sjdp{ 41033965Sjdp const char *msg; 41133965Sjdp static char buf[32]; 41233965Sjdp 41360484Sobrien#ifndef HAVE_SYS_SIGLIST 41433965Sjdp 41533965Sjdp if (signal_names == NULL) 41633965Sjdp { 41733965Sjdp init_signal_tables (); 41833965Sjdp } 41933965Sjdp 42033965Sjdp#endif 42133965Sjdp 42233965Sjdp if ((signo < 0) || (signo >= sys_nsig)) 42333965Sjdp { 42433965Sjdp /* Out of range, just return NULL */ 42533965Sjdp msg = NULL; 42633965Sjdp } 42733965Sjdp else if ((sys_siglist == NULL) || (sys_siglist[signo] == NULL)) 42833965Sjdp { 42933965Sjdp /* In range, but no sys_siglist or no entry at this index. */ 43033965Sjdp sprintf (buf, "Signal %d", signo); 43133965Sjdp msg = (const char *) buf; 43233965Sjdp } 43333965Sjdp else 43433965Sjdp { 43533965Sjdp /* In range, and a valid message. Just return the message. */ 43633965Sjdp msg = (const char *) sys_siglist[signo]; 43733965Sjdp } 43833965Sjdp 43933965Sjdp return (msg); 44033965Sjdp} 44133965Sjdp 44260484Sobrien#endif /* ! HAVE_STRSIGNAL */ 44333965Sjdp 44433965Sjdp/* 44533965Sjdp 44689857Sobrien@deftypefn Extension {const char*} strsigno (int @var{signo}) 44733965Sjdp 44889857SobrienGiven an signal number, returns a pointer to a string containing the 44989857Sobriensymbolic name of that signal number, as found in @code{<signal.h>}. 45033965Sjdp 45189857SobrienIf the supplied signal number is within the valid range of indices for 45289857Sobriensymbolic names, but no name is available for the particular signal 45389857Sobriennumber, then returns the string @samp{Signal @var{num}}, where 45489857Sobrien@var{num} is the signal number. 45533965Sjdp 45689857SobrienIf the supplied signal number is not within the range of valid 45789857Sobrienindices, then returns @code{NULL}. 45833965Sjdp 45989857SobrienThe contents of the location pointed to are only guaranteed to be 46089857Sobrienvalid until the next call to @code{strsigno}. 46133965Sjdp 46289857Sobrien@end deftypefn 46333965Sjdp 46433965Sjdp*/ 46533965Sjdp 46633965Sjdpconst char * 467218822Sdimstrsigno (int signo) 46833965Sjdp{ 46933965Sjdp const char *name; 47033965Sjdp static char buf[32]; 47133965Sjdp 47233965Sjdp if (signal_names == NULL) 47333965Sjdp { 47433965Sjdp init_signal_tables (); 47533965Sjdp } 47633965Sjdp 47733965Sjdp if ((signo < 0) || (signo >= num_signal_names)) 47833965Sjdp { 47933965Sjdp /* Out of range, just return NULL */ 48033965Sjdp name = NULL; 48133965Sjdp } 48233965Sjdp else if ((signal_names == NULL) || (signal_names[signo] == NULL)) 48333965Sjdp { 48433965Sjdp /* In range, but no signal_names or no entry at this index. */ 48533965Sjdp sprintf (buf, "Signal %d", signo); 48633965Sjdp name = (const char *) buf; 48733965Sjdp } 48833965Sjdp else 48933965Sjdp { 49033965Sjdp /* In range, and a valid name. Just return the name. */ 49133965Sjdp name = signal_names[signo]; 49233965Sjdp } 49333965Sjdp 49433965Sjdp return (name); 49533965Sjdp} 49633965Sjdp 49733965Sjdp 49833965Sjdp/* 49933965Sjdp 50089857Sobrien@deftypefn Extension int strtosigno (const char *@var{name}) 50133965Sjdp 50289857SobrienGiven the symbolic name of a signal, map it to a signal number. If no 50389857Sobrientranslation is found, returns 0. 50433965Sjdp 50589857Sobrien@end deftypefn 50633965Sjdp 50733965Sjdp*/ 50833965Sjdp 50933965Sjdpint 510218822Sdimstrtosigno (const char *name) 51133965Sjdp{ 51233965Sjdp int signo = 0; 51333965Sjdp 51433965Sjdp if (name != NULL) 51533965Sjdp { 51633965Sjdp if (signal_names == NULL) 51733965Sjdp { 51833965Sjdp init_signal_tables (); 51933965Sjdp } 52033965Sjdp for (signo = 0; signo < num_signal_names; signo++) 52133965Sjdp { 52233965Sjdp if ((signal_names[signo] != NULL) && 52333965Sjdp (strcmp (name, signal_names[signo]) == 0)) 52433965Sjdp { 52533965Sjdp break; 52633965Sjdp } 52733965Sjdp } 52833965Sjdp if (signo == num_signal_names) 52933965Sjdp { 53033965Sjdp signo = 0; 53133965Sjdp } 53233965Sjdp } 53333965Sjdp return (signo); 53433965Sjdp} 53533965Sjdp 53633965Sjdp 53733965Sjdp/* 53833965Sjdp 539218822Sdim@deftypefn Supplemental void psignal (int @var{signo}, char *@var{message}) 54033965Sjdp 54189857SobrienPrint @var{message} to the standard error, followed by a colon, 54289857Sobrienfollowed by the description of the signal specified by @var{signo}, 54389857Sobrienfollowed by a newline. 54433965Sjdp 54589857Sobrien@end deftypefn 54633965Sjdp 54733965Sjdp*/ 54833965Sjdp 54960484Sobrien#ifndef HAVE_PSIGNAL 55033965Sjdp 55133965Sjdpvoid 552218822Sdimpsignal (int signo, char *message) 55333965Sjdp{ 55433965Sjdp if (signal_names == NULL) 55533965Sjdp { 55633965Sjdp init_signal_tables (); 55733965Sjdp } 55833965Sjdp if ((signo <= 0) || (signo >= sys_nsig)) 55933965Sjdp { 56033965Sjdp fprintf (stderr, "%s: unknown signal\n", message); 56133965Sjdp } 56233965Sjdp else 56333965Sjdp { 56433965Sjdp fprintf (stderr, "%s: %s\n", message, sys_siglist[signo]); 56533965Sjdp } 56633965Sjdp} 56733965Sjdp 56860484Sobrien#endif /* ! HAVE_PSIGNAL */ 56933965Sjdp 57033965Sjdp 57133965Sjdp/* A simple little main that does nothing but print all the signal translations 57233965Sjdp if MAIN is defined and this file is compiled and linked. */ 57333965Sjdp 57433965Sjdp#ifdef MAIN 57533965Sjdp 57633965Sjdp#include <stdio.h> 57733965Sjdp 57833965Sjdpint 579218822Sdimmain (void) 58033965Sjdp{ 58133965Sjdp int signo; 58233965Sjdp int maxsigno; 58333965Sjdp const char *name; 58433965Sjdp const char *msg; 58533965Sjdp 58633965Sjdp maxsigno = signo_max (); 58733965Sjdp printf ("%d entries in names table.\n", num_signal_names); 58833965Sjdp printf ("%d entries in messages table.\n", sys_nsig); 58933965Sjdp printf ("%d is max useful index.\n", maxsigno); 59033965Sjdp 59133965Sjdp /* Keep printing values until we get to the end of *both* tables, not 59233965Sjdp *either* table. Note that knowing the maximum useful index does *not* 59333965Sjdp relieve us of the responsibility of testing the return pointer for 59433965Sjdp NULL. */ 59533965Sjdp 59633965Sjdp for (signo = 0; signo <= maxsigno; signo++) 59733965Sjdp { 59833965Sjdp name = strsigno (signo); 59933965Sjdp name = (name == NULL) ? "<NULL>" : name; 60033965Sjdp msg = strsignal (signo); 60133965Sjdp msg = (msg == NULL) ? "<NULL>" : msg; 60233965Sjdp printf ("%-4d%-18s%s\n", signo, name, msg); 60333965Sjdp } 60433965Sjdp 60533965Sjdp return 0; 60633965Sjdp} 60733965Sjdp 60833965Sjdp#endif 609