1108118Smike/*-
21573Srgrimes * Copyright (c) 1988, 1993
31573Srgrimes *	The Regents of the University of California.  All rights reserved.
41573Srgrimes *
51573Srgrimes * Redistribution and use in source and binary forms, with or without
61573Srgrimes * modification, are permitted provided that the following conditions
71573Srgrimes * are met:
81573Srgrimes * 1. Redistributions of source code must retain the above copyright
91573Srgrimes *    notice, this list of conditions and the following disclaimer.
101573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111573Srgrimes *    notice, this list of conditions and the following disclaimer in the
121573Srgrimes *    documentation and/or other materials provided with the distribution.
13251069Semaste * 3. Neither the name of the University nor the names of its contributors
141573Srgrimes *    may be used to endorse or promote products derived from this software
151573Srgrimes *    without specific prior written permission.
161573Srgrimes *
171573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
181573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
191573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
201573Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
211573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
221573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
231573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
241573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
251573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
261573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
271573Srgrimes * SUCH DAMAGE.
281573Srgrimes */
291573Srgrimes
301573Srgrimes#if defined(LIBC_SCCS) && !defined(lint)
311573Srgrimesstatic char sccsid[] = "@(#)strerror.c	8.1 (Berkeley) 6/4/93";
321573Srgrimes#endif /* LIBC_SCCS and not lint */
3386170Sobrien#include <sys/cdefs.h>
3486170Sobrien__FBSDID("$FreeBSD$");
351573Srgrimes
36142667Sphantom#if defined(NLS)
37142667Sphantom#include <nl_types.h>
38142667Sphantom#endif
39142667Sphantom
40142693Sphantom#include <limits.h>
41108044Smike#include <errno.h>
42142667Sphantom#include <string.h>
432505Sbde#include <stdio.h>
441573Srgrimes
45255108Sjilles#include "errlst.h"
46255108Sjilles
47142667Sphantom#define	UPREFIX		"Unknown error"
48108118Smike
49108044Smike/*
50108044Smike * Define a buffer size big enough to describe a 64-bit signed integer
51108044Smike * converted to ASCII decimal (19 bytes), with an optional leading sign
52142667Sphantom * (1 byte); finally, we get the prefix, delimiter (": ") and a trailing
53142667Sphantom * NUL from UPREFIX.
54108044Smike */
55142667Sphantom#define	EBUFSIZE	(20 + 2 + sizeof(UPREFIX))
561573Srgrimes
57108118Smike/*
58108118Smike * Doing this by hand instead of linking with stdio(3) avoids bloat for
59108118Smike * statically linked binaries.
60108118Smike */
61108044Smikestatic void
62142667Sphantomerrstr(int num, char *uprefix, char *buf, size_t len)
6387434Swes{
64108603Smike	char *t;
65108044Smike	unsigned int uerr;
66108044Smike	char tmp[EBUFSIZE];
6787434Swes
68108603Smike	t = tmp + sizeof(tmp);
69108603Smike	*--t = '\0';
70108044Smike	uerr = (num >= 0) ? num : -num;
711573Srgrimes	do {
72108603Smike		*--t = "0123456789"[uerr % 10];
7386944Swes	} while (uerr /= 10);
7487434Swes	if (num < 0)
75108603Smike		*--t = '-';
76142667Sphantom	*--t = ' ';
77142667Sphantom	*--t = ':';
78142667Sphantom	strlcpy(buf, uprefix, len);
79114443Snectar	strlcat(buf, t, len);
801573Srgrimes}
8186944Swes
82108044Smikeint
83108044Smikestrerror_r(int errnum, char *strerrbuf, size_t buflen)
84108044Smike{
85142667Sphantom	int retval = 0;
86142667Sphantom#if defined(NLS)
87142667Sphantom	int saved_errno = errno;
88142667Sphantom	nl_catd catd;
89142667Sphantom	catd = catopen("libc", NL_CAT_LOCALE);
90142667Sphantom#endif
9186944Swes
92255108Sjilles	if (errnum < 0 || errnum >= __hidden_sys_nerr) {
93142667Sphantom		errstr(errnum,
94142667Sphantom#if defined(NLS)
95142667Sphantom			catgets(catd, 1, 0xffff, UPREFIX),
96142667Sphantom#else
97142667Sphantom			UPREFIX,
98142667Sphantom#endif
99142667Sphantom			strerrbuf, buflen);
100142667Sphantom		retval = EINVAL;
101142667Sphantom	} else {
102142667Sphantom		if (strlcpy(strerrbuf,
103142667Sphantom#if defined(NLS)
104255108Sjilles			catgets(catd, 1, errnum, __hidden_sys_errlist[errnum]),
105142667Sphantom#else
106255108Sjilles			__hidden_sys_errlist[errnum],
107142667Sphantom#endif
108142667Sphantom			buflen) >= buflen)
109142667Sphantom		retval = ERANGE;
110108118Smike	}
111142667Sphantom
112142667Sphantom#if defined(NLS)
113142667Sphantom	catclose(catd);
114142667Sphantom	errno = saved_errno;
115142667Sphantom#endif
116142667Sphantom
117142667Sphantom	return (retval);
118108044Smike}
11986944Swes
120108044Smikechar *
121108044Smikestrerror(int num)
12286944Swes{
123142667Sphantom	static char ebuf[NL_TEXTMAX];
12486944Swes
125142667Sphantom	if (strerror_r(num, ebuf, sizeof(ebuf)) != 0)
126232973Skib		errno = EINVAL;
127108044Smike	return (ebuf);
12886944Swes}
129