1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26 /*
27 * Copyright 2015 Joyent, Inc.
28 * Copyright 2024 Oxide Computer Company
29 */
30
31 /* Copyright (c) 1988 AT&T */
32 /* All Rights Reserved */
33
34 #include "lint.h"
35 #include "_libc_gettext.h"
36 #include <string.h>
37 #include <sys/types.h>
38 #include <errno.h>
39
40 extern const char _sys_errs[];
41 extern const int _sys_index[];
42 extern int _sys_num_err;
43 extern const char *_sys_err_names[];
44
45 char *
strerror_l(int errnum,locale_t loc)46 strerror_l(int errnum, locale_t loc)
47 {
48 if (errnum < _sys_num_err && errnum >= 0)
49 return (_libc_gettext_l(&_sys_errs[_sys_index[errnum]],
50 loc));
51
52 errno = EINVAL;
53 return (_libc_gettext_l("Unknown error", loc));
54 }
55
56 char *
strerror(int errnum)57 strerror(int errnum)
58 {
59 return (strerror_l(errnum, uselocale(NULL)));
60 }
61
62 /*
63 * A version of sterror() that always operates in the C locale. It returns NULL
64 * rather than the "Unknown error" string.
65 */
66 const char *
strerrordesc_np(int errnum)67 strerrordesc_np(int errnum)
68 {
69 if (errnum < _sys_num_err && errnum >= 0)
70 return (&_sys_errs[_sys_index[errnum]]);
71
72 errno = EINVAL;
73 return (NULL);
74 }
75
76 const char *
strerrorname_np(int errnum)77 strerrorname_np(int errnum)
78 {
79 if (errnum >= 0 && errnum < _sys_num_err &&
80 _sys_err_names[errnum] != NULL) {
81 return (_sys_err_names[errnum]);
82 }
83
84 errno = EINVAL;
85 return (NULL);
86 }
87
88 /*
89 * Implemented strerror_r in Solaris 10 to comply with SUSv3 2001.
90 */
91 int
strerror_r(int errnum,char * strerrbuf,size_t buflen)92 strerror_r(int errnum, char *strerrbuf, size_t buflen)
93 {
94 char *buf;
95 int ret = 0;
96
97 if (errnum < _sys_num_err && errnum >= 0) {
98 buf = _libc_gettext((char *)&_sys_errs[_sys_index[errnum]]);
99 } else {
100 buf = _libc_gettext("Unknown error");
101 ret = errno = EINVAL;
102 }
103
104 /*
105 * At compile time, there is no way to determine the max size of
106 * language-dependent error message.
107 */
108 if (buflen < (strlen(buf) + 1)) {
109 ret = errno = ERANGE;
110 } else {
111 (void) strcpy(strerrbuf, buf);
112 }
113
114 return (ret);
115 }
116