158f0484fSRodney W. Grimes /* 258f0484fSRodney W. Grimes * Copyright (c) 1988, 1993 358f0484fSRodney W. Grimes * The Regents of the University of California. All rights reserved. 458f0484fSRodney W. Grimes * 558f0484fSRodney W. Grimes * Redistribution and use in source and binary forms, with or without 658f0484fSRodney W. Grimes * modification, are permitted provided that the following conditions 758f0484fSRodney W. Grimes * are met: 858f0484fSRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 958f0484fSRodney W. Grimes * notice, this list of conditions and the following disclaimer. 1058f0484fSRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 1158f0484fSRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 1258f0484fSRodney W. Grimes * documentation and/or other materials provided with the distribution. 1358f0484fSRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 1458f0484fSRodney W. Grimes * must display the following acknowledgement: 1558f0484fSRodney W. Grimes * This product includes software developed by the University of 1658f0484fSRodney W. Grimes * California, Berkeley and its contributors. 1758f0484fSRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 1858f0484fSRodney W. Grimes * may be used to endorse or promote products derived from this software 1958f0484fSRodney W. Grimes * without specific prior written permission. 2058f0484fSRodney W. Grimes * 2158f0484fSRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2258f0484fSRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2358f0484fSRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2458f0484fSRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2558f0484fSRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2658f0484fSRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2758f0484fSRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2858f0484fSRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2958f0484fSRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3058f0484fSRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3158f0484fSRodney W. Grimes * SUCH DAMAGE. 3258f0484fSRodney W. Grimes */ 3358f0484fSRodney W. Grimes 3458f0484fSRodney W. Grimes #if defined(LIBC_SCCS) && !defined(lint) 3558f0484fSRodney W. Grimes static char sccsid[] = "@(#)strerror.c 8.1 (Berkeley) 6/4/93"; 3658f0484fSRodney W. Grimes #endif /* LIBC_SCCS and not lint */ 37de5fe5d5SDavid E. O'Brien #include <sys/cdefs.h> 38de5fe5d5SDavid E. O'Brien __FBSDID("$FreeBSD$"); 3958f0484fSRodney W. Grimes 405ec11cf0SBruce Evans #include <stdio.h> 4158f0484fSRodney W. Grimes #include <string.h> 429c324dc0SWes Peters #include <errno.h> 439c324dc0SWes Peters 449c324dc0SWes Peters 459c324dc0SWes Peters int 469c324dc0SWes Peters strerror_r(int errnum, char *strerrbuf, size_t buflen) 479c324dc0SWes Peters { 489c324dc0SWes Peters #define UPREFIX "Unknown error: " 499c324dc0SWes Peters unsigned int uerr; 509c324dc0SWes Peters char *p, *t; 519c324dc0SWes Peters char tmp[40]; /* 64-bit number + slop */ 529c324dc0SWes Peters int len; 539c324dc0SWes Peters 549c324dc0SWes Peters uerr = errnum; /* convert to unsigned */ 559c324dc0SWes Peters if (uerr < sys_nerr) { 569c324dc0SWes Peters len = strlcpy(strerrbuf, (char *)sys_errlist[uerr], buflen); 579c324dc0SWes Peters return (len <= buflen) ? 0 : ERANGE; 589c324dc0SWes Peters } 599c324dc0SWes Peters 609c324dc0SWes Peters /* Print unknown errno by hand so we don't link to stdio(3). */ 619c324dc0SWes Peters t = tmp; 629c324dc0SWes Peters if (errnum < 0) 639c324dc0SWes Peters uerr = -uerr; 649c324dc0SWes Peters do { 659c324dc0SWes Peters *t++ = "0123456789"[uerr % 10]; 669c324dc0SWes Peters } while (uerr /= 10); 679c324dc0SWes Peters 689c324dc0SWes Peters if (errnum < 0) 699c324dc0SWes Peters *t++ = '-'; 709c324dc0SWes Peters 719c324dc0SWes Peters strlcpy(strerrbuf, UPREFIX, buflen); 729c324dc0SWes Peters for (p = strerrbuf + sizeof(UPREFIX) - 1; p < strerrbuf + buflen; ) { 739c324dc0SWes Peters *p++ = *--t; 749c324dc0SWes Peters if (t <= tmp) 759c324dc0SWes Peters break; 769c324dc0SWes Peters } 779c324dc0SWes Peters 789c324dc0SWes Peters if (p < strerrbuf + buflen) { 799c324dc0SWes Peters *p = '\0'; 809c324dc0SWes Peters return 0; 819c324dc0SWes Peters } 829c324dc0SWes Peters 839c324dc0SWes Peters return ERANGE; 849c324dc0SWes Peters } 859c324dc0SWes Peters 869c324dc0SWes Peters 879c324dc0SWes Peters /* 889c324dc0SWes Peters * NOTE: the following length should be enough to hold the longest defined 899c324dc0SWes Peters * error message in sys_errlist, defined in ../gen/errlst.c. This is a WAG 909c324dc0SWes Peters * that is better than the previous value. 919c324dc0SWes Peters */ 929c324dc0SWes Peters #define ERR_LEN 64 9358f0484fSRodney W. Grimes 9458f0484fSRodney W. Grimes char * 9558f0484fSRodney W. Grimes strerror(num) 9658f0484fSRodney W. Grimes int num; 9758f0484fSRodney W. Grimes { 989c324dc0SWes Peters unsigned int uerr; 999c324dc0SWes Peters static char ebuf[ERR_LEN]; 10058f0484fSRodney W. Grimes 1019c324dc0SWes Peters uerr = num; /* convert to unsigned */ 1029c324dc0SWes Peters if (uerr < sys_nerr) 1039c324dc0SWes Peters return (char *)sys_errlist[uerr]; 10458f0484fSRodney W. Grimes 1059c324dc0SWes Peters /* strerror can't fail so handle truncation semi-elegantly */ 1069c324dc0SWes Peters if (strerror_r(num, ebuf, (size_t) ERR_LEN) != 0) 1079c324dc0SWes Peters ebuf[ERR_LEN - 1] = '\0'; 1089c324dc0SWes Peters 1099c324dc0SWes Peters return ebuf; 11058f0484fSRodney W. Grimes } 1119c324dc0SWes Peters 1129c324dc0SWes Peters 1139c324dc0SWes Peters #ifdef STANDALONE_TEST 1149c324dc0SWes Peters main() 1159c324dc0SWes Peters { 1169c324dc0SWes Peters char mybuf[64]; 1179c324dc0SWes Peters int ret; 1189c324dc0SWes Peters 1199c324dc0SWes Peters printf("strerror(47) yeilds: %s\n", strerror(47)); 1209c324dc0SWes Peters strerror_r(11, mybuf, 64); 1219c324dc0SWes Peters printf("strerror_r(11) yeilds: %s\n", mybuf); 1229c324dc0SWes Peters strerror_r(1234, mybuf, 64); 1239c324dc0SWes Peters printf("strerror_r(1234) yeilds: %s\n", mybuf); 1249c324dc0SWes Peters memset(mybuf, '*', 63); 1259c324dc0SWes Peters ret = strerror_r(4321, mybuf, 16); 1269c324dc0SWes Peters printf("strerror_r on short buffer returns %d (%s)\n", ret, mybuf); 12758f0484fSRodney W. Grimes } 1289c324dc0SWes Peters #endif 129