changeset 9616:878f41b0e41e

New module 'strsignal'.
author Colin Watson <cjwatson@debian.org>
date Mon, 14 Jan 2008 00:26:30 +0100
parents e6a7466840b2
children ba0cb910b71e
files ChangeLog lib/siglist.h lib/string.in.h lib/strsignal.c m4/string_h.m4 m4/strsignal.m4 modules/string modules/strsignal
diffstat 8 files changed, 409 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2008-01-13  Colin Watson  <cjwatson@debian.org>
+
+	* lib/strsignal.c: New file, from glibc with modifications.
+	* lib/siglist.h: New file, from glibc with modifications.
+	* lib/string.in.h (strsignal): New declaration.
+	* m4/strsignal.m4: New file.
+	* m4/string_h.m4 (gl_HEADER_STRING_H_DEFAULTS): Initialize
+	GNULIB_STRSIGNAL and HAVE_DECL_STRSIGNAL.
+	* modules/strsignal: New file.
+	* modules/string (Makefile.am): Substitute GNULIB_STRSIGNAL and
+	HAVE_DECL_STRSIGNAL.
+
 2008-01-13  Bruno Haible  <bruno@clisp.org>
 
 	* m4/locale-fr.m4 (gt_LOCALE_FR, gt_LOCALE_FR_UTF8): Check that the
new file mode 100644
--- /dev/null
+++ b/lib/siglist.h
@@ -0,0 +1,131 @@
+/* Canonical list of all signal names.
+   Copyright (C) 1996,97,98,99,2008 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+/* This file should be usable for any platform, since it just associates
+   the SIG* macros with text names and descriptions.  The actual values
+   come from <bits/signum.h> (via <signal.h>).  For any signal macros do not
+   exist on every platform, we can use #ifdef tests here and still use
+   this single common file for all platforms.  */
+
+/* This file is included multiple times.  */
+
+/* Standard signals  */
+#ifdef SIGHUP
+  init_sig (SIGHUP, "HUP", N_("Hangup"))
+#endif
+#ifdef SIGINT
+  init_sig (SIGINT, "INT", N_("Interrupt"))
+#endif
+#ifdef SIGQUIT
+  init_sig (SIGQUIT, "QUIT", N_("Quit"))
+#endif
+#ifdef SIGILL
+  init_sig (SIGILL, "ILL", N_("Illegal instruction"))
+#endif
+#ifdef SIGTRAP
+  init_sig (SIGTRAP, "TRAP", N_("Trace/breakpoint trap"))
+#endif
+#ifdef SIGABRT
+  init_sig (SIGABRT, "ABRT", N_("Aborted"))
+#endif
+#ifdef SIGFPE
+  init_sig (SIGFPE, "FPE", N_("Floating point exception"))
+#endif
+#ifdef SIGKILL
+  init_sig (SIGKILL, "KILL", N_("Killed"))
+#endif
+#ifdef SIGBUS
+  init_sig (SIGBUS, "BUS", N_("Bus error"))
+#endif
+#ifdef SIGSEGV
+  init_sig (SIGSEGV, "SEGV", N_("Segmentation fault"))
+#endif
+#ifdef SIGPIPE
+  init_sig (SIGPIPE, "PIPE", N_("Broken pipe"))
+#endif
+#ifdef SIGALRM
+  init_sig (SIGALRM, "ALRM", N_("Alarm clock"))
+#endif
+#ifdef SIGTERM
+  init_sig (SIGTERM, "TERM", N_("Terminated"))
+#endif
+#ifdef SIGURG
+  init_sig (SIGURG, "URG", N_("Urgent I/O condition"))
+#endif
+#ifdef SIGSTOP
+  init_sig (SIGSTOP, "STOP", N_("Stopped (signal)"))
+#endif
+#ifdef SIGTSTP
+  init_sig (SIGTSTP, "TSTP", N_("Stopped"))
+#endif
+#ifdef SIGCONT
+  init_sig (SIGCONT, "CONT", N_("Continued"))
+#endif
+#ifdef SIGCHLD
+  init_sig (SIGCHLD, "CHLD", N_("Child exited"))
+#endif
+#ifdef SIGTTIN
+  init_sig (SIGTTIN, "TTIN", N_("Stopped (tty input)"))
+#endif
+#ifdef SIGTTOU
+  init_sig (SIGTTOU, "TTOU", N_("Stopped (tty output)"))
+#endif
+#ifdef SIGIO
+  init_sig (SIGIO, "IO", N_("I/O possible"))
+#endif
+#ifdef SIGXCPU
+  init_sig (SIGXCPU, "XCPU", N_("CPU time limit exceeded"))
+#endif
+#ifdef SIGXFSZ
+  init_sig (SIGXFSZ, "XFSZ", N_("File size limit exceeded"))
+#endif
+#ifdef SIGVTALRM
+  init_sig (SIGVTALRM, "VTALRM", N_("Virtual timer expired"))
+#endif
+#ifdef SIGPROF
+  init_sig (SIGPROF, "PROF", N_("Profiling timer expired"))
+#endif
+#ifdef SIGWINCH
+  init_sig (SIGWINCH, "WINCH", N_("Window changed"))
+#endif
+#ifdef SIGUSR1
+  init_sig (SIGUSR1, "USR1", N_("User defined signal 1"))
+#endif
+#ifdef SIGUSR2
+  init_sig (SIGUSR2, "USR2", N_("User defined signal 2"))
+#endif
+
+/* Variations  */
+#ifdef SIGEMT
+  init_sig (SIGEMT, "EMT", N_("EMT trap"))
+#endif
+#ifdef SIGSYS
+  init_sig (SIGSYS, "SYS", N_("Bad system call"))
+#endif
+#ifdef SIGSTKFLT
+  init_sig (SIGSTKFLT, "STKFLT", N_("Stack fault"))
+#endif
+#ifdef SIGINFO
+  init_sig (SIGINFO, "INFO", N_("Information request"))
+#elif defined(SIGPWR) && (!defined(SIGLOST) || (SIGPWR != SIGLOST))
+  init_sig (SIGPWR, "PWR", N_("Power failure"))
+#endif
+#ifdef SIGLOST
+  init_sig (SIGLOST, "LOST", N_("Resource lost"))
+#endif
--- a/lib/string.in.h
+++ b/lib/string.in.h
@@ -541,6 +541,18 @@
      strerror (e))
 #endif
 
