strerror.c revision 87480
1/*
2 * Copyright (c) 1988, 1993
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 *    must display the following acknowledgement:
15 *	This product includes software developed by the University of
16 *	California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if defined(LIBC_SCCS) && !defined(lint)
35static 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 87480 2001-12-07 06:28:58Z wes $");
39
40#include <stdio.h>
41#include <string.h>
42#include <errno.h>
43
44int
45strerror_r(int errnum, char *strerrbuf, size_t buflen)
46{
47	int             len;
48
49	if ((errnum >= 0) && (errnum < sys_nerr)) {
50		len = strlcpy(strerrbuf, (char *)sys_errlist[errnum], buflen);
51		return ((len < buflen) ? 0 : ERANGE);
52	}
53	return (EINVAL);
54}
55
56char *
57strerror(num)
58	int             num;
59{
60	char           *p, *t;
61	unsigned int	uerr;
62	static char const unknown_prefix[] = "Unknown error: ";
63
64	/*
65	 * Define a buffer size big enough to describe a 64-bit
66	 * number in ASCII decimal (19), with optional leading sign
67	 * (+1) and trailing NUL (+1).
68	 */
69#       define		NUMLEN 21
70#	define		EBUFLEN (sizeof unknown_prefix + NUMLEN)
71	char            tmp[NUMLEN];	/* temporary number */
72	static char     ebuf[EBUFLEN];	/* error message */
73
74	if ((num >= 0) && (num < sys_nerr))
75		return ((char *)sys_errlist[num]);
76
77	/*
78	 * Set errno to EINVAL per P1003.1-200x Draft June 14, 2001.
79	 */
80	errno = EINVAL;
81
82	/*
83	 * Print unknown errno by hand so we don't link to stdio(3).
84	 * This collects the ASCII digits in reverse order.
85	 */
86	uerr = (num > 0) ? num : -num;
87	t = tmp;
88	do {
89		*t++ = "0123456789"[uerr % 10];
90	} while (uerr /= 10);
91	if (num < 0)
92		*t++ = '-';
93
94	/*
95	 * Copy the "unknown" message and the number into the caller
96	 * supplied buffer, inverting the number string.
97	 */
98	strcpy(ebuf, unknown_prefix);
99	for (p = ebuf + sizeof unknown_prefix - 1; t >= tmp; )
100		*p++ = *--t;
101	*p = '\0';
102	return (ebuf);
103}
104
105#ifdef STANDALONE_TEST
106
107#include <limits.h>
108
109main()
110{
111	char            mybuf[64];
112	int             ret;
113
114	errno = 0;
115
116	printf("strerror(0) yeilds: %s\n", strerror(0));
117	printf("strerror(1) yeilds: %s\n", strerror(1));
118	printf("strerror(47) yeilds: %s\n", strerror(47));
119	printf("strerror(sys_nerr - 1) yeilds: %s\n", strerror(sys_nerr - 1));
120	printf("errno = %d\n", errno); errno = 0;
121
122	printf("strerror(sys_nerr) yeilds: %s\n", strerror(sys_nerr));
123	printf("errno = %d\n", errno);  errno = 0;
124
125	printf("strerror(437) yeilds: %s\n", strerror(437));
126	printf("errno = %d\n", errno);  errno = 0;
127
128	printf("strerror(LONG_MAX) yeilds: %s\n", strerror(LONG_MAX));
129	printf("strerror(LONG_MIN) yeilds: %s\n", strerror(LONG_MIN));
130	printf("strerror(ULONG_MAX) yeilds: %s\n", strerror(ULONG_MAX));
131
132	memset(mybuf, '*', 63); mybuf[63] = '\0';
133	strerror_r(11, mybuf, 64);
134	printf("strerror_r(11) yeilds: %s\n", mybuf);
135
136	memset(mybuf, '*', 63); mybuf[63] = '\0';
137	ret = strerror_r(1234, mybuf, 64);
138	printf("strerror_r(1234) returns %d (%s)\n", ret, mybuf);
139
140	memset(mybuf, '*', 63); mybuf[63] = '\0';
141	ret = strerror_r(1, mybuf, 10);
142	printf("strerror_r on short buffer returns %d (%s)\n", ret, mybuf);
143}
144#endif
145