]> Savannah Git Hosting - gnulib.git/commitdiff
newlocale: Work around NetBSD bug.
authorBruno Haible <bruno@clisp.org>
Fri, 14 Feb 2025 14:42:22 +0000 (15:42 +0100)
committerBruno Haible <bruno@clisp.org>
Fri, 14 Feb 2025 14:43:39 +0000 (15:43 +0100)
* 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.

ChangeLog
doc/posix-functions/newlocale.texi
lib/newlocale.c

index 5c52985015962b71fecf84fb137733463ec550f5..3d8d3bb3f04ef5d860c5bff31469cf56228567da 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
index b4dc3661bd26d5a7bdf9f894304ea8ac9e501ab3..54af40a76f4377709be692f326a2978916622f75 100644 (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:
index d5f902b8fbac729ff233e1b22bf416f820cfd199..ccce71585257ba9e3a947be53ff385f54eec3731 100644 (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);