+#if @GNULIB_STRSIGNAL@
+# if ! @HAVE_DECL_STRSIGNAL@
+extern char *strsignal (int __sig);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef strsignal
+# define strsignal(a) \
+    (GL_LINK_WARNING ("strsignal is unportable - " \
+                      "use gnulib module strsignal for portability"), \
+     strsignal (a))
+#endif
+
 
 #ifdef __cplusplus
 }
new file mode 100644
--- /dev/null
+++ b/lib/strsignal.c
@@ -0,0 +1,196 @@
+/* Copyright (C) 1991, 1994-2002, 2005, 2008 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _LIBC
+# include <config.h>
+#endif
+
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef _LIBC
+# include <libintl.h>
+#else /* !_LIBC */
+# include "gettext.h"
+# define _(msgid) gettext (msgid)
+# define N_(msgid) gettext_noop (msgid)
+#endif /* _LIBC */
+
+#ifdef _LIBC
+# include <bits/libc-lock.h>
+#else /* !_LIBC */
+# include "lock.h"
+# include "tls.h"
+# define __libc_once_define(CLASS, NAME) gl_once_define (CLASS, NAME)
+# define __libc_once(NAME, INIT) gl_once ((NAME), (INIT))
+# define __libc_key_t gl_tls_key_t
+# define __libc_getspecific(NAME) gl_tls_get ((NAME))
+# define __libc_setspecific(NAME, POINTER) gl_tls_set ((NAME), (POINTER))
+# define __snprintf snprintf
+#endif /* _LIBC */
+
+#ifdef _LIBC
+
+/* Defined in siglist.c.  */
+extern const char *const _sys_siglist[];
+extern const char *const _sys_siglist_internal[] attribute_hidden;
+
+#else /* !_LIBC */
+
+/* NetBSD declares sys_siglist in unistd.h. */
+# include <unistd.h>
+
+# define INTUSE(x) (x)
+
+# if HAVE_DECL_SYS_SIGLIST
+#  undef _sys_siglist
+#  define _sys_siglist sys_siglist
+# else /* !HAVE_DECL_SYS_SIGLIST */
+#  ifndef NSIG
+#   define NSIG 32
+#  endif /* NSIG */
+static const char *_sys_siglist[NSIG];
+# endif /* !HAVE_DECL_SYS_SIGLIST */
+
+#endif /* _LIBC */
+
+static __libc_key_t key;
+
+/* If nonzero the key allocation failed and we should better use a
+   static buffer than fail.  */
+#define BUFFERSIZ	100
+static char local_buf[BUFFERSIZ];
+static char *static_buf;
+
+/* Destructor for the thread-specific data.  */
+static void init (void);
+static void free_key_mem (void *mem);
+static char *getbuffer (void);
+
+
+/* Return a string describing the meaning of the signal number SIGNUM.  */
+char *
+strsignal (int signum)
+{
+  const char *desc;
+  __libc_once_define (static, once);
+
+  /* If we have not yet initialized the buffer do it now.  */
+  __libc_once (once, init);
+
+  if (
+#ifdef SIGRTMIN
+      (signum >= SIGRTMIN && signum <= SIGRTMAX) ||
+#endif
+      signum < 0 || signum >= NSIG
+      || (desc = INTUSE(_sys_siglist)[signum]) == NULL)
+    {
+      char *buffer = getbuffer ();
+      int len;
+#ifdef SIGRTMIN
+      if (signum >= SIGRTMIN && signum <= SIGRTMAX)
+	len = __snprintf (buffer, BUFFERSIZ - 1, _("Real-time signal %d"),
+			  signum - SIGRTMIN);
+      else
+#endif
+	len = __snprintf (buffer, BUFFERSIZ - 1, _("Unknown signal %d"),
+			  signum);
+      if (len >= BUFFERSIZ)
+	buffer = NULL;
+      else
+	buffer[len] = '\0';
+
+      return buffer;
+    }
+
+  return (char *) _(desc);
+}
+
+
+/* Initialize buffer.  */
+static void
+init (void)
+{
+#ifdef _LIBC
+  if (__libc_key_create (&key, free_key_mem))
+    /* Creating the key failed.  This means something really went
+       wrong.  In any case use a static buffer which is better than
+       nothing.  */
+    static_buf = local_buf;
+#else /* !_LIBC */
+  gl_tls_key_init (key, free_key_mem);
+
+# if !HAVE_DECL_SYS_SIGLIST
+  memset (_sys_siglist, 0, NSIG * sizeof *_sys_siglist);
+
+  /* No need to use a do {} while (0) here since init_sig(...) must expand
+     to a complete statement.  (We cannot use the ISO C99 designated array
+     initializer syntax since it is not supported by ANSI C compilers and
+     since some signal numbers might exceed NSIG.)  */
+#  define init_sig(sig, abbrev, desc) \
+  if (sig >= 0 && sig < NSIG) \
+    _sys_siglist[sig] = desc;
+} while (0);
+
+#  include "siglist.h"
+
+#  undef init_sig
+
+# endif /* !HAVE_DECL_SYS_SIGLIST */
+#endif /* !_LIBC */
+}
+
+
+/* Free the thread specific data, this is done if a thread terminates.  */
+static void
+free_key_mem (void *mem)
+{
+  free (mem);
+  __libc_setspecific (key, NULL);
+}
+
+
+/* Return the buffer to be used.  */
+static char *
+getbuffer (void)
+{
+  char *result;
+
+  if (static_buf != NULL)
+    result = static_buf;
+  else
+    {
+      /* We don't use the static buffer and so we have a key.  Use it
+	 to get the thread-specific buffer.  */
+      result = __libc_getspecific (key);
+      if (result == NULL)
+	{
+	  /* No buffer allocated so far.  */
+	  result = malloc (BUFFERSIZ);
+	  if (result == NULL)
+	    /* No more memory available.  We use the static buffer.  */
+	    result = local_buf;
+	  else
+	    __libc_setspecific (key, result);
+	}
+    }
+
+  return result;
+}
--- a/m4/string_h.m4
+++ b/m4/string_h.m4
@@ -61,6 +61,7 @@
   GNULIB_MBSSEP=0;      AC_SUBST([GNULIB_MBSSEP])
   GNULIB_MBSTOK_R=0;    AC_SUBST([GNULIB_MBSTOK_R])
   GNULIB_STRERROR=0;    AC_SUBST([GNULIB_STRERROR])
