Blame string/strsignal.c

Packit 6c4009
/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
Packit 6c4009
   This file is part of the GNU C Library.
Packit 6c4009
Packit 6c4009
   The GNU C Library is free software; you can redistribute it and/or
Packit 6c4009
   modify it under the terms of the GNU Lesser General Public
Packit 6c4009
   License as published by the Free Software Foundation; either
Packit 6c4009
   version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
   The GNU C Library is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
   Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public
Packit 6c4009
   License along with the GNU C Library; if not, see
Packit 6c4009
   <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
#include <signal.h>
Packit 6c4009
#include <stdio.h>
Packit 6c4009
#include <stdlib.h>
Packit 6c4009
#include <string.h>
Packit 6c4009
#include <libintl.h>
Packit 6c4009
#include <libc-lock.h>
Packit 6c4009
Packit 6c4009
static __libc_key_t key;
Packit 6c4009
Packit 6c4009
/* If nonzero the key allocation failed and we should better use a
Packit 6c4009
   static buffer than fail.  */
Packit 6c4009
#define BUFFERSIZ	100
Packit 6c4009
static char local_buf[BUFFERSIZ];
Packit 6c4009
static char *static_buf;
Packit 6c4009
Packit 6c4009
/* Destructor for the thread-specific data.  */
Packit 6c4009
static void init (void);
Packit 6c4009
static void free_key_mem (void *mem);
Packit 6c4009
static char *getbuffer (void);
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Return a string describing the meaning of the signal number SIGNUM.  */
Packit 6c4009
char *
Packit 6c4009
strsignal (int signum)
Packit 6c4009
{
Packit 6c4009
  __libc_once_define (static, once);
Packit 6c4009
  const char *desc;
Packit 6c4009
Packit 6c4009
  /* If we have not yet initialized the buffer do it now.  */
Packit 6c4009
  __libc_once (once, init);
Packit 6c4009
Packit 6c4009
  if (
Packit 6c4009
#ifdef SIGRTMIN
Packit 6c4009
      (signum >= SIGRTMIN && signum <= SIGRTMAX) ||
Packit 6c4009
#endif
Packit 6c4009
      signum < 0 || signum >= NSIG
Packit 6c4009
      || (desc = _sys_siglist[signum]) == NULL)
Packit 6c4009
    {
Packit 6c4009
      char *buffer = getbuffer ();
Packit 6c4009
      int len;
Packit 6c4009
#ifdef SIGRTMIN
Packit 6c4009
      if (signum >= SIGRTMIN && signum <= SIGRTMAX)
Packit 6c4009
	len = __snprintf (buffer, BUFFERSIZ - 1, _("Real-time signal %d"),
Packit 6c4009
			  signum - SIGRTMIN);
Packit 6c4009
      else
Packit 6c4009
#endif
Packit 6c4009
	len = __snprintf (buffer, BUFFERSIZ - 1, _("Unknown signal %d"),
Packit 6c4009
			  signum);
Packit 6c4009
      if (len >= BUFFERSIZ)
Packit 6c4009
	buffer = NULL;
Packit 6c4009
      else
Packit 6c4009
	buffer[len] = '\0';
Packit 6c4009
Packit 6c4009
      return buffer;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  return (char *) _(desc);
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Initialize buffer.  */
Packit 6c4009
static void
Packit 6c4009
init (void)
Packit 6c4009
{
Packit 6c4009
  if (__libc_key_create (&key, free_key_mem))
Packit 6c4009
    /* Creating the key failed.  This means something really went
Packit 6c4009
       wrong.  In any case use a static buffer which is better than
Packit 6c4009
       nothing.  */
Packit 6c4009
    static_buf = local_buf;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Free the thread specific data, this is done if a thread terminates.  */
Packit 6c4009
static void
Packit 6c4009
free_key_mem (void *mem)
Packit 6c4009
{
Packit 6c4009
  free (mem);
Packit 6c4009
  __libc_setspecific (key, NULL);
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Return the buffer to be used.  */
Packit 6c4009
static char *
Packit 6c4009
getbuffer (void)
Packit 6c4009
{
Packit 6c4009
  char *result;
Packit 6c4009
Packit 6c4009
  if (static_buf != NULL)
Packit 6c4009
    result = static_buf;
Packit 6c4009
  else
Packit 6c4009
    {
Packit 6c4009
      /* We don't use the static buffer and so we have a key.  Use it
Packit 6c4009
	 to get the thread-specific buffer.  */
Packit 6c4009
      result = __libc_getspecific (key);
Packit 6c4009
      if (result == NULL)
Packit 6c4009
	{
Packit 6c4009
	  /* No buffer allocated so far.  */
Packit 6c4009
	  result = malloc (BUFFERSIZ);
Packit 6c4009
	  if (result == NULL)
Packit 6c4009
	    /* No more memory available.  We use the static buffer.  */
Packit 6c4009
	    result = local_buf;
Packit 6c4009
	  else
Packit 6c4009
	    __libc_setspecific (key, result);
Packit 6c4009
	}
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  return result;
Packit 6c4009
}