Blame gnulib/lib/strsignal.c

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