+  GNULIB_STRSIGNAL=0;   AC_SUBST([GNULIB_STRSIGNAL])
   dnl Assume proper GNU behavior unless another module says otherwise.
   HAVE_DECL_MEMMEM=1;		AC_SUBST([HAVE_DECL_MEMMEM])
   HAVE_MEMPCPY=1;		AC_SUBST([HAVE_MEMPCPY])
@@ -77,6 +78,7 @@
   HAVE_STRCASESTR=1;		AC_SUBST([HAVE_STRCASESTR])
   HAVE_DECL_STRTOK_R=1;		AC_SUBST([HAVE_DECL_STRTOK_R])
   HAVE_DECL_STRERROR=1;		AC_SUBST([HAVE_DECL_STRERROR])
+  HAVE_DECL_STRSIGNAL=1;	AC_SUBST([HAVE_DECL_STRSIGNAL])
   REPLACE_STRERROR=0;		AC_SUBST([REPLACE_STRERROR])
   REPLACE_MEMMEM=0;		AC_SUBST([REPLACE_MEMMEM])
   REPLACE_STRSTR=0;		AC_SUBST([REPLACE_STRSTR])
new file mode 100644
--- /dev/null
+++ b/m4/strsignal.m4
@@ -0,0 +1,24 @@
+# strsignal.m4 serial 1
+dnl Copyright (C) 2008 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_STRSIGNAL],
+[
+  dnl Persuade glibc <string.h> to declare strsignal().
+  AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+
+  AC_REQUIRE([AC_DECL_SYS_SIGLIST])
+
+  AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
+  AC_REPLACE_FUNCS([strsignal])
+  AC_CHECK_DECLS_ONCE([strsignal])
+  if test $ac_cv_have_decl_strsignal = no; then
+    HAVE_DECL_STRSIGNAL=0
+    gl_PREREQ_STRSIGNAL
+  fi
+])
+
+# Prerequisites of lib/strsignal.c.
+AC_DEFUN([gl_PREREQ_STRSIGNAL], [:])
--- a/modules/string
+++ b/modules/string
@@ -52,6 +52,7 @@
 	      -e 's|@''GNULIB_STRCASESTR''@|$(GNULIB_STRCASESTR)|g' \
 	      -e 's|@''GNULIB_STRTOK_R''@|$(GNULIB_STRTOK_R)|g' \
 	      -e 's|@''GNULIB_STRERROR''@|$(GNULIB_STRERROR)|g' \
