diff options
-rw-r--r-- | signame.c | 268 |
1 files changed, 268 insertions, 0 deletions
diff --git a/signame.c b/signame.c new file mode 100644 index 0000000..72435c6 --- /dev/null +++ b/signame.c @@ -0,0 +1,268 @@ +/* Convert between signal names and numbers. + Copyright (C) 1990, 1992, 1993 Free Software Foundation, Inc. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include <stdio.h> +#include <sys/types.h> /* Some systems need this for <signal.h>. */ +#include <signal.h> + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* Some systems do not define NSIG in <signal.h>. */ +#ifndef NSIG +#ifdef _NSIG +#define NSIG _NSIG +#else +#define NSIG 32 +#endif +#endif + +#if !__STDC__ +#define const +#endif + +#include "signame.h" + +#ifndef HAVE_SYS_SIGLIST +/* There is too much variation in Sys V signal numbers and names, so + we must initialize them at runtime. */ + +static const char undoc[] = "unknown signal"; + +const char *sys_siglist[NSIG]; +#endif /* !HAVE_SYS_SIGLIST */ + +/* Table of abbreviations for signals. Note: A given number can + appear more than once with different abbreviations. */ +typedef struct + { + int number; + const char *abbrev; + } num_abbrev; +static num_abbrev sig_table[NSIG*2]; +/* Number of elements of sig_table used. */ +static int sig_table_nelts = 0; + +/* Enter signal number NUMBER into the tables with ABBREV and NAME. */ + +static void +init_sig (number, abbrev, name) + int number; + const char *abbrev; + const char *name; +{ +#ifndef HAVE_SYS_SIGLIST + sys_siglist[number] = name; +#endif + sig_table[sig_table_nelts].number = number; + sig_table[sig_table_nelts++].abbrev = abbrev; +} + +void +signame_init () +{ +#ifndef HAVE_SYS_SIGLIST + int i; + /* Initialize signal names. */ + for (i = 0; i < NSIG; i++) + sys_siglist[i] = undoc; +#endif /* !HAVE_SYS_SIGLIST */ + + /* Initialize signal names. */ +#if defined (SIGHUP) + init_sig (SIGHUP, "HUP", "Hangup"); +#endif +#if defined (SIGINT) + init_sig (SIGINT, "INT", "Interrupt"); +#endif +#if defined (SIGQUIT) + init_sig (SIGQUIT, "QUIT", "Quit"); +#endif +#if defined (SIGILL) + init_sig (SIGILL, "ILL", "Illegal Instruction"); +#endif +#if defined (SIGTRAP) + init_sig (SIGTRAP, "TRAP", "Trace/breakpoint trap"); +#endif + /* If SIGIOT == SIGABRT, we want to print it as SIGABRT because + SIGABRT is in ANSI and POSIX.1 and SIGIOT isn't. */ +#if defined (SIGABRT) + init_sig (SIGABRT, "ABRT", "Aborted"); +#endif +#if defined (SIGIOT) + init_sig (SIGIOT, "IOT", "IOT trap"); +#endif +#if defined (SIGEMT) + init_sig (SIGEMT, "EMT", "EMT trap"); +#endif +#if defined (SIGFPE) + init_sig (SIGFPE, "FPE", "Floating point exception"); +#endif +#if defined (SIGKILL) + init_sig (SIGKILL, "KILL", "Killed"); +#endif +#if defined (SIGBUS) + init_sig (SIGBUS, "BUS", "Bus error"); +#endif +#if defined (SIGSEGV) + init_sig (SIGSEGV, "SEGV", "Segmentation fault"); +#endif +#if defined (SIGSYS) + init_sig (SIGSYS, "SYS", "Bad system call"); +#endif +#if defined (SIGPIPE) + init_sig (SIGPIPE, "PIPE", "Broken pipe"); +#endif +#if defined (SIGALRM) + init_sig (SIGALRM, "ALRM", "Alarm clock"); +#endif +#if defined (SIGTERM) + init_sig (SIGTERM, "TERM", "Terminated"); +#endif +#if defined (SIGUSR1) + init_sig (SIGUSR1, "USR1", "User defined signal 1"); +#endif +#if defined (SIGUSR2) + init_sig (SIGUSR2, "USR2", "User defined signal 2"); +#endif + /* If SIGCLD == SIGCHLD, we want to print it as SIGCHLD because that + is what is in POSIX.1. */ +#if defined (SIGCHLD) + init_sig (SIGCHLD, "CHLD", "Child exited"); +#endif +#if defined (SIGCLD) + init_sig (SIGCLD, "CLD", "Child exited"); +#endif +#if defined (SIGPWR) + init_sig (SIGPWR, "PWR", "Power failure"); +#endif +#if defined (SIGTSTP) + init_sig (SIGTSTP, "TSTP", "Stopped"); +#endif +#if defined (SIGTTIN) + init_sig (SIGTTIN, "TTIN", "Stopped (tty input)"); +#endif +#if defined (SIGTTOU) + init_sig (SIGTTOU, "TTOU", "Stopped (tty output)"); +#endif +#if defined (SIGSTOP) + init_sig (SIGSTOP, "STOP", "Stopped (signal)"); +#endif +#if defined (SIGXCPU) + init_sig (SIGXCPU, "XCPU", "CPU time limit exceeded"); +#endif +#if defined (SIGXFSZ) + init_sig (SIGXFSZ, "XFSZ", "File size limit exceeded"); +#endif +#if defined (SIGVTALRM) + init_sig (SIGVTALRM, "VTALRM", "Virtual timer expired"); +#endif +#if defined (SIGPROF) + init_sig (SIGPROF, "PROF", "Profiling timer expired"); +#endif +#if defined (SIGWINCH) + /* "Window size changed" might be more accurate, but even if that + is all that it means now, perhaps in the future it will be + extended to cover other kinds of window changes. */ + init_sig (SIGWINCH, "WINCH", "Window changed"); +#endif +#if defined (SIGCONT) + init_sig (SIGCONT, "CONT", "Continued"); +#endif +#if defined (SIGURG) + init_sig (SIGURG, "URG", "Urgent I/O condition"); +#endif +#if defined (SIGIO) + /* "I/O pending" has also been suggested. A disadvantage is + that signal only happens when the process has + asked for it, not everytime I/O is pending. Another disadvantage + is the confusion from giving it a different name than under Unix. */ + init_sig (SIGIO, "IO", "I/O possible"); +#endif +#if defined (SIGWIND) + init_sig (SIGWIND, "WIND", "SIGWIND"); +#endif +#if defined (SIGPHONE) + init_sig (SIGPHONE, "PHONE", "SIGPHONE"); +#endif +#if defined (SIGPOLL) + init_sig (SIGPOLL, "POLL", "I/O possible"); +#endif +#if defined (SIGLOST) + init_sig (SIGLOST, "LOST", "Resource lost"); +#endif +#if defined (SIGDANGER) + init_sig (SIGDANGER, "DANGER", "Danger signal"); +#endif +} + +/* Return the abbreviation for signal NUMBER. */ + +char * +sig_abbrev (number) + int number; +{ + int i; + + if (sig_table_nelts == 0) + signame_init (); + + for (i = 0; i < sig_table_nelts; i++) + if (sig_table[i].number == number) + return (char *)sig_table[i].abbrev; + return NULL; +} + +/* Return the signal number for an ABBREV, or -1 if there is no + signal by that name. */ + +int +sig_number (abbrev) + const char *abbrev; +{ + int i; + + if (sig_table_nelts == 0) + signame_init (); + + /* Skip over "SIG" if present. */ + if (abbrev[0] == 'S' && abbrev[1] == 'I' && abbrev[2] == 'G') + abbrev += 3; + + for (i = 0; i < sig_table_nelts; i++) + if (abbrev[0] == sig_table[i].abbrev[0] + && strcmp (abbrev, sig_table[i].abbrev) == 0) + return sig_table[i].number; + return -1; +} + +#ifndef HAVE_PSIGNAL +/* Print to standard error the name of SIGNAL, preceded by MESSAGE and + a colon, and followed by a newline. */ + +void +psignal (signal, message) + int signal; + const char *message; +{ + if (signal <= 0 || signal >= NSIG) + fprintf (stderr, "%s: unknown signal", message); + else + fprintf (stderr, "%s: %s\n", message, sys_siglist[signal]); +} +#endif |