summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>2002-04-28 21:17:45 +0000
committerJim Meyering <jim@meyering.net>2002-04-28 21:17:45 +0000
commitb41ca51fc6bff00f11ab42a5d518fe2ebb558f45 (patch)
tree6103b63a22667d9ea4082bb2d7485a5eae9278e2 /lib
parent8e6c9373c16bd2f68b08fea01e2f2c8a45e867f9 (diff)
downloadcoreutils-b41ca51fc6bff00f11ab42a5d518fe2ebb558f45.tar.xz
New file: from Paul Eggert.
Diffstat (limited to 'lib')
-rw-r--r--lib/sig2str.c353
-rw-r--r--lib/sig2str.h49
2 files changed, 402 insertions, 0 deletions
diff --git a/lib/sig2str.c b/lib/sig2str.c
new file mode 100644
index 000000000..1edc9f119
--- /dev/null
+++ b/lib/sig2str.c
@@ -0,0 +1,353 @@
+/* sig2str.c -- convert between signal names and numbers
+
+ Copyright (C) 2002 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; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by Paul Eggert. */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <limits.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#if HAVE_SYS_WAIT_H
+# include <sys/wait.h>
+#endif
+#ifndef WTERMSIG
+# define WTERMSIG(s) ((s) & 0x7F)
+#endif
+
+#include "sig2str.h"
+
+#ifndef SIGRTMIN
+# define SIGRTMIN 0
+# undef SIGRTMAX
+#endif
+#ifndef SIGRTMAX
+# define SIGRTMAX (SIGRTMIN - 1)
+#endif
+
+#define NUMNAME(name) { SIG##name, #name }
+
+/* Signal names and numbers. Put the preferred name first. */
+static struct numname { int num; char const name[8]; } numname_table[] =
+ {
+ /* Signals required by POSIX 1003.1-2001 base, listed in
+ traditional numeric order. */
+#ifdef SIGHUP
+ NUMNAME (HUP),
+#endif
+#ifdef SIGINT
+ NUMNAME (INT),
+#endif
+#ifdef SIGQUIT
+ NUMNAME (QUIT),
+#endif
+#ifdef SIGILL
+ NUMNAME (ILL),
+#endif
+#ifdef SIGTRAP
+ NUMNAME (TRAP),
+#endif
+#ifdef SIGABRT
+ NUMNAME (ABRT),
+#endif
+#ifdef SIGFPE
+ NUMNAME (FPE),
+#endif
+#ifdef SIGKILL
+ NUMNAME (KILL),
+#endif
+#ifdef SIGBUS
+ NUMNAME (BUS),
+#endif
+#ifdef SIGSEGV
+ NUMNAME (SEGV),
+#endif
+#ifdef SIGPIPE
+ NUMNAME (PIPE),
+#endif
+#ifdef SIGALRM
+ NUMNAME (ALRM),
+#endif
+#ifdef SIGTERM
+ NUMNAME (TERM),
+#endif
+#ifdef SIGUSR1
+ NUMNAME (USR1),
+#endif
+#ifdef SIGUSR2
+ NUMNAME (USR2),
+#endif
+#ifdef SIGCHLD
+ NUMNAME (CHLD),
+#endif
+#ifdef SIGURG
+ NUMNAME (URG),
+#endif
+#ifdef SIGSTOP
+ NUMNAME (STOP),
+#endif
+#ifdef SIGTSTP
+ NUMNAME (TSTP),
+#endif
+#ifdef SIGCONT
+ NUMNAME (CONT),
+#endif
+#ifdef SIGTTIN
+ NUMNAME (TTIN),
+#endif
+#ifdef SIGTTOU
+ NUMNAME (TTOU),
+#endif
+
+ /* Signals required by POSIX 1003.1-2001 with the XSI extension. */
+#ifdef SIGSYS
+ NUMNAME (SYS),
+#endif
+#ifdef SIGPOLL
+ NUMNAME (POLL),
+#endif
+#ifdef SIGVTALRM
+ NUMNAME (VTALRM),
+#endif
+#ifdef SIGPROF
+ NUMNAME (PROF),
+#endif
+#ifdef SIGXCPU
+ NUMNAME (XCPU),
+#endif
+#ifdef SIGXFSZ
+ NUMNAME (XFSZ),
+#endif
+
+ /* Unix Version 7. */
+#ifdef SIGIOT
+ NUMNAME (IOT), /* Older name for ABRT. */
+#endif
+#ifdef SIGEMT
+ NUMNAME (EMT),
+#endif
+
+ /* USG Unix. */
+#ifdef SIGPHONE
+ NUMNAME (PHONE),
+#endif
+#ifdef SIGWIND
+ NUMNAME (WIND),
+#endif
+
+ /* Unix System V. */
+#ifdef SIGCLD
+ NUMNAME (CLD),
+#endif
+#ifdef SIGPWR
+ NUMNAME (PWR),
+#endif
+
+ /* GNU/Linux 2.2 and Solaris 8. */
+#ifdef SIGCANCEL
+ NUMNAME (CANCEL),
+#endif
+#ifdef SIGLWP
+ NUMNAME (LWP),
+#endif
+#ifdef SIGWAITING
+ NUMNAME (WAITING),
+#endif
+#ifdef SIGFREEZE
+ NUMNAME (FREEZE),
+#endif
+#ifdef SIGTHAW
+ NUMNAME (THAW),
+#endif
+#ifdef SIGLOST
+ NUMNAME (LOST),
+#endif
+#ifdef SIGWINCH
+ NUMNAME (WINCH),
+#endif
+
+ /* GNU/Linux 2.2. */
+#ifdef SIGINFO
+ NUMNAME (INFO),
+#endif
+#ifdef SIGIO
+ NUMNAME (IO),
+#endif
+#ifdef SIGSTKFLT
+ NUMNAME (STKFLT),
+#endif
+
+ /* AIX 5L. */
+#ifdef SIGDANGER
+ NUMNAME (DANGER),
+#endif
+#ifdef SIGGRANT
+ NUMNAME (GRANT),
+#endif
+#ifdef SIGMIGRATE
+ NUMNAME (MIGRATE),
+#endif
+#ifdef SIGMSG
+ NUMNAME (MSG),
+#endif
+#ifdef SIGPRE
+ NUMNAME (PRE),
+#endif
+#ifdef SIGRETRACT
+ NUMNAME (RETRACT),
+#endif
+#ifdef SIGSAK
+ NUMNAME (SAK),
+#endif
+#ifdef SIGSOUND
+ NUMNAME (SOUND),
+#endif
+
+ /* Older AIX versions. */
+#ifdef SIGALRM1
+ NUMNAME (ALRM1), /* unknown; taken from Bash 2.05 */
+#endif
+#ifdef SIGKAP
+ NUMNAME (KAP), /* Older name for SIGGRANT. */
+#endif
+#ifdef SIGVIRT
+ NUMNAME (VIRT), /* unknown; taken from Bash 2.05 */
+#endif
+#ifdef SIGWINDOW
+ NUMNAME (WINDOW), /* Older name for SIGWINCH. */
+#endif
+
+ /* BeOS */
+#ifdef SIGKILLTHR
+ NUMNAME (KILLTHR),
+#endif
+
+ /* Older HP-UX versions. */
+#ifdef SIGDIL
+ NUMNAME (DIL),
+#endif
+
+ /* Korn shell and Bash, of uncertain vintage. */
+ { 0, "EXIT" }
+ };
+
+#define NUMNAME_ENTRIES (sizeof numname_table / sizeof numname_table[0])
+
+/* ISDIGIT differs from isdigit, as follows:
+ - Its arg may be any int or unsigned int; it need not be an unsigned char.
+ - It's guaranteed to evaluate its argument exactly once.
+ - It's typically faster.
+ POSIX says that only '0' through '9' are digits. Prefer ISDIGIT to
+ ISDIGIT_LOCALE unless it's important to use the locale's definition
+ of `digit' even when the host does not conform to POSIX. */
+#define ISDIGIT(c) ((unsigned) (c) - '0' <= 9)
+
+/* Convert the signal name SIGNAME to a signal number. Return the
+ signal number if successful, -1 otherwise. */
+
+static int
+str2signum (char const *signame)
+{
+ if (ISDIGIT (*signame))
+ {
+ char *endp;
+ long int n = strtol (signame, &endp, 10);
+ if (! *endp && n <= SIGNUM_BOUND)
+ return n;
+ }
+ else
+ {
+ int i;
+ for (i = 0; i < NUMNAME_ENTRIES; i++)
+ if (strcmp (numname_table[i].name, signame) == 0)
+ return numname_table[i].num;
+
+ {
+ char *endp;
+ int rtmin = SIGRTMIN;
+ int rtmax = SIGRTMAX;
+
+ if (0 < rtmin && strncmp (signame, "RTMIN", 5) == 0)
+ {
+ long int n = strtol (signame + 5, &endp, 10);
+ if (! *endp && 0 <= n && n <= rtmax - rtmin)
+ return rtmin + n;
+ }
+ else if (0 < rtmax && strncmp (signame, "RTMAX", 5) == 0)
+ {
+ long int n = strtol (signame + 5, &endp, 10);
+ if (! *endp && rtmin - rtmax <= n && n <= 0)
+ return rtmax + n;
+ }
+ }
+ }
+
+ return -1;
+}
+
+/* Convert the signal name SIGNAME to the signal number *SIGNUM.
+ Return 0 if successful, -1 otherwise. */
+
+int
+str2sig (char const *signame, int *signum)
+{
+ *signum = str2signum (signame);
+ return *signum < 0 ? -1 : 0;
+}
+
+/* Convert SIGNUM to a signal name in SIGNAME. SIGNAME must point to
+ a buffer of at least SIG2STR_MAX bytes. Return 0 if successful, -1
+ otherwise. */
+
+int
+sig2str (int signum, char *signame)
+{
+ int i;
+ for (i = 0; i < NUMNAME_ENTRIES; i++)
+ if (numname_table[i].num == signum)
+ {
+ strcpy (signame, numname_table[i].name);
+ return 0;
+ }
+
+ {
+ int rtmin = SIGRTMIN;
+ int rtmax = SIGRTMAX;
+
+ if (! (rtmin <= signum && signum <= rtmax))
+ return -1;
+
+ if (signum <= rtmin + (rtmax - rtmin) / 2)
+ {
+ int delta = signum - rtmin;
+ sprintf (signame, delta ? "RTMIN+%d" : "RTMIN", delta);
+ }
+ else
+ {
+ int delta = rtmax - signum;
+ sprintf (signame, delta ? "RTMAX-%d" : "RTMAX", delta);
+ }
+
+ return 0;
+ }
+}
diff --git a/lib/sig2str.h b/lib/sig2str.h
new file mode 100644
index 000000000..3a46a8ce8
--- /dev/null
+++ b/lib/sig2str.h
@@ -0,0 +1,49 @@
+/* sig2str.h -- convert between signal names and numbers
+
+ Copyright (C) 2002 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; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by Paul Eggert. */
+
+/* Include <signal.h> before including this file. */
+
+/* Don't override system declarations of SIG2STR_MAX, sig2str, str2sig. */
+#ifndef SIG2STR_MAX
+
+/* Upper bound on the string length of an integer converted to string.
+ 302 / 1000 is ceil (log10 (2.0)). Subtract 1 for the sign bit;
+ add 1 for integer division truncation; add 1 more for a minus sign. */
+# define INT_STRLEN_BOUND(t) ((sizeof (t) * CHAR_BIT - 1) * 302 / 1000 + 2)
+
+/* Size of a buffer needed to hold a signal name like "HUP". */
+# define SIG2STR_MAX (sizeof "SIGRTMAX" + INT_STRLEN_BOUND (int) - 1)
+
+int sig2str (int, char *);
+int str2sig (char const *, int *);
+
+#endif
+
+/* An upper bound on signal numbers allowed by the system. */
+
+#if defined _sys_nsig
+# define SIGNUM_BOUND (_sys_nsig - 1)
+#elif defined NSIG
+# define SIGNUM_BOUND (NSIG - 1)
+#elif defined WTERMSIG
+# define SIGNUM_BOUND WTERMSIG (~ 0)
+#else
+# define SIGNUM_BOUND 127
+#endif