1 /* strerror_l - Get errno description string in given locale. Mach version.
2 Copyright (C) 2007-2022 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
18
19 #include <libintl.h>
20 #include <locale.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <mach/error.h>
26 #include <errorlib.h>
27 #include <tls-internal.h>
28
29
30 static const char *
translate(const char * str,locale_t loc)31 translate (const char *str, locale_t loc)
32 {
33 locale_t oldloc = __uselocale (loc);
34 const char *res = _(str);
35 __uselocale (oldloc);
36 return res;
37 }
38
39
40 /* Return a string describing the errno code in ERRNUM. */
41 char *
__strerror_l(int errnum,locale_t loc)42 __strerror_l (int errnum, locale_t loc)
43 {
44 int saved_errno = errno;
45 char *err;
46 int system;
47 int sub;
48 int code;
49 const struct error_system *es;
50 extern void __mach_error_map_compat (int *);
51
52 __mach_error_map_compat (&errnum);
53
54 system = err_get_system (errnum);
55 sub = err_get_sub (errnum);
56 code = err_get_code (errnum);
57
58 if (system > err_max_system || ! __mach_error_systems[system].bad_sub)
59 {
60 struct tls_internal_t *tls_internal = __glibc_tls_internal ();
61 free (tls_internal->strerror_l_buf);
62 if (__asprintf (&tls_internal->strerror_l_buf, "%s%X",
63 translate ("Error in unknown error system: ", loc),
64 errnum) == -1)
65 tls_internal->strerror_l_buf = NULL;
66
67 __set_errno (saved_errno);
68 return tls_internal->strerror_l_buf;
69 }
70
71 es = &__mach_error_systems[system];
72
73 if (sub >= es->max_sub)
74 err = (char *) translate (es->bad_sub, loc);
75 else if (code >= es->subsystem[sub].max_code)
76 {
77 struct tls_internal_t *tls_internal = __glibc_tls_internal ();
78 free (tls_internal->strerror_l_buf);
79 if (__asprintf (&tls_internal->strerror_l_buf, "%s%s %d",
80 translate ("Unknown error ", loc),
81 translate (es->subsystem[sub].subsys_name, loc),
82 errnum) == -1)
83 tls_internal->strerror_l_buf = NULL;
84
85 err = tls_internal->strerror_l_buf;
86 }
87 else
88 err = (char *) translate (es->subsystem[sub].codes[code], loc);
89
90 __set_errno (saved_errno);
91 return err;
92 }
93 weak_alias (__strerror_l, strerror_l)
94 libc_hidden_def (__strerror_l)
95