root/maint/gnulib/lib/strsignal.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. strsignal
  2. init
  3. free_key_mem
  4. getbuffer

   1 /* Copyright (C) 1991, 1994-2002, 2005, 2008-2021 Free Software Foundation,
   2    Inc.
   3    This file is part of the GNU C Library.
   4 
   5    This file is free software: you can redistribute it and/or modify
   6    it under the terms of the GNU Lesser General Public License as
   7    published by the Free Software Foundation; either version 2.1 of the
   8    License, or (at your option) any later version.
   9 
  10    This file is distributed in the hope that it will be useful,
  11    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13    GNU Lesser General Public License for more details.
  14 
  15    You should have received a copy of the GNU Lesser General Public License
  16    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
  17 
  18 #ifndef _LIBC
  19 # include <config.h>
  20 #endif
  21 
  22 /* Specification.  */
  23 #include <string.h>
  24 
  25 #include <signal.h>
  26 #include <stdio.h>
  27 #include <stdlib.h>
  28 
  29 #ifdef _LIBC
  30 # include <libintl.h>
  31 #else /* !_LIBC */
  32 # include "gettext.h"
  33 # define _(msgid) gettext (msgid)
  34 # define N_(msgid) gettext_noop (msgid)
  35 #endif /* _LIBC */
  36 
  37 #ifdef _LIBC
  38 # include <bits/libc-lock.h>
  39 #else /* !_LIBC */
  40 # include "glthread/lock.h"
  41 # include "glthread/tls.h"
  42 # define __libc_once_define(CLASS, NAME) gl_once_define (CLASS, NAME)
  43 # define __libc_once(NAME, INIT) gl_once ((NAME), (INIT))
  44 # define __libc_key_t gl_tls_key_t
  45 # define __libc_getspecific(NAME) gl_tls_get ((NAME))
  46 # define __libc_setspecific(NAME, POINTER) gl_tls_set ((NAME), (POINTER))
  47 # define __snprintf snprintf
  48 #endif /* _LIBC */
  49 
  50 #ifdef _LIBC
  51 
  52 /* Defined in siglist.c.  */
  53 extern const char *const _sys_siglist[];
  54 extern const char *const _sys_siglist_internal[] attribute_hidden;
  55 
  56 #else /* !_LIBC */
  57 
  58 /* NetBSD declares sys_siglist in unistd.h. */
  59 # if HAVE_UNISTD_H
  60 #  include <unistd.h>
  61 # endif
  62 
  63 # define INTUSE(x) (x)
  64 
  65 # if HAVE_DECL_SYS_SIGLIST
  66 #  undef _sys_siglist
  67 #  define _sys_siglist sys_siglist
  68 # else /* !HAVE_DECL_SYS_SIGLIST */
  69 #  ifndef NSIG
  70 #   define NSIG 32
  71 #  endif /* NSIG */
  72 #  if !HAVE_DECL__SYS_SIGLIST
  73 static const char *_sys_siglist[NSIG];
  74 #  endif
  75 # endif /* !HAVE_DECL_SYS_SIGLIST */
  76 
  77 #endif /* _LIBC */
  78 
  79 static __libc_key_t key;
  80 
  81 /* If nonzero the key allocation failed and we should better use a
  82    static buffer than fail.  */
  83 #define BUFFERSIZ       100
  84 static char local_buf[BUFFERSIZ];
  85 static char *static_buf;
  86 
  87 /* Destructor for the thread-specific data.  */
  88 static void init (void);
  89 static void free_key_mem (void *mem);
  90 static char *getbuffer (void);
  91 
  92 
  93 /* Return a string describing the meaning of the signal number SIGNUM.  */
  94 char *
  95 strsignal (int signum)
     /* [previous][next][first][last][top][bottom][index][help] */
  96 {
  97   const char *desc;
  98   __libc_once_define (static, once);
  99 
 100   /* If we have not yet initialized the buffer do it now.  */
 101   __libc_once (once, init);
 102 
 103   if (
 104 #ifdef SIGRTMIN
 105       (signum >= SIGRTMIN && signum <= SIGRTMAX) ||
 106 #endif
 107       signum < 0 || signum >= NSIG
 108       || (desc = INTUSE(_sys_siglist)[signum]) == NULL)
 109     {
 110       char *buffer = getbuffer ();
 111       int len;
 112 #ifdef SIGRTMIN
 113       if (signum >= SIGRTMIN && signum <= SIGRTMAX)
 114         len = __snprintf (buffer, BUFFERSIZ - 1, _("Real-time signal %d"),
 115                           signum - (int) SIGRTMIN);
 116       else
 117 #endif
 118         len = __snprintf (buffer, BUFFERSIZ - 1, _("Unknown signal %d"),
 119                           signum);
 120       if (len >= BUFFERSIZ)
 121         buffer = NULL;
 122       else
 123         buffer[len] = '\0';
 124 
 125       return buffer;
 126     }
 127 
 128   return (char *) _(desc);
 129 }
 130 
 131 
 132 /* Initialize buffer.  */
 133 static void
 134 init (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 135 {
 136 #ifdef _LIBC
 137   if (__libc_key_create (&key, free_key_mem))
 138     /* Creating the key failed.  This means something really went
 139        wrong.  In any case use a static buffer which is better than
 140        nothing.  */
 141     static_buf = local_buf;
 142 #else /* !_LIBC */
 143   gl_tls_key_init (key, free_key_mem);
 144 
 145 # if !HAVE_DECL_SYS_SIGLIST
 146   memset (_sys_siglist, 0, NSIG * sizeof *_sys_siglist);
 147 
 148   /* No need to use a do {} while (0) here since init_sig(...) must expand
 149      to a complete statement.  (We cannot use the ISO C99 designated array
 150      initializer syntax since it is not supported by ANSI C compilers and
 151      since some signal numbers might exceed NSIG.)  */
 152 #  define init_sig(sig, abbrev, desc) \
 153   if (sig >= 0 && sig < NSIG) \
 154     _sys_siglist[sig] = desc;
 155 
 156 #  include "siglist.h"
 157 
 158 #  undef init_sig
 159 
 160 # endif /* !HAVE_DECL_SYS_SIGLIST */
 161 #endif /* !_LIBC */
 162 }
 163 
 164 
 165 /* Free the thread specific data, this is done if a thread terminates.  */
 166 static void
 167 free_key_mem (void *mem)
     /* [previous][next][first][last][top][bottom][index][help] */
 168 {
 169   free (mem);
 170   __libc_setspecific (key, NULL);
 171 }
 172 
 173 
 174 /* Return the buffer to be used.  */
 175 static char *
 176 getbuffer (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 177 {
 178   char *result;
 179 
 180   if (static_buf != NULL)
 181     result = static_buf;
 182   else
 183     {
 184       /* We don't use the static buffer and so we have a key.  Use it
 185          to get the thread-specific buffer.  */
 186       result = __libc_getspecific (key);
 187       if (result == NULL)
 188         {
 189           /* No buffer allocated so far.  */
 190           result = malloc (BUFFERSIZ);
 191           if (result == NULL)
 192             /* No more memory available.  We use the static buffer.  */
 193             result = local_buf;
 194           else
 195             __libc_setspecific (key, result);
 196         }
 197     }
 198 
 199   return result;
 200 }

/* [previous][next][first][last][top][bottom][index][help] */