Blame gnulib/lib/strsignal.c

Packit eba2e2
/* Copyright (C) 1991, 1994-2002, 2005, 2008-2014 Free Software Foundation,
Packit eba2e2
   Inc.
Packit eba2e2
   This file is part of the GNU C Library.
Packit eba2e2
Packit eba2e2
   This program is free software: you can redistribute it and/or modify
Packit eba2e2
   it under the terms of the GNU General Public License as published by
Packit eba2e2
   the Free Software Foundation; either version 3 of the License, or
Packit eba2e2
   (at your option) any later version.
Packit eba2e2
Packit eba2e2
   This program is distributed in the hope that it will be useful,
Packit eba2e2
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit eba2e2
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit eba2e2
   GNU General Public License for more details.
Packit eba2e2
Packit eba2e2
   You should have received a copy of the GNU General Public License
Packit eba2e2
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
Packit eba2e2
Packit eba2e2
#ifndef _LIBC
Packit eba2e2
# include <config.h>
Packit eba2e2
#endif
Packit eba2e2
Packit eba2e2
/* Specification.  */
Packit eba2e2
#include <string.h>
Packit eba2e2
Packit eba2e2
#include <signal.h>
Packit eba2e2
#include <stdio.h>
Packit eba2e2
#include <stdlib.h>
Packit eba2e2
Packit eba2e2
#ifdef _LIBC
Packit eba2e2
# include <libintl.h>
Packit eba2e2
#else /* !_LIBC */
Packit eba2e2
# include "gettext.h"
Packit eba2e2
# define _(msgid) gettext (msgid)
Packit eba2e2
# define N_(msgid) gettext_noop (msgid)
Packit eba2e2
#endif /* _LIBC */
Packit eba2e2
Packit eba2e2
#ifdef _LIBC
Packit eba2e2
# include <bits/libc-lock.h>
Packit eba2e2
#else /* !_LIBC */
Packit eba2e2
# include "glthread/lock.h"
Packit eba2e2
# include "glthread/tls.h"
Packit eba2e2
# define __libc_once_define(CLASS, NAME) gl_once_define (CLASS, NAME)
Packit eba2e2
# define __libc_once(NAME, INIT) gl_once ((NAME), (INIT))
Packit eba2e2
# define __libc_key_t gl_tls_key_t
Packit eba2e2
# define __libc_getspecific(NAME) gl_tls_get ((NAME))
Packit eba2e2
# define __libc_setspecific(NAME, POINTER) gl_tls_set ((NAME), (POINTER))
Packit eba2e2
# define __snprintf snprintf
Packit eba2e2
#endif /* _LIBC */
Packit eba2e2
Packit eba2e2
#ifdef _LIBC
Packit eba2e2
Packit eba2e2
/* Defined in siglist.c.  */
Packit eba2e2
extern const char *const _sys_siglist[];
Packit eba2e2
extern const char *const _sys_siglist_internal[] attribute_hidden;
Packit eba2e2
Packit eba2e2
#else /* !_LIBC */
Packit eba2e2
Packit eba2e2
/* NetBSD declares sys_siglist in unistd.h. */
Packit eba2e2
# if HAVE_UNISTD_H
Packit eba2e2
#  include <unistd.h>
Packit eba2e2
# endif
Packit eba2e2
Packit eba2e2
# define INTUSE(x) (x)
Packit eba2e2
Packit eba2e2
# if HAVE_DECL_SYS_SIGLIST
Packit eba2e2
#  undef _sys_siglist
Packit eba2e2
#  define _sys_siglist sys_siglist
Packit eba2e2
# else /* !HAVE_DECL_SYS_SIGLIST */
Packit eba2e2
#  ifndef NSIG
Packit eba2e2
#   define NSIG 32
Packit eba2e2
#  endif /* NSIG */
Packit eba2e2
#  if !HAVE_DECL__SYS_SIGLIST
Packit eba2e2
static const char *_sys_siglist[NSIG];
Packit eba2e2
#  endif
Packit eba2e2
# endif /* !HAVE_DECL_SYS_SIGLIST */
Packit eba2e2
Packit eba2e2
#endif /* _LIBC */
Packit eba2e2
Packit eba2e2
static __libc_key_t key;
Packit eba2e2
Packit eba2e2
/* If nonzero the key allocation failed and we should better use a
Packit eba2e2
   static buffer than fail.  */
