From: Bruno Haible Date: Fri, 14 Feb 2025 14:42:22 +0000 (+0100) Subject: newlocale: Work around NetBSD bug. X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=49564bc5410d4480a847a772628eec176fc68582;p=gnulib.git newlocale: Work around NetBSD bug. * lib/newlocale.c (newlocale) [NetBSD]: Test whether the locale name is valid; fail with error ENOENT if not. * doc/posix-functions/newlocale.texi: Mention the NetBSD bug. --- diff --git a/ChangeLog b/ChangeLog index 5c52985015..3d8d3bb3f0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2025-02-14 Bruno Haible + + newlocale: Work around NetBSD bug. + * lib/newlocale.c (newlocale) [NetBSD]: Test whether the locale name is + valid; fail with error ENOENT if not. + * doc/posix-functions/newlocale.texi: Mention the NetBSD bug. + 2025-02-14 Bruno Haible newlocale: Work around macOS, NetBSD, Solaris 11 OpenIndiana bug. diff --git a/doc/posix-functions/newlocale.texi b/doc/posix-functions/newlocale.texi index b4dc3661bd..54af40a76f 100644 --- a/doc/posix-functions/newlocale.texi +++ b/doc/posix-functions/newlocale.texi @@ -20,6 +20,10 @@ z/OS. When the third argument is NULL, this function uses locale category data from the current locale instead of from the "C" locale on some platforms: macOS, NetBSD 10.0, Solaris 11 OpenIndiana. +@item +When the second argument is an invalid or unsupported locale name, +this function uses the "C" locale instead of failing on some platforms: +NetBSD 10.0. @end itemize Portability problems not fixed by Gnulib: diff --git a/lib/newlocale.c b/lib/newlocale.c index d5f902b8fb..ccce715852 100644 --- a/lib/newlocale.c +++ b/lib/newlocale.c @@ -26,6 +26,9 @@ #if HAVE_NEWLOCALE /* Only provide workarounds. */ +# include +# include + locale_t newlocale (int category_mask, const char *name, locale_t base) # undef newlocale @@ -36,6 +39,33 @@ newlocale (int category_mask, const char *name, locale_t base) return NULL; } +# if defined __NetBSD__ + /* Work around a NetBSD bug: newlocale does not fail (unlike setlocale) + when NAME is an invalid locale name. */ + if (category_mask != 0) + { + /* Test whether NAME is valid. */ + if (!(strcmp (name, "C") == 0 || strcmp (name, "POSIX") == 0)) + { + char *filename = (char *) malloc (18 + strlen (name) + 9 + 1); + if (filename == NULL) + { + errno = ENOMEM; + return NULL; + } + sprintf (filename, "/usr/share/locale/%s/LC_CTYPE", name); + struct stat statbuf; + if (stat (filename, &statbuf) < 0) + { + free (filename); + errno = ENOENT; + return NULL; + } + free (filename); + } + } +# endif + if (category_mask != LC_ALL_MASK && base == NULL) base = newlocale (LC_ALL_MASK, "C", NULL);