Back to index

glibc  2.9
strsignal.c
Go to the documentation of this file.
00001 /* Copyright (C) 1991, 1994-2002, 2005 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003 
00004    The GNU C Library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Lesser General Public
00006    License as published by the Free Software Foundation; either
00007    version 2.1 of the License, or (at your option) any later version.
00008 
00009    The GNU C Library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Lesser General Public License for more details.
00013 
00014    You should have received a copy of the GNU Lesser General Public
00015    License along with the GNU C Library; if not, write to the Free
00016    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00017    02111-1307 USA.  */
00018 
00019 #include <signal.h>
00020 #include <stdio.h>
00021 #include <stdlib.h>
00022 #include <string.h>
00023 #include <libintl.h>
00024 #include <bits/libc-lock.h>
00025 
00026 
00027 /* Defined in siglist.c.  */
00028 extern const char *const _sys_siglist[];
00029 extern const char *const _sys_siglist_internal[] attribute_hidden;
00030 static __libc_key_t key;
00031 
00032 /* If nonzero the key allocation failed and we should better use a
00033    static buffer than fail.  */
00034 #define BUFFERSIZ    100
00035 static char local_buf[BUFFERSIZ];
00036 static char *static_buf;
00037 
00038 /* Destructor for the thread-specific data.  */
00039 static void init (void);
00040 static void free_key_mem (void *mem);
00041 static char *getbuffer (void);
00042 
00043 
00044 /* Return a string describing the meaning of the signal number SIGNUM.  */
00045 char *
00046 strsignal (int signum)
00047 {
00048   __libc_once_define (static, once);
00049   const char *desc;
00050 
00051   /* If we have not yet initialized the buffer do it now.  */
00052   __libc_once (once, init);
00053 
00054   if (
00055 #ifdef SIGRTMIN
00056       (signum >= SIGRTMIN && signum <= SIGRTMAX) ||
00057 #endif
00058       signum < 0 || signum >= NSIG
00059       || (desc = INTUSE(_sys_siglist)[signum]) == NULL)
00060     {
00061       char *buffer = getbuffer ();
00062       int len;
00063 #ifdef SIGRTMIN
00064       if (signum >= SIGRTMIN && signum <= SIGRTMAX)
00065        len = __snprintf (buffer, BUFFERSIZ - 1, _("Real-time signal %d"),
00066                        signum - SIGRTMIN);
00067       else
00068 #endif
00069        len = __snprintf (buffer, BUFFERSIZ - 1, _("Unknown signal %d"),
00070                        signum);
00071       if (len >= BUFFERSIZ)
00072        buffer = NULL;
00073       else
00074        buffer[len] = '\0';
00075 
00076       return buffer;
00077     }
00078 
00079   return (char *) _(desc);
00080 }
00081 
00082 
00083 /* Initialize buffer.  */
00084 static void
00085 init (void)
00086 {
00087   if (__libc_key_create (&key, free_key_mem))
00088     /* Creating the key failed.  This means something really went
00089        wrong.  In any case use a static buffer which is better than
00090        nothing.  */
00091     static_buf = local_buf;
00092 }
00093 
00094 
00095 /* Free the thread specific data, this is done if a thread terminates.  */
00096 static void
00097 free_key_mem (void *mem)
00098 {
00099   free (mem);
00100   __libc_setspecific (key, NULL);
00101 }
00102 
00103 
00104 /* Return the buffer to be used.  */
00105 static char *
00106 getbuffer (void)
00107 {
00108   char *result;
00109 
00110   if (static_buf != NULL)
00111     result = static_buf;
00112   else
00113     {
00114       /* We don't use the static buffer and so we have a key.  Use it
00115         to get the thread-specific buffer.  */
00116       result = __libc_getspecific (key);
00117       if (result == NULL)
00118        {
00119          /* No buffer allocated so far.  */
00120          result = malloc (BUFFERSIZ);
00121          if (result == NULL)
00122            /* No more memory available.  We use the static buffer.  */
00123            result = local_buf;
00124          else
00125            __libc_setspecific (key, result);
00126        }
00127     }
00128 
00129   return result;
00130 }