diff options
| author | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2020-05-18 17:41:25 -0300 |
|---|---|---|
| committer | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2020-07-07 15:02:57 -0300 |
| commit | 325081b9eb2035f8f025255206889208f330b590 (patch) | |
| tree | 43a32de8fdd6777e290d7310795b41ea86df12b6 | |
| parent | bfe05aa289054744b68f136b701705cfd242c4de (diff) | |
| download | glibc-325081b9eb2035f8f025255206889208f330b590.tar.xz glibc-325081b9eb2035f8f025255206889208f330b590.zip | |
string: Add strerrorname_np and strerrordesc_np
The strerrorname_np returns error number name (e.g. "EINVAL" for EINVAL)
while strerrordesc_np returns string describing error number (e.g
"Invalid argument" for EINVAL). Different than strerror,
strerrordesc_np does not attempt to translate the return description,
both functions return NULL for an invalid error number.
They should be used instead of sys_errlist and sys_nerr, both are
thread and async-signal safe. These functions are GNU extensions.
Checked on x86-64-linux-gnu, i686-linux-gnu, powerpc64le-linux-gnu,
and s390x-linux-gnu.
Tested-by: Carlos O'Donell <carlos@redhat.com>
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
42 files changed, 259 insertions, 1 deletions
@@ -57,6 +57,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 strerrorname_np and strerrordesc_np have been added. The + strerroname_np returns error number name (e.g. "EINVAL" for EINVAL) while + strerrordesc_np returns string describing error number + (e.g "Invalid argument" for EINVAL). Different than strerror, + strerrordesc_np does not attempt to translate the return description, both + functions return NULL for an invalid error number. + + They should be used instead of sys_errlist and sys_nerr, 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 diff --git a/include/stdio.h b/include/stdio.h index 9e3bf6fe42..bc67d020d4 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -187,6 +187,7 @@ libc_hidden_proto (__libc_readline_unlocked); extern const char *const _sys_errlist_internal[] attribute_hidden; extern const char *__get_errlist (int) attribute_hidden; +extern const char *__get_errname (int) attribute_hidden; libc_hidden_ldbl_proto (__asprintf) diff --git a/manual/errno.texi b/manual/errno.texi index 8cb4ce8b48..1834339220 100644 --- a/manual/errno.texi +++ b/manual/errno.texi @@ -1207,6 +1207,29 @@ to @code{errno}. The function @code{perror} is declared in @file{stdio.h}. @end deftypefun +@deftypefun void strerrorname_np (int @var{errnum}) +@standards{GNU, string.h} +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} +This function returns the name describing the error @var{errnum} or +@code{NULL} if there is no known constant with this value (e.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 strerrordesc_np (int @var{errnum}) +@standards{GNU, string.h} +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} +This function returns the message describing the error @var{errnum} or +@code{NULL} if there is no known constant with this value (e.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 diff --git a/stdio-common/errlist.c b/stdio-common/errlist.c index df52356066..d15f13a22a 100644 --- a/stdio-common/errlist.c +++ b/stdio-common/errlist.c @@ -35,4 +35,37 @@ __get_errlist (int errnum) return NULL; } +static const union sys_errname_t +{ + struct + { +#define MSGSTRFIELD1(line) str##line +#define MSGSTRFIELD(line) MSGSTRFIELD1(line) +#define _S(n, str) char MSGSTRFIELD(__LINE__)[sizeof(str)]; +#include <errlist.h> +#undef _S + }; + char str[0]; +} _sys_errname = { { +#define _S(n, s) s, +#include <errlist.h> +#undef _S +} }; + +static const unsigned short _sys_errnameidx[] = +{ +#define _S(n, s) [n] = offsetof(union sys_errname_t, MSGSTRFIELD(__LINE__)), +#include <errlist.h> +#undef _S +}; + +const char * +__get_errname (int errnum) +{ + if (errnum < 0 || errnum >= array_length (_sys_errnameidx) + || (errnum > 0 && _sys_errnameidx[errnum] == 0)) + return NULL; + return _sys_errname.str + _sys_errnameidx[errnum]; +} + #include <errlist-compat.c> diff --git a/stdio-common/test-strerr.c b/stdio-common/test-strerr.c new file mode 100644 index 0000000000..fded208118 --- /dev/null +++ b/stdio-common/test-strerr.c @@ -0,0 +1,65 @@ +/* Test strerrorname_np and strerrordesc_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> + }; + +#define MSGSTR_T errname_t +#define MSGSTR errname +#define MSGIDX errnameidx +#include <errlist-name.h> +#undef MSGSTR +#undef MSGIDX + +static int +do_test (void) +{ + TEST_VERIFY (strerrordesc_np (-1) == NULL); + TEST_VERIFY (strerrordesc_np (array_length (errlist)) == NULL); + for (size_t i = 0; i < array_length (errlist); i++) + { + if (errlist[i] == NULL) + continue; + TEST_COMPARE_STRING (strerrordesc_np (i), errlist[i]); + } + + TEST_VERIFY (strerrorname_np (-1) == NULL); + TEST_VERIFY (strerrorname_np (array_length (errlist)) == NULL); + for (size_t i = 0; i < array_length (errlist); i++) + { + if (errlist[i] == NULL) + continue; + TEST_COMPARE_STRING (strerrorname_np (i), errname.str + errnameidx[i]); + } + + return 0; +} + +#include <support/test-driver.c> diff --git a/string/Makefile b/string/Makefile index 8fe7e17fe2..f8d3104e16 100644 --- a/string/Makefile +++ b/string/Makefile @@ -45,7 +45,8 @@ 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 strerrorname_np \ + strerrordesc_np strop-tests := memchr memcmp memcpy memmove mempcpy memset memccpy \ stpcpy stpncpy strcat strchr strcmp strcpy strcspn \ diff --git a/string/Versions b/string/Versions index 6f8dd2d372..298ecd401a 100644 --- a/string/Versions +++ b/string/Versions @@ -87,5 +87,6 @@ libc { } GLIBC_2.32 { sigdescr_np; sigabbrev_np; + strerrordesc_np; strerrorname_np; } } diff --git a/string/strerrordesc_np.c b/string/strerrordesc_np.c new file mode 100644 index 0000000000..cdaf3a7f44 --- /dev/null +++ b/string/strerrordesc_np.c @@ -0,0 +1,26 @@ +/* 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 * +__strerrordesc_np (int errnum) +{ + return __get_errlist (errnum); +} +weak_alias (__strerrordesc_np, strerrordesc_np) diff --git a/string/strerrorname_np.c b/string/strerrorname_np.c new file mode 100644 index 0000000000..bc337d20c2 --- /dev/null +++ b/string/strerrorname_np.c @@ -0,0 +1,25 @@ +/* Return string describing errno name. + 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 * +strerrorname_np (int errnum) +{ + return __get_errname (errnum); +} diff --git a/string/string.h b/string/string.h index 0119d7f45d..b0be00c0f7 100644 --- a/string/string.h +++ b/string/string.h @@ -428,6 +428,13 @@ 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 +/* Return a string describing the meaning of tthe error in ERR. */ +extern const char *strerrordesc_np (int __err) __THROW; +/* Return a string with the error name in ERR. */ +extern const char *strerrorname_np (int __err) __THROW; +# endif #endif #ifdef __USE_XOPEN2K8 diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist index 881b689788..5f6154d518 100644 --- a/sysdeps/mach/hurd/i386/libc.abilist +++ b/sysdeps/mach/hurd/i386/libc.abilist @@ -2186,6 +2186,8 @@ GLIBC_2.32 mach_print F GLIBC_2.32 mremap F GLIBC_2.32 sigabbrev_np F GLIBC_2.32 sigdescr_np F +GLIBC_2.32 strerrordesc_np F +GLIBC_2.32 strerrorname_np F GLIBC_2.32 thrd_current F GLIBC_2.32 thrd_equal F GLIBC_2.32 thrd_sleep F diff --git a/sysdeps/mach/hurd/test-err_np.c b/sysdeps/mach/hurd/test-err_np.c new file mode 100644 index 0000000000..3127141128 --- /dev/null +++ b/sysdeps/mach/hurd/test-err_np.c @@ -0,0 +1,4 @@ +#include <mach/error.h> + +#define ERR_MAP(value) err_get_code (value) +#include <stdio-common/test-err_np.c> |
