1/* strerror_l - Get errno description string in given locale. Mach version.
2 Copyright (C) 2007-2024 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
30static const char *
31translate (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. */
41char *
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 (ptr: tls_internal->strerror_l_buf);
62 if (__asprintf (&tls_internal->strerror_l_buf, "%s%X",
63 translate (str: "Error in unknown error system: ", loc),
64 errnum) > 0)
65 err = tls_internal->strerror_l_buf;
66 else
67 {
68 /* The memory was freed above. */
69 tls_internal->strerror_l_buf = NULL;
70 /* Provide a fallback translation. */
71 err = (char *) translate (str: "Unknown error", loc);
72 }
73
74 __set_errno (saved_errno);
75 return err;
76 }
77
78 es = &__mach_error_systems[system];
79
80 if (sub >= es->max_sub)
81 err = (char *) translate (str: es->bad_sub, loc);
82 else if (code >= es->subsystem[sub].max_code)
83 {
84 struct tls_internal_t *tls_internal = __glibc_tls_internal ();
85 free (ptr: tls_internal->strerror_l_buf);
86 if (__asprintf (&tls_internal->strerror_l_buf, "%s%s %d",
87 translate (str: "Unknown error ", loc),
88 translate (str: es->subsystem[sub].subsys_name, loc),
89 errnum) > 0)
90 err = tls_internal->strerror_l_buf;
91 else
92 {
93 /* The memory was freed above. */
94 tls_internal->strerror_l_buf = NULL;
95 /* Provide a fallback translation. */
96 err = (char *) translate (str: "Unknown error", loc);
97 }
98 }
99 else
100 err = (char *) translate (str: es->subsystem[sub].codes[code], loc);
101
102 __set_errno (saved_errno);
103 return err;
104}
105weak_alias (__strerror_l, strerror_l)
106libc_hidden_def (__strerror_l)
107

source code of glibc/sysdeps/mach/strerror_l.c