* Adhemerval Zanella via Libc-alpha:
> The errname_np returns error number name (i.g. "EINVAL" for EINVAL)
> while errdescr_np returns string describing error number (i.g
> "Invalid argument" for EINVAL). Different than strerror, errdescr_np
> does not attempt to translate the return description and both functions
> return NULL for an invalid error number.
If you use a name that starts with "str", it's in the implementation
namespace, and you don't need the _np suffix.
Is errdescr_np really that useful? If yes, maybe we should define a
global C locale object, similar to LC_GLOBAL_LOCALE, so that programmers
can simply use strerror_l for this instead (except that it won't be
async-signal-safe, hmm)?
> diff --git a/manual/errno.texi b/manual/errno.texi
> index 8cb4ce8b48..97ba3916ed 100644
> --- a/manual/errno.texi
> +++ b/manual/errno.texi
> @@ -1207,6 +1207,28 @@ to @code{errno}.
> The function @code{perror} is declared in @file{stdio.h}.
> @end deftypefun
>
> +@deftypefun void errname_np (int @var{errnum})
> +@standards{GNU, string.h}
> +@safety{@prelim{}@mtsafe{@mtssigintr{}}@assafe{}@acsafe{}}
> +This function returns the name describing the error @var{errnum} or
> +@code{NULL} for invalid error number (i.g "EINVAL" for @code{EINVAL}).
> +
> +@pindex string.h
> +This function is a GNU extension, declared in the header file @file{string.h}.
> +@end deftypefun
> +
> +@deftypefun void errdesc_np (int @var{errnum})
> +@standards{GNU, string.h}
> +@safety{@prelim{}@mtsafe{@mtssigintr{}}@assafe{}@acsafe{}}
> +This function returns the message describing the error @var{errnum} or
> +@code{NULL} for invalid error number (i.g Invalid argument" for
> +@code{EINVAL}). Different than @code{strerror} the returned description is
> +not translated.
> +
> +@pindex string.h
> +This function is a GNU extension, declared in the header file @file{string.h}.
> +@end deftypefun
Why @mtssigintr{} (twice)?
I think error numbers for which no constant exist are still valid (in
the C++ sense), so maybe we should phrase this differently: These
functions return NULL if there is no known E* constant with this value.
> diff --git a/stdio-common/errlist.c b/stdio-common/errlist.c
> index f7a49fbf35..dd078143f2 100644
> --- a/stdio-common/errlist.c
> +++ b/stdio-common/errlist.c
> @@ -28,4 +28,12 @@ const char *const _sys_errlist_internal[] =
>
> const int _sys_nerr_internal = array_length (_sys_errlist_internal);
>
> +const char *const _sys_errname_internal[] =
> + {
> +/* This file is auto-generated from errlist.def. */
> +#include <errlist-name.h>
> + };
> +
> +const int _sys_nname_internal = array_length (_sys_errname_internal);
> +
> #include <errlist-compat.c>
There should not be a reason to emit a separate constant for the length
to the data segment. And we should eliminate the extra relocations this
array adds. But I think we can add these changes later as an
optimization.
> diff --git a/stdio-common/test-err_np.c b/stdio-common/test-err_np.c
> new file mode 100644
> index 0000000000..b463c9f3ef
> --- /dev/null
> +++ b/stdio-common/test-err_np.c
I would expect this test to compare against strerror and the E*
constants directly. For the latter, we should generate a table
containing elements like:
{ EINVAL, "EINVAL" },
> diff --git a/string/_strerror.c b/string/_strerror.c
> index 6ae8d47f0f..8bb9bfeaa9 100644
> --- a/string/_strerror.c
> +++ b/string/_strerror.c
> @@ -24,14 +24,14 @@
> char *
> __strerror_r (int errnum, char *buf, size_t buflen)
> {
> - if (__glibc_unlikely (errnum < 0 || errnum >= _sys_nerr_internal
> - || _sys_errlist_internal[errnum] == NULL))
> + const char *r = __errdescr_np (errnum);
> + if (r == NULL)
> {
> __snprintf (buf, buflen, "%s%d", _("Unknown error "), errnum);
> return buf;
> }
>
> - return (char *) _(_sys_errlist_internal[errnum]);
> + return _(_sys_errlist_internal[errnum]);
Shouldn't the last line re-use r?
> diff --git a/string/errname_np.c b/string/errname_np.c
> new file mode 100644
> index 0000000000..61455da219
> --- /dev/null
> +++ b/string/errname_np.c
> +const char *const
> +errname_np (int errnum)
> +{
> + const char *name = NULL;
> +
> + if (errnum >= 0 && errnum < _sys_nname_internal)
> + name = _sys_errname_internal[errnum];
> +
> + return name;
> +}
I'm surprised that index 0 is looked up in the table.
It may make sense to move the definition of the array out ouf errlist.c,
so that it can be shared across all ports.
Thanks,
Florian
On 28/05/2020 09:28, Florian Weimer wrote:
> * Adhemerval Zanella via Libc-alpha:
>
>> The errname_np returns error number name (i.g. "EINVAL" for EINVAL)
>> while errdescr_np returns string describing error number (i.g
>> "Invalid argument" for EINVAL). Different than strerror, errdescr_np
>> does not attempt to translate the return description and both functions
>> return NULL for an invalid error number.
>
> If you use a name that starts with "str", it's in the implementation
> namespace, and you don't need the _np suffix.
I don't have a strong preference here, maybe 'strerror_as'?
>
> Is errdescr_np really that useful? If yes, maybe we should define a
> global C locale object, similar to LC_GLOBAL_LOCALE, so that programmers
> can simply use strerror_l for this instead (except that it won't be
> async-signal-safe, hmm)?
The errdescr_np is added to provide the async-signal-safe strerror
analogous of the patch deprecated sys_errlist. The libSegfault itself
could use it, although I am not sure if async-safeness is really that
useful. It is way simpler than define a extra global C locale though.
>
>> diff --git a/manual/errno.texi b/manual/errno.texi
>> index 8cb4ce8b48..97ba3916ed 100644
>> --- a/manual/errno.texi
>> +++ b/manual/errno.texi
>> @@ -1207,6 +1207,28 @@ to @code{errno}.
>> The function @code{perror} is declared in @file{stdio.h}.
>> @end deftypefun
>>
>> +@deftypefun void errname_np (int @var{errnum})
>> +@standards{GNU, string.h}
>> +@safety{@prelim{}@mtsafe{@mtssigintr{}}@assafe{}@acsafe{}}
>> +This function returns the name describing the error @var{errnum} or
>> +@code{NULL} for invalid error number (i.g "EINVAL" for @code{EINVAL}).
>> +
>> +@pindex string.h
>> +This function is a GNU extension, declared in the header file @file{string.h}.
>> +@end deftypefun
>> +
>> +@deftypefun void errdesc_np (int @var{errnum})
>> +@standards{GNU, string.h}
>> +@safety{@prelim{}@mtsafe{@mtssigintr{}}@assafe{}@acsafe{}}
>> +This function returns the message describing the error @var{errnum} or
>> +@code{NULL} for invalid error number (i.g Invalid argument" for
>> +@code{EINVAL}). Different than @code{strerror} the returned description is
>> +not translated.
>> +
>> +@pindex string.h
>> +This function is a GNU extension, declared in the header file @file{string.h}.
>> +@end deftypefun
>
> Why @mtssigintr{} (twice)?
I am not following, each one annotates a different symbol (one for errname_np
and another for errdesc_np).
>
> I think error numbers for which no constant exist are still valid (in
> the C++ sense), so maybe we should phrase this differently: These
> functions return NULL if there is no known E* constant with this value.
Ack.
>
>> diff --git a/stdio-common/errlist.c b/stdio-common/errlist.c
>> index f7a49fbf35..dd078143f2 100644
>> --- a/stdio-common/errlist.c
>> +++ b/stdio-common/errlist.c
>> @@ -28,4 +28,12 @@ const char *const _sys_errlist_internal[] =
>>
>> const int _sys_nerr_internal = array_length (_sys_errlist_internal);
>>
>> +const char *const _sys_errname_internal[] =
>> + {
>> +/* This file is auto-generated from errlist.def. */
>> +#include <errlist-name.h>
>> + };
>> +
>> +const int _sys_nname_internal = array_length (_sys_errname_internal);
>> +
>> #include <errlist-compat.c>
>
> There should not be a reason to emit a separate constant for the length
> to the data segment. And we should eliminate the extra relocations this
> array adds. But I think we can add these changes later as an
> optimization.
Alright, I think it could be feasible to auto-generate both
_sys_errlist_internal and _sys_errname_internal with its expected size
(as we do for __sys_siglist_internal) and optimize the script to
emit the expected string size for each element.
>
>> diff --git a/stdio-common/test-err_np.c b/stdio-common/test-err_np.c
>> new file mode 100644
>> index 0000000000..b463c9f3ef
>> --- /dev/null
>> +++ b/stdio-common/test-err_np.c
>
> I would expect this test to compare against strerror and the E*
> constants directly. For the latter, we should generate a table
> containing elements like:
>
> { EINVAL, "EINVAL" },
The 'errname' does have this mapping. Should I add an extra test for
strerror as well?
>
>> diff --git a/string/_strerror.c b/string/_strerror.c
>> index 6ae8d47f0f..8bb9bfeaa9 100644
>> --- a/string/_strerror.c
>> +++ b/string/_strerror.c
>> @@ -24,14 +24,14 @@
>> char *
>> __strerror_r (int errnum, char *buf, size_t buflen)
>> {
>> - if (__glibc_unlikely (errnum < 0 || errnum >= _sys_nerr_internal
>> - || _sys_errlist_internal[errnum] == NULL))
>> + const char *r = __errdescr_np (errnum);
>> + if (r == NULL)
>> {
>> __snprintf (buf, buflen, "%s%d", _("Unknown error "), errnum);
>> return buf;
>> }
>>
>> - return (char *) _(_sys_errlist_internal[errnum]);
>> + return _(_sys_errlist_internal[errnum]);
>
> Shouldn't the last line re-use r?
It should, I have change it.
>
>> diff --git a/string/errname_np.c b/string/errname_np.c
>> new file mode 100644
>> index 0000000000..61455da219
>> --- /dev/null
>> +++ b/string/errname_np.c
>
>> +const char *const
>> +errname_np (int errnum)
>> +{
>> + const char *name = NULL;
>> +
>> + if (errnum >= 0 && errnum < _sys_nname_internal)
>> + name = _sys_errname_internal[errnum];
>> +
>> + return name;
>> +}
>
> I'm surprised that index 0 is looked up in the table.
It is defined a no error ('Success').
>
> It may make sense to move the definition of the array out ouf errlist.c,
> so that it can be shared across all ports.
On third patch on this set [1] I moved the generation to a script based
on errlist.def. Hurd requires its own version because it uses different
internal names (maybe we could cleanup this up later).
[1] https://sourceware.org/pipermail/libc-alpha/2020-May/113700.html
>
> Thanks,
> Florian
>
@@ -33,6 +33,16 @@ Major new features:
They should be used instead of sys_siglist or sys_sigabbrev and they
are both thread and async-signal safe. These functions are GNU extensions.
+* The functions errname_np and errdescr_np have been added. The errname_np
+ returns error number name (i.g. "EINVAL" for EINVAL) while errdescr_np
+ returns string describing error number (i.g "Invalid argument" for EINVAL).
+ Different than strerror, errdescr_np does not attempt to translate the
+ return description and both functions return NULL for an invalid error
+ number.
+
+ They should be used instead of sys_errlist and sys_nerr and both are
+ thread and async-signal safe. These functions are GNU extensions.
+
Deprecated and removed features, and other changes affecting compatibility:
* The deprecated <sys/sysctl.h> header and the sysctl function have been
@@ -187,6 +187,11 @@ libc_hidden_proto (__libc_readline_unlocked);
extern const char *const _sys_errlist_internal[] attribute_hidden;
extern const int _sys_nerr_internal attribute_hidden;
+extern const char *const _sys_errname_internal[] attribute_hidden;
+extern const int _sys_nname_internal attribute_hidden;
+
+extern const char *const __errdescr_np (int errnum);
+libc_hidden_proto (__errdescr_np)
libc_hidden_ldbl_proto (__asprintf)
@@ -1207,6 +1207,28 @@ to @code{errno}.
The function @code{perror} is declared in @file{stdio.h}.
@end deftypefun
+@deftypefun void errname_np (int @var{errnum})
+@standards{GNU, string.h}
+@safety{@prelim{}@mtsafe{@mtssigintr{}}@assafe{}@acsafe{}}
+This function returns the name describing the error @var{errnum} or
+@code{NULL} for invalid error number (i.g "EINVAL" for @code{EINVAL}).
+
+@pindex string.h
+This function is a GNU extension, declared in the header file @file{string.h}.
+@end deftypefun
+
+@deftypefun void errdesc_np (int @var{errnum})
+@standards{GNU, string.h}
+@safety{@prelim{}@mtsafe{@mtssigintr{}}@assafe{}@acsafe{}}
+This function returns the message describing the error @var{errnum} or
+@code{NULL} for invalid error number (i.g Invalid argument" for
+@code{EINVAL}). Different than @code{strerror} the returned description is
+not translated.
+
+@pindex string.h
+This function is a GNU extension, declared in the header file @file{string.h}.
+@end deftypefun
+
@code{strerror} and @code{perror} produce the exact same message for any
given error code; the precise text varies from system to system. With
@theglibc{}, the messages are fairly short; there are no multi-line
@@ -19,16 +19,26 @@
import sys
import argparse
+from enum import Enum
# The input file should be in the form
#
# VALUE, DESCRIPTION
#
-# An entry for each will be created in the output file in the form:
+# An entry for each will be created in the output file in the form
+# for mode 'descr':
#
# [VALUE] = "DESCRIPTION",
+#
+# or in the form for mode 'name':
+#
+# [VALUE] = "VALUE",
+
+class Mode(Enum):
+ NAME = 0
+ DESCR = 1
-def generate_errlist(input_file, output_file):
+def generate_errlist(mode, input_file, output_file):
with open(input_file, 'r') as fin, open(output_file, 'w') as fout:
fout.write("#ifndef ERR_MAP\n")
fout.write("#define ERR_MAP(value) value\n")
@@ -38,16 +48,21 @@ def generate_errlist(input_file, output_file):
continue
fields = [f.strip() for f in line.rstrip('\n').split(',')]
fout.write("[ERR_MAP(%s)] = N_(\"%s\"),\n" % (fields[0],
- fields[1]))
+ fields[mode.value]))
def main():
parser = argparse.ArgumentParser(description='Generate errlist.h')
+ parser.add_argument('-m', dest='mode',
+ help='Output mode', default='name',
+ choices=('name', 'desc'),
+ required=True)
parser.add_argument('-i', dest='input', metavar='FILE',
help='Error definitions')
parser.add_argument('-o', dest='output', metavar='FILE',
help='Include file')
args = parser.parse_args()
- generate_errlist(args.input, args.output)
+ generate_errlist(Mode.NAME if args.mode == 'name' else Mode.DESCR,
+ args.input, args.output)
if __name__ == '__main__':
main()
@@ -66,7 +66,8 @@ tests := tstscanf test_rdwr test-popen tstgetln test-fseek \
tst-scanf-round \
tst-renameat2 tst-bz11319 tst-bz11319-fortify2 \
scanf14a scanf16a \
- tst-printf-bz25691
+ tst-printf-bz25691 \
+ test-err_np
test-srcs = tst-unbputc tst-printf tst-printfsz-islongdouble
@@ -92,10 +93,17 @@ errlist-def = $(firstword $(wildcard $(addsuffix /errlist.def,$(sysdirs) .)))
$(objpfx)errlist.h: $(errlist-def) \
$(..)scripts/gen-errlist.py
- $(PYTHON) $(..)scripts/gen-errlist.py -i $(errlist-def) -o $@
+ $(PYTHON) $(..)scripts/gen-errlist.py -m desc -i $(errlist-def) -o $@
+
+$(objpfx)errlist-name.h: $(errlist-def) \
+ $(..)scripts/gen-errlist.py
+ $(PYTHON) $(..)scripts/gen-errlist.py -m name -i $(errlist-def) -o $@
+
+$(foreach o,$(object-suffixes) $(object-suffixes:=.d),\
+ $(objpfx)errlist$o): $(objpfx)errlist.h $(objpfx)errlist-name.h
$(foreach o,$(object-suffixes) $(object-suffixes:=.d),\
- $(objpfx)errlist$o): $(objpfx)errlist.h
+ $(objpfx)test-err_np$o): $(objpfx)errlist.h $(objpfx)errlist-name.h
ifeq ($(run-built-tests),yes)
LOCALES := de_DE.ISO-8859-1 de_DE.UTF-8 en_US.ISO-8859-1 ja_JP.EUC-JP
@@ -28,4 +28,12 @@ const char *const _sys_errlist_internal[] =
const int _sys_nerr_internal = array_length (_sys_errlist_internal);
+const char *const _sys_errname_internal[] =
+ {
+/* This file is auto-generated from errlist.def. */
+#include <errlist-name.h>
+ };
+
+const int _sys_nname_internal = array_length (_sys_errname_internal);
+
#include <errlist-compat.c>
new file mode 100644
@@ -0,0 +1,60 @@
+/* Test and errname_np and errdesc_np.
+ Copyright (C) 2020 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <string.h>
+#include <errno.h>
+#include <array_length.h>
+
+#include <support/support.h>
+#include <support/check.h>
+
+#define N_(name) name
+
+static const char *const errlist[] =
+ {
+/* This file is auto-generated from errlist.def. */
+#include <errlist.h>
+ };
+
+static const char *const errname[] =
+ {
+/* This file is auto-generated from errlist.def. */
+#include <errlist-name.h>
+ };
+
+static int
+do_test (void)
+{
+ for (size_t i = 0; i < array_length (errlist); i++)
+ {
+ if (errlist[i] == NULL)
+ continue;
+ TEST_COMPARE_STRING (errdescr_np (i), errlist[i]);
+ }
+
+ for (size_t i = 0; i < array_length (errname); i++)
+ {
+ if (errname[i] == NULL)
+ continue;
+ TEST_COMPARE_STRING (errname_np (i), errname[i]);
+ }
+
+ return 0;
+}
+
+#include <support/test-driver.c>
@@ -45,7 +45,7 @@ routines := strcat strchr strcmp strcoll strcpy strcspn \
envz basename \
strcoll_l strxfrm_l string-inlines memrchr \
xpg-strerror strerror_l explicit_bzero \
- sigdescr_np sigabbrev_np
+ sigdescr_np sigabbrev_np errname_np errdescr_np
strop-tests := memchr memcmp memcpy memmove mempcpy memset memccpy \
stpcpy stpncpy strcat strchr strcmp strcpy strcspn \
@@ -87,5 +87,6 @@ libc {
}
GLIBC_2.32 {
sigdescr_np; sigabbrev_np;
+ errdescr_np; errname_np;
}
}
@@ -24,14 +24,14 @@
char *
__strerror_r (int errnum, char *buf, size_t buflen)
{
- if (__glibc_unlikely (errnum < 0 || errnum >= _sys_nerr_internal
- || _sys_errlist_internal[errnum] == NULL))
+ const char *r = __errdescr_np (errnum);
+ if (r == NULL)
{
__snprintf (buf, buflen, "%s%d", _("Unknown error "), errnum);
return buf;
}
- return (char *) _(_sys_errlist_internal[errnum]);
+ return _(_sys_errlist_internal[errnum]);
}
weak_alias (__strerror_r, strerror_r)
libc_hidden_def (__strerror_r)
new file mode 100644
@@ -0,0 +1,32 @@
+/* Return string describing error number.
+ Copyright (C) 2020 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <stdio.h>
+
+const char *const
+__errdescr_np (int errnum)
+{
+ const char *descr = NULL;
+
+ if (errnum >= 0 && errnum < _sys_nerr_internal)
+ descr = _sys_errlist_internal[errnum];
+
+ return descr;
+}
+libc_hidden_def (__errdescr_np)
+weak_alias (__errdescr_np, errdescr_np)
new file mode 100644
@@ -0,0 +1,30 @@
+/* Return string describing signal abbreviation.
+ Copyright (C) 2020 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <stdio.h>
+
+const char *const
+errname_np (int errnum)
+{
+ const char *name = NULL;
+
+ if (errnum >= 0 && errnum < _sys_nname_internal)
+ name = _sys_errname_internal[errnum];
+
+ return name;
+}
@@ -37,10 +37,9 @@ char *
__strerror_l (int errnum, locale_t loc)
{
int saved_errno = errno;
- char *r;
- if (__glibc_unlikely (errnum < 0 || errnum >= _sys_nerr_internal
- || _sys_errlist_internal[errnum] == NULL))
+ const char *r = __errdescr_np (errnum);
+ if (r == NULL)
{
struct tls_internal_t *tls_internal = __glibc_tls_internal ();
free (tls_internal->strerror_l_buf);
@@ -51,10 +50,10 @@ __strerror_l (int errnum, locale_t loc)
r = tls_internal->strerror_l_buf;
}
else
- r = (char *) translate (_sys_errlist_internal[errnum], loc);
+ r = translate (_sys_errlist_internal[errnum], loc);
__set_errno (saved_errno);
- return r;
+ return (char *) r;
}
weak_alias (__strerror_l, strerror_l)
libc_hidden_def (__strerror_l)
@@ -428,6 +428,11 @@ extern int __xpg_strerror_r (int __errnum, char *__buf, size_t __buflen)
extern char *strerror_r (int __errnum, char *__buf, size_t __buflen)
__THROW __nonnull ((2)) __wur __attr_access ((__write_only__, 2, 3));
# endif
+
+# ifdef __USE_GNU
+extern const char *errdescr_np (int __err) __THROW;
+extern const char *errname_np (int __err) __THROW;
+# endif
#endif
#ifdef __USE_XOPEN2K8
@@ -30,5 +30,15 @@ const char *const _hurd_errlist[] =
{
#include <errlist.h>
};
+strong_alias (_hurd_errlist, _sys_errlist_internal)
const int _hurd_nerr = array_length (_hurd_errlist);
+strong_alias (_hurd_nerr, _sys_nerr_internal)
+
+const char *const _sys_errname_internal[] =
+ {
+/* This file is auto-generated from errlist.def. */
+#include <errlist-name.h>
+ };
+
+const int _sys_nname_internal = array_length (_sys_errname_internal);
@@ -2181,6 +2181,8 @@ GLIBC_2.3.4 setsourcefilter F
GLIBC_2.3.4 xdr_quad_t F
GLIBC_2.3.4 xdr_u_quad_t F
GLIBC_2.30 twalk_r F
+GLIBC_2.32 errdescr_np F
+GLIBC_2.32 errname_np F
GLIBC_2.32 mach_print F
GLIBC_2.32 sigabbrev_np F
GLIBC_2.32 sigdescr_np F
new file mode 100644
@@ -0,0 +1,4 @@
+#include <mach/error.h>
+
+#define ERR_MAP(value) err_get_code (value)
+#include <stdio-common/test-err_np.c>
@@ -2146,6 +2146,8 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.32 errdescr_np F
+GLIBC_2.32 errname_np F
GLIBC_2.32 pthread_sigmask F
GLIBC_2.32 sigabbrev_np F
GLIBC_2.32 sigdescr_np F
@@ -2226,6 +2226,8 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.32 errdescr_np F
+GLIBC_2.32 errname_np F
GLIBC_2.32 pthread_sigmask F
GLIBC_2.32 sigabbrev_np F
GLIBC_2.32 sigdescr_np F
@@ -133,6 +133,8 @@ GLIBC_2.30 twalk_r F
GLIBC_2.31 msgctl F
GLIBC_2.31 semctl F
GLIBC_2.31 shmctl F
+GLIBC_2.32 errdescr_np F
+GLIBC_2.32 errname_np F
GLIBC_2.32 pthread_sigmask F
GLIBC_2.32 sigabbrev_np F
GLIBC_2.32 sigdescr_np F
@@ -130,6 +130,8 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.32 errdescr_np F
+GLIBC_2.32 errname_np F
GLIBC_2.32 pthread_sigmask F
GLIBC_2.32 sigabbrev_np F
GLIBC_2.32 sigdescr_np F
@@ -2090,6 +2090,8 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.32 errdescr_np F
+GLIBC_2.32 errname_np F
GLIBC_2.32 pthread_sigmask F
GLIBC_2.32 sigabbrev_np F
GLIBC_2.32 sigdescr_np F
@@ -2047,6 +2047,8 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.32 errdescr_np F
+GLIBC_2.32 errname_np F
GLIBC_2.32 pthread_sigmask F
GLIBC_2.32 sigabbrev_np F
GLIBC_2.32 sigdescr_np F
@@ -2213,6 +2213,8 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.32 errdescr_np F
+GLIBC_2.32 errname_np F
GLIBC_2.32 pthread_sigmask F
GLIBC_2.32 sigabbrev_np F
GLIBC_2.32 sigdescr_np F
@@ -2079,6 +2079,8 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.32 errdescr_np F
+GLIBC_2.32 errname_np F
GLIBC_2.32 pthread_sigmask F
GLIBC_2.32 sigabbrev_np F
GLIBC_2.32 sigdescr_np F
@@ -134,6 +134,8 @@ GLIBC_2.30 twalk_r F
GLIBC_2.31 msgctl F
GLIBC_2.31 semctl F
GLIBC_2.31 shmctl F
+GLIBC_2.32 errdescr_np F
+GLIBC_2.32 errname_np F
GLIBC_2.32 pthread_sigmask F
GLIBC_2.32 sigabbrev_np F
GLIBC_2.32 sigdescr_np F
@@ -2159,6 +2159,8 @@ GLIBC_2.30 twalk_r F
GLIBC_2.31 msgctl F
GLIBC_2.31 semctl F
GLIBC_2.31 shmctl F
+GLIBC_2.32 errdescr_np F
+GLIBC_2.32 errname_np F
GLIBC_2.32 pthread_sigmask F
GLIBC_2.32 sigabbrev_np F
GLIBC_2.32 sigdescr_np F
@@ -2141,6 +2141,8 @@ GLIBC_2.30 twalk_r F
GLIBC_2.31 msgctl F
GLIBC_2.31 semctl F
GLIBC_2.31 shmctl F
+GLIBC_2.32 errdescr_np F
+GLIBC_2.32 errname_np F
GLIBC_2.32 pthread_sigmask F
GLIBC_2.32 sigabbrev_np F
GLIBC_2.32 sigdescr_np F
@@ -2138,6 +2138,8 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.32 errdescr_np F
+GLIBC_2.32 errname_np F
GLIBC_2.32 pthread_sigmask F
GLIBC_2.32 sigabbrev_np F
GLIBC_2.32 sigdescr_np F
@@ -2130,6 +2130,8 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.32 errdescr_np F
+GLIBC_2.32 errname_np F
GLIBC_2.32 pthread_sigmask F
GLIBC_2.32 sigabbrev_np F
GLIBC_2.32 sigdescr_np F
@@ -2128,6 +2128,8 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.32 errdescr_np F
+GLIBC_2.32 errname_np F
GLIBC_2.32 pthread_sigmask F
GLIBC_2.32 sigabbrev_np F
GLIBC_2.32 sigdescr_np F
@@ -2136,6 +2136,8 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.32 errdescr_np F
+GLIBC_2.32 errname_np F
GLIBC_2.32 pthread_sigmask F
GLIBC_2.32 sigabbrev_np F
GLIBC_2.32 sigdescr_np F
@@ -2130,6 +2130,8 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.32 errdescr_np F
+GLIBC_2.32 errname_np F
GLIBC_2.32 pthread_sigmask F
GLIBC_2.32 sigabbrev_np F
GLIBC_2.32 sigdescr_np F
@@ -2179,6 +2179,8 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.32 errdescr_np F
+GLIBC_2.32 errname_np F
GLIBC_2.32 pthread_sigmask F
GLIBC_2.32 sigabbrev_np F
GLIBC_2.32 sigdescr_np F
@@ -2186,6 +2186,8 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.32 errdescr_np F
+GLIBC_2.32 errname_np F
GLIBC_2.32 pthread_sigmask F
GLIBC_2.32 sigabbrev_np F
GLIBC_2.32 sigdescr_np F
@@ -2219,6 +2219,8 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.32 errdescr_np F
+GLIBC_2.32 errname_np F
GLIBC_2.32 pthread_sigmask F
GLIBC_2.32 sigabbrev_np F
GLIBC_2.32 sigdescr_np F
@@ -2049,6 +2049,8 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.32 errdescr_np F
+GLIBC_2.32 errname_np F
GLIBC_2.32 pthread_sigmask F
GLIBC_2.32 sigabbrev_np F
GLIBC_2.32 sigdescr_np F
@@ -2341,6 +2341,8 @@ GLIBC_2.32 __wcstoieee128_l F
GLIBC_2.32 __wprintf_chkieee128 F
GLIBC_2.32 __wprintfieee128 F
GLIBC_2.32 __wscanfieee128 F
+GLIBC_2.32 errdescr_np F
+GLIBC_2.32 errname_np F
GLIBC_2.32 pthread_sigmask F
GLIBC_2.32 sigabbrev_np F
GLIBC_2.32 sigdescr_np F
@@ -2108,6 +2108,8 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.32 errdescr_np F
+GLIBC_2.32 errname_np F
GLIBC_2.32 pthread_sigmask F
GLIBC_2.32 sigabbrev_np F
GLIBC_2.32 sigdescr_np F
@@ -2184,6 +2184,8 @@ GLIBC_2.30 twalk_r F
GLIBC_2.31 msgctl F
GLIBC_2.31 semctl F
GLIBC_2.31 shmctl F
+GLIBC_2.32 errdescr_np F
+GLIBC_2.32 errname_np F
GLIBC_2.32 pthread_sigmask F
GLIBC_2.32 sigabbrev_np F
GLIBC_2.32 sigdescr_np F
@@ -2085,6 +2085,8 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.32 errdescr_np F
+GLIBC_2.32 errname_np F
GLIBC_2.32 pthread_sigmask F
GLIBC_2.32 sigabbrev_np F
GLIBC_2.32 sigdescr_np F
@@ -2054,6 +2054,8 @@ GLIBC_2.30 twalk_r F
GLIBC_2.31 msgctl F
GLIBC_2.31 semctl F
GLIBC_2.31 shmctl F
+GLIBC_2.32 errdescr_np F
+GLIBC_2.32 errname_np F
GLIBC_2.32 pthread_sigmask F
GLIBC_2.32 sigabbrev_np F
GLIBC_2.32 sigdescr_np F
@@ -2051,6 +2051,8 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.32 errdescr_np F
+GLIBC_2.32 errname_np F
GLIBC_2.32 pthread_sigmask F
GLIBC_2.32 sigabbrev_np F
GLIBC_2.32 sigdescr_np F
@@ -2175,6 +2175,8 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.32 errdescr_np F
+GLIBC_2.32 errname_np F
GLIBC_2.32 pthread_sigmask F
GLIBC_2.32 sigabbrev_np F
GLIBC_2.32 sigdescr_np F
@@ -2102,6 +2102,8 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.32 errdescr_np F
+GLIBC_2.32 errname_np F
GLIBC_2.32 pthread_sigmask F
GLIBC_2.32 sigabbrev_np F
GLIBC_2.32 sigdescr_np F
@@ -2060,6 +2060,8 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.32 errdescr_np F
+GLIBC_2.32 errname_np F
GLIBC_2.32 pthread_sigmask F
GLIBC_2.32 sigabbrev_np F
GLIBC_2.32 sigdescr_np F
@@ -2159,6 +2159,8 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.32 errdescr_np F
+GLIBC_2.32 errname_np F
GLIBC_2.32 pthread_sigmask F
GLIBC_2.32 sigabbrev_np F
GLIBC_2.32 sigdescr_np F