strerror.c revision 251069
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: head/lib/libc/string/strerror.c 251069 2013-05-28 20:57:40Z emaste $");
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
45142667Sphantom#define	UPREFIX		"Unknown error"
46108118Smike
47108044Smike/*
48108044Smike * Define a buffer size big enough to describe a 64-bit signed integer
49108044Smike * converted to ASCII decimal (19 bytes), with an optional leading sign
50142667Sphantom * (1 byte); finally, we get the prefix, delimiter (": ") and a trailing
51142667Sphantom * NUL from UPREFIX.
52108044Smike */
53142667Sphantom#define	EBUFSIZE	(20 + 2 + sizeof(UPREFIX))
541573Srgrimes
55108118Smike/*
56108118Smike * Doing this by hand instead of linking with stdio(3) avoids bloat for
57108118Smike * statically linked binaries.
58108118Smike */
59108044Smikestatic void
60142667Sphantomerrstr(int num, char *uprefix, char *buf, size_t len)
6187434Swes{
62108603Smike	char *t;
63108044Smike	unsigned int uerr;
64108044Smike	char tmp[EBUFSIZE];
6587434Swes
66108603Smike	t = tmp + sizeof(tmp);
67108603Smike	*--t = '\0';
68108044Smike	uerr = (num >= 0) ? num : -num;
691573Srgrimes	do {
70108603Smike		*--t = "0123456789"[uerr % 10];
7186944Swes	} while (uerr /= 10);
7287434Swes	if (num < 0)
73108603Smike		*--t = '-';
74142667Sphantom	*--t = ' ';
75142667Sphantom	*--t = ':';
76142667Sphantom	strlcpy(buf, uprefix, len);
77114443Snectar	strlcat(buf, t, len);
781573Srgrimes}
7986944Swes
80108044Smikeint
81108044Smikestrerror_r(int errnum, char *strerrbuf, size_t buflen)
82108044Smike{
83142667Sphantom	int retval = 0;
84142667Sphantom#if defined(NLS)
85142667Sphantom	int saved_errno = errno;
86142667Sphantom	nl_catd catd;
87142667Sphantom	catd = catopen("libc", NL_CAT_LOCALE);
88142667Sphantom#endif
8986944Swes
90220376Sjilles	if (errnum < 0 || errnum >= sys_nerr) {
91142667Sphantom		errstr(errnum,
92142667Sphantom#if defined(NLS)
93142667Sphantom			catgets(catd, 1, 0xffff, UPREFIX),
94142667Sphantom#else
95142667Sphantom			UPREFIX,
96142667Sphantom#endif
97142667Sphantom			strerrbuf, buflen);
98142667Sphantom		retval = EINVAL;
99142667Sphantom	} else {
100142667Sphantom		if (strlcpy(strerrbuf,
101142667Sphantom#if defined(NLS)
102142667Sphantom			catgets(catd, 1, errnum, sys_errlist[errnum]),
103142667Sphantom#else
104142667Sphantom			sys_errlist[errnum],
105142667Sphantom#endif
106142667Sphantom			buflen) >= buflen)
107142667Sphantom		retval = ERANGE;
108108118Smike	}
109142667Sphantom
110142667Sphantom#if defined(NLS)
111142667Sphantom	catclose(catd);
112142667Sphantom	errno = saved_errno;
113142667Sphantom#endif
114142667Sphantom
115142667Sphantom	return (retval);
116108044Smike}
11786944Swes
118108044Smikechar *
119108044Smikestrerror(int num)
12086944Swes{
121142667Sphantom	static char ebuf[NL_TEXTMAX];
12286944Swes
123142667Sphantom	if (strerror_r(num, ebuf, sizeof(ebuf)) != 0)
124232973Skib		errno = EINVAL;
125108044Smike	return (ebuf);
12686944Swes}
127