+	      -e 's|@''GNULIB_STRSIGNAL''@|$(GNULIB_STRSIGNAL)|g' \
 	      -e 's|@''HAVE_DECL_MEMMEM''@|$(HAVE_DECL_MEMMEM)|g' \
 	      -e 's|@''HAVE_MEMPCPY''@|$(HAVE_MEMPCPY)|g' \
 	      -e 's|@''HAVE_DECL_MEMRCHR''@|$(HAVE_DECL_MEMRCHR)|g' \
@@ -67,6 +68,7 @@
 	      -e 's|@''HAVE_STRCASESTR''@|$(HAVE_STRCASESTR)|g' \
 	      -e 's|@''HAVE_DECL_STRTOK_R''@|$(HAVE_DECL_STRTOK_R)|g' \
 	      -e 's|@''HAVE_DECL_STRERROR''@|$(HAVE_DECL_STRERROR)|g' \
+	      -e 's|@''HAVE_DECL_STRSIGNAL''@|$(HAVE_DECL_STRSIGNAL)|g' \
 	      -e 's|@''REPLACE_MEMMEM''@|$(REPLACE_MEMMEM)|g' \
 	      -e 's|@''REPLACE_STRSTR''@|$(REPLACE_STRSTR)|g' \
 	      -e 's|@''REPLACE_STRERROR''@|$(REPLACE_STRERROR)|g' \
new file mode 100644
--- /dev/null
+++ b/modules/strsignal
@@ -0,0 +1,30 @@
+Description:
+strsignal() function: return string describing signal.
+
+Files:
+lib/strsignal.c
+lib/siglist.h
+m4/strsignal.m4
+
+Depends-on:
+string
+gettext-h
+lock
+tls
+snprintf
+memset
+
+configure.ac:
+gl_FUNC_STRSIGNAL
+gl_STRING_MODULE_INDICATOR([strsignal])
+
+Makefile.am:
+
+Include:
+"strsignal.h"
+
+License:
+LGPLv2+
+
+Maintainer:
+Colin Watson, glibc