strerror.c revision 220376
175584Sru/*- 275584Sru * Copyright (c) 1988, 1993 375584Sru * The Regents of the University of California. All rights reserved. 475584Sru * 575584Sru * Redistribution and use in source and binary forms, with or without 675584Sru * modification, are permitted provided that the following conditions 775584Sru * are met: 875584Sru * 1. Redistributions of source code must retain the above copyright 975584Sru * notice, this list of conditions and the following disclaimer. 1075584Sru * 2. Redistributions in binary form must reproduce the above copyright 1175584Sru * notice, this list of conditions and the following disclaimer in the 1275584Sru * documentation and/or other materials provided with the distribution. 1375584Sru * 4. Neither the name of the University nor the names of its contributors 1475584Sru * may be used to endorse or promote products derived from this software 1575584Sru * without specific prior written permission. 1675584Sru * 1775584Sru * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 1875584Sru * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1975584Sru * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2075584Sru * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2175584Sru * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2275584Sru * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2375584Sru * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2475584Sru * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2575584Sru * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2675584Sru * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2775584Sru * SUCH DAMAGE. 2875584Sru */ 2975584Sru 3075584Sru#if defined(LIBC_SCCS) && !defined(lint) 3175584Srustatic char sccsid[] = "@(#)strerror.c 8.1 (Berkeley) 6/4/93"; 3275584Sru#endif /* LIBC_SCCS and not lint */ 3375584Sru#include <sys/cdefs.h> 3475584Sru__FBSDID("$FreeBSD: head/lib/libc/string/strerror.c 220376 2011-04-05 21:56:05Z jilles $"); 3575584Sru 3675584Sru#if defined(NLS) 3775584Sru#include <nl_types.h> 3875584Sru#endif 3975584Sru 4075584Sru#include <limits.h> 4175584Sru#include <errno.h> 4275584Sru#include <string.h> 4375584Sru#include <stdio.h> 4475584Sru 4575584Sru#define UPREFIX "Unknown error" 4675584Sru 4775584Sru/* 4875584Sru * Define a buffer size big enough to describe a 64-bit signed integer 4975584Sru * converted to ASCII decimal (19 bytes), with an optional leading sign 5075584Sru * (1 byte); finally, we get the prefix, delimiter (": ") and a trailing 5175584Sru * NUL from UPREFIX. 5275584Sru */ 5375584Sru#define EBUFSIZE (20 + 2 + sizeof(UPREFIX)) 5475584Sru 5575584Sru/* 5675584Sru * Doing this by hand instead of linking with stdio(3) avoids bloat for 5775584Sru * statically linked binaries. 5875584Sru */ 5975584Srustatic void 6075584Sruerrstr(int num, char *uprefix, char *buf, size_t len) 6175584Sru{ 6275584Sru char *t; 6375584Sru unsigned int uerr; 6475584Sru char tmp[EBUFSIZE]; 6575584Sru 6675584Sru t = tmp + sizeof(tmp); 6775584Sru *--t = '\0'; 6875584Sru uerr = (num >= 0) ? num : -num; 6975584Sru do { 7075584Sru *--t = "0123456789"[uerr % 10]; 7175584Sru } while (uerr /= 10); 7275584Sru if (num < 0) 7375584Sru *--t = '-'; 7475584Sru *--t = ' '; 7575584Sru *--t = ':'; 7675584Sru strlcpy(buf, uprefix, len); 7775584Sru strlcat(buf, t, len); 7875584Sru} 7975584Sru 8075584Sruint 8175584Srustrerror_r(int errnum, char *strerrbuf, size_t buflen) 8275584Sru{ 8375584Sru int retval = 0; 8475584Sru#if defined(NLS) 8575584Sru int saved_errno = errno; 8675584Sru nl_catd catd; 8775584Sru catd = catopen("libc", NL_CAT_LOCALE); 8875584Sru#endif 8975584Sru 9075584Sru if (errnum < 0 || errnum >= sys_nerr) { 9175584Sru errstr(errnum, 9275584Sru#if defined(NLS) 9375584Sru catgets(catd, 1, 0xffff, UPREFIX), 9475584Sru#else 9575584Sru UPREFIX, 9675584Sru#endif 9775584Sru strerrbuf, buflen); 9875584Sru retval = EINVAL; 9975584Sru } else { 10075584Sru if (strlcpy(strerrbuf, 10175584Sru#if defined(NLS) 10275584Sru catgets(catd, 1, errnum, sys_errlist[errnum]), 10375584Sru#else 10475584Sru sys_errlist[errnum], 10575584Sru#endif 10675584Sru buflen) >= buflen) 10775584Sru retval = ERANGE; 10875584Sru } 10975584Sru 11075584Sru#if defined(NLS) 11175584Sru catclose(catd); 11275584Sru errno = saved_errno; 11375584Sru#endif 11475584Sru 11575584Sru return (retval); 11675584Sru} 11775584Sru 11875584Sruchar * 11975584Srustrerror(int num) 12075584Sru{ 12175584Sru static char ebuf[NL_TEXTMAX]; 12275584Sru 12375584Sru if (strerror_r(num, ebuf, sizeof(ebuf)) != 0) 12475584Sru errno = EINVAL; 12575584Sru return (ebuf); 12675584Sru} 12775584Sru