strerror.c revision 142667
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.
131573Srgrimes * 3. All advertising materials mentioning features or use of this software
141573Srgrimes *    must display the following acknowledgement:
151573Srgrimes *	This product includes software developed by the University of
161573Srgrimes *	California, Berkeley and its contributors.
171573Srgrimes * 4. Neither the name of the University nor the names of its contributors
181573Srgrimes *    may be used to endorse or promote products derived from this software
191573Srgrimes *    without specific prior written permission.
201573Srgrimes *
211573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
221573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
231573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
241573Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
251573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
261573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
271573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
281573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
291573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
301573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
311573Srgrimes * SUCH DAMAGE.
321573Srgrimes */
331573Srgrimes
341573Srgrimes#if defined(LIBC_SCCS) && !defined(lint)
351573Srgrimesstatic char sccsid[] = "@(#)strerror.c	8.1 (Berkeley) 6/4/93";
361573Srgrimes#endif /* LIBC_SCCS and not lint */
3786170Sobrien#include <sys/cdefs.h>
3886170Sobrien__FBSDID("$FreeBSD: head/lib/libc/string/strerror.c 142667 2005-02-27 16:58:28Z phantom $");
391573Srgrimes
40142667Sphantom#if defined(NLS)
41142667Sphantom#include <limits.h>
42142667Sphantom#include <nl_types.h>
43142667Sphantom#endif
44142667Sphantom
45108044Smike#include <errno.h>
46142667Sphantom#include <string.h>
472505Sbde#include <stdio.h>
481573Srgrimes
49142667Sphantom#define	UPREFIX		"Unknown error"
50108118Smike
51108044Smike/*
52108044Smike * Define a buffer size big enough to describe a 64-bit signed integer
53108044Smike * converted to ASCII decimal (19 bytes), with an optional leading sign
54142667Sphantom * (1 byte); finally, we get the prefix, delimiter (": ") and a trailing
55142667Sphantom * NUL from UPREFIX.
56108044Smike */
57142667Sphantom#define	EBUFSIZE	(20 + 2 + sizeof(UPREFIX))
581573Srgrimes
59108118Smike/*
60108118Smike * Doing this by hand instead of linking with stdio(3) avoids bloat for
61108118Smike * statically linked binaries.
62108118Smike */
63108044Smikestatic void
64142667Sphantomerrstr(int num, char *uprefix, char *buf, size_t len)
6587434Swes{
66108603Smike	char *t;
67108044Smike	unsigned int uerr;
68108044Smike	char tmp[EBUFSIZE];
6987434Swes
70108603Smike	t = tmp + sizeof(tmp);
71108603Smike	*--t = '\0';
72108044Smike	uerr = (num >= 0) ? num : -num;
731573Srgrimes	do {
74108603Smike		*--t = "0123456789"[uerr % 10];
7586944Swes	} while (uerr /= 10);
7687434Swes	if (num < 0)
77108603Smike		*--t = '-';
78142667Sphantom	*--t = ' ';
79142667Sphantom	*--t = ':';
80142667Sphantom	strlcpy(buf, uprefix, len);
81114443Snectar	strlcat(buf, t, len);
821573Srgrimes}
8386944Swes
84108044Smikeint
85108044Smikestrerror_r(int errnum, char *strerrbuf, size_t buflen)
86108044Smike{
87142667Sphantom	int retval = 0;
88142667Sphantom#if defined(NLS)
89142667Sphantom	int saved_errno = errno;
90142667Sphantom	nl_catd catd;
91142667Sphantom	catd = catopen("libc", NL_CAT_LOCALE);
92142667Sphantom#endif
9386944Swes
94108044Smike	if (errnum < 1 || errnum >= sys_nerr) {
95142667Sphantom		errstr(errnum,
96142667Sphantom#if defined(NLS)
97142667Sphantom			catgets(catd, 1, 0xffff, UPREFIX),
98142667Sphantom#else
99142667Sphantom			UPREFIX,
100142667Sphantom#endif
101142667Sphantom			strerrbuf, buflen);
102142667Sphantom		retval = EINVAL;
103142667Sphantom	} else {
104142667Sphantom		if (strlcpy(strerrbuf,
105142667Sphantom#if defined(NLS)
106142667Sphantom			catgets(catd, 1, errnum, sys_errlist[errnum]),
107142667Sphantom#else
108142667Sphantom			sys_errlist[errnum],
109142667Sphantom#endif
110142667Sphantom			buflen) >= buflen)
111142667Sphantom		retval = ERANGE;
112108118Smike	}
113142667Sphantom
114142667Sphantom#if defined(NLS)
115142667Sphantom	catclose(catd);
116142667Sphantom	errno = saved_errno;
117142667Sphantom#endif
118142667Sphantom
119142667Sphantom	return (retval);
120108044Smike}
12186944Swes
122108044Smikechar *
123108044Smikestrerror(int num)
12486944Swes{
125142667Sphantom	static char ebuf[NL_TEXTMAX];
12686944Swes
127142667Sphantom	if (strerror_r(num, ebuf, sizeof(ebuf)) != 0)
128108044Smike	errno = EINVAL;
129108044Smike	return (ebuf);
13086944Swes}
131