strsignal.c revision 33965
133965Sjdp/* Extended support for using signal values. 233965Sjdp Written by Fred Fish. fnf@cygnus.com 333965Sjdp This file is in the public domain. */ 433965Sjdp 533965Sjdp#include "ansidecl.h" 633965Sjdp#include "libiberty.h" 733965Sjdp 833965Sjdp#include "config.h" 933965Sjdp 1033965Sjdp/* We need to declare sys_siglist, because even if the system provides 1133965Sjdp it we can't assume that it is declared in <signal.h> (for example, 1233965Sjdp SunOS provides sys_siglist, but it does not declare it in any 1333965Sjdp header file). fHowever, we can't declare sys_siglist portably, 1433965Sjdp because on some systems it is declared with const and on some 1533965Sjdp systems it is declared without const. If we were using autoconf, 1633965Sjdp we could work out the right declaration. Until, then we just 1733965Sjdp ignore any declaration in the system header files, and always 1833965Sjdp declare it ourselves. With luck, this will always work. */ 1933965Sjdp#define sys_siglist no_such_symbol 2033965Sjdp 2133965Sjdp#include <stdio.h> 2233965Sjdp#include <signal.h> 2333965Sjdp 2433965Sjdp/* Routines imported from standard C runtime libraries. */ 2533965Sjdp 2633965Sjdp#ifdef __STDC__ 2733965Sjdp#include <stddef.h> 2833965Sjdpextern void *malloc (size_t size); /* 4.10.3.3 */ 2933965Sjdpextern void *memset (void *s, int c, size_t n); /* 4.11.6.1 */ 3033965Sjdp#else /* !__STDC__ */ 3133965Sjdpextern char *malloc (); /* Standard memory allocater */ 3233965Sjdpextern char *memset (); 3333965Sjdp#endif /* __STDC__ */ 3433965Sjdp 3533965Sjdp/* Undefine the macro we used to hide the definition of sys_siglist 3633965Sjdp found in the system header files. */ 3733965Sjdp#undef sys_siglist 3833965Sjdp 3933965Sjdp#ifndef NULL 4033965Sjdp# ifdef __STDC__ 4133965Sjdp# define NULL (void *) 0 4233965Sjdp# else 4333965Sjdp# define NULL 0 4433965Sjdp# endif 4533965Sjdp#endif 4633965Sjdp 4733965Sjdp#ifndef MAX 4833965Sjdp# define MAX(a,b) ((a) > (b) ? (a) : (b)) 4933965Sjdp#endif 5033965Sjdp 5133965Sjdpstatic void init_signal_tables PARAMS ((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{ 6533965Sjdp int value; /* The numeric value from <signal.h> */ 6633965Sjdp const char *name; /* The equivalent symbolic value */ 6733965Sjdp#ifdef NEED_sys_siglist 6833965Sjdp const char *msg; /* Short message about this value */ 6933965Sjdp#endif 7033965Sjdp}; 7133965Sjdp 7233965Sjdp#ifdef NEED_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 23933965Sjdp#ifdef NEED_sys_siglist 24033965Sjdp 24133965Sjdpstatic int sys_nsig; 24233965Sjdpstatic const char **sys_siglist; 24333965Sjdp 24433965Sjdp#else 24533965Sjdp 24633965Sjdpstatic int sys_nsig = NSIG; 24733965Sjdpextern const char * const sys_siglist[]; 24833965Sjdp 24933965Sjdp#endif 25033965Sjdp 25133965Sjdp 25233965Sjdp/* 25333965Sjdp 25433965SjdpNAME 25533965Sjdp 25633965Sjdp init_signal_tables -- initialize the name and message tables 25733965Sjdp 25833965SjdpSYNOPSIS 25933965Sjdp 26033965Sjdp static void init_signal_tables (); 26133965Sjdp 26233965SjdpDESCRIPTION 26333965Sjdp 26433965Sjdp Using the signal_table, which is initialized at compile time, generate 26533965Sjdp the signal_names and the sys_siglist (if needed) tables, which are 26633965Sjdp indexed at runtime by a specific signal value. 26733965Sjdp 26833965SjdpBUGS 26933965Sjdp 27033965Sjdp The initialization of the tables may fail under low memory conditions, 27133965Sjdp in which case we don't do anything particularly useful, but we don't 27233965Sjdp bomb either. Who knows, it might succeed at a later point if we free 27333965Sjdp some memory in the meantime. In any case, the other routines know 27433965Sjdp how to deal with lack of a table after trying to initialize it. This 27533965Sjdp may or may not be considered to be a bug, that we don't specifically 27633965Sjdp warn about this particular failure mode. 27733965Sjdp 27833965Sjdp*/ 27933965Sjdp 28033965Sjdpstatic void 28133965Sjdpinit_signal_tables () 28233965Sjdp{ 28333965Sjdp const struct signal_info *eip; 28433965Sjdp int nbytes; 28533965Sjdp 28633965Sjdp /* If we haven't already scanned the signal_table once to find the maximum 28733965Sjdp signal value, then go find it now. */ 28833965Sjdp 28933965Sjdp if (num_signal_names == 0) 29033965Sjdp { 29133965Sjdp for (eip = signal_table; eip -> name != NULL; eip++) 29233965Sjdp { 29333965Sjdp if (eip -> value >= num_signal_names) 29433965Sjdp { 29533965Sjdp num_signal_names = eip -> value + 1; 29633965Sjdp } 29733965Sjdp } 29833965Sjdp } 29933965Sjdp 30033965Sjdp /* Now attempt to allocate the signal_names table, zero it out, and then 30133965Sjdp initialize it from the statically initialized signal_table. */ 30233965Sjdp 30333965Sjdp if (signal_names == NULL) 30433965Sjdp { 30533965Sjdp nbytes = num_signal_names * sizeof (char *); 30633965Sjdp if ((signal_names = (const char **) malloc (nbytes)) != NULL) 30733965Sjdp { 30833965Sjdp memset (signal_names, 0, nbytes); 30933965Sjdp for (eip = signal_table; eip -> name != NULL; eip++) 31033965Sjdp { 31133965Sjdp signal_names[eip -> value] = eip -> name; 31233965Sjdp } 31333965Sjdp } 31433965Sjdp } 31533965Sjdp 31633965Sjdp#ifdef NEED_sys_siglist 31733965Sjdp 31833965Sjdp /* Now attempt to allocate the sys_siglist table, zero it out, and then 31933965Sjdp initialize it from the statically initialized signal_table. */ 32033965Sjdp 32133965Sjdp if (sys_siglist == NULL) 32233965Sjdp { 32333965Sjdp nbytes = num_signal_names * sizeof (char *); 32433965Sjdp if ((sys_siglist = (const char **) malloc (nbytes)) != NULL) 32533965Sjdp { 32633965Sjdp memset (sys_siglist, 0, nbytes); 32733965Sjdp sys_nsig = num_signal_names; 32833965Sjdp for (eip = signal_table; eip -> name != NULL; eip++) 32933965Sjdp { 33033965Sjdp sys_siglist[eip -> value] = eip -> msg; 33133965Sjdp } 33233965Sjdp } 33333965Sjdp } 33433965Sjdp 33533965Sjdp#endif 33633965Sjdp 33733965Sjdp} 33833965Sjdp 33933965Sjdp 34033965Sjdp/* 34133965Sjdp 34233965SjdpNAME 34333965Sjdp 34433965Sjdp signo_max -- return the max signo value 34533965Sjdp 34633965SjdpSYNOPSIS 34733965Sjdp 34833965Sjdp int signo_max (); 34933965Sjdp 35033965SjdpDESCRIPTION 35133965Sjdp 35233965Sjdp Returns the maximum signo value for which a corresponding symbolic 35333965Sjdp name or message is available. Note that in the case where 35433965Sjdp we use the sys_siglist supplied by the system, it is possible for 35533965Sjdp there to be more symbolic names than messages, or vice versa. 35633965Sjdp In fact, the manual page for psignal(3b) explicitly warns that one 35733965Sjdp should check the size of the table (NSIG) before indexing it, 35833965Sjdp since new signal codes may be added to the system before they are 35933965Sjdp added to the table. Thus NSIG might be smaller than value 36033965Sjdp implied by the largest signo value defined in <signal.h>. 36133965Sjdp 36233965Sjdp We return the maximum value that can be used to obtain a meaningful 36333965Sjdp symbolic name or message. 36433965Sjdp 36533965Sjdp*/ 36633965Sjdp 36733965Sjdpint 36833965Sjdpsigno_max () 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 38333965SjdpNAME 38433965Sjdp 38533965Sjdp strsignal -- map a signal number to a signal message string 38633965Sjdp 38733965SjdpSYNOPSIS 38833965Sjdp 38933965Sjdp const char *strsignal (int signo) 39033965Sjdp 39133965SjdpDESCRIPTION 39233965Sjdp 39333965Sjdp Maps an signal number to an signal message string, the contents of 39433965Sjdp which are implementation defined. On systems which have the external 39533965Sjdp variable sys_siglist, these strings will be the same as the ones used 39633965Sjdp by psignal(). 39733965Sjdp 39833965Sjdp If the supplied signal number is within the valid range of indices 39933965Sjdp for the sys_siglist, but no message is available for the particular 40033965Sjdp signal number, then returns the string "Signal NUM", where NUM is the 40133965Sjdp signal number. 40233965Sjdp 40333965Sjdp If the supplied signal number is not a valid index into sys_siglist, 40433965Sjdp returns NULL. 40533965Sjdp 40633965Sjdp The returned string is only guaranteed to be valid only until the 40733965Sjdp next call to strsignal. 40833965Sjdp 40933965Sjdp*/ 41033965Sjdp 41133965Sjdp#ifdef NEED_strsignal 41233965Sjdp 41333965Sjdpconst char * 41433965Sjdpstrsignal (signo) 41533965Sjdp int signo; 41633965Sjdp{ 41733965Sjdp const char *msg; 41833965Sjdp static char buf[32]; 41933965Sjdp 42033965Sjdp#ifdef NEED_sys_siglist 42133965Sjdp 42233965Sjdp if (signal_names == NULL) 42333965Sjdp { 42433965Sjdp init_signal_tables (); 42533965Sjdp } 42633965Sjdp 42733965Sjdp#endif 42833965Sjdp 42933965Sjdp if ((signo < 0) || (signo >= sys_nsig)) 43033965Sjdp { 43133965Sjdp /* Out of range, just return NULL */ 43233965Sjdp msg = NULL; 43333965Sjdp } 43433965Sjdp else if ((sys_siglist == NULL) || (sys_siglist[signo] == NULL)) 43533965Sjdp { 43633965Sjdp /* In range, but no sys_siglist or no entry at this index. */ 43733965Sjdp sprintf (buf, "Signal %d", signo); 43833965Sjdp msg = (const char *) buf; 43933965Sjdp } 44033965Sjdp else 44133965Sjdp { 44233965Sjdp /* In range, and a valid message. Just return the message. */ 44333965Sjdp msg = (const char *) sys_siglist[signo]; 44433965Sjdp } 44533965Sjdp 44633965Sjdp return (msg); 44733965Sjdp} 44833965Sjdp 44933965Sjdp#endif /* NEED_strsignal */ 45033965Sjdp 45133965Sjdp/* 45233965Sjdp 45333965SjdpNAME 45433965Sjdp 45533965Sjdp strsigno -- map an signal number to a symbolic name string 45633965Sjdp 45733965SjdpSYNOPSIS 45833965Sjdp 45933965Sjdp const char *strsigno (int signo) 46033965Sjdp 46133965SjdpDESCRIPTION 46233965Sjdp 46333965Sjdp Given an signal number, returns a pointer to a string containing 46433965Sjdp the symbolic name of that signal number, as found in <signal.h>. 46533965Sjdp 46633965Sjdp If the supplied signal number is within the valid range of indices 46733965Sjdp for symbolic names, but no name is available for the particular 46833965Sjdp signal number, then returns the string "Signal NUM", where NUM is 46933965Sjdp the signal number. 47033965Sjdp 47133965Sjdp If the supplied signal number is not within the range of valid 47233965Sjdp indices, then returns NULL. 47333965Sjdp 47433965SjdpBUGS 47533965Sjdp 47633965Sjdp The contents of the location pointed to are only guaranteed to be 47733965Sjdp valid until the next call to strsigno. 47833965Sjdp 47933965Sjdp*/ 48033965Sjdp 48133965Sjdpconst char * 48233965Sjdpstrsigno (signo) 48333965Sjdp int signo; 48433965Sjdp{ 48533965Sjdp const char *name; 48633965Sjdp static char buf[32]; 48733965Sjdp 48833965Sjdp if (signal_names == NULL) 48933965Sjdp { 49033965Sjdp init_signal_tables (); 49133965Sjdp } 49233965Sjdp 49333965Sjdp if ((signo < 0) || (signo >= num_signal_names)) 49433965Sjdp { 49533965Sjdp /* Out of range, just return NULL */ 49633965Sjdp name = NULL; 49733965Sjdp } 49833965Sjdp else if ((signal_names == NULL) || (signal_names[signo] == NULL)) 49933965Sjdp { 50033965Sjdp /* In range, but no signal_names or no entry at this index. */ 50133965Sjdp sprintf (buf, "Signal %d", signo); 50233965Sjdp name = (const char *) buf; 50333965Sjdp } 50433965Sjdp else 50533965Sjdp { 50633965Sjdp /* In range, and a valid name. Just return the name. */ 50733965Sjdp name = signal_names[signo]; 50833965Sjdp } 50933965Sjdp 51033965Sjdp return (name); 51133965Sjdp} 51233965Sjdp 51333965Sjdp 51433965Sjdp/* 51533965Sjdp 51633965SjdpNAME 51733965Sjdp 51833965Sjdp strtosigno -- map a symbolic signal name to a numeric value 51933965Sjdp 52033965SjdpSYNOPSIS 52133965Sjdp 52233965Sjdp int strtosigno (char *name) 52333965Sjdp 52433965SjdpDESCRIPTION 52533965Sjdp 52633965Sjdp Given the symbolic name of a signal, map it to a signal number. 52733965Sjdp If no translation is found, returns 0. 52833965Sjdp 52933965Sjdp*/ 53033965Sjdp 53133965Sjdpint 53233965Sjdpstrtosigno (name) 53333965Sjdp const char *name; 53433965Sjdp{ 53533965Sjdp int signo = 0; 53633965Sjdp 53733965Sjdp if (name != NULL) 53833965Sjdp { 53933965Sjdp if (signal_names == NULL) 54033965Sjdp { 54133965Sjdp init_signal_tables (); 54233965Sjdp } 54333965Sjdp for (signo = 0; signo < num_signal_names; signo++) 54433965Sjdp { 54533965Sjdp if ((signal_names[signo] != NULL) && 54633965Sjdp (strcmp (name, signal_names[signo]) == 0)) 54733965Sjdp { 54833965Sjdp break; 54933965Sjdp } 55033965Sjdp } 55133965Sjdp if (signo == num_signal_names) 55233965Sjdp { 55333965Sjdp signo = 0; 55433965Sjdp } 55533965Sjdp } 55633965Sjdp return (signo); 55733965Sjdp} 55833965Sjdp 55933965Sjdp 56033965Sjdp/* 56133965Sjdp 56233965SjdpNAME 56333965Sjdp 56433965Sjdp psignal -- print message about signal to stderr 56533965Sjdp 56633965SjdpSYNOPSIS 56733965Sjdp 56833965Sjdp void psignal (unsigned signo, char *message); 56933965Sjdp 57033965SjdpDESCRIPTION 57133965Sjdp 57233965Sjdp Print to the standard error the message, followed by a colon, 57333965Sjdp followed by the description of the signal specified by signo, 57433965Sjdp followed by a newline. 57533965Sjdp*/ 57633965Sjdp 57733965Sjdp#ifdef NEED_psignal 57833965Sjdp 57933965Sjdpvoid 58033965Sjdppsignal (signo, message) 58133965Sjdp unsigned signo; 58233965Sjdp char *message; 58333965Sjdp{ 58433965Sjdp if (signal_names == NULL) 58533965Sjdp { 58633965Sjdp init_signal_tables (); 58733965Sjdp } 58833965Sjdp if ((signo <= 0) || (signo >= sys_nsig)) 58933965Sjdp { 59033965Sjdp fprintf (stderr, "%s: unknown signal\n", message); 59133965Sjdp } 59233965Sjdp else 59333965Sjdp { 59433965Sjdp fprintf (stderr, "%s: %s\n", message, sys_siglist[signo]); 59533965Sjdp } 59633965Sjdp} 59733965Sjdp 59833965Sjdp#endif /* NEED_psignal */ 59933965Sjdp 60033965Sjdp 60133965Sjdp/* A simple little main that does nothing but print all the signal translations 60233965Sjdp if MAIN is defined and this file is compiled and linked. */ 60333965Sjdp 60433965Sjdp#ifdef MAIN 60533965Sjdp 60633965Sjdp#include <stdio.h> 60733965Sjdp 60833965Sjdpint 60933965Sjdpmain () 61033965Sjdp{ 61133965Sjdp int signo; 61233965Sjdp int maxsigno; 61333965Sjdp const char *name; 61433965Sjdp const char *msg; 61533965Sjdp 61633965Sjdp maxsigno = signo_max (); 61733965Sjdp printf ("%d entries in names table.\n", num_signal_names); 61833965Sjdp printf ("%d entries in messages table.\n", sys_nsig); 61933965Sjdp printf ("%d is max useful index.\n", maxsigno); 62033965Sjdp 62133965Sjdp /* Keep printing values until we get to the end of *both* tables, not 62233965Sjdp *either* table. Note that knowing the maximum useful index does *not* 62333965Sjdp relieve us of the responsibility of testing the return pointer for 62433965Sjdp NULL. */ 62533965Sjdp 62633965Sjdp for (signo = 0; signo <= maxsigno; signo++) 62733965Sjdp { 62833965Sjdp name = strsigno (signo); 62933965Sjdp name = (name == NULL) ? "<NULL>" : name; 63033965Sjdp msg = strsignal (signo); 63133965Sjdp msg = (msg == NULL) ? "<NULL>" : msg; 63233965Sjdp printf ("%-4d%-18s%s\n", signo, name, msg); 63333965Sjdp } 63433965Sjdp 63533965Sjdp return 0; 63633965Sjdp} 63733965Sjdp 63833965Sjdp#endif 639