1 /*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 1988, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 #if defined(LIBC_SCCS) && !defined(lint) 33 static char sccsid[] = "@(#)strerror.c 8.1 (Berkeley) 6/4/93"; 34 #endif /* LIBC_SCCS and not lint */ 35 #include "namespace.h" 36 #if defined(NLS) 37 #include <nl_types.h> 38 #endif 39 #include <limits.h> 40 #include <errno.h> 41 #include <stdlib.h> 42 #include <string.h> 43 #include <signal.h> 44 #include "reentrant.h" 45 #include "un-namespace.h" 46 47 #define UPREFIX "Unknown signal" 48 49 static char sig_ebuf[NL_TEXTMAX]; 50 static char sig_ebuf_err[NL_TEXTMAX]; 51 static once_t sig_init_once = ONCE_INITIALIZER; 52 static thread_key_t sig_key; 53 static int sig_keycreated = 0; 54 55 static void 56 sig_keycreate(void) 57 { 58 sig_keycreated = (thr_keycreate(&sig_key, free) == 0); 59 } 60 61 static char * 62 sig_tlsalloc(void) 63 { 64 char *ebuf = NULL; 65 66 if (thr_main() != 0) 67 ebuf = sig_ebuf; 68 else { 69 if (thr_once(&sig_init_once, sig_keycreate) != 0 || 70 !sig_keycreated) 71 goto thr_err; 72 if ((ebuf = thr_getspecific(sig_key)) == NULL) { 73 if ((ebuf = malloc(sizeof(sig_ebuf))) == NULL) 74 goto thr_err; 75 if (thr_setspecific(sig_key, ebuf) != 0) { 76 free(ebuf); 77 ebuf = NULL; 78 goto thr_err; 79 } 80 } 81 } 82 thr_err: 83 if (ebuf == NULL) 84 ebuf = sig_ebuf_err; 85 return (ebuf); 86 } 87 88 /* XXX: negative 'num' ? (REGR) */ 89 char * 90 strsignal(int num) 91 { 92 char *ebuf; 93 char tmp[20]; 94 size_t n; 95 int signum; 96 char *t, *p; 97 98 #if defined(NLS) 99 int saved_errno = errno; 100 nl_catd catd; 101 catd = catopen("libc", NL_CAT_LOCALE); 102 #endif 103 104 ebuf = sig_tlsalloc(); 105 106 if (num > 0 && num < sys_nsig) { 107 n = strlcpy(ebuf, 108 #if defined(NLS) 109 catgets(catd, 2, num, sys_siglist[num]), 110 #else 111 sys_siglist[num], 112 #endif 113 sizeof(sig_ebuf)); 114 } else { 115 n = strlcpy(ebuf, 116 #if defined(NLS) 117 catgets(catd, 2, 0xffff, UPREFIX), 118 #else 119 UPREFIX, 120 #endif 121 sizeof(sig_ebuf)); 122 123 signum = num; 124 if (num < 0) 125 signum = -signum; 126 127 t = tmp; 128 do { 129 *t++ = "0123456789"[signum % 10]; 130 } while (signum /= 10); 131 if (num < 0) 132 *t++ = '-'; 133 134 p = (ebuf + n); 135 *p++ = ':'; 136 *p++ = ' '; 137 138 for (;;) { 139 *p++ = *--t; 140 if (t <= tmp) 141 break; 142 } 143 *p = '\0'; 144 } 145 146 #if defined(NLS) 147 catclose(catd); 148 errno = saved_errno; 149 #endif 150 return (ebuf); 151 } 152