stdlib: Fix stdbit.h with -Wconversion for clang
[glibc.git] / sysdeps / mach / strerror_l.c
blob46820e9dbe9b7a4f626dc9d0ae1c7e4b1a70c55d
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.
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.
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.
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/>. */
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>
30 static const char *
31 translate (const char *str, locale_t loc)
33 locale_t oldloc = __uselocale (loc);
34 const char *res = _(str);
35 __uselocale (oldloc);
36 return res;
40 /* Return a string describing the errno code in ERRNUM. */
41 char *
42 __strerror_l (int errnum, locale_t loc)
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 *);
52 __mach_error_map_compat (&errnum);
54 system = err_get_system (errnum);
55 sub = err_get_sub (errnum);
56 code = err_get_code (errnum);
58 if (system > err_max_system || ! __mach_error_systems[system].bad_sub)
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) > 0)
65 err = tls_internal->strerror_l_buf;
66 else
68 /* The memory was freed above. */
69 tls_internal->strerror_l_buf = NULL;
70 /* Provide a fallback translation. */
71 err = (char *) translate ("Unknown error", loc);
74 __set_errno (saved_errno);
75 return err;
78 es = &__mach_error_systems[system];
80 if (sub >= es->max_sub)
81 err = (char *) translate (es->bad_sub, loc);
82 else if (code >= es->subsystem[sub].max_code)
84 struct tls_internal_t *tls_internal = __glibc_tls_internal ();
85 free (tls_internal->strerror_l_buf);
86 if (__asprintf (&tls_internal->strerror_l_buf, "%s%s %d",
87 translate ("Unknown error ", loc),
88 translate (es->subsystem[sub].subsys_name, loc),
89 errnum) > 0)
90 err = tls_internal->strerror_l_buf;
91 else
93 /* The memory was freed above. */
94 tls_internal->strerror_l_buf = NULL;
95 /* Provide a fallback translation. */
96 err = (char *) translate ("Unknown error", loc);
99 else
100 err = (char *) translate (es->subsystem[sub].codes[code], loc);
102 __set_errno (saved_errno);
103 return err;
105 weak_alias (__strerror_l, strerror_l)
106 libc_hidden_def (__strerror_l)