Date: Wed, 16 Dec 2020 09:02:10 +0000 (UTC) From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r368692 - in head: include/xlocale lib/libc/include lib/libc/nls lib/libc/string Message-ID: <202012160902.0BG92A19072702@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kib Date: Wed Dec 16 09:02:09 2020 New Revision: 368692 URL: https://svnweb.freebsd.org/changeset/base/368692 Log: Implement strerror_l(). Only for the arches that provide user-mode TLS. PR: 251651 Requested by: yuri Discussed with: emaste, jilles, tijl Sponsored by: The FreeBSD Foundation Differential revision: https://reviews.freebsd.org/D27495 MFC after: 2 weeks Modified: head/include/xlocale/_string.h head/lib/libc/include/libc_private.h head/lib/libc/nls/msgcat.c head/lib/libc/string/Makefile.inc head/lib/libc/string/Symbol.map head/lib/libc/string/strerror.3 head/lib/libc/string/strerror.c Modified: head/include/xlocale/_string.h ============================================================================== --- head/include/xlocale/_string.h Wed Dec 16 08:43:38 2020 (r368691) +++ head/include/xlocale/_string.h Wed Dec 16 09:02:09 2020 (r368692) @@ -46,6 +46,7 @@ typedef struct _xlocale *locale_t; * POSIX2008 functions */ int strcoll_l(const char *, const char *, locale_t); +char *strerror_l(int num, locale_t); size_t strxfrm_l(char *, const char *, size_t, locale_t); #endif /* _XLOCALE_STRING1_H */ Modified: head/lib/libc/include/libc_private.h ============================================================================== --- head/lib/libc/include/libc_private.h Wed Dec 16 08:43:38 2020 (r368691) +++ head/lib/libc/include/libc_private.h Wed Dec 16 09:02:09 2020 (r368692) @@ -431,4 +431,9 @@ void ___pthread_cleanup_pop_imp(int); void __throw_constraint_handler_s(const char * restrict msg, int error); +struct __nl_cat_d; +struct _xlocale; +struct __nl_cat_d *__catopen_l(const char *name, int type, + struct _xlocale *locale); + #endif /* _LIBC_PRIVATE_H_ */ Modified: head/lib/libc/nls/msgcat.c ============================================================================== --- head/lib/libc/nls/msgcat.c Wed Dec 16 08:43:38 2020 (r368691) +++ head/lib/libc/nls/msgcat.c Wed Dec 16 09:02:09 2020 (r368692) @@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$"); #include "un-namespace.h" #include "../locale/xlocale_private.h" +#include "libc_private.h" #define _DEFAULT_NLS_PATH "/usr/share/nls/%L/%N.cat:/usr/share/nls/%N/%L:" \ _PATH_LOCALBASE "/share/nls/%L/%N.cat:" \ @@ -122,6 +123,12 @@ SLIST_HEAD(listhead, catentry) cache = nl_catd catopen(const char *name, int type) { + return (__catopen_l(name, type, __get_locale())); +} + +nl_catd +__catopen_l(const char *name, int type, locale_t locale) +{ struct stat sbuf; struct catentry *np; char *base, *cptr, *cptr1, *nlspath, *pathP, *pcode; @@ -139,7 +146,7 @@ catopen(const char *name, int type) lang = NULL; else { if (type == NL_CAT_LOCALE) - lang = querylocale(LC_MESSAGES_MASK, __get_locale()); + lang = querylocale(LC_MESSAGES_MASK, locale); else lang = getenv("LANG"); Modified: head/lib/libc/string/Makefile.inc ============================================================================== --- head/lib/libc/string/Makefile.inc Wed Dec 16 08:43:38 2020 (r368691) +++ head/lib/libc/string/Makefile.inc Wed Dec 16 09:02:09 2020 (r368692) @@ -64,6 +64,7 @@ MLINKS+=strcpy.3 stpcpy.3 \ strcpy.3 strncpy.3 MLINKS+=strdup.3 strndup.3 MLINKS+=strerror.3 perror.3 \ + strerror.3 strerror_l.3 \ strerror.3 strerror_r.3 \ strerror.3 sys_errlist.3 \ strerror.3 sys_nerr.3 Modified: head/lib/libc/string/Symbol.map ============================================================================== --- head/lib/libc/string/Symbol.map Wed Dec 16 08:43:38 2020 (r368691) +++ head/lib/libc/string/Symbol.map Wed Dec 16 09:02:09 2020 (r368692) @@ -110,6 +110,10 @@ FBSD_1.5 { timingsafe_memcmp; }; +FBSD_1.6 { + strerror_l; +}; + FBSDprivate_1.0 { __strtok_r; }; Modified: head/lib/libc/string/strerror.3 ============================================================================== --- head/lib/libc/string/strerror.3 Wed Dec 16 08:43:38 2020 (r368691) +++ head/lib/libc/string/strerror.3 Wed Dec 16 09:02:09 2020 (r368692) @@ -32,12 +32,13 @@ .\" @(#)strerror.3 8.1 (Berkeley) 6/9/93 .\" $FreeBSD$ .\" -.Dd April 5, 2011 +.Dd December 7, 2020 .Dt STRERROR 3 .Os .Sh NAME .Nm perror , .Nm strerror , +.Nm strerror_l , .Nm strerror_r , .Nm sys_errlist , .Nm sys_nerr @@ -53,12 +54,15 @@ .In string.h .Ft "char *" .Fn strerror "int errnum" +.Ft "char *" +.Fn strerror_l "int errnum" "locale_t" .Ft int .Fn strerror_r "int errnum" "char *strerrbuf" "size_t buflen" .Sh DESCRIPTION The .Fn strerror , -.Fn strerror_r +.Fn strerror_l , +.Fn strerror_r , and .Fn perror functions look up the error message string corresponding to an @@ -68,10 +72,30 @@ The .Fn strerror function accepts an error number argument .Fa errnum -and returns a pointer to the corresponding -message string. +and returns a pointer to the corresponding message string +in the current locale. +.Fn strerror +is not thread-safe. +It returns a pointer to an internal static buffer that could be +overwritten by a +.Fn strerror +call from another thread. .Pp The +.Fn strerror_l +function accepts +.Fa errnum +error number and +.Fa locale +locale handle arguments and returns a pointer to a string +corresponding to the specified error in the given locale. +.Fn strerror_l +is thread-safe, its result can be only overwritten by +another call to +.Fn strerror_l +from the current thread. +.Pp +The .Fn strerror_r function renders the same result into .Fa strerrbuf @@ -141,7 +165,8 @@ The external value contains a count of the messages in .Va sys_errlist . The use of these variables is deprecated; -.Fn strerror +.Fn strerror , +.Fn strerror_l , or .Fn strerror_r should be used instead. @@ -160,6 +185,10 @@ The .Fn strerror_r function conforms to .St -p1003.1-2001 . +The +.Fn strerror_l +function conforms to +.St -p1003.1-2008 . .Sh HISTORY The .Fn strerror @@ -173,18 +202,21 @@ function was implemented in .Fx 4.4 by .An Wes Peters Aq Mt wes@FreeBSD.org . +The +.Fn strerror_l +function was added in +.Fx 13.0 . .Sh BUGS The .Fn strerror function returns its result in a static buffer which will be overwritten by subsequent calls. .Pp -The return type for -.Fn strerror -is missing a type-qualifier; it should actually be -.Vt const char * . -.Pp Programs that use the deprecated .Va sys_errlist variable often fail to compile because they declare it inconsistently. +Size of the +.Va sys_errlist +object might increase during FreeBSD lifetime, +breaking some ABI stability guarantees. Modified: head/lib/libc/string/strerror.c ============================================================================== --- head/lib/libc/string/strerror.c Wed Dec 16 08:43:38 2020 (r368691) +++ head/lib/libc/string/strerror.c Wed Dec 16 09:02:09 2020 (r368692) @@ -45,6 +45,8 @@ __FBSDID("$FreeBSD$"); #include <stdio.h> #include "errlst.h" +#include "../locale/xlocale_private.h" +#include "libc_private.h" /* * Define buffer big enough to contain delimiter (": ", 2 bytes), @@ -78,34 +80,35 @@ errstr(int num, const char *uprefix, char *buf, size_t strlcat(buf, t, len); } -int -strerror_r(int errnum, char *strerrbuf, size_t buflen) +static int +strerror_rl(int errnum, char *strerrbuf, size_t buflen, locale_t locale) { int retval = 0; #if defined(NLS) int saved_errno = errno; nl_catd catd; - catd = catopen("libc", NL_CAT_LOCALE); + + catd = __catopen_l("libc", NL_CAT_LOCALE, locale); #endif if (errnum < 0 || errnum >= __hidden_sys_nerr) { errstr(errnum, #if defined(NLS) - catgets(catd, 1, 0xffff, __uprefix), + catgets(catd, 1, 0xffff, __uprefix), #else - __uprefix, + __uprefix, #endif - strerrbuf, buflen); + strerrbuf, buflen); retval = EINVAL; } else { if (strlcpy(strerrbuf, #if defined(NLS) - catgets(catd, 1, errnum, __hidden_sys_errlist[errnum]), + catgets(catd, 1, errnum, __hidden_sys_errlist[errnum]), #else - __hidden_sys_errlist[errnum], + __hidden_sys_errlist[errnum], #endif - buflen) >= buflen) - retval = ERANGE; + buflen) >= buflen) + retval = ERANGE; } #if defined(NLS) @@ -116,12 +119,33 @@ strerror_r(int errnum, char *strerrbuf, size_t buflen) return (retval); } +int +strerror_r(int errnum, char *strerrbuf, size_t buflen) +{ + return (strerror_rl(errnum, strerrbuf, buflen, __get_locale())); +} + char * +strerror_l(int num, locale_t locale) +{ +#ifndef __NO_TLS + static _Thread_local char ebuf[NL_TEXTMAX]; + + if (strerror_rl(num, ebuf, sizeof(ebuf), locale) != 0) + errno = EINVAL; + return (ebuf); +#else + errno = ENOTSUP; + return (NULL); +#endif +} + +char * strerror(int num) { static char ebuf[NL_TEXTMAX]; - if (strerror_r(num, ebuf, sizeof(ebuf)) != 0) + if (strerror_rl(num, ebuf, sizeof(ebuf), __get_locale()) != 0) errno = EINVAL; return (ebuf); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202012160902.0BG92A19072702>