/* Copyright (C) 1991, 1994-2002, 2005, 2008-2020 Free Software Foundation,
   Inc.
   This file is part of the GNU C Library.

   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 3 of the License, 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, see <https://www.gnu.org/licenses/>.  */

#ifndef _LIBC
# include <config.h>
#endif

/* Specification.  */
#include <string.h>

#include <signal.h>
#include <stdio.h>
#include <stdlib.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 "glthread/lock.h"
# include "glthread/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. */
# if HAVE_UNISTD_H
#  include <unistd.h>
# endif

# 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 */
#  if !HAVE_DECL__SYS_SIGLIST
static const char *_sys_siglist[NSIG];
#  endif
# 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 - (int) 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;

#  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;
}
