strerror.c revision 108044
10Sstevel@tonic-gate/*
20Sstevel@tonic-gate * Copyright (c) 1988, 1993
30Sstevel@tonic-gate *	The Regents of the University of California.  All rights reserved.
40Sstevel@tonic-gate *
50Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without
60Sstevel@tonic-gate * modification, are permitted provided that the following conditions
70Sstevel@tonic-gate * are met:
80Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright
90Sstevel@tonic-gate *    notice, this list of conditions and the following disclaimer.
100Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright
110Sstevel@tonic-gate *    notice, this list of conditions and the following disclaimer in the
120Sstevel@tonic-gate *    documentation and/or other materials provided with the distribution.
130Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this software
140Sstevel@tonic-gate *    must display the following acknowledgement:
150Sstevel@tonic-gate *	This product includes software developed by the University of
160Sstevel@tonic-gate *	California, Berkeley and its contributors.
170Sstevel@tonic-gate * 4. Neither the name of the University nor the names of its contributors
180Sstevel@tonic-gate *    may be used to endorse or promote products derived from this software
190Sstevel@tonic-gate *    without specific prior written permission.
200Sstevel@tonic-gate *
210Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
220Sstevel@tonic-gate * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
230Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
240Sstevel@tonic-gate * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
250Sstevel@tonic-gate * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
260Sstevel@tonic-gate * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
270Sstevel@tonic-gate * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
280Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
290Sstevel@tonic-gate * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
300Sstevel@tonic-gate * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
310Sstevel@tonic-gate * SUCH DAMAGE.
320Sstevel@tonic-gate */
330Sstevel@tonic-gate
340Sstevel@tonic-gate#if defined(LIBC_SCCS) && !defined(lint)
350Sstevel@tonic-gatestatic char sccsid[] = "@(#)strerror.c	8.1 (Berkeley) 6/4/93";
36#endif /* LIBC_SCCS and not lint */
37#include <sys/cdefs.h>
38__FBSDID("$FreeBSD: head/lib/libc/string/strerror.c 108044 2002-12-18 16:53:31Z mike $");
39
40#include <errno.h>
41#include <stdio.h>
42#include <string.h>
43
44#define	UPREFIX		"Unknown error: "
45/*
46 * Define a buffer size big enough to describe a 64-bit signed integer
47 * converted to ASCII decimal (19 bytes), with an optional leading sign
48 * (1 byte), finally we get the prefix and a trailing NUL from UPREFIX.
49 */
50#define	EBUFSIZE	(20 + sizeof(UPREFIX))
51
52/* Don't link to stdio(3) to avoid bloat for statically linked binaries. */
53static void
54errstr(int num, char *buf, size_t len)
55{
56	unsigned int uerr;
57	char *p, *t;
58	char tmp[EBUFSIZE];
59
60	if (strlcpy(buf, UPREFIX, len) >= len)
61		return;
62	t = tmp;
63	uerr = (num >= 0) ? num : -num;
64	do {
65		*t++ = "0123456789"[uerr % 10];
66	} while (uerr /= 10);
67	if (num < 0)
68		*t++ = '-';
69	for (p = buf + strlen(UPREFIX); t > tmp && p < buf + len - 1;)
70		*p++ = *--t;
71	*p = '\0';
72}
73
74int
75strerror_r(int errnum, char *strerrbuf, size_t buflen)
76{
77	int retval;
78
79	retval = 0;
80	if (errnum < 1 || errnum >= sys_nerr) {
81		errstr(errnum, strerrbuf, buflen);
82		retval = EINVAL;
83	} else if (strlcpy(strerrbuf, sys_errlist[errnum], buflen) >= buflen)
84		retval = ERANGE;
85	return (retval);
86}
87
88char *
89strerror(int num)
90{
91	static char ebuf[EBUFSIZE];
92
93	if (num > 0 && num < sys_nerr)
94		return ((char *)sys_errlist[num]);
95	errno = EINVAL;
96	errstr(num, ebuf, sizeof(ebuf));
97	return (ebuf);
98}
99