xref: /freebsd/lib/libc/string/strsignal.c (revision b8d472d710a89d29a70ef1d98120ad6d9d84521f)
178121e79SPeter Wemm /*
278121e79SPeter Wemm  * Copyright (c) 1988, 1993
378121e79SPeter Wemm  *	The Regents of the University of California.  All rights reserved.
478121e79SPeter Wemm  *
578121e79SPeter Wemm  * Redistribution and use in source and binary forms, with or without
678121e79SPeter Wemm  * modification, are permitted provided that the following conditions
778121e79SPeter Wemm  * are met:
878121e79SPeter Wemm  * 1. Redistributions of source code must retain the above copyright
978121e79SPeter Wemm  *    notice, this list of conditions and the following disclaimer.
1078121e79SPeter Wemm  * 2. Redistributions in binary form must reproduce the above copyright
1178121e79SPeter Wemm  *    notice, this list of conditions and the following disclaimer in the
1278121e79SPeter Wemm  *    documentation and/or other materials provided with the distribution.
1378121e79SPeter Wemm  * 4. Neither the name of the University nor the names of its contributors
1478121e79SPeter Wemm  *    may be used to endorse or promote products derived from this software
1578121e79SPeter Wemm  *    without specific prior written permission.
1678121e79SPeter Wemm  *
1778121e79SPeter Wemm  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1878121e79SPeter Wemm  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1978121e79SPeter Wemm  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2078121e79SPeter Wemm  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2178121e79SPeter Wemm  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2278121e79SPeter Wemm  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2378121e79SPeter Wemm  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2478121e79SPeter Wemm  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2578121e79SPeter Wemm  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2678121e79SPeter Wemm  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2778121e79SPeter Wemm  * SUCH DAMAGE.
2878121e79SPeter Wemm  */
2978121e79SPeter Wemm 
3078121e79SPeter Wemm #if defined(LIBC_SCCS) && !defined(lint)
3178121e79SPeter Wemm static char sccsid[] = "@(#)strerror.c	8.1 (Berkeley) 6/4/93";
3278121e79SPeter Wemm #endif /* LIBC_SCCS and not lint */
33de5fe5d5SDavid E. O'Brien #include <sys/cdefs.h>
34de5fe5d5SDavid E. O'Brien __FBSDID("$FreeBSD$");
3578121e79SPeter Wemm 
364f86602cSHajimu UMEMOTO #include "namespace.h"
37fba5c5faSAlexey Zelkin #if defined(NLS)
38fba5c5faSAlexey Zelkin #include <nl_types.h>
39fba5c5faSAlexey Zelkin #endif
40fc7c3528SAlexey Zelkin #include <limits.h>
41fba5c5faSAlexey Zelkin #include <errno.h>
424f86602cSHajimu UMEMOTO #include <stdlib.h>
4378121e79SPeter Wemm #include <string.h>
4478121e79SPeter Wemm #include <signal.h>
454f86602cSHajimu UMEMOTO #include "reentrant.h"
464f86602cSHajimu UMEMOTO #include "un-namespace.h"
4778121e79SPeter Wemm 
48fba5c5faSAlexey Zelkin #define	UPREFIX		"Unknown signal"
49fba5c5faSAlexey Zelkin 
504f86602cSHajimu UMEMOTO static char		sig_ebuf[NL_TEXTMAX];
514f86602cSHajimu UMEMOTO static char		sig_ebuf_err[NL_TEXTMAX];
524f86602cSHajimu UMEMOTO static once_t		sig_init_once = ONCE_INITIALIZER;
534f86602cSHajimu UMEMOTO static thread_key_t	sig_key;
544f86602cSHajimu UMEMOTO static int		sig_keycreated = 0;
554f86602cSHajimu UMEMOTO 
564f86602cSHajimu UMEMOTO static void
574f86602cSHajimu UMEMOTO sig_keycreate(void)
584f86602cSHajimu UMEMOTO {
594f86602cSHajimu UMEMOTO 	sig_keycreated = (thr_keycreate(&sig_key, free) == 0);
604f86602cSHajimu UMEMOTO }
614f86602cSHajimu UMEMOTO 
624f86602cSHajimu UMEMOTO static char *
634f86602cSHajimu UMEMOTO sig_tlsalloc(void)
644f86602cSHajimu UMEMOTO {
654f86602cSHajimu UMEMOTO 	char *ebuf = NULL;
664f86602cSHajimu UMEMOTO 
674f86602cSHajimu UMEMOTO 	if (thr_main() != 0)
684f86602cSHajimu UMEMOTO 		ebuf = sig_ebuf;
694f86602cSHajimu UMEMOTO 	else {
704f86602cSHajimu UMEMOTO 		if (thr_once(&sig_init_once, sig_keycreate) != 0 ||
714f86602cSHajimu UMEMOTO 		    !sig_keycreated)
724f86602cSHajimu UMEMOTO 			goto thr_err;
734f86602cSHajimu UMEMOTO 		if ((ebuf = thr_getspecific(sig_key)) == NULL) {
744f86602cSHajimu UMEMOTO 			if ((ebuf = malloc(sizeof(sig_ebuf))) == NULL)
754f86602cSHajimu UMEMOTO 				goto thr_err;
764f86602cSHajimu UMEMOTO 			if (thr_setspecific(sig_key, ebuf) != 0) {
774f86602cSHajimu UMEMOTO 				free(ebuf);
784f86602cSHajimu UMEMOTO 				ebuf = NULL;
794f86602cSHajimu UMEMOTO 				goto thr_err;
804f86602cSHajimu UMEMOTO 			}
814f86602cSHajimu UMEMOTO 		}
824f86602cSHajimu UMEMOTO 	}
834f86602cSHajimu UMEMOTO thr_err:
844f86602cSHajimu UMEMOTO 	if (ebuf == NULL)
854f86602cSHajimu UMEMOTO 		ebuf = sig_ebuf_err;
864f86602cSHajimu UMEMOTO 	return (ebuf);
874f86602cSHajimu UMEMOTO }
884f86602cSHajimu UMEMOTO 
89fba5c5faSAlexey Zelkin /* XXX: negative 'num' ? (REGR) */
9078121e79SPeter Wemm char *
91fba5c5faSAlexey Zelkin strsignal(int num)
9278121e79SPeter Wemm {
934f86602cSHajimu UMEMOTO 	char *ebuf;
94fba5c5faSAlexey Zelkin 	char tmp[20];
95cea5da04SMaxime Henrion 	size_t n;
96cea5da04SMaxime Henrion 	int signum;
97fba5c5faSAlexey Zelkin 	char *t, *p;
9878121e79SPeter Wemm 
99fba5c5faSAlexey Zelkin #if defined(NLS)
100fba5c5faSAlexey Zelkin 	int saved_errno = errno;
101fba5c5faSAlexey Zelkin 	nl_catd catd;
102fba5c5faSAlexey Zelkin 	catd = catopen("libc", NL_CAT_LOCALE);
103fba5c5faSAlexey Zelkin #endif
10478121e79SPeter Wemm 
1054f86602cSHajimu UMEMOTO 	ebuf = sig_tlsalloc();
1064f86602cSHajimu UMEMOTO 
107fba5c5faSAlexey Zelkin 	if (num > 0 && num < sys_nsig) {
108cea5da04SMaxime Henrion 		n = strlcpy(ebuf,
109fba5c5faSAlexey Zelkin #if defined(NLS)
110fba5c5faSAlexey Zelkin 			catgets(catd, 2, num, sys_siglist[num]),
111fba5c5faSAlexey Zelkin #else
112fba5c5faSAlexey Zelkin 			sys_siglist[num],
113fba5c5faSAlexey Zelkin #endif
1144f86602cSHajimu UMEMOTO 			sizeof(sig_ebuf));
115fba5c5faSAlexey Zelkin 	} else {
116fba5c5faSAlexey Zelkin 		n = strlcpy(ebuf,
117fba5c5faSAlexey Zelkin #if defined(NLS)
118fba5c5faSAlexey Zelkin 			catgets(catd, 2, 0xffff, UPREFIX),
119fba5c5faSAlexey Zelkin #else
120fba5c5faSAlexey Zelkin 			UPREFIX,
121fba5c5faSAlexey Zelkin #endif
1224f86602cSHajimu UMEMOTO 			sizeof(sig_ebuf));
123fba5c5faSAlexey Zelkin 
124fba5c5faSAlexey Zelkin 	signum = num;
12578121e79SPeter Wemm 	if (num < 0)
12678121e79SPeter Wemm 		signum = -signum;
127fba5c5faSAlexey Zelkin 
128fba5c5faSAlexey Zelkin 	t = tmp;
12978121e79SPeter Wemm 	do {
13078121e79SPeter Wemm 		*t++ = "0123456789"[signum % 10];
13178121e79SPeter Wemm 	} while (signum /= 10);
13278121e79SPeter Wemm 	if (num < 0)
13378121e79SPeter Wemm 		*t++ = '-';
134fba5c5faSAlexey Zelkin 
135fba5c5faSAlexey Zelkin 	p = (ebuf + n);
136fba5c5faSAlexey Zelkin 	*p++ = ':';
137fba5c5faSAlexey Zelkin 	*p++ = ' ';
138fba5c5faSAlexey Zelkin 
139fba5c5faSAlexey Zelkin 	for (;;) {
14078121e79SPeter Wemm 		*p++ = *--t;
14178121e79SPeter Wemm 		if (t <= tmp)
14278121e79SPeter Wemm 			break;
14378121e79SPeter Wemm 	}
14478121e79SPeter Wemm 	*p = '\0';
145*b8d472d7SJilles Tjoelker 	}
146fba5c5faSAlexey Zelkin 
147fba5c5faSAlexey Zelkin #if defined(NLS)
148fba5c5faSAlexey Zelkin 	catclose(catd);
149fba5c5faSAlexey Zelkin 	errno = saved_errno;
150fba5c5faSAlexey Zelkin #endif
15178121e79SPeter Wemm 	return (ebuf);
15278121e79SPeter Wemm }
153