Packit eba2e2
#define BUFFERSIZ       100
Packit eba2e2
static char local_buf[BUFFERSIZ];
Packit eba2e2
static char *static_buf;
Packit eba2e2
Packit eba2e2
/* Destructor for the thread-specific data.  */
Packit eba2e2
static void init (void);
Packit eba2e2
static void free_key_mem (void *mem);
Packit eba2e2
static char *getbuffer (void);
Packit eba2e2
Packit eba2e2
Packit eba2e2
/* Return a string describing the meaning of the signal number SIGNUM.  */
Packit eba2e2
char *
Packit eba2e2
strsignal (int signum)
Packit eba2e2
{
Packit eba2e2
  const char *desc;
Packit eba2e2
  __libc_once_define (static, once);
Packit eba2e2
Packit eba2e2
  /* If we have not yet initialized the buffer do it now.  */
Packit eba2e2
  __libc_once (once, init);
Packit eba2e2
Packit eba2e2
  if (
Packit eba2e2
#ifdef SIGRTMIN
Packit eba2e2
      (signum >= SIGRTMIN && signum <= SIGRTMAX) ||
Packit eba2e2
#endif
Packit eba2e2
      signum < 0 || signum >= NSIG
Packit eba2e2
      || (desc = INTUSE(_sys_siglist)[signum]) == NULL)
Packit eba2e2
    {
Packit eba2e2
      char *buffer = getbuffer ();
Packit eba2e2
      int len;
Packit eba2e2
#ifdef SIGRTMIN
Packit eba2e2
      if (signum >= SIGRTMIN && signum <= SIGRTMAX)
Packit eba2e2
        len = __snprintf (buffer, BUFFERSIZ - 1, _("Real-time signal %d"),
Packit eba2e2
                          signum - (int) SIGRTMIN);
Packit eba2e2
      else
Packit eba2e2
#endif
Packit eba2e2
        len = __snprintf (buffer, BUFFERSIZ - 1, _("Unknown signal %d"),
Packit eba2e2
                          signum);
Packit eba2e2
      if (len >= BUFFERSIZ)
Packit eba2e2
        buffer = NULL;
Packit eba2e2
      else
Packit eba2e2
        buffer[len] = '\0';
Packit eba2e2
Packit eba2e2
      return buffer;
Packit eba2e2
    }
Packit eba2e2
Packit eba2e2
  return (char *) _(desc);
Packit eba2e2
}
Packit eba2e2
Packit eba2e2
Packit eba2e2
/* Initialize buffer.  */
Packit eba2e2
static void
Packit eba2e2
init (void)
Packit eba2e2
{
Packit eba2e2
#ifdef _LIBC
Packit eba2e2
  if (__libc_key_create (&key, free_key_mem))
Packit eba2e2
    /* Creating the key failed.  This means something really went
Packit eba2e2
       wrong.  In any case use a static buffer which is better than
Packit eba2e2
       nothing.  */
Packit eba2e2
    static_buf = local_buf;
Packit eba2e2
#else /* !_LIBC */
Packit eba2e2
  gl_tls_key_init (key, free_key_mem);
Packit eba2e2
Packit eba2e2
# if !HAVE_DECL_SYS_SIGLIST
Packit eba2e2
  memset (_sys_siglist, 0, NSIG * sizeof *_sys_siglist);
Packit eba2e2
Packit eba2e2
  /* No need to use a do {} while (0) here since init_sig(...) must expand
Packit eba2e2
     to a complete statement.  (We cannot use the ISO C99 designated array
Packit eba2e2
     initializer syntax since it is not supported by ANSI C compilers and
Packit eba2e2
     since some signal numbers might exceed NSIG.)  */
Packit eba2e2
#  define init_sig(sig, abbrev, desc) \
Packit eba2e2
  if (sig >= 0 && sig < NSIG) \
Packit eba2e2
    _sys_siglist[sig] = desc;
Packit eba2e2
Packit eba2e2
#  include "siglist.h"
Packit eba2e2
Packit eba2e2
#  undef init_sig
Packit eba2e2
Packit eba2e2
# endif /* !HAVE_DECL_SYS_SIGLIST */
Packit eba2e2
#endif /* !_LIBC */
Packit eba2e2
}
Packit eba2e2
Packit eba2e2
Packit eba2e2
/* Free the thread specific data, this is done if a thread terminates.  */
Packit eba2e2
static void
Packit eba2e2
free_key_mem (void *mem)
Packit eba2e2
{
Packit eba2e2
  free (mem);
Packit eba2e2
  __libc_setspecific (key, NULL);
Packit eba2e2
}
Packit eba2e2
Packit eba2e2
Packit eba2e2
/* Return the buffer to be used.  */
Packit eba2e2
static char *
Packit eba2e2
getbuffer (void)
Packit eba2e2
{
Packit eba2e2
  char *result;
Packit eba2e2
Packit eba2e2
  if (static_buf != NULL)
Packit eba2e2
    result = static_buf;
Packit eba2e2
  else
Packit eba2e2
    {
Packit eba2e2
      /* We don't use the static buffer and so we have a key.  Use it
Packit eba2e2
         to get the thread-specific buffer.  */
Packit eba2e2
      result = __libc_getspecific (key);
Packit eba2e2
      if (result == NULL)
Packit eba2e2
        {
Packit eba2e2
          /* No buffer allocated so far.  */
Packit eba2e2
          result = malloc (BUFFERSIZ);
Packit eba2e2
          if (result == NULL)
Packit eba2e2
            /* No more memory available.  We use the static buffer.  */
Packit eba2e2
            result = local_buf;
Packit eba2e2
          else
Packit eba2e2
            __libc_setspecific (key, result);
Packit eba2e2
        }
Packit eba2e2
    }
Packit eba2e2
Packit eba2e2
  return result;
Packit eba2e2
}