168cd9bedSMike Barcroft /*- 28a16b7a1SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause 38a16b7a1SPedro F. Giffuni * 458f0484fSRodney W. Grimes * Copyright (c) 1988, 1993 558f0484fSRodney W. Grimes * The Regents of the University of California. All rights reserved. 658f0484fSRodney W. Grimes * 758f0484fSRodney W. Grimes * Redistribution and use in source and binary forms, with or without 858f0484fSRodney W. Grimes * modification, are permitted provided that the following conditions 958f0484fSRodney W. Grimes * are met: 1058f0484fSRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 1158f0484fSRodney W. Grimes * notice, this list of conditions and the following disclaimer. 1258f0484fSRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 1358f0484fSRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 1458f0484fSRodney W. Grimes * documentation and/or other materials provided with the distribution. 153fb3b97cSEd Maste * 3. Neither the name of the University nor the names of its contributors 1658f0484fSRodney W. Grimes * may be used to endorse or promote products derived from this software 1758f0484fSRodney W. Grimes * without specific prior written permission. 1858f0484fSRodney W. Grimes * 1958f0484fSRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2058f0484fSRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2158f0484fSRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2258f0484fSRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2358f0484fSRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2458f0484fSRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2558f0484fSRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2658f0484fSRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2758f0484fSRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2858f0484fSRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2958f0484fSRodney W. Grimes * SUCH DAMAGE. 3058f0484fSRodney W. Grimes */ 3158f0484fSRodney W. Grimes 32fba5c5faSAlexey Zelkin #if defined(NLS) 33fba5c5faSAlexey Zelkin #include <nl_types.h> 34fba5c5faSAlexey Zelkin #endif 359c324dc0SWes Peters 36fc7c3528SAlexey Zelkin #include <limits.h> 37fba5c5faSAlexey Zelkin #include <errno.h> 38fba5c5faSAlexey Zelkin #include <string.h> 39fba5c5faSAlexey Zelkin #include <stdio.h> 40fba5c5faSAlexey Zelkin 41e73151ebSJilles Tjoelker #include "errlst.h" 42675079b1SKonstantin Belousov #include "../locale/xlocale_private.h" 43675079b1SKonstantin Belousov #include "libc_private.h" 44e73151ebSJilles Tjoelker 455a98f074SMike Barcroft /* 46cd49e866SKonstantin Belousov * Define buffer big enough to contain delimiter (": ", 2 bytes), 47cd49e866SKonstantin Belousov * 64-bit signed integer converted to ASCII decimal (19 bytes) with 48cd49e866SKonstantin Belousov * optional leading sign (1 byte), and a trailing NUL. 495a98f074SMike Barcroft */ 50cd49e866SKonstantin Belousov #define EBUFSIZE (2 + 19 + 1 + 1) 515a98f074SMike Barcroft 5268cd9bedSMike Barcroft /* 5368cd9bedSMike Barcroft * Doing this by hand instead of linking with stdio(3) avoids bloat for 5468cd9bedSMike Barcroft * statically linked binaries. 5568cd9bedSMike Barcroft */ 565a98f074SMike Barcroft static void 57311a1725SKonstantin Belousov errstr(int num, const char *uprefix, char *buf, size_t len) 589c324dc0SWes Peters { 59e37f8b53SMike Barcroft char *t; 6068cd9bedSMike Barcroft unsigned int uerr; 615a98f074SMike Barcroft char tmp[EBUFSIZE]; 6258f0484fSRodney W. Grimes 63e37f8b53SMike Barcroft t = tmp + sizeof(tmp); 64e37f8b53SMike Barcroft *--t = '\0'; 655a98f074SMike Barcroft uerr = (num >= 0) ? num : -num; 66f61a2edeSWes Peters do { 67e37f8b53SMike Barcroft *--t = "0123456789"[uerr % 10]; 68f61a2edeSWes Peters } while (uerr /= 10); 69f61a2edeSWes Peters if (num < 0) 70e37f8b53SMike Barcroft *--t = '-'; 71fba5c5faSAlexey Zelkin *--t = ' '; 72fba5c5faSAlexey Zelkin *--t = ':'; 73fba5c5faSAlexey Zelkin strlcpy(buf, uprefix, len); 74d0509082SJacques Vidrine strlcat(buf, t, len); 755a98f074SMike Barcroft } 765a98f074SMike Barcroft 77*92771bc0SKonstantin Belousov int 78*92771bc0SKonstantin Belousov __strerror_rl(int errnum, char *strerrbuf, size_t buflen, locale_t locale) 795a98f074SMike Barcroft { 80fba5c5faSAlexey Zelkin int retval = 0; 81fba5c5faSAlexey Zelkin #if defined(NLS) 82fba5c5faSAlexey Zelkin int saved_errno = errno; 83fba5c5faSAlexey Zelkin nl_catd catd; 84675079b1SKonstantin Belousov 85675079b1SKonstantin Belousov catd = __catopen_l("libc", NL_CAT_LOCALE, locale); 86fba5c5faSAlexey Zelkin #endif 875a98f074SMike Barcroft 88e73151ebSJilles Tjoelker if (errnum < 0 || errnum >= __hidden_sys_nerr) { 89fba5c5faSAlexey Zelkin errstr(errnum, 90fba5c5faSAlexey Zelkin #if defined(NLS) 91cd49e866SKonstantin Belousov catgets(catd, 1, 0xffff, __uprefix), 92fba5c5faSAlexey Zelkin #else 93cd49e866SKonstantin Belousov __uprefix, 94fba5c5faSAlexey Zelkin #endif 95fba5c5faSAlexey Zelkin strerrbuf, buflen); 96fba5c5faSAlexey Zelkin retval = EINVAL; 97fba5c5faSAlexey Zelkin } else { 98fba5c5faSAlexey Zelkin if (strlcpy(strerrbuf, 99fba5c5faSAlexey Zelkin #if defined(NLS) 100e73151ebSJilles Tjoelker catgets(catd, 1, errnum, __hidden_sys_errlist[errnum]), 101fba5c5faSAlexey Zelkin #else 102e73151ebSJilles Tjoelker __hidden_sys_errlist[errnum], 103fba5c5faSAlexey Zelkin #endif 104fba5c5faSAlexey Zelkin buflen) >= buflen) 105fba5c5faSAlexey Zelkin retval = ERANGE; 10668cd9bedSMike Barcroft } 107fba5c5faSAlexey Zelkin 108fba5c5faSAlexey Zelkin #if defined(NLS) 109fba5c5faSAlexey Zelkin catclose(catd); 110fba5c5faSAlexey Zelkin errno = saved_errno; 111fba5c5faSAlexey Zelkin #endif 112fba5c5faSAlexey Zelkin 113fba5c5faSAlexey Zelkin return (retval); 1145a98f074SMike Barcroft } 1155a98f074SMike Barcroft 116675079b1SKonstantin Belousov int 117675079b1SKonstantin Belousov strerror_r(int errnum, char *strerrbuf, size_t buflen) 118675079b1SKonstantin Belousov { 119*92771bc0SKonstantin Belousov return (__strerror_rl(errnum, strerrbuf, buflen, __get_locale())); 120675079b1SKonstantin Belousov } 121675079b1SKonstantin Belousov 122675079b1SKonstantin Belousov char * 123675079b1SKonstantin Belousov strerror_l(int num, locale_t locale) 124675079b1SKonstantin Belousov { 125675079b1SKonstantin Belousov static _Thread_local char ebuf[NL_TEXTMAX]; 126675079b1SKonstantin Belousov 127*92771bc0SKonstantin Belousov if (__strerror_rl(num, ebuf, sizeof(ebuf), locale) != 0) 128675079b1SKonstantin Belousov errno = EINVAL; 129675079b1SKonstantin Belousov return (ebuf); 130675079b1SKonstantin Belousov } 131675079b1SKonstantin Belousov 1325a98f074SMike Barcroft char * 1335a98f074SMike Barcroft strerror(int num) 1345a98f074SMike Barcroft { 135fba5c5faSAlexey Zelkin static char ebuf[NL_TEXTMAX]; 1365a98f074SMike Barcroft 137*92771bc0SKonstantin Belousov if (__strerror_rl(num, ebuf, sizeof(ebuf), __get_locale()) != 0) 1385a98f074SMike Barcroft errno = EINVAL; 139f61a2edeSWes Peters return (ebuf); 14058f0484fSRodney W. Grimes } 141