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.
This commit is contained in:
Bruno Haible
2025-02-14 15:43:39 +01:00
parent bc2d70ee57
commit 49564bc541
3 changed files with 41 additions and 0 deletions
+7
View File
@@ -1,3 +1,10 @@
2025-02-14 Bruno Haible <bruno@clisp.org>
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 <bruno@clisp.org>
newlocale: Work around macOS, NetBSD, Solaris 11 OpenIndiana bug.
+4
View File
@@ -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:
+30
View File
@@ -26,6 +26,9 @@
#if HAVE_NEWLOCALE
/* Only provide workarounds. */
# include <sys/types.h>
# include <sys/stat.h>
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);