Make internationalization tests stricter on musl systems

2023-06-13 Thread Bruno Haible
Many i18n tests in gnulib and gettext are not really exercised, because so far
all m4/locale-*.m4 tests report that there is no usable French / Turkish / etc.
locale on a musl system. This is correct when one looks at all locale categories
together and expects e.g. in the French UTF-8 locale a French decimal separator,
French month names, a French currency and so on. But in musl libc, only the
LC_CTYPE category is reasonably implemented, not the other locale categories.

Citing Rich Felker in <https://www.openwall.com/lists/musl/2017/11/08/1>:
"The choice I made at the time to avoid this was to declare that all
 locale names are valid locales, and if there's no actual file defining
 the locale, it's simply a clone of C.UTF-8. So for example if you run
 with LC_ALL=fr_FR but no fr_FR translation file, you get a locale
 named fr_FR (that's what setlocale reports as the active locale) but
 with no translated messages/dates/etc., just UTF-8 character encoding
 (so you're still able to access all characters properly and use
 localized or multilingual data)."

With this patch, gnulib sets LOCALE_FR_UTF8 to "fr_FR.UTF-8" instead of "none"
and thus enables the tests of some i18n functions, such as mbrtowc and wcrtomb.

Doing the same thing with the LOCALE_TR_UTF8 variable is not appropriate,
because our tests of the Turkish locale test the 'i'/'I' behaviour
in particular, which is not implemented in musl libc; thus these tests would
fail.


2023-06-13  Bruno Haible  

Make internationalization tests stricter on musl systems.
--
* m4/locale-fr.m4 (gt_LOCALE_FR): On musl systems, set LOCALE_FR_UTF8 to
"fr_FR.UTF-8" instead of "none". Set and substitute
LC_COLLATE_IMPLEMENTED, LC_NUMERIC_IMPLEMENTED, LC_TIME_IMPLEMENTED,
LC_MONETARY_IMPLEMENTED.
* m4/iswdigit.m4 (gl_FUNC_ISWDIGIT): Skip testing a certain locale if
that locale is "none".
* m4/iswxdigit.m4 (gl_FUNC_ISWXDIGIT): Likewise.
* m4/mbrlen.m4 (gl_MBRLEN_RETVAL): Likewise.
* m4/mbrtowc.m4 (gl_MBRTOWC_RETVAL): Likewise.
* m4/mbrtoc32.m4 (gl_MBRTOC32_SANITYCHECK): Likewise.
* m4/mbsrtowcs.m4 (gl_MBSRTOWCS_WORKS): Likewise.
* m4/wcrtomb.m4 (gl_FUNC_WCRTOMB): Likewise.
--
* tests/test-c32isalpha.c (main): On musl libc, disable tests that fail.
* tests/test-c32iscntrl.c (main): Likewise.
* tests/test-c32isgraph.c (main): Likewise.
* tests/test-c32islower.c (main): Likewise.
* tests/test-c32isprint.c (main): Likewise.
* tests/test-c32toupper.c (main): Likewise.
* tests/test-nl_langinfo1.c (main): Likewise.
* tests/test-nl_langinfo2.c (main): Likewise.
* modules/c32isalpha-tests (Files): Add musl.m4.
(configure.ac): Invoke gl_MUSL_LIBC.
* modules/c32iscntrl-tests (Files): Add musl.m4.
(configure.ac): Invoke gl_MUSL_LIBC.
* modules/c32isgraph-tests (Files): Add musl.m4.
(configure.ac): Invoke gl_MUSL_LIBC.
* modules/c32islower-tests (Files): Add musl.m4.
(configure.ac): Invoke gl_MUSL_LIBC.
* modules/c32isprint-tests (Files): Add musl.m4.
(configure.ac): Invoke gl_MUSL_LIBC.
* modules/c32toupper-tests (Files): Add musl.m4.
(configure.ac): Invoke gl_MUSL_LIBC.
* modules/nl_langinfo-tests (Files): Add musl.m4.
(configure.ac): Invoke gl_MUSL_LIBC.
--
* tests/test-strtod1.sh: Skip the test if LC_NUMERIC_IMPLEMENTED is
false.
* tests/test-strtold1.sh: Likewise.
* tests/test-vasnprintf-posix2.sh: Likewise.
* tests/test-vasnwprintf-posix2.sh: Likewise.
* modules/strtod-tests (Makefile.am): Set LC_NUMERIC_IMPLEMENTED in the
tests environment.
* modules/strtold-tests (Makefile.am): Likewise.
* modules/vasnprintf-posix-tests (Makefile.am): Likewise.
* modules/vasnwprintf-posix-tests (Makefile.am): Likewise.

diff --git a/m4/iswdigit.m4 b/m4/iswdigit.m4
index 0df7b303fc..54a2943ead 100644
--- a/m4/iswdigit.m4
+++ b/m4/iswdigit.m4
@@ -1,4 +1,4 @@
-# iswdigit.m4 serial 3
+# iswdigit.m4 serial 4
 dnl Copyright (C) 2020-2023 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -63,7 +63,8 @@ AC_DEFUN([gl_FUNC_ISWDIGIT]
   int is;
   int result = 0;
 
-  if (setlocale (LC_ALL, "$LOCALE_FR") != NULL)
+  if (strcmp ("$LOCALE_FR", "none") != 0
+  && setlocale (LC_ALL, "$LOCALE_FR") != NULL)
 {
   /* This fails on mingw, MSVC 14.  */
   /* U+00B2 SUPERSCRIPT TWO */
@@ -71,7 +72,8 @@ AC_DEFUN([gl_FUNC_ISWDIGIT]
   if (!(is == 0))
 result |= 1;
 }
-  if (setlocale (LC_ALL, "$LOCALE_JA") != NULL)
+  if (strcmp ("$LOCALE_JA", "none&quo

Re: Why require SLOW_BUT_NO_HACKS for stubs?

2012-06-12 Thread Paolo Bonzini
Il 12/06/2012 03:22, Isaac Dunham ha scritto:
  Performance, surely.  But if there's
  consensus that performance does not matter that
  much with musl, perhaps we should default to the
  slow version with musl.
 The test as it stands is error out on unsupported platforms unless
 user specifies to use slow method.
 My proposal is On unsupported platforms, use the slow method instead
 of erroring out.

I agree, downgrading to a #warning and removing SLOW_BUT_NO_HACKS should be 
enough.
That would be something like this, but it would fail the tests.  What to do?

Paolo
 8 

From e2aa7434ad06a0ec4e2c47b57564313d16561c14 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini pbonz...@redhat.com
Date: Tue, 12 Jun 2012 13:26:57 +0200
Subject: [PATCH 1/1] freadahead, freadptr, freadseek: Never fail compilation

2012-06-12  Paolo Bonzini  bonz...@gnu.org

* lib/freadahead.c [!SLOW_BUT_NO_HACKS]: Use the slow alternative,
downgrading the #error to a #warning.
* lib/freadptr.c [!SLOW_BUT_NO_HACKS]: Likewise.
* lib/freadseek.c [!SLOW_BUT_NO_HACKS]: Likewise.
* modules/freadahead: Depend on freading.
---
 lib/freadahead.c   |9 +
 lib/freadptr.c |5 ++---
 lib/freadseek.c|4 ++--
 modules/freadahead |1 +
 4 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/lib/freadahead.c b/lib/freadahead.c
index 2ba8b34..473911f 100644
--- a/lib/freadahead.c
+++ b/lib/freadahead.c
@@ -21,6 +21,7 @@
 
 #include stdlib.h
 #include stdio-impl.h
+#include freading.h
 
 size_t
 freadahead (FILE *fp)
@@ -84,10 +85,10 @@ freadahead (FILE *fp)
   if (fp-state == 4 /* WR */ || fp-rp = fp-wp)
 return 0;
   return fp-wp - fp-rp;
-#elif defined SLOW_BUT_NO_HACKS /* users can define this */
-  abort ();
-  return 0;
 #else
- #error Please port gnulib freadahead.c to your platform! Look at the 
definition of fflush, fread, ungetc on your system, then report this to 
bug-gnulib.
+  /* This implementation is correct on any ANSI C platform.  It is just
+ awfully slow.  */
+  return freading(fp)  !feof(fp);
+ #warning Please port gnulib freadahead.c to your platform! Look at the 
definition of fflush, fread, ungetc on your system, then report this to 
bug-gnulib.
 #endif
 }
diff --git a/lib/freadptr.c b/lib/freadptr.c
index 27c2285..325d91d 100644
--- a/lib/freadptr.c
+++ b/lib/freadptr.c
@@ -108,11 +108,10 @@ freadptr (FILE *fp, size_t *sizep)
 return NULL;
   *sizep = fp-wp - fp-rp;
   return fp-rp;
-#elif defined SLOW_BUT_NO_HACKS /* users can define this */
+#else
   /* This implementation is correct on any ANSI C platform.  It is just
  awfully slow.  */
   return NULL;
-#else
- #error Please port gnulib freadptr.c to your platform! Look at the 
definition of fflush, fread, getc, getc_unlocked on your system, then report 
this to bug-gnulib.
+ #warning Please port gnulib freadptr.c to your platform! Look at the 
definition of fflush, fread, getc, getc_unlocked on your system, then report 
this to bug-gnulib.
 #endif
 }
diff --git a/lib/freadseek.c b/lib/freadseek.c
index 4145173..67de1c0 100644
--- a/lib/freadseek.c
+++ b/lib/freadseek.c
@@ -60,9 +60,9 @@ freadptrinc (FILE *fp, size_t increment)
   fp-__bufp += increment;
 #elif defined EPLAN9/* Plan9 */
   fp-rp += increment;
-#elif defined SLOW_BUT_NO_HACKS /* users can define this */
 #else
- #error Please port gnulib freadseek.c to your platform! Look at the 
definition of getc, getc_unlocked on your system, then report this to 
bug-gnulib.
+  /* Doing nothing is fine on any ANSI C platform.  It is just awfully slow.  
*/
+ #warning Please port gnulib freadseek.c to your platform! Look at the 
definition of getc, getc_unlocked on your system, then report this to 
bug-gnulib.
 #endif
 }
 
diff --git a/modules/freadahead b/modules/freadahead
index 96ef2e8..4730695 100644
--- a/modules/freadahead
+++ b/modules/freadahead
@@ -8,6 +8,7 @@ lib/freadahead.c
 lib/stdio-impl.h
 
 Depends-on:
+freading
 
 configure.ac:
 
-- 
1.7.10.2




Re: rationale for closein

2012-06-18 Thread Eric Blake
On 06/18/2012 06:01 PM, Rich Felker wrote:

 
 If the closeout approach works best for coreutils, that's the
 business of the coreutils' maintainers, not my business. However, as I
 discussed on the musl list, I think it's bad design, and I would
 highly recommend other projects not follow it.

And that's where I disagree - the POSIX folks _specifically_ recommend
the closeout approach of an atexit() handler:

http://austingroupbugs.net/view.php?id=555

Since after the call to fclose() any use of stream results in undefined
behavior, fclose() should not be used on stdin, stdout, or stderr except
immediately before process termination (see XBD 3.297 on page 81), so as
to avoid triggering undefined behavior in other standard interfaces that
rely on these streams. If there are any atexit() handlers registered by
the application, such a call to fclose() should not occur until the last
handler is finishing. Once fclose() has been used to close stdin,
stdout, or stderr, there is no standard way to reopen any of these streams.

 Conceptually, you're
 turning something that's a local variable (stdout is global, but if
 it's only used from one point as a generic FILE standing in for
 something that would otherwise have been obtained by fopen, it's
 conceptually local) into a global, and thereby losing the _local_
 information of whether it was used in the first place, which has to be
 recovered with the non-portable __fpending.

But our argument is that __fpending (well, 'fpending') _should_ be
portable, and I am in the process of proposing it for standardization in
the next version of POSIX because it is so useful.

 
 If on the other hand programs just handle stdout as yet another
 FILE, the same code that checks for write errors and reports failure
 for explicitly-opened files would also check and report write errors
 on stdout. It's not longer a special-case. And special-cases are where
 errors like to hide.

Any program that treats stdout as just like any other file risks closing
stdout too early, and then causing undefined behavior in the rest of the
program when some other standard interface accidentally ends up using fd
1.  The atexit() handler is the easiest way to guarantee that things are
closed properly on all normal exit paths.

 
 'closein' is similar - an attempt to fix an issue that affects many programs,
 once and for all. By Eric Blake.
 
 I think closein is just a no-op for conformant implementations. exit
 implicitly closes all streams, including stdin,

But the implicit close by exit(), while properly repositioning stdin (on
working implementations; glibc is broken but I fixed cygwin to be
working), has the drawback of silently eating errors if something went
wrong.  If you WANT to detect read errors, and consolidate the error
detection into a single ferror() location rather than littering the rest
of your code with harder-to-maintain checks, then closein is the way to
go.  If you don't want to detect read errors in a central location, then
yes, avoiding the use of the closein module should have no effect on a
compliant environment; but it is still necessary to work around broken
environments such as glibc.

 Incidentally, I suspect musl is _not_ currently handling this case
 correctly. Does gnulib have some tests that assert the required
 behavior, which I could use to test the current behavior and any
 efforts to fix it if it's wrong?

tests/test-closein.{c,sh}

are sufficient to test the closein module; if you comment out the
atexit() call, it will be sufficient to demonstrate that glibc leaves
stdin at the wrong file offset on exit(); it is also sufficient to
demonstrate that even with a compliant exit(), the implicit close of
exit() eats errors and does not affect error status, whereas the use of
the closein module _does_ detect read errors at a central location.

-- 
Eric Blake   ebl...@redhat.com+1-919-301-3266
Libvirt virtualization library http://libvirt.org





signature.asc
Description: OpenPGP digital signature


Re: rationale for closein

2012-06-18 Thread Rich Felker
On Mon, Jun 18, 2012 at 08:17:25PM -0600, Eric Blake wrote:
 On 06/18/2012 06:01 PM, Rich Felker wrote:
 
  
  If the closeout approach works best for coreutils, that's the
  business of the coreutils' maintainers, not my business. However, as I
  discussed on the musl list, I think it's bad design, and I would
  highly recommend other projects not follow it.
 
 And that's where I disagree - the POSIX folks _specifically_ recommend
 the closeout approach of an atexit() handler:

Yes, they also recommend invoking extremely serious UB (aliasing
violation, which GCC _will_ miscompile) when using dlsym to obtain a
function pointer...

With that said, they have a good point, but it's also arguable that
random parts of the program should not be using stdin/stdout.
Conceptually, these streams belong to the main program flow, and
except in really simple programs, they probably should not be used
explicitly (either by name, or by calling stdio functions that
explicitly use them) except in main or a similar function; other
functions should just get a FILE * from the caller.

 But our argument is that __fpending (well, 'fpending') _should_ be
 portable, and I am in the process of proposing it for standardization in
 the next version of POSIX because it is so useful.

Are you proposing that it be called __fpending or fpending?

 Any program that treats stdout as just like any other file risks closing
 stdout too early, and then causing undefined behavior in the rest of the
 program when some other standard interface accidentally ends up using fd

If you're not trating stdout special at all, just as an ordinary
stream like any other, then accessing it after closing it is a major
logic bug in your program equivalent to accessing a FILE* obtained by
fopen after calling fclose on it.

With that said, in order to avoid the situation, the way I would
actually deal with it is with minimal special-casing, something like:

fflush(f);
if (ferror(f)) report_error();
if (f!=stdout) fclose(f);

I'm aware that this does not detect errors from the actual close
syscall, but I'm unconvinced that it's beneficial to do so; after a
successful flush, I consider it the operating system's data loss, not
the application's, if the data fails to end up on permanent storage.
Even if close() returned zero, you could still get this situation with
hardware failures, etc.

 1.  The atexit() handler is the easiest way to guarantee that things are
 closed properly on all normal exit paths.

But it also runs on failure exit paths, which is probably undesirable
for many programs. Unless you use extra global-var hacks to disable it
from running..

  'closein' is similar - an attempt to fix an issue that affects many 
  programs,
  once and for all. By Eric Blake.
  
  I think closein is just a no-op for conformant implementations. exit
  implicitly closes all streams, including stdin,
 
 But the implicit close by exit(), while properly repositioning stdin (on
 working implementations; glibc is broken but I fixed cygwin to be
 working), has the drawback of silently eating errors if something went
 wrong.  If you WANT to detect read errors, and consolidate the error
 detection into a single ferror() location rather than littering the rest
 of your code with harder-to-maintain checks, then closein is the way to

Anywhere you read, you could hit EOF, so you already need to be
testing for that. Once you get to the we can't read anymore code,
it's trivial to check ferror(f). And again it can be done in general
without any special attention to whether the file is stdin.

  Incidentally, I suspect musl is _not_ currently handling this case
  correctly. Does gnulib have some tests that assert the required
  behavior, which I could use to test the current behavior and any
  efforts to fix it if it's wrong?
 
 tests/test-closein.{c,sh}
 
 are sufficient to test the closein module; if you comment out the
 atexit() call, it will be sufficient to demonstrate that glibc leaves
 stdin at the wrong file offset on exit(); it is also sufficient to

OK. I'll see if I can fix this on our side.

Rich



strtold: work around Cygwin bug

2019-12-12 Thread Bruno Haible
numeric_equal (long double x, long double y)
    [case "$host_os" in
# Guess yes on musl systems.
   *-musl*) gl_cv_func_strtold_works="guessing yes" ;;
+   # Guess 'no (underflow problem)' on Cygwin.
+  cygwin*) gl_cv_func_strtold_works="guessing no (underflow 
problem)" ;;
   *)   gl_cv_func_strtold_works="$gl_cross_guess_normal" ;;
 esac
])
@@ -110,6 +127,12 @@ numeric_equal (long double x, long double y)
   *yes) ;;
   *)
 REPLACE_STRTOLD=1
+case "$gl_cv_func_strtold_works" in
+  *"no (underflow problem)")
+AC_DEFINE([STRTOLD_HAS_UNDERFLOW_BUG], [1],
+  [Define to 1 if strtold does not set errno upon underflow.])
+;;
+esac
 ;;
 esac
   fi




Re: [PATCH] tests: skip thread-using tests when threading is disabled

2020-01-05 Thread Bruno Haible
Hi Jim,

> sed's configure.ac specifies gl_DISABLE_THREADS, and that caused three
> thread-using gnulib tests to fail. Add an #if-guarded exit (77) to each
> of those, so they are skipped in this case.

Thanks for this. I prefer to move the #if around most of the file,
  - because the main() function here already is quite complex,
  - so that there's less trouble if someone wants to use --avoid=thread
some day.

Pushed the attached patch.

Bruno
>From a7903da07d3d18c23314aa0815adbb4058fd7cec Mon Sep 17 00:00:00 2001
From: Jim Meyering 
Date: Sun, 5 Jan 2020 10:25:27 -0800
Subject: [PATCH] tests: skip thread-using tests when threading is disabled

sed's configure.ac specifies gl_DISABLE_THREADS, and that caused three
thread-using gnulib tests to fail. Add an #if-guarded exit (77) to each
of those, so they are skipped in this case.
* tests/test-nl_langinfo-mt.c (main): Exit 77 when threading is disabled.
* tests/test-setlocale_null-mt-all.c (main): Likewise.
* tests/test-setlocale_null-mt-one.c (main): Likewise.
---
 ChangeLog  | 10 ++
 tests/test-nl_langinfo-mt.c| 17 +
 tests/test-setlocale_null-mt-all.c | 17 +
 tests/test-setlocale_null-mt-one.c | 17 +
 4 files changed, 61 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index c8a9dbf..6d5228e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2020-01-05  Jim Meyering  
+
+	tests: skip thread-using tests when threading is disabled
+	sed's configure.ac specifies gl_DISABLE_THREADS, and that caused three
+	thread-using gnulib tests to fail. Add an #if-guarded exit (77) to each
+	of those, so they are skipped in this case.
+	* tests/test-nl_langinfo-mt.c (main): Exit 77 when threading is disabled.
+	* tests/test-setlocale_null-mt-all.c (main): Likewise.
+	* tests/test-setlocale_null-mt-one.c (main): Likewise.
+
 2020-01-05  Bruno Haible  
 
 	tests: Avoid GCC over-optimization caused by _GL_ARG_NONNULL attributes.
diff --git a/tests/test-nl_langinfo-mt.c b/tests/test-nl_langinfo-mt.c
index 55f9db9..de6cd99 100644
--- a/tests/test-nl_langinfo-mt.c
+++ b/tests/test-nl_langinfo-mt.c
@@ -18,6 +18,8 @@
 
 #include 
 
+#if USE_ISOC_THREADS || USE_POSIX_THREADS || USE_ISOC_AND_POSIX_THREADS || USE_WINDOWS_THREADS
+
 /* Specification.  */
 #include 
 
@@ -236,3 +238,18 @@ main (int argc, char *argv[])
 
   return 0;
 }
+
+#else
+
+/* No multithreading available.  */
+
+#include 
+
+int
+main ()
+{
+  fputs ("Skipping test: multithreading not enabled\n", stderr);
+  return 77;
+}
+
+#endif
diff --git a/tests/test-setlocale_null-mt-all.c b/tests/test-setlocale_null-mt-all.c
index a4f91d9..19bdb55 100644
--- a/tests/test-setlocale_null-mt-all.c
+++ b/tests/test-setlocale_null-mt-all.c
@@ -18,6 +18,8 @@
 
 #include 
 
+#if USE_ISOC_THREADS || USE_POSIX_THREADS || USE_ISOC_AND_POSIX_THREADS || USE_WINDOWS_THREADS
+
 /* Specification.  */
 #include 
 
@@ -131,6 +133,21 @@ main (int argc, char *argv[])
   return 0;
 }
 
+#else
+
+/* No multithreading available.  */
+
+#include 
+
+int
+main ()
+{
+  fputs ("Skipping test: multithreading not enabled\n", stderr);
+  return 77;
+}
+
+#endif
+
 /* Without locking, the results of this test would be:
 glibcOK
 musl libccrash < 10 sec
diff --git a/tests/test-setlocale_null-mt-one.c b/tests/test-setlocale_null-mt-one.c
index dc9d4aa..fd6083a 100644
--- a/tests/test-setlocale_null-mt-one.c
+++ b/tests/test-setlocale_null-mt-one.c
@@ -18,6 +18,8 @@
 
 #include 
 
+#if USE_ISOC_THREADS || USE_POSIX_THREADS || USE_ISOC_AND_POSIX_THREADS || USE_WINDOWS_THREADS
+
 /* Specification.  */
 #include 
 
@@ -131,6 +133,21 @@ main (int argc, char *argv[])
   return 0;
 }
 
+#else
+
+/* No multithreading available.  */
+
+#include 
+
+int
+main ()
+{
+  fputs ("Skipping test: multithreading not enabled\n", stderr);
+  return 77;
+}
+
+#endif
+
 /* Without locking, the results of this test would be:
 glibcOK
 musl libcOK
-- 
2.7.4



tzset: Remove workaround for Solaris 2.6

2020-07-26 Thread Bruno Haible
 853958121;
-  struct tm *p, s;
-  putenv ("TZ=GMT0");
-  p = localtime ();
-  s = *p;
-  putenv ("TZ=EST+3EDT+2,M10.1.0/00:00:00,M2.3.0/00:00:00");
-  tzset ();
-  return (p->tm_year != s.tm_year
-  || p->tm_mon != s.tm_mon
-  || p->tm_mday != s.tm_mday
-  || p->tm_hour != s.tm_hour
-  || p->tm_min != s.tm_min
-  || p->tm_sec != s.tm_sec);
-}
-  ]])],
-   [gl_cv_func_tzset_clobber=no],
-   [gl_cv_func_tzset_clobber=yes],
-   [case "$host_os" in
- # Guess all is fine on glibc systems.
-  *-gnu* | gnu*) gl_cv_func_tzset_clobber="guessing no" ;;
- # Guess all is fine on musl systems.
-  *-musl*)   gl_cv_func_tzset_clobber="guessing no" ;;
- # Guess no on native Windows.
-  mingw*)gl_cv_func_tzset_clobber="guessing no" ;;
- # If we don't know, obey --enable-cross-guesses.
-  *) gl_cv_func_tzset_clobber="$gl_cross_guess_inverted" ;;
-esac
-   ])
-])
-
-  AC_DEFINE([HAVE_RUN_TZSET_TEST], [1],
-[Define to 1 if you have run the test for working tzset.])
-])
diff --git a/modules/tzset b/modules/tzset
index 5f036b0..ff7e60b 100644
--- a/modules/tzset
+++ b/modules/tzset
@@ -7,7 +7,6 @@ m4/tzset.m4
 
 Depends-on:
 time
-localtime-buffer [test $NEED_LOCALTIME_BUFFER = 1]
 
 configure.ac:
 gl_FUNC_TZSET




ffsll: Override completely broken implementation on AIX in 32-bit mode

2021-01-04 Thread Bruno Haible
On AIX 7.2 in 32-bit mode, ffsll() is completely broken. In some
cases it returns the sign bit of the argument, in other cases always 1.

This patch provides an override.


2021-01-05  Bruno Haible  

ffsll: Override completely broken implementation on AIX in 32-bit mode.
* m4/ffsll.m4 (gl_FUNC_FFSLL): Test whether ffsll minimally works. If
not, set REPLACE_FFSLL.
* lib/string.in.h (ffsll): Consider REPLACE_FFSLL.
* m4/string_h.m4 (gl_HEADER_STRING_H_DEFAULTS): Initialize
REPLACE_FFSLL.
* modules/string (Makefile.am): Substitute REPLACE_FFSLL.
* modules/ffsll (Depends-on, configure.ac): Consider REPLACE_FFSLL.
* doc/glibc-functions/ffsll.texi: Mention the AIX 7.2 bug.

diff --git a/doc/glibc-functions/ffsll.texi b/doc/glibc-functions/ffsll.texi
index 718ccfc..41e701e 100644
--- a/doc/glibc-functions/ffsll.texi
+++ b/doc/glibc-functions/ffsll.texi
@@ -15,6 +15,9 @@ Mac OS X 10.5, FreeBSD 6.0, NetBSD 9.0, OpenBSD 6.7, Minix 
3.1.8, AIX 5.1, HP-UX
 This function is declared in @code{} instead of @code{}
 on some platforms:
 AIX 7.2.
+@item
+This function returns completely wrong values on some platforms:
+AIX 7.2 in 32-bit mode.
 @end itemize
 
 Portability problems not fixed by Gnulib:
diff --git a/lib/string.in.h b/lib/string.in.h
index 2f2e07b..bac515d 100644
--- a/lib/string.in.h
+++ b/lib/string.in.h
@@ -118,10 +118,18 @@ _GL_WARN_ON_USE (ffsl, "ffsl is not portable - use the 
ffsl module");
 
 /* Find the index of the least-significant set bit.  */
 #if @GNULIB_FFSLL@
-# if !@HAVE_FFSLL@
+# if @REPLACE_FFSLL@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define ffsll rpl_ffsll
+#  endif
+_GL_FUNCDECL_RPL (ffsll, int, (long long int i));
+_GL_CXXALIAS_RPL (ffsll, int, (long long int i));
+# else
+#  if !@HAVE_FFSLL@
 _GL_FUNCDECL_SYS (ffsll, int, (long long int i));
-# endif
+#  endif
 _GL_CXXALIAS_SYS (ffsll, int, (long long int i));
+# endif
 _GL_CXXALIASWARN (ffsll);
 #elif defined GNULIB_POSIXCHECK
 # undef ffsll
diff --git a/m4/ffsll.m4 b/m4/ffsll.m4
index f99ea9c..97491eb 100644
--- a/m4/ffsll.m4
+++ b/m4/ffsll.m4
@@ -1,4 +1,4 @@
-# ffsll.m4 serial 1
+# ffsll.m4 serial 2
 dnl Copyright (C) 2011-2021 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -7,12 +7,50 @@ dnl with or without modifications, as long as this notice is 
preserved.
 AC_DEFUN([gl_FUNC_FFSLL],
 [
   AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
 
-  dnl Persuade glibc  to declare ffsll().
+  dnl Persuade glibc  and AIX  to declare ffsll().
   AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
 
   AC_CHECK_FUNCS_ONCE([ffsll])
-  if test $ac_cv_func_ffsll = no; then
+  if test $ac_cv_func_ffsll = yes; then
+dnl Test whether ffsll works.
+dnl On AIX 7.2 in 32-bit mode it is completely broken.
+AC_CACHE_CHECK([whether ffsll works],
+  [gl_cv_func_ffsll_works],
+  [AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([[
+#include 
+#include 
+int dummy (long long x) { return 42; }
+int main (int argc, char *argv[])
+{
+  int (* volatile my_ffsll) (long long) = argc ? ffsll : dummy;
+  long long int x = -128LL;
+  return my_ffsll (x) != 8;
+}
+  ]])],
+ [gl_cv_func_ffsll_works=yes],
+ [gl_cv_func_ffsll_works=no],
+ [case "$host_os" in
+   # Guess yes on glibc systems.
+*-gnu* | gnu*) gl_cv_func_ffsll_works="guessing yes" ;;
+   # Guess yes on musl systems.
+*-musl*)   gl_cv_func_ffsll_works="guessing yes" ;;
+   # Guess yes on native Windows.
+mingw*)gl_cv_func_ffsll_works="guessing yes" ;;
+   # Guess no on AIX.
+aix*)  gl_cv_func_ffsll_works="guessing no" ;;
+   # If we don't know, obey --enable-cross-guesses.
+*) gl_cv_func_ffsll_works="$gl_cross_guess_normal" ;;
+  esac
+ ])
+  ])
+case "$gl_cv_func_ffsll_works" in
+  *yes) ;;
+  *) REPLACE_FFSLL=1 ;;
+esac
+  else
 HAVE_FFSLL=0
   fi
 ])
diff --git a/m4/string_h.m4 b/m4/string_h.m4
index 3e65355..a4cc5b4 100644
--- a/m4/string_h.m4
+++ b/m4/string_h.m4
@@ -5,7 +5,7 @@
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 28
+# serial 29
 
 # Written by Paul Eggert.
 
@@ -113,6 +113,7 @@ AC_DEFUN([gl_HEADER_STRING_H_DEFAULTS],
   HAVE_SIGDESCR_NP=1;   AC_SUBST([HAVE_SIGDESCR_NP])
   HAVE_DECL_STRSIGNAL=1;AC_SUBST([HAVE_DECL_STRSIGNAL])
   HAVE_STRVERSCMP=1;

expm1f-ieee: Work around AIX 7.2 bug

2021-01-05 Thread Bruno Haible
On AIX 7.2 I see a test failure:

FAIL: test-expm1f-ieee
==

../../gltests/test-expm1-ieee.h:37: assertion '!!signbit (z) == !!signbit 
(MINUS_ZERO)' failed
FAIL test-expm1f-ieee (exit status: 134)

The cause is that expm1f (-0.0f) return +0.0f instead of -0.0f.
This patch fixes it.


2021-01-04  Bruno Haible  

expm1f-ieee: Work around AIX 7.2 bug.
* m4/expm1f.m4 (gl_FUNC_EXPM1F): Initialize gl_expm1f_required. If
module 'expm1f-ieee' is in use, check whether expm1f works according to
IEEE.
* m4/expm1f-ieee.m4: New file.
* modules/expm1f-ieee (Files): Add it.
(Depends-on): Update conditions.
(configure.ac): Invoke gl_FUNC_EXPM1F_IEEE.
* doc/posix-functions/expm1f.texi: Mention the AIX bug.

diff --git a/doc/posix-functions/expm1f.texi b/doc/posix-functions/expm1f.texi
index c732cfe..e95e510 100644
--- a/doc/posix-functions/expm1f.texi
+++ b/doc/posix-functions/expm1f.texi
@@ -4,9 +4,9 @@
 
 POSIX specification:@* 
@url{https://pubs.opengroup.org/onlinepubs/9699919799/functions/expm1f.html}
 
-Gnulib module: expm1f
+Gnulib module: expm1f or expm1f-ieee
 
-Portability problems fixed by Gnulib:
+Portability problems fixed by either Gnulib module @code{expm1f} or 
@code{expm1f-ieee}:
 @itemize
 @item
 This function is missing on some platforms:
@@ -16,6 +16,14 @@ This function produces wrong results for arguments <= 
@minus{}17.32868 on some p
 IRIX 6.5.
 @end itemize
 
+Portability problems fixed by Gnulib module @code{expm1f-ieee}:
+@itemize
+@item
+This function returns a positive zero for a minus zero argument
+on some platforms:
+AIX 7.2.
+@end itemize
+
 Portability problems not fixed by Gnulib:
 @itemize
 @end itemize
diff --git a/m4/expm1f-ieee.m4 b/m4/expm1f-ieee.m4
new file mode 100644
index 000..5344955
--- /dev/null
+++ b/m4/expm1f-ieee.m4
@@ -0,0 +1,15 @@
+# expm1f-ieee.m4 serial 1
+dnl Copyright (C) 2021 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl This macro is in a separate file (not in expm1f.m4 and not inlined in the
+dnl module description), so that gl_FUNC_EXPM1F can test whether 'aclocal' has
+dnl found uses of this macro.
+
+AC_DEFUN([gl_FUNC_EXPM1F_IEEE],
+[
+  m4_divert_text([INIT_PREPARE], [gl_expm1f_required=ieee])
+  AC_REQUIRE([gl_FUNC_EXPM1F])
+])
diff --git a/m4/expm1f.m4 b/m4/expm1f.m4
index 5cb661f..c18ff1a 100644
--- a/m4/expm1f.m4
+++ b/m4/expm1f.m4
@@ -1,4 +1,4 @@
-# expm1f.m4 serial 3
+# expm1f.m4 serial 4
 dnl Copyright (C) 2011-2021 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -6,6 +6,7 @@ dnl with or without modifications, as long as this notice is 
preserved.
 
 AC_DEFUN([gl_FUNC_EXPM1F],
 [
+  m4_divert_text([DEFAULTS], [gl_expm1f_required=plain])
   AC_REQUIRE([gl_MATH_H_DEFAULTS])
   AC_REQUIRE([gl_FUNC_EXPM1])
 
@@ -20,6 +21,7 @@ AC_DEFUN([gl_FUNC_EXPM1F],
   LIBS="$save_LIBS"
   if test $ac_cv_func_expm1f = yes; then
 EXPM1F_LIBM="$EXPM1_LIBM"
+
 save_LIBS="$LIBS"
 LIBS="$LIBS $EXPM1F_LIBM"
 gl_FUNC_EXPM1F_WORKS
@@ -28,6 +30,73 @@ AC_DEFUN([gl_FUNC_EXPM1F],
   *yes) ;;
   *) REPLACE_EXPM1F=1 ;;
 esac
+
+m4_ifdef([gl_FUNC_EXPM1F_IEEE], [
+  if test $gl_expm1f_required = ieee && test $REPLACE_EXPM1F = 0; then
+AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+AC_CACHE_CHECK([whether expm1f works according to ISO C 99 with IEC 
60559],
+  [gl_cv_func_expm1f_ieee],
+  [
+save_LIBS="$LIBS"
+LIBS="$LIBS $EXPM1F_LIBM"
+AC_RUN_IFELSE(
+  [AC_LANG_SOURCE([[
+#ifndef __NO_MATH_INLINES
+# define __NO_MATH_INLINES 1 /* for glibc */
+#endif
+#include 
+]gl_FLOAT_MINUS_ZERO_CODE[
+]gl_FLOAT_SIGNBIT_CODE[
+#ifndef expm1f
+extern
+#ifdef __cplusplus
+"C"
+#endif
+float expm1f (float);
+#endif
+/* Compare two numbers with ==.
+   This is a separate function because IRIX 6.5 "cc -O" miscompiles an
+   'x == x' test.  */
+static int
+numeric_equal (float x, float y)
+{
+  return x == y;
+}
+static float dummy (float x) { return 0; }
+int main (int argc, char *argv[])
+{
+  float (* volatile my_expm1f) (float) = argc ? expm1f : dummy;
+  /* Test expm1f(-0.0f).
+ This test fails on AIX 7.2.  */
+  float y = my_expm1f (minus_zerof);
+  if (signbitf (minus_zerof) && !signbitf (y))
+return 1;
+  return 0;
+}
+  ]])],
+  [gl_cv_func_expm1f_ieee=yes],
+  [gl_cv_func_expm1f_ieee=no],
+  [case "$host_os" in
+# Guess yes on glibc systems.
+ *-gnu* 

localeconv: Work around a mingw bug

2023-04-27 Thread Bruno Haible
right (C) 2012-2023 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -8,10 +8,45 @@ AC_DEFUN([gl_FUNC_LOCALECONV]
 [
   AC_REQUIRE([gl_LOCALE_H_DEFAULTS])
   AC_REQUIRE([gl_LOCALE_H])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
 
   if test $REPLACE_STRUCT_LCONV = 1; then
 REPLACE_LOCALECONV=1
   fi
+  if test $REPLACE_LOCALECONV = 0; then
+dnl Test whether fields of type 'char' are filled correctly.
+dnl This test fails on mingw 5.0.3.
+AC_CACHE_CHECK([whether localeconv works],
+  [gl_cv_func_localeconv_works],
+  [AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([[
+#include 
+#include 
+int main ()
+{
+  struct lconv *l = localeconv ();
+  return l->frac_digits != CHAR_MAX && l->frac_digits < 0;
+}
+ ]])],
+ [gl_cv_func_localeconv_works=yes],
+ [gl_cv_func_localeconv_works=no],
+ [case "$host_os" in
+# Guess yes on glibc systems.
+    *-gnu* | gnu*)  gl_cv_func_localeconv_works="guessing yes" ;;
+# Guess yes on musl systems.
+*-musl* | midipix*) gl_cv_func_localeconv_works="guessing yes" ;;
+# Guess no on native Windows.
+mingw*) gl_cv_func_localeconv_works="guessing no" ;;
+# If we don't know, obey 
--enable-cross-guesses.
+*)  
gl_cv_func_localeconv_works="$gl_cross_guess_normal" ;;
+  esac
+ ])
+  ])
+case "$gl_cv_func_localeconv_works" in
+  *yes) ;;
+  *) REPLACE_LOCALECONV=1 ;;
+esac
+  fi
 ])
 
 # Prerequisites of lib/localeconv.c.
@@ -19,4 +54,6 @@ AC_DEFUN([gl_PREREQ_LOCALECONV]
 [
   AC_CHECK_MEMBERS([struct lconv.decimal_point], [], [],
 [[#include ]])
+  AC_CHECK_MEMBERS([struct lconv.int_p_cs_precedes], [], [],
+[[#include ]])
 ])






Re: Android NDK r26 and utmpx

2024-01-20 Thread Paul Eggert
Thanks for reporting that. Would something like the attached Gnulib 
patch fix the Android issue?


This patch assumes that readutmp-like functions have never worked on 
Android (always report nothing); is that the case?


I haven't installed this, or tested it on Android.From 60aa07c1ccd5aa18a9f87997a51acc8507515ef1 Mon Sep 17 00:00:00 2001
From: Paul Eggert 
Date: Sat, 20 Jan 2024 19:01:12 -0800
Subject: [PATCH] readutmp: port to Android NDK r26
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* lib/readutmp.c (read_utmp_from_file) [__ANDROID__]:
Don’t bother trying to read from a real file, as this
has never worked with Android and the useless code
stops working on Android NDK r26.
---
 ChangeLog  |  8 
 lib/readutmp.c | 48 
 2 files changed, 32 insertions(+), 24 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index d8d2a13d9e..4533eaceb2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2024-01-20  Paul Eggert  
+
+	readutmp: port to Android NDK r26
+	* lib/readutmp.c (read_utmp_from_file) [__ANDROID__]:
+	Don’t bother trying to read from a real file, as this
+	has never worked with Android and the useless code
+	stops working on Android NDK r26.
+
 2024-01-19  Bruno Haible  
 
 	fenv-environment: Fix for NetBSD/powerpc.
diff --git a/lib/readutmp.c b/lib/readutmp.c
index ae2e3ae8c6..59074d68c1 100644
--- a/lib/readutmp.c
+++ b/lib/readutmp.c
@@ -330,7 +330,27 @@ read_utmp_from_file (char const *file, idx_t *n_entries, STRUCT_UTMP **utmp_buf,
 
 # if READUTMP_USE_SYSTEMD || HAVE_UTMPX_H || HAVE_UTMP_H
 
-#  if defined UTMP_NAME_FUNCTION /* glibc, musl, macOS, FreeBSD, NetBSD, Minix, AIX, IRIX, Solaris, Cygwin, Android */
+#  ifdef __ANDROID__
+  /* On Android, there is no /var, and normal processes don't have access
+ to system files.  Therefore use the kernel's uptime counter, although
+ it produces wrong values after the date has been bumped in the running
+ system.  */
+  if ((options & (READ_UTMP_USER_PROCESS | READ_UTMP_NO_BOOT_TIME)) == 0
+  && strcmp (file, UTMP_FILE) == 0
+  && !have_boot_time (a))
+{
+  struct timespec boot_time;
+  if (get_android_boot_time (_time) >= 0)
+a = add_utmp (a, options,
+  "reboot", strlen ("reboot"),
+  "", 0,
+  "", 0,
+  "", 0,
+  0, BOOT_TIME, boot_time, 0, 0, 0);
+}
+
+#  elif defined UTMP_NAME_FUNCTION
+  /* glibc, musl, macOS, FreeBSD, NetBSD, Minix, AIX, IRIX, Solaris, Cygwin */
 
   /* Ignore the return value for now.
  Solaris' utmpname returns 1 upon success -- which is contrary
@@ -340,7 +360,7 @@ read_utmp_from_file (char const *file, idx_t *n_entries, STRUCT_UTMP **utmp_buf,
 
   SET_UTMP_ENT ();
 
-#   if (defined __linux__ && !defined __ANDROID__) || defined __minix
+#   if defined __linux__ || defined __minix
   bool file_is_utmp = (strcmp (file, UTMP_FILE) == 0);
   /* Timestamp of the "runlevel" entry, if any.  */
   struct timespec runlevel_ts = {0};
@@ -390,7 +410,7 @@ read_utmp_from_file (char const *file, idx_t *n_entries, STRUCT_UTMP **utmp_buf,
 #endif
 UT_EXIT_E_TERMINATION (ut), UT_EXIT_E_EXIT (ut)
);
-#   if defined __linux__ && !defined __ANDROID__
+#   ifdef __linux__
   if (file_is_utmp
   && memcmp (UT_USER (ut), "runlevel", strlen ("runlevel") + 1) == 0
   && memcmp (ut->ut_line, "~", strlen ("~") + 1) == 0)
@@ -406,7 +426,7 @@ read_utmp_from_file (char const *file, idx_t *n_entries, STRUCT_UTMP **utmp_buf,
 
   END_UTMP_ENT ();
 
-#   if defined __linux__ && !defined __ANDROID__
+#   ifdef __linux__
   /* On Alpine Linux, UTMP_FILE is not filled.  It is always empty.
  So, fake a BOOT_TIME entry, by getting the time stamp of a file that
  gets touched only during the boot process.
@@ -449,26 +469,6 @@ read_utmp_from_file (char const *file, idx_t *n_entries, STRUCT_UTMP **utmp_buf,
 }
 #   endif
 
-#   if defined __ANDROID__
-  /* On Android, there is no /var, and normal processes don't have access
- to system files.  Therefore use the kernel's uptime counter, although
- it produces wrong values after the date has been bumped in the running
- system.  */
-  if ((options & (READ_UTMP_USER_PROCESS | READ_UTMP_NO_BOOT_TIME)) == 0
-  && strcmp (file, UTMP_FILE) == 0
-  && !have_boot_time (a))
-{
-  struct timespec boot_time;
-  if (get_android_boot_time (_time) >= 0)
-a = add_utmp (a, options,
-  "reboot", strlen ("reboot"),
-  "", 0,
-  "", 0,
-  "", 0,
-  0, BOOT_TIME, boot_time, 0, 0, 0);
-}
-#   endif
-
 #   if defined __minix
   /* On Minix, during boot,
1. an entry gets written into /var/run/utmp, with ut_type = BOOT_TIME,
-- 
2.40.1



fenv-*: Fix for FreeBSD/powerpc64 and NetBSD/powerpc

2024-01-19 Thread Bruno Haible
test failure on *BSD/powerpc*.
+	* tests/test-fenv-except-trapping-2.c (main): Skip the '4' tests also on
+	FreeBSD/powerpc* and NetBSD/powerpc*.
+
 	fenv-exceptions-state-c99: Fix for FreeBSD/powerpc64 and NetBSD/powerpc.
 	* m4/fenv-exceptions-state.m4 (gl_FENV_EXCEPTIONS_STATE): On
 	FreeBSD/powerpc64 and NetBSD/powerpc, set REPLACE_FESETEXCEPTFLAG.
diff --git a/tests/test-fenv-except-trapping-2.c b/tests/test-fenv-except-trapping-2.c
index 57b9341f46..257107d2ee 100644
--- a/tests/test-fenv-except-trapping-2.c
+++ b/tests/test-fenv-except-trapping-2.c
@@ -433,8 +433,8 @@ main (int argc, char *argv[])
GNU/kFreeBSD/i386, GNU/kFreeBSD/x86_64,
musl libc/i386, musl libc/powerpc64le,
macOS/i386, macOS/x86_64, macOS/arm64,
-   FreeBSD/i386, FreeBSD/x86_64,
-   NetBSD/i386, NetBSD/x86_64,
+   FreeBSD/i386, FreeBSD/x86_64, FreeBSD/powerpc64,
+   NetBSD/i386, NetBSD/x86_64, NetBSD/powerpc,
OpenBSD/i386, OpenBSD/x86_64, OpenBSD/mips64,
Minix/i386,
AIX/powerpc,
@@ -460,6 +460,7 @@ main (int argc, char *argv[])
   || (defined MUSL_LIBC && ((defined __i386 || defined _M_IX86) || defined __powerpc__)) \
   || ((defined __APPLE__ && defined __MACH__) && ((defined __x86_64__ || defined _M_X64) || (defined __i386 || defined _M_IX86) || defined __aarch64__)) \
   || ((defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__) && ((defined __x86_64__ || defined _M_X64) || (defined __i386 || defined _M_IX86))) \
+  || ((defined __FreeBSD__ || defined __NetBSD__) && defined __powerpc__) \
   || (defined __OpenBSD__ && defined __mips64) \
   || (defined __minix && (defined __i386 || defined _M_IX86)) \
   || (defined _AIX && defined __powerpc__) \
-- 
2.34.1

>From 16276ab5c6b6b4154ba1c4577d53e7fe0fecc989 Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Fri, 19 Jan 2024 22:58:43 +0100
Subject: [PATCH 4/4] fenv-environment: Fix for NetBSD/powerpc.

* m4/fenv-environment.m4 (gl_FENV_ENVIRONMENT): For feupdateenv, use
the same configure test on NetBSD/powerpc as on glibc/hppa.
* doc/posix-functions/feupdateenv.texi: Mention the NetBSD/powerpc bug.
---
 ChangeLog|  5 +
 doc/posix-functions/feupdateenv.texi |  3 ++-
 m4/fenv-environment.m4   | 13 +++--
 3 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 7cef961362..d8d2a13d9e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2024-01-19  Bruno Haible  
 
+	fenv-environment: Fix for NetBSD/powerpc.
+	* m4/fenv-environment.m4 (gl_FENV_ENVIRONMENT): For feupdateenv, use
+	the same configure test on NetBSD/powerpc as on glibc/hppa.
+	* doc/posix-functions/feupdateenv.texi: Mention the NetBSD/powerpc bug.
+
 	fenv-exceptions-trapping: Avoid a test failure on *BSD/powerpc*.
 	* tests/test-fenv-except-trapping-2.c (main): Skip the '4' tests also on
 	FreeBSD/powerpc* and NetBSD/powerpc*.
diff --git a/doc/posix-functions/feupdateenv.texi b/doc/posix-functions/feupdateenv.texi
index bb844ec2f1..4fd76416a1 100644
--- a/doc/posix-functions/feupdateenv.texi
+++ b/doc/posix-functions/feupdateenv.texi
@@ -34,7 +34,8 @@
 This function does not trigger traps on
 @c https://sourceware.org/bugzilla/show_bug.cgi?id=31023
 glibc 2.37/hppa,
-musl libc/s390x.
+musl libc/s390x,
+NetBSD 9.3/powerpc.
 @item
 This function may fail on some platforms:
 MSVC 14.
diff --git a/m4/fenv-environment.m4 b/m4/fenv-environment.m4
index 8d3911e6e4..bf4788dc9b 100644
--- a/m4/fenv-environment.m4
+++ b/m4/fenv-environment.m4
@@ -1,4 +1,4 @@
-# fenv-environment.m4 serial 2
+# fenv-environment.m4 serial 3
 dnl Copyright (C) 2023-2024 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -304,9 +304,10 @@ AC_DEFUN([gl_FENV_ENVIRONMENT]
 dnl <https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=a8c79c4088e8c04e4297936efa0dee6c8e6e974d>)
 dnl and on Mac OS X 10.5/{i386,x86_64} (where it forgets about the currently
 dnl set floating-point exception flags)
-dnl and on musl libc/s390x (where it does not trigger traps)
-dnl on musl libc/{i386,x86_64} and AIX and Solaris and mingw 10 (where it
-dnl fails to restore the exception trap bits),
+dnl and on musl libc/s390x and NetBSD 9.3/powerpc (where it does not trigger
+dnl traps)
+dnl and on musl libc/{i386,x86_64} and AIX and Solaris and mingw 10 (where
+dnl it fails to restore the exception trap bits),
 dnl and on FreeBSD 12.2/arm64 (see
 dnl <https://cgit.freebsd.org/src/commit/?id=34cc08e336987a8ebc316595e3f552a4c09f1fd4>).
 dnl On MSVC 14 it may even fail.
@@ -329,8 +330,8 @@ AC_DEFUN([gl_FENV_ENVIRONMENT]
  [gl_cv_func_feupdateenv_works="guessing no"

Re: [PATCH] getdtablesize: support systems without getrlimit like WASI

2024-05-04 Thread Yuta Saito
Hi Bruno,

Thank you for taking a look at this.

>   - How do _you_ compile and run a program in this environment?
> The same way as in [2], or do you do it differently?

Yes, I use wasi-sdk[1] as described in the document. My current motivation
is porting
libidn to WebAssembly and I needed to apply this patch to make it work.
To be precise, I use the following configuration to cross-build libidn with
this Gnulib patch.

```
$ ../libidn/configure --host wasm32-wasi --enable-cross-guesses=risky
--disable-doc \
  CFLAGS='-D_WASI_EMULATED_PROCESS_CLOCKS -fPIC'
LDFLAGS='-lwasi-emulated-process-clocks' \
  RANLIB=$WASI_SDK_PATH/bin/llvm-ranlib AR=$WASI_SDK_PATH/bin/llvm-ar
CC=$WASI_SDK_PATH/bin/clang
```

>  - [1] promises that the programs "may run anywhere—from browsers to
clouds
>to embedded devices". How do you run such a program in a browser?
>How do you run it in the "cloud"? How do you run it on a memory-
>restricted computer?

First of all, WebAssembly is a specification of a set of virtual
instruction set and program format.
It's quite similar to JVM, but it's enough low-level to be able to lower
LLVM IR to the program format.

Recent major browsers have implemented execution engines for WebAssembly
alongside their JavaScript engines.
Those engines typically validate the given program and translate the
virtual instruction sequence into native one _or_
just interpret it. The program effectively has isolated memory space from
the host environment and also needs to have
explicit verifiable metadata to interact with the host system[2].
Therefore, browsers can run such programs without certain
class of security issues.

The spec of WebAssembly does not mention the existence of "browser" at all,
and its runtime can be implemented
outside of browsers. One of the major implementations of such standalone
runtime is wasmtime[3], and also there is a
smaller runtime implementation for restricted environments[4].

WASI is an interface specification between host system and guest program
and we have a libc implementation on the top of
it based on musl[4].

You can see more design rationales at https://github.com/WebAssembly/design

The current major limitations on the WASI and WebAssembly stack are:
1. Control flow is restricted to be _structured_, so setjmp/longjmp cannot
be implemented easily.
   (We have a way based on CPS transformation but it's quite expensive)
2. WASI still defines quite a small space of interfaces compared with POSIX
system calls for now.
It has a basic file system, environment variable, socket, etc..., but
still doesn't have something corresponding to getrlimit or
flock, or something like that.

Given that our libc implementation is based on musl and it's
already supported in this project, I think the work required to port
Gnulib to WASI/WebAssembly would be basically providing stub
implementations for functions that cannot be implemented yet
due to a lack of the system interface spec.

Let me know if you need more information :)

Thanks,
Yuta

[1] https://github.com/WebAssembly/wasi-sdk
[2] https://github.com/WebAssembly/design/blob/main/Modules.md#imports
[3] https://github.com/bytecodealliance/wasmtime
[4] https://github.com/bytecodealliance/wasm-micro-runtime
[5] https://github.com/WebAssembly/wasi-sdk


2024年5月5日(日) 0:01 Bruno Haible :

> Hi Saito-san,
>
> > * lib/getdtablesize.c (getdtablesize): Return INT_MAX if getrlimit
> >   is not available. This is the case for WASI, WebAssembly System
> >   Interface.
>
> Can you please tell us more about this compilation environment?
>
> I want to evaluate how much effort Gnulib should put into supporting this
> environment.
>
> I see [1] and [2], but
>
>   - How do _you_ compile and run a program in this environment?
> The same way as in [2], or do you do it differently?
>
>   - [1] promises that the programs "may run anywhere—from browsers to
> clouds
> to embedded devices". How do you run such a program in a browser?
> How do you run it in the "cloud"? How do you run it on a memory-
> restricted computer?
>
> Bruno
>
> [1] https://wasi.dev/
> [2]
> https://github.com/bytecodealliance/wasmtime/blob/main/docs/WASI-tutorial.md
>
>
>
>


Re: gnulib portability issues

2012-06-10 Thread Rich Felker
On Sat, Jun 09, 2012 at 10:01:38PM -0700, Paul Eggert wrote:
 On 06/09/2012 09:25 PM, Rich Felker wrote:
  For seekable input, comparing ftello(f) and the underlying fd offset
  from lseek(fileno(f),0,SEEK_CUR) would work, but that also will fail
  for non-seekable input.
 
 Thanks, that's better than what I wrote.  Perhaps you could write up
 a patch along those lines.  At least it will work for seekable files.

I don't think it's useful if it fails and makes the program misbehave
on pipes. If the result were only needed/used for optimization
purposes and doesn't have to be right, we could just either always
return 0 or always return 1, but I'm not clear whether it's intended
that the function always give an accurate result. If yes, there are
usage cases in a potential caller that would be broken by either fake
behavior..

 Come to think of it, a variant might even work for seekable files.
 Use dup2 to move the file descriptor somewhere else.  Close the
 fd.  Keep reading until error, and count the bytes read.  Then
 ungetc all the bytes that you read, in reverse order, and restore
 the file descriptor.  Of course ISO C doesn't guarantee this, but
 it should be fairly portable in practice.

No, ungetc normally can only unget one character. musl is fairly
unique in allowing you to unget more, and this is not really
intentional, just a consequence of the fact that we don't do any
buffer switching for unget.

Did you miss the end of my last email? I already sent a sketch of an
idea similar to yours, and it only needs to unget one character, not
an arbitrary number.

Oh, I see now you want to actually make it return the number of bytes
buffered rather than just the fake minimum number based on a boolean.
If the latter is acceptable though, the stdio_ext.h function
__freading might suffice as an implementation.

  it might be better to make sense of WHY it's needed/wanted
 
 Yes, quite true, but that information wasn't communicated to the
 gnulib mailing list.

I'll see what we can find.

Rich



Re: gnulib portability issues

2012-06-11 Thread Eric Blake
On 06/11/2012 06:54 AM, Rich Felker wrote:

 GNU M4 (at least the master branch, although it has not yet been
 released as m4 2.0) _wants_ to use freadahead, because it provides at
 least a 10% speedup in operation.  It _really is_ more efficient to peek
 at the current buffer in one function call than it is to call multiple
 fgetc_unlocked(), in order to rapidly search for the next character of
 interest.

Actually, m4 uses freadptr(), not freadahead(), and _does_ fall back to
slower code when freadptr() returns NULL.  But as noted in the gnulib
code for the two functions, freadahead() can be as simple as whether
freadptr() returns a non-NULL value.  I think a 0/1 freadahead() would
work, but the speedup comes from providing an freadptr() that actually
reads ahead.

 
 Can you explain how knowing the _number_ of buffered characters helps
 you find the next character of interest efficiently?

It doesn't.  Rather, the speedup comes from the ability to peek into
that buffer in advance, using freadptr(), so that you can use strchr(),
strstr(), or other search functions on the buffer, followed by an
fread() of the appropriate size, all in order to minimize the number of
function calls without reading past the ISO C99 1-byte ungetc()
portability limit.  Hence the SLOW_BUT_NO_HACKS definition that loses
out on the speedup if freadptr() always returns NULL (at which point
freadahead() could be treated as always returning 0, implying that there
is no read-ahead buffer).

 As for musl, would adding __freadahead be sufficient to make it use
 __freadahead, or does gnulib hard-code knowledge about which systems
 have which stdio extension functions?

Depending on the function name you choose, we would have to add an m4
check to see if __freadahead() is defined; but once we know the name of
the function to check for at configure time, then it is quite simple to
code up gnulib's freadahead.c to call into the internal __freadahead()
function of libc, when one exists.

-- 
Eric Blake   ebl...@redhat.com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: gnulib portability issues

2012-06-11 Thread Rich Felker
On Mon, Jun 11, 2012 at 07:14:56AM -0600, Eric Blake wrote:
 On 06/11/2012 06:54 AM, Rich Felker wrote:
 
  GNU M4 (at least the master branch, although it has not yet been
  released as m4 2.0) _wants_ to use freadahead, because it provides at
  least a 10% speedup in operation.  It _really is_ more efficient to peek
  at the current buffer in one function call than it is to call multiple
  fgetc_unlocked(), in order to rapidly search for the next character of
  interest.
 
 Actually, m4 uses freadptr(), not freadahead(), and _does_ fall back to

OK that makes a lot more sense.

But if your goal is to read up until the next character in a
particular set of special characters, why not fscanf(f, %100[^xyz],
...) with 100 replaced by your buffer size and xyz replaced by the
specials? If fscanf is too slow, it seems like this is a QOI bug in
fscanf (I'll admit mine is too slow here), but it seems like the right
way to do this operation in a way that _can_ be fast if the underlying
library handles it well.

  Can you explain how knowing the _number_ of buffered characters helps
  you find the next character of interest efficiently?
 
 It doesn't.  Rather, the speedup comes from the ability to peek into
 that buffer in advance, using freadptr(), so that you can use strchr(),
 strstr(), or other search functions on the buffer, followed by an
 fread() of the appropriate size, all in order to minimize the number of
 function calls without reading past the ISO C99 1-byte ungetc()

BTW if you're going to propose something to POSIX, I think a variant
of getdelim with a scanset rather than a single delimiter character
might be a cleaner proposal.. Note that it could be implemented in
terms of fscanf and %m[...] on systems that don't have it but which
already conform to POSIX 2008.

  As for musl, would adding __freadahead be sufficient to make it use
  __freadahead, or does gnulib hard-code knowledge about which systems
  have which stdio extension functions?
 
 Depending on the function name you choose, we would have to add an m4
 check to see if __freadahead() is defined; but once we know the name of
 the function to check for at configure time, then it is quite simple to
 code up gnulib's freadahead.c to call into the internal __freadahead()
 function of libc, when one exists.

So right now, for DragonFly, it's just hard-coded? If you're willing
to put in a test for it, I'm willing to add the function.

Rich



Re: why is MB_LEN_MAX so large (16) on glibc

2015-05-13 Thread Bruno Haible
[CCing bug-gnulib to share the understanding about i18n issues]

Pádraig Brady wrote on 13.05.2015:
 MB_LEN_MAX was changed from 6 to 16 with:
 https://sourceware.org/git/?p=glibc.git;a=commit;f=include/limits.h;h=d64b6ad075
 Do you know why the value 16 is used exactly?

This was motivated either by the desire to be completely future-proof
for the next 30 years (and you don't know what kinds of encodings will
be invented).

Or because for a couple of months Ulrich Drepper  François Pinard were
considering to add locales with stateful encodings such as ISO-2022-JP-2.
This later turned out to be not worth the effort (as the user experience
with filenames and shell in such locales was found to be terrible).

 BTW I see MB_LEN_MAX is 4 on musl libc.

The value of 4 is sufficient to accommodate all stateless encodings in
use, including UTF-8 (which was restricted from max. 6 to 4 bytes by
an ISO standard) and GB18030. But it's not necessarily future-proof.

 I was worried that it implied that wctomb() might convert a wide char to 
 _multiple_ encoded chars
 for some character/encoding combinations?

No, neither POSIX nor glibc supports locales with encodings where
a wide char would correspond to multiple characters or a where a
character would correspond to multiple wide chars. In particular,
this prevented EUC-JISX0213 from being used as a locale encoding in
glibc [1], thus accelerating the move to UTF-8.

 For example iso-2022-kr can have up to 7 bytes per encoded char,
 so maybe wctomb() might output two of those for some wide chars,
 and the extra two bytes were added for alignment?

Yes, this was part of the considerations regarding stateful encodings.

 Specifically why I'm wondering about this is to size the
 output buffer for wctomb() appropriately.
 Note the linux man page for wctomb() says to use MB_CUR_MAX,
 while the freebsd man page says to use MB_LEN_MAX

That's simply because MB_CUR_MAX is not a compile-time constant,
and therefore for a long time the declaration of a local variable
  char buf[MB_CUR_MAX];
required GCC or C++, and the FreeBSD people are not keen adopters
of GCC extensions.

 I also asked this at:
 http://stackoverflow.com/q/30222107/4421

Bruno

[1] https://sourceware.org/git/?p=glibc.git;a=blob;f=iconvdata/euc-jisx0213.c




Re: what platforms are you testing on?

2016-10-20 Thread Bruno Haible
Hi all,

Thanks for all your answers. Here's the new proposed portion of the section
'Target Platforms'. Please reply if you think does it misrepresents the
current situation!

   As of 2016, the list of supported platforms is the following:

   * glibc systems.  With glibc 2.15 or newer, they are frequently
 tested.  About the kernels:
* glibc on Linux is frequently tested.
* glibc on kFreeBSD is rarely tested.
   * Mac OS X. In versions 10.11, it's occasionally tested.  In version
 10.5, it's rarely tested.
   * FreeBSD 9.1 or newer is occasionally tested.
   * OpenBSD 5.8 or newer is occasionally tested.
   * AIX 7.1 is occasionally tested.
   * Solaris 10 and 11 are occasionally tested.  Solaris 9 and older are
 rarely tested and low priority.
   * Cygwin 2.6 is occasionally tested.  Cygwin 1.7.x is rarely tested.
   * mingw is occasionally tested.  But note that some modules are
 currently unsupported on mingw: 'mgetgroups', 'getugroups',
 'idcache', 'userspec', 'openpty', 'login_tty', 'forkpty',
 'pt_chown', 'grantpt', 'pty', 'savewd', 'mkancesdirs', 'mkdir-p',
 'euidaccess', 'faccessat'.  The versions of Windows that are
 supported are Windows XP and newer.  Only the latest version of
 mingw is tested; older versions are not supported.
   * GNU Hurd 0.7 is rarely tested.
   * NetBSD 7.0 or newer is rarely tested.
   * Native Windows, with MSVC as compiler, is rarely tested and low
 priority.
   * musl libc is rarely tested.
   * Minix 3.3.0 is rarely tested.
   * HP-UX 11.31 is very rarely tested.
   * IRIX 6.5 is no longer tested.
   * OSF/1 5.1 is no longer tested.
   * Interix 6.1 is no longer tested, and requires the 'suacomp' library
 (<http://sourceforge.net/projects/suacomp/>) in version 0.6.8 or
 newer.
   * Haiku and BeOS are no longer tested.
   * uClibc on Linux is no longer tested.
   * QNX is no longer tested.


Paul, since you say that HP-UX is still living on but none of us has access to
a HP-UX machine, I wrote "HP-UX 11.31 is very rarely tested."

I did not mention particular GNU/Linux distributions, because they don't differ
much, because they evolve (merge, split, get renamed) rather quickly, and
because I don't want to make propaganda for some of them but not for others.

Bruno




announcing support for C++

2019-12-11 Thread Bruno Haible
A testdir created with
  ./gnulib-tool --create-testdir --dir=../testdir1 --single-configure 
--with-c++-tests `./posix-modules`
is now known to build fine on the following platforms:

  - glibc
  - musl libc
  - macOS 10.13
  - FreeBSD 12
  - NetBSD 7
  - OpenBSD 6.5
  - Solaris 10, 11.0, 11.4, OpenIndiana
  - AIX 7.1, 7.2
  - HP-UX 11.31
  - Haiku
  - Cygwin
  - mingw
  - MSVC 14

This means that the ISO C and POSIX substitutes of gnulib are now supported
in C++ mode.

I don't think future platforms or future versions of existing platforms will
create unsurmountable problems in maintaining this support, because newer
platforms tend to be closer to POSIX than older ones, thus requiring fewer
workarounds.

Therefore we can now declare C++ as being supported for these modules.


2019-12-11  Bruno Haible  

doc: Document that ISO C or POSIX substitutes are supported in C++ mode.
* doc/gnulib-intro.texi (Various Kinds of Modules): Document that ISO C
and POSIX substitutes are supported in C++ mode.
* NEWS: Likewise.

diff --git a/NEWS b/NEWS
index 30bb223..8085c35 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,12 @@ Important general notes
 
 DateModules Changes
 
+2019-12-11  Support for These modules are now supported in C++ mode as 
well.
+ISO C or POSIX  This means, while the autoconfiguration uses the C
+functions   compiler, the resulting header files and function
+substitutes can be used with a matching C++ 
compiler
+as well.
+
 2019-02-14  gnulib-tool If you use multiple --local-dir options at once:
 The first one now has the highest priority, not the
 last one.
diff --git a/doc/gnulib-intro.texi b/doc/gnulib-intro.texi
index 26f8cb8..5d75c9b 100644
--- a/doc/gnulib-intro.texi
+++ b/doc/gnulib-intro.texi
@@ -323,6 +323,11 @@ with @samp{.in} inserted before the @samp{.h} extension, 
so that on
 systems which do provide a correct
 header file the system's one is used.
 
+The modules in this category are supported in C++ mode as well.  This
+means, while the autoconfiguration uses the C compiler, the resulting
+header files and function substitutes can be used with a matching C++
+compiler as well.
+
 @subsection Enhancements of ISO C or POSIX functions
 
 These are sometimes POSIX functions with GNU extensions also found in




Re: iconv replacements

2020-07-30 Thread Bruno Haible
[Dropping bug-bison from CC]

> > Yes and no. The code is not making assumptions about a particular iconv()
> > implementation. But it needs to distinguish two categories of replacements
> > done by iconv():
> >   - those that are harmless (for example when replacing a Unicode TAG
> > character U+E00xx with an empty output),
> >   - those that are better not presented to the user, if the programmer has
> > specified a fallback (for example, replacing all non-ASCII characters
> > with NUL, '?', or '*').
> >
> > The standards don't help in making the distinction.
> >
> > Therefore whether you consider said glibc and libiconv behaviour as
> > "non-conforming" or not is irrelevant.
> 
> Could you sketch briefly what you need?  We have identified some issues
> with the existing iconv interface.  If we add an enhancement, it would
> make sense to cover these requirements.

POSIX [1] says:

  "If iconv() encounters a character in the input buffer that is valid, but for
   which an identical character does not exist in the target codeset, iconv()
   shall perform an implementation-defined conversion on this character."

  "The iconv() function shall ... return the number of non-identical 
conversions performed."

This is sufficient for detecting that iconv() did something that the
application might or might not like.

For decent application behaviour in UTF-8, legacy 8-bit, and ASCII locales
I wrote a module 'unicodeio' that accepts an ASCII fallback given by the
programmer. For example, for the string "François Pinard" a fallback
"Francois Pinard" can be given, and for the string "•" a fallback "." can
be given.

In this code, it needs to analyze what iconv() actually did and distinguish
replacements that are OK (no need to activate the ASCII fallback) and those
that are worse than the ASCII fallback. For example:
  - Replacing 'ç' with '?' (NetBSD, Solaris 11) or '*' (musl) or NUL (IRIX)
is worse than the ASCII fallback.
  - Replacing a Unicode tag character with an empty string is OK.
  - Replacing GREEK SMALL LETTER MU with MICRO SIGN is OK.
  - Replacing FULLWIDTH COLON with ':' is OK (most likely equivalent to the
ASCII fallback).

That's my requirement from the application side. I don't know whether an
iconv() implementation can help here, given the limited interface of iconv.

Maybe there could be an alternative to //TRANSLIT in the iconv_open()
argument, that would specify e.g. that tag characters and  and 
replacements in UnicodeData.txt are OK but other replacements are not OK?
Where either
  - OK means a conversion that does not increment the return value,
  - "not OK" means a conversion that increments the return value,
or
  - OK means a conversion that increments the return value,
  - "not OK" means an error return (-1 / EILSEQ).

Bruno

[1] https://pubs.opengroup.org/onlinepubs/9699919799/functions/iconv.html




Re: ptrdiff_t overflow checks for malloc-posix etc.

2021-04-18 Thread Paul Eggert
[[#include 
   ]],
-  [[char *p = malloc (0);
+  [[void *p = malloc (0);
 int result = !p;
 free (p);
 return result;]])
@@ -23,22 +24,17 @@ AC_DEFUN([_AC_FUNC_MALLOC_IF],
[ac_cv_func_malloc_0_nonnull=no],
[case "$host_os" in
   # Guess yes on platforms where we know the result.
-  *-gnu* | gnu* | *-musl* | freebsd* | midnightbsd* | netbsd* | openbsd* \
-  | hpux* | solaris* | cygwin* | mingw*)
+  *-gnu* | freebsd* | netbsd* | openbsd* | bitrig* \
+  | gnu* | *-musl* | midnightbsd* \
+  | hpux* | solaris* | cygwin* | mingw* | msys* )
 ac_cv_func_malloc_0_nonnull="guessing yes" ;;
   # If we don't know, obey --enable-cross-guesses.
   *) ac_cv_func_malloc_0_nonnull="$gl_cross_guess_normal" ;;
 esac
])
 ])
-  case "$ac_cv_func_malloc_0_nonnull" in
-*yes)
-  $1
-  ;;
-*)
-  $2
-  ;;
-  esac
+  AS_IF([case $ac_cv_func_malloc_0_nonnull in *yes) :;; *) false;; esac],
+[$1], [$2])
 ])# _AC_FUNC_MALLOC_IF
 
 # gl_FUNC_MALLOC_GNU
diff --git a/m4/realloc.m4 b/m4/realloc.m4
index 4939516a0..cde906192 100644
--- a/m4/realloc.m4
+++ b/m4/realloc.m4
@@ -1,20 +1,21 @@
-# realloc.m4 serial 21
+# realloc.m4 serial 22
 dnl Copyright (C) 2007, 2009-2021 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
 dnl with or without modifications, as long as this notice is preserved.
 
 # This is adapted with modifications from upstream Autoconf here:
-# https://git.savannah.gnu.org/cgit/autoconf.git/commit/?id=04be2b7a29d65d9a08e64e8e56e594c91749598c
+# https://git.savannah.gnu.org/cgit/autoconf.git/tree/lib/autoconf/functions.m4?id=v2.70#n1455
 AC_DEFUN([_AC_FUNC_REALLOC_IF],
-[ AC_REQUIRE([AC_CANONICAL_HOST])dnl for cross-compiles
+[
+  AC_REQUIRE([AC_CANONICAL_HOST])dnl for cross-compiles
   AC_CACHE_CHECK([whether realloc (0, 0) returns nonnull],
 [ac_cv_func_realloc_0_nonnull],
 [AC_RUN_IFELSE(
[AC_LANG_PROGRAM(
   [[#include 
   ]],
-  [[char *p = realloc (0, 0);
+  [[void *p = realloc (0, 0);
 int result = !p;
 free (p);
 return result;]])
@@ -23,22 +24,17 @@ AC_DEFUN([_AC_FUNC_REALLOC_IF],
[ac_cv_func_realloc_0_nonnull=no],
[case "$host_os" in
   # Guess yes on platforms where we know the result.
-  *-gnu* | gnu* | *-musl* | freebsd* | midnightbsd* | netbsd* | openbsd* \
-  | hpux* | solaris* | cygwin* | mingw*)
+  *-gnu* | freebsd* | netbsd* | openbsd* | bitrig* \
+  | gnu* | *-musl* | midnightbsd* \
+  | hpux* | solaris* | cygwin* | mingw* | msys* )
 ac_cv_func_realloc_0_nonnull="guessing yes" ;;
   # If we don't know, obey --enable-cross-guesses.
   *) ac_cv_func_realloc_0_nonnull="$gl_cross_guess_normal" ;;
 esac
])
 ])
-  case "$ac_cv_func_realloc_0_nonnull" in
-*yes)
-  $1
-  ;;
-*)
-  $2
-  ;;
-  esac
+  AS_IF([case $ac_cv_func_realloc_0_nonnull in *yes) :;; *) false;; esac],
+[$1], [$2])
 ])# AC_FUNC_REALLOC
 
 # gl_FUNC_REALLOC_GNU
-- 
2.27.0

From 6a9be1acc3445f09d7dd875a14271bbb7cb05c0c Mon Sep 17 00:00:00 2001
From: Paul Eggert 
Date: Sun, 18 Apr 2021 11:31:02 -0700
Subject: [PATCH 2/2] malloc-gnu, etc.: prefer AS_CASE to woolly AS_IF

* m4/calloc.m4 (_AC_FUNC_CALLOC_IF):
* m4/malloc.m4 (_AC_FUNC_MALLOC_IF):
* m4/realloc.m4 (_AC_FUNC_REALLOC_IF): Use AS_CASE.
---
 ChangeLog | 5 +
 m4/calloc.m4  | 3 +--
 m4/malloc.m4  | 3 +--
 m4/realloc.m4 | 3 +--
 4 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index fa630a758..dd491f07b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2021-04-18  Paul Eggert  
 
+	malloc-gnu, etc.: prefer AS_CASE to woolly AS_IF
+	* m4/calloc.m4 (_AC_FUNC_CALLOC_IF):
+	* m4/malloc.m4 (_AC_FUNC_MALLOC_IF):
+	* m4/realloc.m4 (_AC_FUNC_REALLOC_IF): Use AS_CASE.
+
 	malloc-gnu, etc.: sync better with Autoconf
 	* m4/calloc.m4 (_AC_FUNC_CALLOC_IF):
 	* m4/malloc.m4 (_AC_FUNC_MALLOC_IF):
diff --git a/m4/calloc.m4 b/m4/calloc.m4
index 776979d25..2f0abee03 100644
--- a/m4/calloc.m4
+++ b/m4/calloc.m4
@@ -47,8 +47,7 @@ AC_DEFUN([_AC_FUNC_CALLOC_IF],
esac
  fi
 ])
-  AS_IF([case $ac_cv_func_calloc_0_nonnull in *yes) :;; *) false;; esac],
-[$1], [$2])
+  AS_CASE([$ac_cv_func_calloc_0_nonnull], [*yes], [$1], [$2])
 ])
 
 
diff --git a/m4/malloc.m4 b/m4/malloc.m4
index 9734dab05..c09006df5 100644
--- a/m4/malloc.m4
+++ b/m4/malloc.m4
@@ -33,8 +33,7 @@ AC_DEFUN([_AC_FUNC_MALLOC_IF],
 esac
])
 ])
-  AS_IF([case $ac_cv_func_malloc_0_nonnull in *yes) :;; *) false;; esac],
-[$1], [$2])
+  AS_CASE([$ac_cv_func_malloc_0_nonnull], [*yes], [$1], [$2])

Fix cross-compilation test results

2021-07-17 Thread Bruno Haible
Before testing __GNU_LIBRARY__, one has to include either 
(which only exists on glibc, musl, Android, and Cygwin systems) or some
header file such as  or .


2021-07-17  Bruno Haible  

Fix cross-compilation test results.
* m4/memmem.m4 (gl_FUNC_MEMMEM_SIMPLE): When cross-compiling, include
 before testing __GNU_LIBRARY__.
* m4/strstr.m4 (gl_FUNC_STRSTR_SIMPLE): Likewise.
* m4/strcasestr.m4 (gl_FUNC_STRCASESTR_SIMPLE): Likewise.

diff --git a/m4/memmem.m4 b/m4/memmem.m4
index f4a167b..6dac766 100644
--- a/m4/memmem.m4
+++ b/m4/memmem.m4
@@ -1,4 +1,4 @@
-# memmem.m4 serial 28
+# memmem.m4 serial 29
 dnl Copyright (C) 2002-2004, 2007-2021 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -50,6 +50,7 @@ AC_DEFUN([gl_FUNC_MEMMEM_SIMPLE],
  dnl Assume that it works on all other platforms (even if not linear).
  AC_EGREP_CPP([Lucky user],
[
+#include  /* for __GNU_LIBRARY__ */
 #ifdef __GNU_LIBRARY__
  #include 
  #if ((__GLIBC__ == 2 && ((__GLIBC_MINOR > 0 && __GLIBC_MINOR__ < 9) \
diff --git a/m4/strcasestr.m4 b/m4/strcasestr.m4
index e9dc3e2..6939144 100644
--- a/m4/strcasestr.m4
+++ b/m4/strcasestr.m4
@@ -1,4 +1,4 @@
-# strcasestr.m4 serial 27
+# strcasestr.m4 serial 28
 dnl Copyright (C) 2005, 2007-2021 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -26,7 +26,7 @@ AC_DEFUN([gl_FUNC_STRCASESTR_SIMPLE],
 [gl_cv_func_strcasestr_works_always],
 [AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
-#include  /* for strcasestr */
+#include  /* for __GNU_LIBRARY__, strcasestr */
 #ifdef __GNU_LIBRARY__
  #include 
  #if __GLIBC__ == 2 && __GLIBC_MINOR__ == 28
@@ -48,6 +48,7 @@ AC_DEFUN([gl_FUNC_STRCASESTR_SIMPLE],
 dnl linear.
 AC_EGREP_CPP([Lucky user],
   [
+#include  /* for __GNU_LIBRARY__ */
 #ifdef __GNU_LIBRARY__
  #include 
  #if ((__GLIBC__ == 2 && __GLIBC_MINOR__ > 12) || (__GLIBC__ > 2)) \
diff --git a/m4/strstr.m4 b/m4/strstr.m4
index 9604fe2..a32e9c1 100644
--- a/m4/strstr.m4
+++ b/m4/strstr.m4
@@ -1,4 +1,4 @@
-# strstr.m4 serial 23
+# strstr.m4 serial 24
 dnl Copyright (C) 2008-2021 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -18,7 +18,7 @@ AC_DEFUN([gl_FUNC_STRSTR_SIMPLE],
   [gl_cv_func_strstr_works_always],
   [AC_RUN_IFELSE(
  [AC_LANG_PROGRAM([[
-#include  /* for strstr */
+#include  /* for __GNU_LIBRARY__, strstr */
 #ifdef __GNU_LIBRARY__
  #include 
  #if __GLIBC__ == 2 && __GLIBC_MINOR__ == 28
@@ -40,6 +40,7 @@ AC_DEFUN([gl_FUNC_STRSTR_SIMPLE],
   dnl linear.
   AC_EGREP_CPP([Lucky user],
 [
+#include  /* for __GNU_LIBRARY__ */
 #ifdef __GNU_LIBRARY__
  #include 
  #if ((__GLIBC__ == 2 && __GLIBC_MINOR__ > 12) || (__GLIBC__ > 2)) \




fenv-exceptions-tracking-c99: Work around a NetBSD/x86_64 bug

2023-11-04 Thread Bruno Haible
On NetBSD/x86_64, I see test failures in soon-to-be-added unit tests.
The cause is that fetestexcept(), which of course is meant to be
side-effect-free, clears the exception trap bits.

The bug is evident from looking at the definition of fetestexcept()
http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libm/arch/x86_64/fenv.c?rev=1.10=text/x-cvsweb-markup_with_tag=MAIN
It uses an 'fnstenv' instruction without subsequent 'fldenv' or 'fldcw'.


2023-11-04  Bruno Haible  

fenv-exceptions-tracking-c99: Work around a NetBSD/x86_64 bug.
* m4/fenv-exceptions-tracking.m4 (gl_FENV_EXCEPTIONS_TRACKING): On
NetBSD/x86_64, set REPLACE_FETESTEXCEPT to 1.
* doc/posix-functions/fetestexcept.texi: Document the NetBSD bug.

diff --git a/doc/posix-functions/fetestexcept.texi 
b/doc/posix-functions/fetestexcept.texi
index b8eba903be..7e9b8e3327 100644
--- a/doc/posix-functions/fetestexcept.texi
+++ b/doc/posix-functions/fetestexcept.texi
@@ -11,6 +11,10 @@
 @item
 This function is missing on some platforms:
 FreeBSD 6.0, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 5.1, IRIX 6.5, Solaris 
9, Cygwin 1.7.7, MSVC 9, Android 4.4.
+@item
+This function clears the floating-point exception trap bits on some platforms:
+@c It uses an 'fnstenv' instruction without subsequent 'fldenv' or 'fldcw'.
+NetBSD 9.3/x86_64.
 @end itemize
 
 Portability problems not fixed by Gnulib:
diff --git a/m4/fenv-exceptions-tracking.m4 b/m4/fenv-exceptions-tracking.m4
index a7ffa80784..1aa378f971 100644
--- a/m4/fenv-exceptions-tracking.m4
+++ b/m4/fenv-exceptions-tracking.m4
@@ -1,4 +1,4 @@
-# fenv-exceptions-tracking.m4 serial 1
+# fenv-exceptions-tracking.m4 serial 2
 dnl Copyright (C) 2023 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -20,6 +20,8 @@ AC_DEFUN_ONCE([gl_FENV_EXCEPTIONS_TRACKING]
 dnl On musl libc, on those CPUs where fenv-except-tracking-raise.c
 dnl uses the "generic" approach, feraiseexcept does not trigger traps
 dnl because it merely manipulates flags in the control register.
+dnl On NetBSD 9.3/x86_64, fetestexcept clears the exception trap bits,
+dnl causing the fenv-environment tests to fail.
 case "$host" in
   arm*-*-linux*)
 AC_CACHE_CHECK([whether feraiseexcept works],
@@ -110,6 +112,12 @@ AC_DEFUN_ONCE([gl_FENV_EXCEPTIONS_TRACKING]
   *) REPLACE_FERAISEEXCEPT=1 ;;
 esac
 ;;
+  x86_64-*-netbsd*)
+dnl On NetBSD 9.3/x86_64, fetestexcept is broken: it clears the
+dnl floating-point exception trap bits (because it uses an
+dnl 'fnstenv' instruction without subsequent 'fldenv' or 'fldcw').
+REPLACE_FETESTEXCEPT=1
+;;
 esac
 if test $REPLACE_FECLEAREXCEPT = 1 \
&& test $REPLACE_FETESTEXCEPT = 1 \






Re: argp: Correct documentation

2022-12-06 Thread Alfred M. Szmidt
   >+This variable is missing on all non-glibc platforms:
   > 
   > How about we just say "non-GNU systems" -- the majority of operating
   > systems in the world are 'non-glibc platforms', and there is no
   > platform that is called 'glibc'.  Our system is called GNU after
   > all...

   First, "glibc platforms" and "GNU systems" are not the same thing.

True, since there is nothing like a "glibc platform", it is a bad term
that has no good meaning.  

The text reads strangley anyway, if you use gnulib (or via some other
means, in the case of argp there used to be a libargp that was
portable across many systems) on a operating system that does not use
the GNU C Library, then .. it does exist.  But the text claims that it
does not.

Does a system become a `glibc platform' if one uses gnulib? Seeing
that all or most of the things glibc provides, so does gnulib.

 * RMS decided that the NetBSD kernel, plus the NetBSD libc, plus GNU
   userland is a GNU system and to be called "GNU/NetBSD". [1]
   Whereas the NetBSD kernel, plus glibc, plus GNU userland is to be
   called "GNU/kNetBSD". [2]

I could not find this decision in those two references, both are pages
from Debian, and nothing from RMS on the topic.

 * According to the definition of GNU system [3], it looks like a
   distro based on Linux, glibc, and lots of proprietary software
   would not be a GNU system.

   Second, in technical documentation, I prefer to have unambiguous terms,
   and there is ambiguity in the term "GNU system":

We have plenty of texts that clear up any ambiguity, where as there is
nothing on 'glibc platform'.  There is little ambiguity about what it
means, and even if it did the little extra is worth to mention our own
operating system in a list of other operating systems.

 - Is Alpine Linux a GNU system? (It uses musl libc instead of glibc.) [4]

No, Alpine is not based on the GNU system, much like Android. See
https://www.gnu.org/philosophy/android-and-users-freedom.en.html

 - Is Windows with WSL and a GNU distro a GNU system? [5][6]

Windows is the operating system here, that is what your computer is
running.  Just becaues you run another operating system inside an
existing one, doesn't mean that one becomes the other.  




vasnwprintf-posix: Work around %La bug in glibc 2.15 and Haiku

2023-04-07 Thread Bruno Haible
  long double arg = a.arg[dp->arg_index].a.a_longdouble;
 
 if (isnanl (arg))
diff --git a/m4/printf.m4 b/m4/printf.m4
index cf4e225cfe..f513da0c84 100644
--- a/m4/printf.m4
+++ b/m4/printf.m4
@@ -1,4 +1,4 @@
-# printf.m4 serial 80
+# printf.m4 serial 81
 dnl Copyright (C) 2003, 2007-2023 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -1950,6 +1950,65 @@ int main()
 ])
 ])
 
+dnl Test whether the *wprintf family of functions supports the 'a' and 'A'
+dnl conversion specifier for hexadecimal output of 'long double' numbers.
+dnl (ISO C99, POSIX:2001)
+dnl Result is gl_cv_func_swprintf_directive_la.
+
+AC_DEFUN([gl_SWPRINTF_DIRECTIVE_LA],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_CACHE_CHECK([whether swprintf supports the 'La' and 'LA' directives],
+[gl_cv_func_swprintf_directive_la],
+[
+  AC_RUN_IFELSE(
+[AC_LANG_SOURCE([[
+#include 
+#include 
+static wchar_t buf[100];
+int main ()
+{
+  int result = 0;
+  /* This catches a glibc 2.15 and Haiku 2022 bug.  */
+  if (swprintf (buf, sizeof (buf) / sizeof (wchar_t),
+L"%La %d", 3.1416015625L, 33, 44, 55) < 0
+  || (wcscmp (buf, L"0x1.922p+1 33") != 0
+  && wcscmp (buf, L"0x3.244p+0 33") != 0
+  && wcscmp (buf, L"0x6.488p-1 33") != 0
+  && wcscmp (buf, L"0xc.91p-2 33") != 0))
+result |= 1;
+  return result;
+}]])],
+[gl_cv_func_swprintf_directive_la=yes],
+[gl_cv_func_swprintf_directive_la=no],
+[case "$host_os" in
+ # Guess yes on glibc >= 2.17 systems.
+   *-gnu* | gnu*)
+ AC_EGREP_CPP([Unlucky], [
+   #include 
+   #ifdef __GNU_LIBRARY__
+#if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 17) || (__GLIBC__ > 
2)) && !defined __UCLIBC__
+ Unlucky
+#endif
+   #endif
+   ],
+   [gl_cv_func_swprintf_directive_la="guessing yes"],
+   [gl_cv_func_swprintf_directive_la="guessing no"])
+ ;;
+ # Guess yes on musl systems.
+   *-musl* | midipix*)   gl_cv_func_swprintf_directive_la="guessing 
yes";;
+ # Guess yes on Android.
+   linux*-android*)  gl_cv_func_swprintf_directive_la="guessing 
no";;
+ # Guess yes on native Windows.
+   mingw*)   gl_cv_func_swprintf_directive_la="guessing 
no";;
+ # If we don't know, obey 
--enable-cross-guesses.
+   *)
gl_cv_func_swprintf_directive_la="$gl_cross_guess_normal";;
+ esac
+])
+])
+])
+
 dnl The results of these tests on various platforms are:
 dnl
 dnl 1 = gl_PRINTF_SIZES_C99
@@ -1977,6 +2036,7 @@ dnl 22 = gl_SNPRINTF_DIRECTIVE_N
 dnl 23 = gl_SNPRINTF_SIZE1
 dnl 24 = gl_VSNPRINTF_ZEROSIZE_C99
 dnl 25 = gl_SWPRINTF_WORKS
+dnl 26 = gl_SWPRINTF_DIRECTIVE_LA
 dnl
 dnl 1 = checking whether printf supports size specifiers as in C99...
 dnl 2 = checking whether printf supports size specifiers as in C23...
@@ -2003,47 +2063,48 @@ dnl 22 = checking whether snprintf fully supports the 
'n' directive...
 dnl 23 = checking whether snprintf respects a size of 1...
 dnl 24 = checking whether vsnprintf respects a zero size as in C99...
 dnl 25 = checking whether swprintf works...
+dnl 26 = checking whether swprintf supports the 'La' and 'LA' directives...
 dnl
 dnl . = yes, # = no.
 dnl
-dnl  1  2  3  4  5  6  7  8  9 10 11 12 13 14 
15 16 17 18 19 20 21 22 23 24 25
-dnl   musl libc 1.2.3.  #  .  .  .  .  #  #  .  .  .  .  .  .  
.  .  .  .  .  .  .  .  .  .  #
-dnl   glibc 2.35 .  #  .  .  .  .  .  .  .  .  .  #  .  .  
.  .  .  .  .  .  .  .  .  .  .
-dnl   glibc 2.5  .  #  .  .  .  .  #  #  .  .  .  #  .  .  
.  .  .  .  .  .  .  .  .  .  ?
-dnl   glibc 2.3.6.  #  .  .  .  #  #  #  .  .  .  #  .  .  
.  .  .  .  .  .  .  .  .  .  ?
-dnl   FreeBSD 13.0   .  #  .  .  .  #  #  #  .  .  .  #  .  .  
.  .  .  #  .  .  .  .  .  .  #
-dnl   FreeBSD 5.4, 6.1   .  #  .  .  .  #  #  #  .  .  .  #  .  .  
.  #  .  #  .  .  .  .  .  .  #
-dnl   Mac OS X 10.13.5   .  #  .  .  #  #  #  #  .  #  .  #  .  .  
.  .  .  .  .  .  .  #  .  .  #
-dnl   Mac OS X 10.5.8.  #  .  .  #  #  #  #  .  .  .  #  .  .  
.  #  .  .  .  .  .  .  .  .  #
-dnl   Mac OS X 10.3.9.  #  .  .  .  #  #  #  .  .  .  #  .  . 

[PATCH] Do not decorate symbols as dllexport on Cygwin

2023-02-05 Thread Corinna Vinschen
Note that dllimport/dllexport decorations are not at all required on
Cygwin for quite some time.

Worse, this breaks building DLLs and DLL import libs using libtool.

On Cygwin --export-all-symbols is default.  However, if just a single
symbol is decorated with dllexport, ld switches to exporting only these
symbols.

So, when creating DLLs and DLL import libs which are also linked against
libgnu.a, the result is that the actual DLL (i. e. cygfoo-1.dll)
contains all symbols of all object files given on the command line.
However, the DLL import lib (i. e. libfoo.dll.a) will contain only the
default symbols and the single symbol gl_get_setlocale_null_lock.

This in turn breaks linking against the just created cygfoo-1.dll.

An example of that is current recode.  Building this package with
--enable-shared is broken, unless one adds -Wl,--export-all-symbols to
the link stage command line explicitely, because of the decorated
gl_get_setlocale_null_lock variable.

Fix this by dropping the dllexport decoration when building for the
Cygwin target.

* lib/setlocale-lock.c: don't decorate gl_get_setlocale_null_lock
as dllexport on Cygwin.
* lib/setlocale_null.c: don't dllimport gl_get_setlocale_null_lock
on Cygwin.
---
 lib/setlocale-lock.c | 2 +-
 lib/setlocale_null.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/setlocale-lock.c b/lib/setlocale-lock.c
index b70ba09b0020..ab23cadd2939 100644
--- a/lib/setlocale-lock.c
+++ b/lib/setlocale-lock.c
@@ -41,7 +41,7 @@ typedef int dummy;
 #  if HAVE_VISIBILITY
   /* Override the effect of the compiler option '-fvisibility=hidden'.  */
 #   define DLL_EXPORTED __attribute__((__visibility__("default")))
-#  elif defined _WIN32 || defined __CYGWIN__
+#  elif defined _WIN32 && !defined __CYGWIN__
 #   define DLL_EXPORTED __declspec(dllexport)
 #  else
 #   define DLL_EXPORTED
diff --git a/lib/setlocale_null.c b/lib/setlocale_null.c
index 6ac563db14a9..5bf04a5ad84d 100644
--- a/lib/setlocale_null.c
+++ b/lib/setlocale_null.c
@@ -201,7 +201,7 @@ setlocale_null_with_lock (int category, char *buf, size_t 
bufsize)
 # elif HAVE_PTHREAD_API /* musl libc, macOS, FreeBSD, NetBSD, OpenBSD, AIX, 
Haiku, Cygwin */
 
 extern
-#  if defined _WIN32 || defined __CYGWIN__
+#  if defined _WIN32 && !defined __CYGWIN__
   __declspec(dllimport)
 #  endif
   pthread_mutex_t *gl_get_setlocale_null_lock (void);
-- 
2.39.1




Re: bug#64937: "who" reports funny dates

2023-08-08 Thread Thorsten Kukuk
On Mon, Aug 07, Paul Eggert wrote:

> On 2023-08-07 04:22, Bruno Haible wrote:
> 
> > sooner than later. My guess is that Fedora and Ubuntu/Debian are only
> > waiting for 'who' (coreutils) and 'last' (util-linux / wtmpdb) to
> > stop accessing these two files.
> 
> It's not just those two programs. Emacs looks at utmp, for example, when 
> creating the symlinks it uses to implement its own file locking, because 
>   symlink contents contain the boot time (so that Emacs can better 
> detect stale locks) and the boot time is retrieved from /var/run/utmp.

Something emacs needs to get fixed. On musl libc systems like Alpine,
you don't have utmp nor wtmp.
Beside that the emacs heuristic to find backups of wmtp is very
questionable, it wouldn't match on any of my systems.
There are better ways to determine the boot time.

> I expect that other programs look at utmp and/or wtmp, besides obvious 
> candidates like 'login'. A quick scan through my Ubuntu /usr/bin found 
> sessreg, for example; it was originally developed for X but is now used 
> elsewhere.

There are some few:
https://github.com/thkukuk/utmpx/blob/main/Y2038.md#depending-on-utmpwtmpbtmplastlog-directly
And yes, the list is incomplete.

But to be honest, the majority is only creating entries (no longer
necessary) or counting the number of logged in users.
Other don't work since a long time since nobody writes the entries they
are looking for (like e.g. adjtimex).

So it's not that worse as it looks first.

> >> Although Ubuntu does not maintain /var/log/btmp
> > 
> > What do you mean by that?
> 
> Oh, my mistake. I checked a workstation that was behind a restrictive 
> firewall, and nobody had ever attempted to attack it. You're right, 
> Ubuntu maintains btmp.

Does they really maintain btmp or is it just openssh, where you cannot
disable btmp entries?
In the last case, the file is pretty useless, as all failed logins via
other ways (e.g. login itself) are not logged.

I know that Fedora tries to maintain it via pam_lastlog.so, but do to
all the problems with this interface that module is deprecated and will
be removed in a future release.

  Thorsten

-- 
Thorsten Kukuk, Distinguished Engineer, Senior Architect, Future Technologies
SUSE Software Solutions Germany GmbH, Frankenstraße 146, 90461 Nuernberg, 
Germany
Managing Director: Ivo Totev, Andrew McDonald, Werner Knoblich
(HRB 36809, AG Nürnberg)



localename: Notice setlocale() invocations on more platforms

2024-02-14 Thread Bruno Haible
When a program calls setlocale() with some argument that is not reflected in
the environment variables, ideally the gl_locale_name function should return
that locale.

Currently this is enabled only for glibc systems. But it is actually possible
to do the same thing on some other platforms as well:
  musl, FreeBSD, NetBSD, Solaris, Haiku.

This patch does it. (This was on my TODO list for GNU gettext for many years.)


2024-02-14  Bruno Haible  

localename: Notice setlocale() invocations on more platforms.
* lib/localename.c (HAVE_LOCALE_NULL): Define also on musl, FreeBSD,
NetBSD, Solaris, Haiku.
* modules/localename (Files): Add m4/musl.m4.
(configure.ac): Invoke gl_MUSL_LIBC.
* tests/test-localename.c (C_CANONICALIZED): New macro, for Haiku.
(is_default): New function, for musl libc and Haiku.
(test_locale_name, test_locale_name_posix): Use these definitions.
* modules/localename-tests (Files): Add m4/musl.m4.
(configure.ac): Invoke gl_MUSL_LIBC.

diff --git a/lib/localename.c b/lib/localename.c
index b4c78df8ae..3bfcdabf4f 100644
--- a/lib/localename.c
+++ b/lib/localename.c
@@ -3297,9 +3297,31 @@ gl_locale_name_thread (int category, _GL_UNUSED const 
char *categoryname)
"Directs 'setlocale()' to query 'category' and return the current
 setting of 'local'."
However it does not specify the exact format.  Neither do SUSV2 and
-   ISO C 99.  So we can use this feature only on selected systems (e.g.
-   those using GNU C Library).  */
-#if defined _LIBC || ((defined __GLIBC__ && __GLIBC__ >= 2) && !defined 
__UCLIBC__)
+   ISO C 99.  So we can use this feature only on selected systems, where
+   the return value has the XPG syntax
+ language[_territory][.codeset][@modifier]
+   or
+ C[.codeset]
+   namely
+ - glibc systems (except for aliases from /usr/share/locale/locale.alias,
+   that no one uses any more),
+ - musl libc,
+ - FreeBSD, NetBSD,
+ - Solaris,
+ - Haiku.
+   We cannot use it on
+ - macOS, Cygwin (because these systems have a facility for customizing the
+   default locale, and setlocale (category, NULL) ignores it and merely
+   returns "C" or "C.UTF-8"),
+ - OpenBSD (because on OpenBSD ≤ 6.1, LC_ALL does not set the LC_NUMERIC,
+   LC_TIME, LC_COLLATE, LC_MONETARY categories).
+ - AIX (because here the return value has the syntax
+ language[_script]_territory[.codeset]
+   e.g. zh_Hans_CN.UTF-8),
+ - native Windows (because it has locale names such as French_France.1252),
+ - Android (because it only supports the C and C.UTF-8 locales).
+ */
+#if defined _LIBC || ((defined __GLIBC__ && __GLIBC__ >= 2) && !defined 
__UCLIBC__) || MUSL_LIBC || defined __FreeBSD__ || defined __NetBSD__ || 
defined __sun || defined __HAIKU__
 # define HAVE_LOCALE_NULL
 #endif
 
@@ -3334,8 +3356,8 @@ gl_locale_name_posix (int category, _GL_UNUSED const char 
*categoryname)
 /* On other systems we ignore what setlocale reports and instead look at 
the
environment variables directly.  This is necessary
  1. on systems which have a facility for customizing the default locale
-(Mac OS X, native Windows, Cygwin) and where the system's 
setlocale()
-function ignores this default locale (Mac OS X, Cygwin), in two 
cases:
+(macOS, native Windows, Cygwin) and where the system's setlocale()
+function ignores this default locale (macOS, Cygwin), in two cases:
 a. when the user missed to use the setlocale() override from 
libintl
(for example by not including ),
 b. when setlocale supports only the "C" locale, such as on Cygwin
diff --git a/modules/localename b/modules/localename
index fc097829be..4c33624548 100644
--- a/modules/localename
+++ b/modules/localename
@@ -10,6 +10,7 @@ m4/localename.m4
 m4/intl-thread-locale.m4
 m4/intlmacosx.m4
 m4/lcmessage.m4
+m4/musl.m4
 
 Depends-on:
 extensions
@@ -26,6 +27,7 @@ thread-optim
 configure.ac:
 gl_LOCALENAME
 gl_LOCALE_MODULE_INDICATOR([localename])
+gl_MUSL_LIBC
 
 Makefile.am:
 lib_SOURCES += localename.c localename-table.c
diff --git a/modules/localename-tests b/modules/localename-tests
index f90d82da0d..0c24d5b4b6 100644
--- a/modules/localename-tests
+++ b/modules/localename-tests
@@ -1,6 +1,7 @@
 Files:
 tests/test-localename.c
 tests/macros.h
+m4/musl.m4
 
 Depends-on:
 locale
@@ -11,6 +12,7 @@ strdup
 
 configure.ac:
 gl_CHECK_FUNCS_ANDROID([newlocale], [[#include ]])
+gl_MUSL_LIBC
 
 Makefile.am:
 TESTS += test-localename
diff --git a/tests/test-localename.c b/tests/test-localename.c
index fe31201361..03b70527d5 100644
--- a/tests/test-localename.c
+++ b/tests/test-localename.c
@@ -40,6 +40,26 @@
 # pragma GCC diagnostic ignored "-Wanalyzer-use-of-uninitialized-value"
 #endif
 
+/* The name that setlocale(,

new module 'fenv-environment'

2023-11-05 Thread Bruno Haible
Here comes the module 'fenv-environment', which implements the ISO C 99 
functions
  fegetenv
  feholdexcept
  fesetenv
  feupdateenv
and the macro
  FE_DFL_ENV.

This is the largest module in the fenv-* series, because of the massive amount
of platform bugs that need to be worked around. No operating system gets all
four functions right on all CPUs! On many platforms, there's even two or three
bugs to work around together. Really, it feels like I'm the first person in the
world who has written unit tests for these functions.

Additionally, it has complexity because the fenv_t type is dependent on OS and
architecture. But fortunately, for most architectures, it is merely binary-
equivalent to an 'unsigned int' or 'unsigned long'.


2023-11-05  Bruno Haible  

fenv-environment: Add tests.
* tests/test-fenv-env-1.c: New file.
* tests/test-fenv-env-2.c: New file.
* tests/test-fenv-env-3.c: New file.
* tests/test-fenv-env-4.c: New file.
* tests/test-fenv-env-5.sh: New file.
* tests/test-fenv-env-5.c: New file.
* modules/fenv-environment-tests: New file.

fenv-environment: New module.
* lib/fenv.in.h (fenv_t) [hppa]: Remove the __exception field.
(FE_DFL_ENV): Override if  exists but HAVE_FE_DFL_ENV is not
defined.
(fegetenv, fesetenv, feupdateenv, feholdexcept): New declarations.
* lib/fenv-env.c: New file, based on glibc.
* lib/fenv-env-hold.c: New file.
* lib/fenv-env-update.c: New file.
* m4/fenv-environment.m4: New file.
* m4/mathfunc.m4 (gl_MATHFUNC): Handle also the 'fenv_t *' type.
* m4/fenv_h.m4 (gl_FENV_H_DEFAULTS): Initialize REPLACE_FEGETENV,
REPLACE_FEHOLDEXCEPT, REPLACE_FESETENV, REPLACE_FEUPDATEENV.
* modules/fenv (Makefile.am): Substitute REPLACE_FEGETENV,
REPLACE_FEHOLDEXCEPT, REPLACE_FESETENV, REPLACE_FEUPDATEENV.
* modules/fenv-environment: New file.
* doc/posix-functions/fegetenv.texi: Mention the new module and the bugs
on glibc, macOS, AIX.
* doc/posix-functions/feholdexcept.texi: Mention the new module and the
bugs on glibc, musl libc, FreeBSD, AIX, mingw, MSVC.
* doc/posix-functions/fesetenv.texi: Mention the new module and the bugs
on musl libc, FreeBSD, NetBSD, AIX, Solaris, Cygwin, mingw, MSVC.
* doc/posix-functions/feupdateenv.texi: Mention the new module and the
bugs on glibc, musl libc, macOS, FreeBSD, AIX, Solaris, mingw, MSVC.

From c19cabc0bf5d8e1afec9fd50fee47104000fa3e4 Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Sun, 5 Nov 2023 15:00:29 +0100
Subject: [PATCH 1/2] fenv-environment: New module.

* lib/fenv.in.h (fenv_t) [hppa]: Remove the __exception field.
(FE_DFL_ENV): Override if  exists but HAVE_FE_DFL_ENV is not
defined.
(fegetenv, fesetenv, feupdateenv, feholdexcept): New declarations.
* lib/fenv-env.c: New file, based on glibc.
* lib/fenv-env-hold.c: New file.
* lib/fenv-env-update.c: New file.
* m4/fenv-environment.m4: New file.
* m4/mathfunc.m4 (gl_MATHFUNC): Handle also the 'fenv_t *' type.
* m4/fenv_h.m4 (gl_FENV_H_DEFAULTS): Initialize REPLACE_FEGETENV,
REPLACE_FEHOLDEXCEPT, REPLACE_FESETENV, REPLACE_FEUPDATEENV.
* modules/fenv (Makefile.am): Substitute REPLACE_FEGETENV,
REPLACE_FEHOLDEXCEPT, REPLACE_FESETENV, REPLACE_FEUPDATEENV.
* modules/fenv-environment: New file.
* doc/posix-functions/fegetenv.texi: Mention the new module and the bugs
on glibc, macOS, AIX.
* doc/posix-functions/feholdexcept.texi: Mention the new module and the
bugs on glibc, musl libc, FreeBSD, AIX, mingw, MSVC.
* doc/posix-functions/fesetenv.texi: Mention the new module and the bugs
on musl libc, FreeBSD, NetBSD, AIX, Solaris, Cygwin, mingw, MSVC.
* doc/posix-functions/feupdateenv.texi: Mention the new module and the
bugs on glibc, musl libc, macOS, FreeBSD, AIX, Solaris, mingw, MSVC.
---
 ChangeLog |   26 +
 doc/posix-functions/fegetenv.texi |   16 +-
 doc/posix-functions/feholdexcept.texi |   25 +-
 doc/posix-functions/fesetenv.texi |   25 +-
 doc/posix-functions/feupdateenv.texi  |   35 +-
 lib/fenv-env-hold.c   |   32 +
 lib/fenv-env-update.c |   31 +
 lib/fenv-env.c| 1165 +
 lib/fenv.in.h |   91 +-
 m4/fenv-environment.m4|  515 +++
 m4/fenv_h.m4  |6 +-
 m4/mathfunc.m4|6 +-
 modules/fenv  |4 +
 modules/fenv-environment  |   56 ++
 14 files changed, 2013 insertions(+), 20 deletions(-)
 create mode 100644 lib/fenv-env-hold.c
 create mode 100644 lib/fenv-env-update.c
 create mode 100644 lib/fenv-env.c
 create mode 100644 m4/fenv-environment.m4
 create mode 100644 modules/fenv-environment

diff --git a/ChangeLog b/ChangeLog
index 7c2d58913d..18ee7639c2 100644
--- a/ChangeLog
+++ b

Re: parse-datetime test failure

2020-11-11 Thread Paul Eggert

On 11/11/20 8:20 AM, Bruno Haible wrote:

It works fine on Alpine Linux 3.7 (32-bit, 64-bit) and 3.9 (64-bit).

On Alpine Linux 3.10 and 3.12 (64-bit) it fails:
../../gltests/test-parse-datetime.c:448: assertion 'result.tv_sec == 1 * 60 * 60 + 2 * 
60 + 3 && result.tv_nsec == 123456789' failed
Aborted

So, to me it looks like a regression between Alpine Linux 3.9 and 3.10.


It's arguably a bug in the test case, since Alpine uses musl libc which does not 
support time zone abbreviations longer than 6 bytes, whereas the test case uses 
an time zone abbreviation of 2000 bytes (to test a bug in an old Gnulib version 
when running on GNU/Linux). POSIX does not define behavior if you go over the limit.


I worked around the problem by changing the test case to not go over the limit 
as determined by sysconf (_SC_TZNAME_MAX), in the first attached patch. Plus I 
refactored and/or slightly improved the Gnulib overflow checking while I was in 
the neighborhood (last two attached patches).


Arguably this is a quality-of-implementation issue here, since Alpine and/or 
musl goes beserk with long timezone abbreviations whereas every other 
implementation I know of either works or silently substitutes localtime or UTC 
(which is good enough for this test case). But I'll leave that issue to the 
Alpine and/or musl libc folks.


I'll cc this to the musl bug reporting list. Although the Gnulib test failure 
has been fixed, it may be the symptom of a more-severe bug in musl. For those 
new to the problem, this thread starts here:


https://lists.gnu.org/r/bug-gnulib/2020-11/msg00039.html
>From 4c9a3c65e279977af4e345748ba73ab0441dc04a Mon Sep 17 00:00:00 2001
From: Paul Eggert 
Date: Wed, 11 Nov 2020 19:08:27 -0800
Subject: [PATCH 1/3] parse-datetime-tests: port to Alpine Linux 3.12.1

* tests/test-parse-datetime.c: Include errno.h for errno,
and unistd.h for _SC_TZNAME_MAX and sysconf.
(main): In the outlandishly-long time zone abbreviation test,
do not exceed TZNAME_MAX as this has undefined behavior,
and on Alpine Linux 3.12.1 it makes the test fail.
---
 ChangeLog   |  9 +
 tests/test-parse-datetime.c | 16 +---
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index a5999557b..e1828df64 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2020-11-11  Paul Eggert  
+
+	parse-datetime-tests: port to Alpine Linux 3.12.1
+	* tests/test-parse-datetime.c: Include errno.h for errno,
+	and unistd.h for _SC_TZNAME_MAX and sysconf.
+	(main): In the outlandishly-long time zone abbreviation test,
+	do not exceed TZNAME_MAX as this has undefined behavior,
+	and on Alpine Linux 3.12.1 it makes the test fail.
+
 2020-11-09  Pádraig Brady  
 
 	mgetgroups: avoid warning with clang
diff --git a/tests/test-parse-datetime.c b/tests/test-parse-datetime.c
index 920c9ae84..187e7c703 100644
--- a/tests/test-parse-datetime.c
+++ b/tests/test-parse-datetime.c
@@ -20,9 +20,11 @@
 
 #include "parse-datetime.h"
 
+#include 
 #include 
 #include 
 #include 
+#include 
 
 #include "macros.h"
 
@@ -435,13 +437,21 @@ main (int argc _GL_UNUSED, char **argv)
   /* Outlandishly-long time zone abbreviations should not cause problems.  */
   {
 static char const bufprefix[] = "TZ=\"";
-enum { tzname_len = 2000 };
+long int tzname_max = -1;
+errno = 0;
+#ifdef _SC_TZNAME_MAX
+tzname_max = sysconf (_SC_TZNAME_MAX);
+#endif
+enum { tzname_alloc = 2000 };
+if (tzname_max < 0)
+  tzname_max = errno ? 6 : tzname_alloc;
+int tzname_len = tzname_alloc < tzname_max ? tzname_alloc : tzname_max;
 static char const bufsuffix[] = "0\" 1970-01-01 01:02:03.123456789";
-enum { bufsize = sizeof bufprefix - 1 + tzname_len + sizeof bufsuffix };
+enum { bufsize = sizeof bufprefix - 1 + tzname_alloc + sizeof bufsuffix };
 char buf[bufsize];
 memcpy (buf, bufprefix, sizeof bufprefix - 1);
 memset (buf + sizeof bufprefix - 1, 'X', tzname_len);
-strcpy (buf + bufsize - sizeof bufsuffix, bufsuffix);
+strcpy (buf + sizeof bufprefix - 1 + tzname_len, bufsuffix);
 ASSERT (parse_datetime (, buf, ));
 LOG (buf, now, result);
 ASSERT (result.tv_sec == 1 * 60 * 60 + 2 * 60 + 3
-- 
2.25.1

>From 00ffb79c529942eab5c81568808bd317c753213a Mon Sep 17 00:00:00 2001
From: Paul Eggert 
Date: Wed, 11 Nov 2020 19:16:23 -0800
Subject: [PATCH 2/3] parse-datetime: streamline overflow checking
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

When parse-datetime.y’s overflow code was written, INT_ADD_WRAPV
did not work for unsigned destinations, and since time_t might
be unsigned that meant it did not work for time_t destinations.
This limitation of INT_ADD_WRAPV has been fixed, so we can
now streamline parse-datetime.y a bit.
* lib/parse-datetime.y: Do not include limits.h, as LONG_MAX
has not been used for a while.
(yylex, pa

wcscmp: Work around two ISO C compliance bugs on several platforms

2023-04-18 Thread Bruno Haible
These two patches work around an ISO C compliance bug of wcscmp()
on several platforms, and another one specific to AIX.

The point is that in ISO C, a "wide character" is any wchar_t value.
A "wide character" is not constrained to the range 0..INT_MAX. For
the precise reasoning, see
<https://www.openwall.com/lists/musl/2023/04/18/5>.

In particular, the module 'wcscmp' is no longer obsolete.


2023-04-18  Bruno Haible  

wcscmp: Add tests.
* tests/test-wcscmp.c: New file, based on tests/unistr/test-strcmp.h.
* modules/wcscmp-tests: New file.

wcscmp: Work around two ISO C compliance bugs on several platforms.
* lib/wchar.in.h (wcscmp): Consider REPLACE_WCSCMP.
* lib/wcscmp-impl.h (wcscmp): Don't assume that the two wide characters
are in the range 0..INT_MAX.
* m4/wcscmp.m4 (gl_FUNC_WCSCMP): Test whether wcscmp works for all wide
characters. Set REPLACE_WCSCMP.
* m4/wchar_h.m4 (gl_WCHAR_H_DEFAULTS): Initialize REPLACE_WCSCMP.
* modules/wchar (Makefile.am): Substitute REPLACE_WCSCMP.
* modules/wcscmp (Status, Notice): Un-obsolete this module.
(configure.ac): Consider REPLACE_WCSCMP.
* doc/posix-functions/wcscmp.texi: Mention the two bugs.

>From 4b440d3568b01dd9acd5242bea8b63fc43428f5a Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Wed, 19 Apr 2023 02:14:09 +0200
Subject: [PATCH 1/2] wcscmp: Work around two ISO C compliance bugs on several
 platforms.

* lib/wchar.in.h (wcscmp): Consider REPLACE_WCSCMP.
* lib/wcscmp-impl.h (wcscmp): Don't assume that the two wide characters
are in the range 0..INT_MAX.
* m4/wcscmp.m4 (gl_FUNC_WCSCMP): Test whether wcscmp works for all wide
characters. Set REPLACE_WCSCMP.
* m4/wchar_h.m4 (gl_WCHAR_H_DEFAULTS): Initialize REPLACE_WCSCMP.
* modules/wchar (Makefile.am): Substitute REPLACE_WCSCMP.
* modules/wcscmp (Status, Notice): Un-obsolete this module.
(configure.ac): Consider REPLACE_WCSCMP.
* doc/posix-functions/wcscmp.texi: Mention the two bugs.
---
 ChangeLog   | 14 
 doc/posix-functions/wcscmp.texi |  8 +
 lib/wchar.in.h  | 14 ++--
 lib/wcscmp-impl.h   |  5 +--
 m4/wchar_h.m4   |  3 +-
 m4/wcscmp.m4| 58 -
 modules/wchar   |  1 +
 modules/wcscmp  |  9 ++---
 8 files changed, 99 insertions(+), 13 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 17596c4b23..bc02f2d5f5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2023-04-18  Bruno Haible  
+
+	wcscmp: Work around two ISO C compliance bugs on several platforms.
+	* lib/wchar.in.h (wcscmp): Consider REPLACE_WCSCMP.
+	* lib/wcscmp-impl.h (wcscmp): Don't assume that the two wide characters
+	are in the range 0..INT_MAX.
+	* m4/wcscmp.m4 (gl_FUNC_WCSCMP): Test whether wcscmp works for all wide
+	characters. Set REPLACE_WCSCMP.
+	* m4/wchar_h.m4 (gl_WCHAR_H_DEFAULTS): Initialize REPLACE_WCSCMP.
+	* modules/wchar (Makefile.am): Substitute REPLACE_WCSCMP.
+	* modules/wcscmp (Status, Notice): Un-obsolete this module.
+	(configure.ac): Consider REPLACE_WCSCMP.
+	* doc/posix-functions/wcscmp.texi: Mention the two bugs.
+
 2023-04-18  Bruno Haible  
 
 	wmemcmp: Add tests.
diff --git a/doc/posix-functions/wcscmp.texi b/doc/posix-functions/wcscmp.texi
index 4c4de8c6dc..bc64d28f56 100644
--- a/doc/posix-functions/wcscmp.texi
+++ b/doc/posix-functions/wcscmp.texi
@@ -8,6 +8,14 @@
 
 Portability problems fixed by Gnulib:
 @itemize
+@item
+This function compares the wide characters as if they were unsigned, although
+@code{wchar_t} is signed, on some platforms:
+glibc 2.14.1 on x86 or x86_64, musl libc 1.2.3, macOS 12.5, FreeBSD 13.2, NetBSD 9.0, OpenBSD 7.2, Solaris 11.4.
+@item
+This function may return a wrong result if the two arguments are of different
+length, on some platforms:
+AIX 7.2 in 64-bit mode.
 @end itemize
 
 Portability problems not fixed by Gnulib:
diff --git a/lib/wchar.in.h b/lib/wchar.in.h
index 6a5b18d39d..c347256368 100644
--- a/lib/wchar.in.h
+++ b/lib/wchar.in.h
@@ -938,11 +938,21 @@ _GL_WARN_ON_USE (wcsncat, "wcsncat is unportable - "
 
 /* Compare S1 and S2.  */
 #if @GNULIB_WCSCMP@
-# if !@HAVE_WCSCMP@
+# if @REPLACE_WCSCMP@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef wcscmp
+#   define wcscmp rpl_wcscmp
+#  endif
+_GL_FUNCDECL_RPL (wcscmp, int, (const wchar_t *s1, const wchar_t *s2)
+   _GL_ATTRIBUTE_PURE);
+_GL_CXXALIAS_RPL (wcscmp, int, (const wchar_t *s1, const wchar_t *s2));
+# else
+#  if !@HAVE_WCSCMP@
 _GL_FUNCDECL_SYS (wcscmp, int, (const wchar_t *s1, const wchar_t *s2)
_GL_ATTRIBUTE_PURE);
-# endif
+#  endif
 _GL_CXXALIAS_SYS (wcscmp, int, (const wchar_t *s1, const wchar_t *s2));
+# endif
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (wcscmp);
 # endif
diff --git a/lib/wcscmp-impl.

Re: getopt.m4 test

2012-06-23 Thread Bruno Haible
Hi Paul, Eric,

I wrote:
 It seems to me that
   - musl's getopt is POSIX compliant (at least it passes the 3 parts of
 the test when run individually).
   - The getopt.m4 test fails only because musl does not support one of
 the 3 known ways to reset option processing. Does it support another
 method, or none at all?
   - coreutils does not rely on resetting option processing with getopt(),
 only with getopt_long() (in coreutils/src/{env.c,nice.c,stty.c}).
   - The use of OPTIND_MIN in getopt.m4 exists purely to run a single
 test program rather than 3 test programs in sequence.
 
 Paul, I would suggest to split out the 3 tests into a sequence of 3 test
 programs, and then remove the determination of gl_optind_min - since
 nothing else uses it.

Here is a proposed patch to do this. Its effect is that on HP-UX, IRIX,
OSF/1, Solaris 9, and likely also musl libc the line

  checking whether getopt is POSIX compatible... no

becomes

  checking whether getopt is POSIX compatible... yes

What this change also does is to stop guaranteeing that either 'optreset'
or setting 'optind = 0;' will reset the option processing. The rationale
is that no program I've seen actually needs this: Normal programs use getopt
to loop over their arguments just once.

Also, I couldn't reproduce the described problem with mingw and leading
'+' sign (with mingw of 2009), so let's drop this from the documentation.

Here's the proposed patch. Tested to not introduce regressions in a testdir
for 'getopt-posix', nor in a testdir for 'getopt-gnu'.


2012-06-23  Bruno Haible  br...@clisp.org

getopt-posix: No longer guarantee that option processing is resettable.
* doc/posix-functions/getopt.texi: Drop description of problem with
internal state. Fix info about mingw and msvc9.
* m4/getopt.m4 (gl_GETOPT_CHECK_HEADERS): Don't require a resettable
option processing by getopt(). Run three test programs instead of one.
Simplify cross-compilation guess.
Reported by Rich Felker dal...@aerifal.cx.

--- doc/posix-functions/getopt.texi.origSat Jun 23 17:21:27 2012
+++ doc/posix-functions/getopt.texi Sat Jun 23 17:09:50 2012
@@ -13,21 +13,17 @@
 Portability problems fixed by either Gnulib module @code{getopt-posix} or 
@code{getopt-gnu}:
 @itemize
 @item
-The @code{getopt} function keeps some internal state that cannot be explicitly
-reset on some platforms:
-mingw.
+This function is missing on some platforms:
+MSVC 9.
 @item
 The value of @code{optind} after a missing required argument is wrong
 on some platforms:
-Mac OS X 10.5, AIX 7.1.
+Mac OS X 10.5, AIX 7.1, mingw.
 @end itemize
 
 Portability problems fixed by Gnulib module @code{getopt-gnu}:
 @itemize
 @item
-This function is missing on some platforms:
-MSVC 9.
-@item
 The function @code{getopt} does not support the @samp{+} flag in the options
 string on some platforms:
 Mac OS X 10.5, AIX 5.2, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 11 2010-11.
--- m4/getopt.m4.orig   Sat Jun 23 17:21:27 2012
+++ m4/getopt.m4Sat Jun 23 17:12:49 2012
@@ -1,4 +1,4 @@
-# getopt.m4 serial 42
+# getopt.m4 serial 43
 dnl Copyright (C) 2002-2006, 2008-2012 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -74,11 +74,6 @@
 AC_CHECK_FUNCS([getopt_long_only], [], [gl_replace_getopt=yes])
   fi
 
-  dnl mingw's getopt (in libmingwex.a) does weird things when the options
-  dnl strings starts with '+' and it's not the first call.  Some internal state
-  dnl is left over from earlier calls, and neither setting optind = 0 nor
-  dnl setting optreset = 1 get rid of this internal state.
-  dnl POSIX is silent on optind vs. optreset, so we allow either behavior.
   dnl POSIX 2008 does not specify leading '+' behavior, but see
   dnl http://austingroupbugs.net/view.php?id=191 for a recommendation on
   dnl the next version of POSIX.  For now, we only guarantee leading '+'
@@ -87,30 +82,16 @@
 AC_CACHE_CHECK([whether getopt is POSIX compatible],
   [gl_cv_func_getopt_posix],
   [
-dnl BSD getopt_long uses an incompatible method to reset option
-dnl processing.  Existence of the optreset variable, in and of
-dnl itself, is not a reason to replace getopt, but knowledge
-dnl of the variable is needed to determine how to reset and
-dnl whether a reset reparses the environment.  Solaris
-dnl supports neither optreset nor optind=0, but keeps no state
-dnl that needs a reset beyond setting optind=1; detect Solaris
-dnl by getopt_clip.
-AC_LINK_IFELSE(
-  [AC_LANG_PROGRAM(
- [[#include unistd.h]],
- [[int *p = optreset; return optreset;]])],
-  [gl_optind_min=1],
-  [AC_COMPILE_IFELSE(
- [AC_LANG_PROGRAM(
-[[#include getopt.h]],
-[[return !getopt_clip

Re: -Wlto-type-mismatch warning in error()

2022-12-08 Thread Arsen Arsenović via Gnulib discussion list
Hi,

Eli Zaretskii  writes:

>> Whereas with the Gnulib 'error' module, there is a conflict between the
>> two global function definitions (with 'T' linkage) in install-info.c and
>> in error.c *always*.
>> 
>> > The simplest way to fix this problem would probably be to rename the 
>> > "error"
>> > function in install-info.c.
>> 
>> Yes, or make it 'static' (like Arsen suggested).
>
> Shouldn't we report this to the GCC folks?  It could be a bug in lto,
> no?  I mean, 'error' is not a symbol that applications cannot use, and
> if an application defines a function by that name, it should not be
> imported from the standard library.  Right?

I believe this would make them part of the same program.  On top of
that, Gnulib is pulling in error anyway:

$ nm ./gnulib/lib/libgnu.a | grep error
 U error
$ nm install-info.o ../gnulib/lib/libgnu.a |& grep '\'
 T error
 U error

My guess is that libgnu_a-xalloc-die.o (the file emitting the U error
symbol) includes gnulib/lib/error.h, GCC records that declaration
(through it's use in xalloc_die), and then detects a mismatch with the
one emitted by install-info.o (the T error symbol) and hence warns.

I imagine this would result is some very strange runtime failures if
anyone ever observed install-info hit an xalloc_die condition.

As a test, building on musl (which lacks the error API, for some reason)
causes the executable to be compiled with the install-info error, rather
than the Gnulib one, demonstrating why this warning happens.

Attempting to --whole-archive link on that platform grants us:

$ x86_64-linux-musl-gcc -o ginstall-info install-info.o \
  -Wl,--whole-archive ../gnulib/lib/libgnu.a -Wl,--no-whole-archive
/usr/libexec/gcc/x86_64-linux-musl/ld: 
../gnulib/lib/libgnu.a(libgnu_a-error.o): in function `error':
error.c:(.text+0xe0): multiple definition of `error'; 
install-info.o:install-info.c:(.text+0x4a0): first defined here
collect2: error: ld returned 1 exit status

I imagine a similar thing would happen with a static glibc link.
Renaming the functions or adding ``static'' elides this issue.

So, GCC appears to be doing the right thing.

Since I went through the process of making all the symbols in that file
(besides main) local, here's the patch that does that, though it's based
on a not-particularly-clean head (so, ChangeLog might conflict):

From 65b7657bfc0bc84178c95211690be94c767d725f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Arsen=20Arsenovi=C4=87?= 
Date: Thu, 8 Dec 2022 09:52:13 +0100
Subject: [PATCH] install-info: Make local symbols static

* install-info/install-info.c: Make local symbols static.
---
 ChangeLog   |  5 +++
 install-info/install-info.c | 62 ++---
 2 files changed, 36 insertions(+), 31 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 9bfba11abb..98c2764b99 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2022-12-08  Arsen Arsenović  
+
+	install-info: Make local symbols static.
+	* install-info/install-info.c: Make local symbols static.
+
 2022-12-01  Arsen Arsenović  
 
 	Re-enable copyable anchors in HTML output
diff --git a/install-info/install-info.c b/install-info/install-info.c
index 8950288f6b..761cbfb4d4 100644
--- a/install-info/install-info.c
+++ b/install-info/install-info.c
@@ -28,11 +28,11 @@ static char *default_section = NULL;
 struct spec_entry;
 struct spec_section;
 
-struct line_data *findlines (char *data, int size, int *nlinesp);
-void insert_entry_here (struct spec_entry *entry, int line_number,
-struct line_data *dir_lines, int n_entries); 
-int compare_section_names (const void *s1, const void *s2);
-int compare_entries_text (const void *e1, const void *e2); 
+static struct line_data *findlines (char *data, int size, int *nlinesp);
+static void insert_entry_here (struct spec_entry *entry, int line_number,
+   struct line_data *dir_lines, int n_entries); 
+static int compare_section_names (const void *s1, const void *s2);
+static int compare_entries_text (const void *e1, const void *e2); 

 /* Data structures.  */
 
@@ -136,7 +136,7 @@ struct menu_section
 /* This table defines all the long-named options, says whether they
use an argument, and maps them into equivalent single-letter options.  */
 
-struct option longopts[] =
+static struct option longopts[] =
 {
   { "add-once",  no_argument, NULL, '1'},
   { "align", required_argument, NULL, 'A'},
@@ -172,39 +172,39 @@ struct option longopts[] =
   { 0 }
 };
 
-regex_t *psecreg = NULL;
+static regex_t *psecreg = NULL;
 
 /* Nonzero means that the name specified for the Info file will be used
(without removing .gz, .info extension or leading path) to match the
entries that must be removed.  */
-int remove_exactly = 0;
+static int remove_exactly = 0;
 
 /* Nonzero means th

Re: why is MB_LEN_MAX so large (16) on glibc

2015-05-14 Thread Pádraig Brady
On 14/05/15 01:30, Bruno Haible wrote:
 [CCing bug-gnulib to share the understanding about i18n issues]
 
 Pádraig Brady wrote on 13.05.2015:
 MB_LEN_MAX was changed from 6 to 16 with:
 https://sourceware.org/git/?p=glibc.git;a=commit;f=include/limits.h;h=d64b6ad075
 Do you know why the value 16 is used exactly?
 
 This was motivated either by the desire to be completely future-proof
 for the next 30 years (and you don't know what kinds of encodings will
 be invented).
 
 Or because for a couple of months Ulrich Drepper  François Pinard were
 considering to add locales with stateful encodings such as ISO-2022-JP-2.
 This later turned out to be not worth the effort (as the user experience
 with filenames and shell in such locales was found to be terrible).

Excellent. Info like that is nigh on impossible to search for.

 BTW I see MB_LEN_MAX is 4 on musl libc.
 
 The value of 4 is sufficient to accommodate all stateless encodings in
 use, including UTF-8 (which was restricted from max. 6 to 4 bytes by
 an ISO standard) and GB18030. But it's not necessarily future-proof.

Right. A good summary of the UTF8 6 - 4 bytes thing is at:
https://stijndewitt.wordpress.com/2014/08/09/max-bytes-in-a-utf-8-char/

I see that MB_CUR_MAX is 6 for UTF8 on glibc.
I wonder could that be reduced to 4?

I see that one has to be more careful with the _compile time_
constant MB_LEN_MAX, though it would be tempting to reduce to 8 at least,
requiring a recompile for the unlikely case of supporting legacy
stateful encodings.

 I was worried that it implied that wctomb() might convert a wide char to 
 _multiple_ encoded chars
 for some character/encoding combinations?
 
 No, neither POSIX nor glibc supports locales with encodings where
 a wide char would correspond to multiple characters or a where a
 character would correspond to multiple wide chars.

This was my key question answered.

 In particular,
 this prevented EUC-JISX0213 from being used as a locale encoding in
 glibc [1], thus accelerating the move to UTF-8.

Interesting, though EUC-JISX0213 might now be supported
with newer unicode standards that include the appropriate chars?

 For example iso-2022-kr can have up to 7 bytes per encoded char,
 so maybe wctomb() might output two of those for some wide chars,
 and the extra two bytes were added for alignment?
 
 Yes, this was part of the considerations regarding stateful encodings.
 
 Specifically why I'm wondering about this is to size the
 output buffer for wctomb() appropriately.
 Note the linux man page for wctomb() says to use MB_CUR_MAX,
 while the freebsd man page says to use MB_LEN_MAX
 
 That's simply because MB_CUR_MAX is not a compile-time constant,
 and therefore for a long time the declaration of a local variable
   char buf[MB_CUR_MAX];
 required GCC or C++, and the FreeBSD people are not keen adopters
 of GCC extensions.
 
 I also asked this at:
 http://stackoverflow.com/q/30222107/4421
 
 Bruno
 
 [1] https://sourceware.org/git/?p=glibc.git;a=blob;f=iconvdata/euc-jisx0213.c

thanks!

Pádraig.




relocatable-prog: Use $ORIGIN trick on more platforms

2019-02-19 Thread Bruno Haible
Paul Smith noted on gnu-prog-discuss that other systems than glibc have support
for $ORIGIN in rpath. This patch changes the 'relocatable-prog' module to
make use of this feature, thus removing the need for a "wrapper"/"trampoline"
executable on these platforms.

Tested on
  - FreeBSD 11,
  - NetBSD 7, 8,
  - OpenBSD 6,
  - Solaris 9, 10, 11,
  - Haiku.


2019-02-19  Bruno Haible  

relocatable-prog: Use $ORIGIN trick on more platforms.
* m4/relocatable.m4 (gl_RELOCATABLE_BODY): Use $ORIGIN trick also on
FreeBSD >= 7.3, DragonFly >= 3.0, NetBSD >= 8.0, OpenBSD >= 5.4,
Solaris >= 10, Haiku. But don't use it on Android.
* build-aux/reloc-ldflags: Allow the use of the $ORIGIN trick also on
Hurd, FreeBSD, DragonFly, NetBSD, OpenBSD, Solaris, Haiku.

diff --git a/m4/relocatable.m4 b/m4/relocatable.m4
index c55f7b4..0044477 100644
--- a/m4/relocatable.m4
+++ b/m4/relocatable.m4
@@ -1,4 +1,4 @@
-# relocatable.m4 serial 19
+# relocatable.m4 serial 20
 dnl Copyright (C) 2003, 2005-2007, 2009-2019 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -40,10 +40,34 @@ AC_DEFUN([gl_RELOCATABLE_BODY],
 enable_rpath=no
 AC_CHECK_HEADERS([mach-o/dyld.h])
 AC_CHECK_FUNCS([_NSGetExecutablePath])
+changequote(,)dnl
 case "$host_os" in
   mingw*) is_noop=yes ;;
+  # For the platforms that support $ORIGIN, see
+  # <https://lekensteyn.nl/rpath.html>.
+  # glibc systems, Linux with musl libc: yes. Android: no.
+  # Hurd: no 
<http://lists.gnu.org/archive/html/bug-hurd/2019-02/msg00049.html>.
+  linux*-android*) ;;
+  gnu*) ;;
   linux* | kfreebsd*) use_elf_origin_trick=yes ;;
+  # FreeBSD >= 7.3, DragonFly >= 3.0: yes.
+  freebsd | freebsd[1-7] | freebsd[1-6].* | freebsd7.[0-2]) ;;
+  dragonfly | dragonfly[1-2] | dragonfly[1-2].*) ;;
+  freebsd* | dragonfly*) use_elf_origin_trick=yes ;;
+  # NetBSD >= 8.0: yes.
+  netbsd | netbsd[1-7] | netbsd[1-7].*) ;;
+  netbsdelf | netbsdelf[1-7] | netbsdelf[1-7].*) ;;
+  netbsd*) use_elf_origin_trick=yes ;;
+  # OpenBSD >= 5.4: yes.
+  openbsd | openbsd[1-5] | openbsd[1-4].* | openbsd5.[0-3]) ;;
+  openbsd*) use_elf_origin_trick=yes ;;
+  # Solaris >= 10: yes.
+  solaris | solaris2.[1-9] | solaris2.[1-9].*) ;;
+  solaris*) use_elf_origin_trick=yes ;;
+  # Haiku: yes.
+  haiku*) use_elf_origin_trick=yes ;;
 esac
+changequote([,])dnl
 if test $is_noop = yes; then
   RELOCATABLE_LDFLAGS=:
   AC_SUBST([RELOCATABLE_LDFLAGS])
diff --git a/build-aux/reloc-ldflags b/build-aux/reloc-ldflags
index 4f2b10d..3aed330 100755
--- a/build-aux/reloc-ldflags
+++ b/build-aux/reloc-ldflags
@@ -54,7 +54,12 @@ case "$installdir" in
 esac
 
 case "$host_os" in
-  linux* | kfreebsd*)
+  linux* | gnu* | kfreebsd* | \
+  freebsd* | dragonfly* | \
+  netbsd* | \
+  openbsd* | \
+  solaris* | \
+  haiku*)
 rpath=
 save_IFS="$IFS"; IFS=":"
 for dir in $library_path_value; do
@@ -89,7 +94,14 @@ case "$host_os" in
 IFS="$save_IFS"
 # Output it.
 if test -n "$rpath"; then
-  echo "-Wl,-rpath,$rpath"
+  case "$host_os" in
+# At least some versions of FreeBSD, DragonFly, and OpenBSD need the
+# linker option "-z origin". See <https://lekensteyn.nl/rpath.html>.
+freebsd* | dragonfly* | openbsd*)
+  echo "-Wl,-z,origin -Wl,-rpath,$rpath" ;;
+*)
+  echo "-Wl,-rpath,$rpath" ;;
+  esac
 fi
 ;;
   *)




new module 'setlocale-null'

2019-12-15 Thread Bruno Haible
It is the usual expectation that use of setlocale() to change the global
locale is not multithread-safe (of course), but that setlocale(...,NULL)
to query the name of the global locale is.

However, POSIX does not guarantee it:
<https://pubs.opengroup.org/onlinepubs/9699919799/functions/setlocale.html>
says
  "The returned string pointer might be invalidated or the string content
   might be overwritten by a subsequent call to setlocale()."

We need to distinguish two cases:

* querying the name of one category of the global locale
  A unit test shows that this is not MT-safe on
  OpenBSD, AIX.

* querying the name of the global locale (LC_ALL case)
  A unit test shows that this is not MT-safe on
  musl libc, macOS, FreeBSD, NetBSD, OpenBSD, AIX, Haiku, Cygwin.

This info, together with a test program that runs setlocale(...,NULL)
in different threads at different times, provides the following answer
to the question "Where is the return value of setlocale (..., NULL)?":


simple categoryLC_ALL

glibcin the category of the localein the locale
musl libcin the category of the localein a global   NOT MT-SAFE!
macOSin the category (global) in a global   NOT MT-SAFE!
FreeBSD  in the category (global) in a global   NOT MT-SAFE!
NetBSD   in the category of the localein a global   NOT MT-SAFE!
OpenBSD  in a global  NOT MT-SAFE!in a global   NOT MT-SAFE!
AIX  in a global  NOT MT-SAFE!in a global   NOT MT-SAFE!
HP-UXin the threadin the thread
IRIX in the category (global) in a global   actually 
MT-SAFE
Solaris 10   in the locale / thread   in the locale
Solaris 11.0 in the category of the localein the locale
Solaris 11.4 in the category of the localein the locale
Solaris OpenIndiana  in the category of the localein the locale
Haikuin the category (global) in a global   NOT MT-SAFE!
Cygwin   in the category (global) in a global   NOT MT-SAFE!
mingwin the category of the localein the thread
MSVC in the category of the locale?   in the thread


The only way to fix this is to introduce a lock around the calls to
setlocale(...,NULL), since in particular
  - in OpenBSD, code inspection shows that there is no way to fetch the infos
directly in a multithread-safe way,
  - in AIX, there is no documented API for fetching the infos either.

How can the API look like?
  (a) We could override setlocale(), so that setlocale (..., NULL) returns
  a string in a buffer in thread-local storage.
  (b) We could introduce a new API, that takes a caller-provided buffer as
  argument. Like the functions getlogin_r, ttyname_r, ptsname_r do.

I decided to go with approach (b), for the following reasons:
  * Returning a string in thread-local storage is technically complex
(1. get a pointer to thread-local storage, 2. store a malloc()ed
buffer in it, resize it when needed, 3. make sure the buffer gets
freed when the thread exits [easy with POSIX and ISO C threads, but
hard with Windows threads]).
Really, it is better to store ALL thread-local data in the thread's
stack. Isn't that what a stack is for?
  * We already have a setlocale() override, and having the ability to
activate one override or the other or both together could lead to
complex code. In approach (b), the setlocale() override will use
the new API - simple.

The attached patches implement this.


2019-12-15  Bruno Haible  

setlocale-null: New module.
* lib/locale.in.h (SETLOCALE_NULL_MAX, SETLOCALE_NULL_ALL_MAX,
setlocale_null): New declarations.
* lib/setlocale_null.c: New file.
* lib/setlocale-lock.c: New file.
* m4/threadlib.m4 (gl_PTHREADLIB_BODY): Define C macro HAVE_PTHREAD_API.
* m4/setlocale_null.m4: New file.
* m4/locale_h.m4 (gl_LOCALE_H_DEFAULTS): Initialize
GNULIB_SETLOCALE_NULL.
* modules/locale (Makefile.am): Substitute GNULIB_SETLOCALE_NULL.
* modules/setlocale-null: New file.
* doc/posix-functions/setlocale.texi: Mention the new module.

setlocale-null: Add tests.
* tests/test-setlocale_null.c: New file.
* tests/test-setlocale_null-one.c: New file.
* tests/test-setlocale_null-all.c: New file.
* modules/setlocale-null-tests: New file.

>From 567591f3b194927a4d7eefa71007be2709796c4e Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Sun, 15 Dec 2019 21:39:55 +0100
Subject: [PATCH 1/2] setlocale-null: New module.

* lib/locale.in.h (SETLOCALE_NULL_MAX, SETLOCALE_NULL_ALL_MAX,
setlocale_null): New declarations.
* lib/setlocale_null.c: New file.
* lib/setlocale-lock.c: New file.
* m4/threadlib.m4 (

[PATCH 1/2] dfa: remove struct lexer_state.cur_mb_len

2019-12-17 Thread Paul Eggert
* lib/dfa.c (struct lexer_state): Remove cur_mb_len member,
as it’s not needed and the code is simpler without it.
All uses removed.
---
 ChangeLog |  7 +++
 lib/dfa.c | 20 
 2 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 237bfdda1..acd67f9dc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2019-12-16  Paul Eggert  
+
+   dfa: remove struct lexer_state.cur_mb_len
+   * lib/dfa.c (struct lexer_state): Remove cur_mb_len member,
+   as it’s not needed and the code is simpler without it.
+   All uses removed.
+
 2019-12-16  Bruno Haible  
 
setlocale-null: Remove need for -lpthread on musl libc, *BSD, Haiku.
diff --git a/lib/dfa.c b/lib/dfa.c
index 6b89613a9..fa947463b 100644
--- a/lib/dfa.c
+++ b/lib/dfa.c
@@ -422,9 +422,6 @@ struct lexer_state
  MB_CUR_MAX > 1.  */
   wint_t wctok;
 
-  /* Length of the multibyte representation of wctok.  */
-  int cur_mb_len;
-
   /* The most recently analyzed multibyte bracket expression.  */
   struct mb_char_classes brack;
 
@@ -921,7 +918,6 @@ fetch_wc (struct dfa *dfa)
 {
   int nbytes = mbs_to_wchar (>lex.wctok, dfa->lex.ptr, dfa->lex.left,
  dfa);
-  dfa->lex.cur_mb_len = nbytes;
   int c = nbytes == 1 ? to_uchar (dfa->lex.ptr[0]) : EOF;
   dfa->lex.ptr += nbytes;
   dfa->lex.left -= nbytes;
@@ -,8 +1107,8 @@ parse_bracket_exp (struct dfa *dfa)
 {
   /* In the case [x-], the - is an ordinary hyphen,
  which is left in c1, the lookahead character.  */
-  dfa->lex.ptr -= dfa->lex.cur_mb_len;
-  dfa->lex.left += dfa->lex.cur_mb_len;
+  dfa->lex.ptr--;
+  dfa->lex.left++;
 }
   else
 {
@@ -1662,21 +1658,22 @@ addtok_wc (struct dfa *dfa, wint_t wc)
   unsigned char buf[MB_LEN_MAX];
   mbstate_t s = { 0 };
   size_t stored_bytes = wcrtomb ((char *) buf, wc, );
+  int buflen;
 
   if (stored_bytes != (size_t) -1)
-dfa->lex.cur_mb_len = stored_bytes;
+buflen = stored_bytes;
   else
 {
   /* This is merely stop-gap.  buf[0] is undefined, yet skipping
  the addtok_mb call altogether can corrupt the heap.  */
-  dfa->lex.cur_mb_len = 1;
+  buflen = 1;
   buf[0] = 0;
 }
 
-  addtok_mb (dfa, buf[0], dfa->lex.cur_mb_len == 1 ? 3 : 1);
-  for (int i = 1; i < dfa->lex.cur_mb_len; i++)
+  addtok_mb (dfa, buf[0], buflen == 1 ? 3 : 1);
+  for (int i = 1; i < buflen; i++)
 {
-  addtok_mb (dfa, buf[i], i == dfa->lex.cur_mb_len - 1 ? 2 : 0);
+  addtok_mb (dfa, buf[i], i == buflen - 1 ? 2 : 0);
   addtok (dfa, CAT);
 }
 }
@@ -4277,7 +4274,6 @@ dfasyntax (struct dfa *dfa, struct localeinfo const 
*linfo,
   dfa->fast = !dfa->localeinfo.multibyte;
 
   dfa->canychar = -1;
-  dfa->lex.cur_mb_len = 1;
   dfa->syntax.syntax_bits_set = true;
   dfa->syntax.case_fold = (bits & RE_ICASE) != 0;
   dfa->syntax.anchor = (dfaopts & DFA_ANCHOR) != 0;
-- 
2.17.1




Re: portability of fopen and 'e' (O_CLOEXEC) flag

2020-05-24 Thread Bruno Haible
dev/null") == 0)
@@ -58,35 +64,88 @@ rpl_fopen (const char *filename, const char *mode)
   /* Parse the mode.  */
   open_direction = 0;
   open_flags_standard = 0;
+#if GNULIB_FOPEN_GNU
+  open_flags_gnu = 0;
+#endif
   {
-const char *m;
+const char *p = mode;
+#if GNULIB_FOPEN_GNU
+char *q = fdopen_mode_buf;
+#endif
 
-for (m = mode; *m != '\0'; m++)
+for (; *p != '\0'; p++)
   {
-switch (*m)
+switch (*p)
   {
   case 'r':
 open_direction = O_RDONLY;
+#if GNULIB_FOPEN_GNU
+if (q < fdopen_mode_buf + BUF_SIZE)
+  *q++ = *p;
+#endif
 continue;
   case 'w':
 open_direction = O_WRONLY;
 open_flags_standard |= O_CREAT | O_TRUNC;
+#if GNULIB_FOPEN_GNU
+if (q < fdopen_mode_buf + BUF_SIZE)
+  *q++ = *p;
+#endif
 continue;
   case 'a':
 open_direction = O_WRONLY;
 open_flags_standard |= O_CREAT | O_APPEND;
+#if GNULIB_FOPEN_GNU
+if (q < fdopen_mode_buf + BUF_SIZE)
+  *q++ = *p;
+#endif
 continue;
   case 'b':
+#if GNULIB_FOPEN_GNU
+if (q < fdopen_mode_buf + BUF_SIZE)
+  *q++ = *p;
+#endif
 continue;
   case '+':
 open_direction = O_RDWR;
+#if GNULIB_FOPEN_GNU
+if (q < fdopen_mode_buf + BUF_SIZE)
+  *q++ = *p;
+#endif
 continue;
+#if GNULIB_FOPEN_GNU
+  case 'x':
+open_flags_gnu |= O_EXCL;
+continue;
+  case 'e':
+open_flags_gnu |= O_CLOEXEC;
+continue;
+#endif
   default:
 break;
   }
+#if GNULIB_FOPEN_GNU
+/* The rest of the mode string can be a platform-dependent extension.
+   Copy it unmodified.  */
+{
+  size_t len = strlen (p);
+  if (len > fdopen_mode_buf + BUF_SIZE - q)
+len = fdopen_mode_buf + BUF_SIZE - q;
+  memcpy (q, p, len);
+  q += len;
+}
+#endif
 break;
   }
+#if GNULIB_FOPEN_GNU
+*q = '\0';
+#endif
   }
+#if GNULIB_FOPEN_GNU
+  open_flags = open_flags_standard | open_flags_gnu;
+#else
+  open_flags = open_flags_standard;
+#endif
 
 #if FOPEN_TRAILING_SLASH_BUG
   /* Fail if the mode requires write access and the filename ends in a slash,
@@ -116,7 +175,7 @@ rpl_fopen (const char *filename, const char *mode)
 return NULL;
   }
 
-fd = open (filename, open_direction | open_flags_standard);
+fd = open (filename, open_direction | open_flags);
 if (fd < 0)
   return NULL;
 
@@ -127,7 +186,11 @@ rpl_fopen (const char *filename, const char *mode)
 return NULL;
   }
 
+# if GNULIB_FOPEN_GNU
+fp = fdopen (fd, fdopen_mode_buf);
+# else
 fp = fdopen (fd, mode);
+# endif
 if (fp == NULL)
   {
 int saved_errno = errno;
@@ -139,5 +202,26 @@ rpl_fopen (const char *filename, const char *mode)
   }
 #endif
 
+#if GNULIB_FOPEN_GNU
+  if (open_flags_gnu != 0)
+{
+  int fd;
+  FILE *fp;
+
+  fd = open (filename, open_direction | open_flags);
+  if (fd < 0)
+return NULL;
+
+  fp = fdopen (fd, fdopen_mode_buf);
+  if (fp == NULL)
+{
+  int saved_errno = errno;
+  close (fd);
+  errno = saved_errno;
+}
+  return fp;
+}
+#endif
+
   return orig_fopen (filename, mode);
 }
diff --git a/m4/fopen.m4 b/m4/fopen.m4
index 2a4b00d..8eab4a6 100644
--- a/m4/fopen.m4
+++ b/m4/fopen.m4
@@ -1,4 +1,4 @@
-# fopen.m4 serial 10
+# fopen.m4 serial 11
 dnl Copyright (C) 2007-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -58,5 +58,90 @@ changequote([,])dnl
   esac
 ])
 
+AC_DEFUN([gl_FUNC_FOPEN_GNU],
+[
+  AC_REQUIRE([gl_FUNC_FOPEN])
+  AC_CACHE_CHECK([whether fopen supports the mode character 'x'],
+[gl_cv_func_fopen_mode_x],
+[rm -f conftest.x
+ AC_RUN_IFELSE(
+   [AC_LANG_SOURCE([[
+#include 
+#include 
+int main ()
+{
+  FILE *fp;
+  fp = fopen ("conftest.x", "w");
+  fclose (fp);
+  fp = fopen ("conftest.x", "wx");
+  if (fp != NULL)
+/* 'x' ignored */
+return 1;
+  else if (errno == EEXIST)
+return 0;
+  else
+/* 'x' rejected */
+return 2;
+}]])],
+   [gl_cv_func_fopen_mode_x=yes],
+   [gl_cv_func_fopen_mode_x=no],
+   [case "$host_os" in
+  # Guess yes on glibc and musl systems.
+  linux*-gnu* | gnu* | kfreebsd*-gnu | *-musl*)
+gl_cv_func_fopen_mode_x="guessing yes" ;;
+  # If we don't know, obey --enable-cross-guesses.
+  *)
+gl_cv_func_fopen_mode_x="$gl_cross_guess_normal" ;;
+esac
+   ])

fenv-exceptions-tracking-c99 tests: Enhance tests

2023-11-05 Thread Bruno Haible
The fenv-exceptions-trapping module, compared to the fpe-trapping module, not
only works on all platforms. It also supports all exception types, not only
FE_INVALID. This can be used to strengthen the fenv-exceptions-tracking-c99
tests.


2023-11-05  Bruno Haible  

fenv-exceptions-tracking-c99 tests: Enhance tests.
* tests/test-fenv-except-tracking-3.sh: Test not only FE_INVALID, but
also FE_DIVBYZERO, FE_OVERFLOW, FE_UNDERFLOW, FE_INEXACT.
* tests/test-fenv-except-tracking-3.c: Include , .
Don't include fpe-trapping.h. Assume HAVE_FPE_TRAPPING is 1.
(main): Receive the exception to test as first argument.

diff --git a/tests/test-fenv-except-tracking-3.c 
b/tests/test-fenv-except-tracking-3.c
index 63fabad48f..e2f16efa65 100644
--- a/tests/test-fenv-except-tracking-3.c
+++ b/tests/test-fenv-except-tracking-3.c
@@ -22,33 +22,49 @@
 #include 
 
 #include 
+#include 
+#include 
 
-#include "fpe-trapping.h"
 #include "macros.h"
 
 /* musl libc does not support floating-point exception trapping, even where
the hardware supports it.  See
<https://wiki.musl-libc.org/functional-differences-from-glibc.html>  */
-#if HAVE_FPE_TRAPPING && (!MUSL_LIBC || GNULIB_FEENABLEEXCEPT)
+#if !MUSL_LIBC || GNULIB_FEENABLEEXCEPT
 
 /* Check that feraiseexcept() can trigger a trap.  */
 
 int
-main ()
+main (int argc, char *argv[])
 {
-  /* Clear FE_INVALID exceptions from past operations.  */
-  feclearexcept (FE_INVALID);
-
-  /* An FE_INVALID exception shall trigger a SIGFPE signal, which by default
- terminates the program.  */
-  if (sigfpe_on_invalid () < 0)
+  if (argc > 1)
 {
-  fputs ("Skipping test: trapping floating-point exceptions are not 
supported on this machine.\n", stderr);
-  return 77;
+  int exception;
+
+  if (STREQ (argv[1], "FE_INVALID"))   exception = FE_INVALID;   else
+  if (STREQ (argv[1], "FE_DIVBYZERO")) exception = FE_DIVBYZERO; else
+  if (STREQ (argv[1], "FE_OVERFLOW"))  exception = FE_OVERFLOW;  else
+  if (STREQ (argv[1], "FE_UNDERFLOW")) exception = FE_UNDERFLOW; else
+  if (STREQ (argv[1], "FE_INEXACT"))   exception = FE_INEXACT;   else
+{
+  printf ("Invalid argument: %s\n", argv[1]);
+  exit (1);
+}
+
+  /* Clear FE_XX exceptions from past operations.  */
+  feclearexcept (exception);
+
+  /* An FE_XX exception shall trigger a SIGFPE signal, which by default
+ terminates the program.  */
+  if (feenableexcept (exception) == -1)
+{
+  fputs ("Skipping test: trapping floating-point exceptions are not 
supported on this machine.\n", stderr);
+  return 77;
+}
+
+  feraiseexcept (exception);
 }
 
-  feraiseexcept (FE_INVALID);
-
   return 0;
 }
 
diff --git a/tests/test-fenv-except-tracking-3.sh 
b/tests/test-fenv-except-tracking-3.sh
index f44e43a59b..263af596b3 100755
--- a/tests/test-fenv-except-tracking-3.sh
+++ b/tests/test-fenv-except-tracking-3.sh
@@ -4,15 +4,17 @@
 
 final_rc=0
 
-${CHECKER} ./test-fenv-except-tracking-3${EXEEXT}
-rc=$?
-if test $rc = 77; then
-  final_rc=77
-else
-  if test $rc = 0; then
-echo "Failed: ./test-fenv-except-tracking-3" 1>&2
-exit 1
+for arg in FE_INVALID FE_DIVBYZERO FE_OVERFLOW FE_UNDERFLOW FE_INEXACT; do
+  ${CHECKER} ./test-fenv-except-tracking-3${EXEEXT} $arg
+  rc=$?
+  if test $rc = 77; then
+final_rc=77
+  else
+if test $rc = 0; then
+  echo "Failed: ./test-fenv-except-tracking-3 $arg" 1>&2
+  exit 1
+fi
   fi
-fi
+done
 
 exit $final_rc






simplify fpe-tracking and fpe-trapping modules

2023-11-05 Thread Bruno Haible
Test whether fpscr was actually changed as desired.  */
-  fenv_t env;
-  fegetenv ();
-  if (((FE_INVALID << 8) & ~env) != 0)
-return -1;
-  #endif
-
   return 0;
 }
 
 /* But it does not work on RISC-V.  That's because the fcsr register has only
bits for floating-point exception status, but no bits for trapping
floating-point exceptions.  */
-# if defined __riscv
-#  undef HAVE_FPE_TRAPPING
-# endif
-
-#elif HAVE_FPSETMASK
-/* FreeBSD ≥ 6.0, NetBSD ≥ 1.4, OpenBSD ≥ 3.1, IRIX, Solaris, Minix ≥ 3.2.  */
-
-# include 
-  /* The type is called 'fp_except_t' on FreeBSD, but 'fp_except' on
- all other systems.  */
-# if !defined __FreeBSD__
-#  define fp_except_t fp_except
-# endif
-
-static int
-sigfpe_on_invalid ()
-{
-  /* Clear FE_INVALID exceptions from past operations.  */
-  feclearexcept (FE_INVALID);
-
-  fpsetmask (fpgetmask () | FP_X_INV);
-
-  #if defined __arm__ || defined __aarch64__
-  /* Test whether the CPU supports the request.  */
-  if ((fpgetmask () & ~FP_X_INV) == 0)
-return -1;
-  #endif
-
-  return 0;
-}
-
-#elif HAVE_FESETTRAPENABLE
-/* HP-UX, QNX */
-
-# include 
-
-static int
-sigfpe_on_invalid ()
-{
-  /* Clear FE_INVALID exceptions from past operations.  */
-  feclearexcept (FE_INVALID);
-
-  fesettrapenable (fegettrapenable () | FE_INVALID);
-
-  return 0;
-}
-
-#elif defined _AIX
-/* AIX */
-
-# include 
-
-static int
-sigfpe_on_invalid ()
-{
-  /* Clear FE_INVALID exceptions from past operations.  */
-  feclearexcept (FE_INVALID);
-
-  /* Enable precise trapping mode.
- Documentation: <https://www.ibm.com/docs/en/aix/7.3?topic=f-fp-trap-subroutine>  */
-  fp_trap (FP_TRAP_SYNC);
-  /* Documentation: <https://www.ibm.com/docs/en/aix/7.3?topic=f-fp-any-enable-fp-is-enabled-fp-enable-all-fp-enable-fp-disable-all-fp-disable-subroutine>  */
-  fp_enable (TRP_INVALID);
-
-  return 0;
-}
-
-#elif __MINGW32__ && defined __x86_64__
-/* mingw/x86_64 */
-
-# include 
-
-static int
-sigfpe_on_invalid ()
-{
-  /* Clear FE_INVALID exceptions from past operations.  */
-  feclearexcept (FE_INVALID);
-
-  /* An FE_INVALID exception shall trigger a SIGFPE signal.
- fctrl bits 5..2,0 indicate which floating-point exceptions shall, when
- occurring in the 387 compatible floating-point unit, trigger a trap rather
- than merely set the corresponding bit in the fstat register.
- mxcsr bits 12..9,7 indicate which floating-point exceptions shall, when
- occurring in the SSE registers floating-point unit, trigger a trap rather
- than merely set the corresponding bit in the lower part of the mxcsr
- register.  */
-  /* mingw's _controlfp_s implementation
- <https://github.com/mingw-w64/mingw-w64/blob/master/mingw-w64-crt/secapi/_controlfp_s.c>
- is broken.  This code here works.  */
-  {
-unsigned short fctrl, orig_fctrl;
-unsigned int mxcsr, orig_mxcsr;
-
-__asm__ __volatile__ ("fstcw %0" : "=m" (*));
-__asm__ __volatile__ ("stmxcsr %0" : "=m" (*));
-orig_fctrl = fctrl;
-orig_mxcsr = mxcsr;
-fctrl &= ~FE_INVALID;
-mxcsr &= ~(FE_INVALID << 7);
-if (!(fctrl == orig_fctrl && mxcsr == orig_mxcsr))
-  {
-__asm__ __volatile__ ("fldcw %0" : : "m" (*));
-__asm__ __volatile__ ("ldmxcsr %0" : : "m" (*));
-  }
-  }
-
-  return 0;
-}
-
-#elif defined _WIN32 && !defined __CYGWIN__
-/* native Windows */
-
-# include 
-
-static int
-sigfpe_on_invalid ()
-{
-  /* Documentation:
- <https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/controlfp-s>  */
-  unsigned int control;
-  if (_controlfp_s (, 0, 0) == 0)
-if (_controlfp_s (, control & ~_EM_INVALID, _MCW_EM) == 0)
-  return 0;
-
-  return -1;
-}
-
-#elif MUSL_LIBC && defined __x86_64__
-/* musl libc/x86_64 */
-
-# include 
-
-static int
-sigfpe_on_invalid ()
-{
-  fenv_t env, orig_env;
-  fegetenv ();
-  orig_env = env;
-
-  /* Clear FE_INVALID exceptions from past operations.
- fstat bits 5..2,0 indicate which floating-point exceptions have occurred
- since the respective bit was last set to zero, in the 387 compatible
- floating-point unit.
- mxcsr bits 5..2,0 indicate which floating-point exceptions have occurred
- since the respective bit was last set to zero, in the SSE registers
- floating-point unit.  */
-  env.__status_word &= ~FE_INVALID;
-  env.__mxcsr &= ~FE_INVALID;
-  /* An FE_INVALID exception shall trigger a SIGFPE signal.
- fctrl bits 5..2,0 indicate which floating-point exceptions shall, when
- occurring in the 387 compatible floating-point unit, trigger a trap rather
- than merely set the corresponding bit in the fstat register.
- mxcsr bits 12..9,7 indicate which floating-point exceptions shall, when
- occurring in the SSE registers floating-point unit, trigger a trap rather
- than 

Re: argp: Correct documentation

2022-12-07 Thread Alfred M. Szmidt


   Alfred M. Szmidt wrote:
   > Does a system become a `glibc platform' if one uses gnulib?

   No, it doesn't, because
 - the term 'platform' or 'system' denotes the basic OS + base libraries,
 - Gnulib does not emcompass glibc.

Ok, so you agree that there is no such thing as a "glibc platform",
seeing that glibc is not "basic OS + base libraries".  So it makes
sense to not use that term.  I suspect that you find it clear since
you came up with it, to others it is not as clear.

   > I could not find this decision in those two references, both are pages
   > from Debian, and nothing from RMS on the topic.

   You can trust my memory on this statement, even though I can't find
   the precise mail where RMS announced this decision. It was probably
   in 2001.

It has little to do with trust, if there is such an "announcment" it
would be useful to put it up on gnu.org.  I do not recall any such
thing from RMS having been announced around that time, or at all.

   >  - Is Alpine Linux a GNU system? (It uses musl libc instead of glibc.) 
[4]
   > 
   > No, Alpine is not based on the GNU system ...
   > 
   >  - Is Windows with WSL and a GNU distro a GNU system? [5][6]
   > 
   > Windows is the operating system here, that is what your computer is
   > running.  Just becaues you run another operating system inside an
   > existing one, doesn't mean that one becomes the other.  

   While you can answer these questions (and I agree with the answers), the mere
   fact that these questions appear on reddit shows that the term "GNU system"
   is not as unambiguous as one might wish.

What reddit, or some other nasty fourm shows does not make something
ambiguous.  What matters is the GNU project, and what we say.  Seeing
that you yourself could answer these two questions, we can agree that
there is little ambigiousity in what constitutes the GNU system.

Overall, the GNU system is not "based on the 'glibc platfrom'", and
lets avoid using that term.  We have far clearer ones, like the 'GNU
system' to use that has wide acceptance in the GNU project, but also
outside.


The text over all is messy on other points as well:

   Portability problems fixed by Gnulib:
   @itemize
  +@item
  +This variable is missing on all non-glibc platforms:
  +macOS 11.1, FreeBSD 13.0, NetBSD 9.0, OpenBSD 6.7, Minix 3.1.8, AIX 5.1, 
HP-UX 11, IRIX 6.5, Solaris 11.4, Cygwin 2.9, mingw, MSVC 14, Android 9.0.
  
  ...

Does this mean that FreeBSD 12 supports it?  What amount Minix 2?  Are
these "all" the platforms, seeing that it is an exhaustive list in
detail.  Will one list other obscure non-free platforms?  We avoid
mentioning them out of principle, since we do not want to promote
them.  Why isn't freedos listed?  Is this list manually updated each,
and every time those companies or projects make a release? That seems
like useless churn.  Etc 



Android and the C locale

2023-01-16 Thread Bruno Haible
f735d520..36b520f7b8 100644
--- a/tests/test-mbrtoc32.c
+++ b/tests/test-mbrtoc32.c
@@ -72,10 +72,6 @@ main (int argc, char *argv[])
 for (c = 0; c < 0x100; c++)
   switch (c)
 {
-default:
-  if (! (c && 1 < argc && argv[1][0] == '5'))
-break;
-  FALLTHROUGH;
 case '\t': case '\v': case '\f':
 case ' ': case '!': case '"': case '#': case '%':
 case '&': case '\'': case '(': case ')': case '*':
@@ -97,25 +93,23 @@ main (int argc, char *argv[])
 case 'p': case 'q': case 'r': case 's': case 't':
 case 'u': case 'v': case 'w': case 'x': case 'y':
 case 'z': case '{': case '|': case '}': case '~':
-  /* c is in the ISO C "basic character set", or argv[1] starts
- with '5' so we are testing all nonnull bytes.  */
+  /* c is in the ISO C "basic character set".  */
+  ASSERT (c < 0x80);
+  /* c is an ASCII character.  */
   buf[0] = c;
+
   wc = (char32_t) 0xBADFACE;
   ret = mbrtoc32 (, buf, 1, );
   ASSERT (ret == 1);
-  if (c < 0x80)
-/* c is an ASCII character.  */
-ASSERT (wc == c);
-  else
-/* argv[1] starts with '5', that is, we are testing the C or POSIX
-   locale.
-   On most platforms, the bytes 0x80..0xFF map to U+0080..U+00FF.
-   But on musl libc, the bytes 0x80..0xFF map to U+DF80..U+DFFF.  */
-ASSERT (wc == (btowc (c) == 0xDF00 + c ? btowc (c) : c));
+  ASSERT (wc == c);
   ASSERT (mbsinit ());
+
   ret = mbrtoc32 (NULL, buf, 1, );
   ASSERT (ret == 1);
   ASSERT (mbsinit ());
+
+  break;
+default:
   break;
 }
   }
@@ -368,7 +362,35 @@ main (int argc, char *argv[])
 return 0;
 
   case '5':
-/* C locale; tested above.  */
+/* C or POSIX locale.  */
+{
+  int c;
+  char buf[1];
+
+  memset (, '\0', sizeof (mbstate_t));
+  for (c = 0; c < 0x100; c++)
+if (c != 0)
+  {
+/* We are testing all nonnull bytes.  */
+buf[0] = c;
+
+wc = (char32_t) 0xBADFACE;
+ret = mbrtoc32 (, buf, 1, );
+ASSERT (ret == 1);
+if (c < 0x80)
+  /* c is an ASCII character.  */
+  ASSERT (wc == c);
+else
+  /* On most platforms, the bytes 0x80..0xFF map to U+0080..U+00FF.
+ But on musl libc, the bytes 0x80..0xFF map to U+DF80..U+DFFF.  */
+  ASSERT (wc == (btowc (c) == 0xDF00 + c ? btowc (c) : c));
+ASSERT (mbsinit ());
+
+ret = mbrtoc32 (NULL, buf, 1, );
+ASSERT (ret == 1);
+ASSERT (mbsinit ());
+  }
+}
 return 0;
   }
 
diff --git a/tests/test-mbrtowc.c b/tests/test-mbrtowc.c
index 9019ea0e71..b358d8d583 100644
--- a/tests/test-mbrtowc.c
+++ b/tests/test-mbrtowc.c
@@ -72,10 +72,6 @@ main (int argc, char *argv[])
 for (c = 0; c < 0x100; c++)
   switch (c)
 {
-default:
-  if (! (c && 1 < argc && argv[1][0] == '5'))
-break;
-  FALLTHROUGH;
 case '\t': case '\v': case '\f':
 case ' ': case '!': case '"': case '#': case '%':
 case '&': case '\'': case '(': case ')': case '*':
@@ -97,25 +93,23 @@ main (int argc, char *argv[])
 case 'p': case 'q': case 'r': case 's': case 't':
 case 'u': case 'v': case 'w': case 'x': case 'y':
 case 'z': case '{': case '|': case '}': case '~':
-  /* c is in the ISO C "basic character set", or argv[1] starts
- with '5' so we are testing all nonnull bytes.  */
+  /* c is in the ISO C "basic character set".  */
+  ASSERT (c < 0x80);
+  /* c is an ASCII character.  */
   buf[0] = c;
+
   wc = (wchar_t) 0xBADFACE;
   ret = mbrtowc (, buf, 1, );
   ASSERT (ret == 1);
-  if (c < 0x80)
-/* c is an ASCII character.  */
-ASSERT (wc == c);
-  else
-/* argv[1] starts with '5', that is, we are testing the C or POSIX
-   locale.
-   On most platforms, the bytes 0x80..0xFF map to U+0080..U+00FF.
-   But on musl libc, the bytes 0x80..0xFF map to U+DF80..U+DFFF.  */
-ASSERT (wc == (btowc (c) == 0xDF00 + c ? btowc (c) : c));
+  ASSERT (wc == c);
   ASSERT (mbsinit ());
+
   ret = mbrtowc (NULL, buf, 1, );
   ASSERT (ret == 1);
   ASSERT (mbsinit ());
+
+  break;
+default:
   break;
 }
   }
@@ -349,7 +343,35 @@ main (

Re: backupfile and backup-rename are introducing the same object to make

2023-01-25 Thread (GalaxyMaster)
Bruno,

On Wed, Jan 25, 2023 at 06:53:57PM +0100, Bruno Haible wrote:
> Hi,
> 
> (GalaxyMaster) wrote:
> > backup-replace
> You mean 'backup-rename', right?

Yeah, it was a typo, it was in the middle of the night and my brain was not
working efficiently.

> > I just stumbled upon the following: when I include both backupfile and
> > backup-replace modules I am getting a broken build due to multiple 
> > definitions
> > of "simple_backup_suffix'.
> 
> This is not expected, because usually the .o files are collected in a .a file,
> from which one of the two backupfile.o will be picked, and it does not matter
> which one since they are identical.

This makes sense.  My use case in not standard since I am actually building
these into a shared library using libtool, so libtool sees the same object file
listed twice and tries to resolve it by renaming one of them and then includes
both in the resulting link command to produce a shared object.  The linker
rightfully complains about duplicates.  Anyway, I think my use case is out of
scope for this project, but the reason why I reported it was that it just does
not look tidy to have two modules claiming ownership of the same files and
including the same configuration to configure.ac/Makefile.am files.

For my project, I am just patching backup-rename module's definition to only
include parts that are different from backupfile and I also made a dependency
on backupfile.

> Please describe your situation:
>   - operating system?

I am building a Linux distribution from ground up.

>   - building what kind of library or binary in which way?

I am basically building what is directly against GNU Lib's philosophy (section
2.2 of the manual), a shared library containing every single compilable module
with all functions defined as weak symbols.  The resulting shared library then
also stripped of all DT_NEEDED sections except for the system libc one, so that
it does not have lots of dependencies (and with weak symbols it is usable in
parts even if the dependencies are not met as long as the corresponding
functions are not called).

I clearly understand that my use case is not something supported or endorsed by
the GNU Lib project and am not trying to change that, but it is another avenue
to test stuff, which may be valueable to the project.

>   - which compiler: $CC = ? $CFLAGS = ? $CPPFLAGS = ? $LDFLAGS = ?
>   - which linker is being used by the compiler?,

I am not sure this would be helpful, since as I described my use case is
definitely not something GNU Lib supports, but for the context purposes: the
system is musl based with GCC as the primary compiler.

So, as you wrote in your message, I think there is no bug and the way how these
two modules are currently set up is fine (unless one does something
non-standard like myself).  However, I would argue that it would still be nicer
not to polute project's build files with duplicate entries if possible, but
this is up to you of course.

-- 
(GM)



wmemcmp: Work around ISO C compliance bug on several platforms

2023-04-18 Thread Bruno Haible
These two patches work around an ISO C compliance bug of wmemcmp()
on several platforms.

The point is that in ISO C, a "wide character" is any wchar_t value.
A "wide character" is not constrained to the range 0..INT_MAX. For
the precise reasoning, see
<https://www.openwall.com/lists/musl/2023/04/18/5>.


2023-04-18  Bruno Haible  

wmemcmp: Add tests.
* tests/test-wmemcmp.c: New file, based on tests/unistr/test-cmp.h.
* modules/wmemcmp-tests: New file.

wmemcmp: Work around ISO C compliance bug on several platforms.
* lib/wchar.in.h (wmemcmp): Consider REPLACE_WMEMCMP.
* lib/wmemcmp-impl.h (wmemcmp): Don't assume that the two wide
characters are in the range 0..INT_MAX.
* m4/wmemcmp.m4 (gl_FUNC_WMEMCMP): Test whether wmemcmp works for all
wide characters. Set REPLACE_WMEMCMP.
* m4/wchar_h.m4 (gl_WCHAR_H_DEFAULTS): Initialize REPLACE_WMEMCMP.
* modules/wchar (Makefile.am): Substitute REPLACE_WMEMCMP.
* modules/wmemcmp (configure.ac): Consider REPLACE_WMEMCMP.
* doc/posix-functions/wmemcmp.texi: Mention the bug.

>From 6c28538c9d6bbf692ab12972de6cc035e54b0c67 Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Wed, 19 Apr 2023 01:01:56 +0200
Subject: [PATCH 1/2] wmemcmp: Work around ISO C compliance bug on several
 platforms.

* lib/wchar.in.h (wmemcmp): Consider REPLACE_WMEMCMP.
* lib/wmemcmp-impl.h (wmemcmp): Don't assume that the two wide
characters are in the range 0..INT_MAX.
* m4/wmemcmp.m4 (gl_FUNC_WMEMCMP): Test whether wmemcmp works for all
wide characters. Set REPLACE_WMEMCMP.
* m4/wchar_h.m4 (gl_WCHAR_H_DEFAULTS): Initialize REPLACE_WMEMCMP.
* modules/wchar (Makefile.am): Substitute REPLACE_WMEMCMP.
* modules/wmemcmp (configure.ac): Consider REPLACE_WMEMCMP.
* doc/posix-functions/wmemcmp.texi: Mention the bug.
---
 ChangeLog| 13 +
 doc/posix-functions/wmemcmp.texi |  4 +++
 lib/wchar.in.h   | 16 +--
 lib/wmemcmp-impl.h   |  5 ++--
 m4/wchar_h.m4|  3 +-
 m4/wmemcmp.m4| 49 +++-
 modules/wchar|  1 +
 modules/wmemcmp  |  3 +-
 8 files changed, 87 insertions(+), 7 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 4b8c72490b..6e885d865c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2023-04-18  Bruno Haible  
+
+	wmemcmp: Work around ISO C compliance bug on several platforms.
+	* lib/wchar.in.h (wmemcmp): Consider REPLACE_WMEMCMP.
+	* lib/wmemcmp-impl.h (wmemcmp): Don't assume that the two wide
+	characters are in the range 0..INT_MAX.
+	* m4/wmemcmp.m4 (gl_FUNC_WMEMCMP): Test whether wmemcmp works for all
+	wide characters. Set REPLACE_WMEMCMP.
+	* m4/wchar_h.m4 (gl_WCHAR_H_DEFAULTS): Initialize REPLACE_WMEMCMP.
+	* modules/wchar (Makefile.am): Substitute REPLACE_WMEMCMP.
+	* modules/wmemcmp (configure.ac): Consider REPLACE_WMEMCMP.
+	* doc/posix-functions/wmemcmp.texi: Mention the bug.
+
 2023-04-18  Bruno Haible  
 
 	doc: Update platform list for posix_spawnp.
diff --git a/doc/posix-functions/wmemcmp.texi b/doc/posix-functions/wmemcmp.texi
index 8d3262c5cb..cebacfb664 100644
--- a/doc/posix-functions/wmemcmp.texi
+++ b/doc/posix-functions/wmemcmp.texi
@@ -11,6 +11,10 @@
 @item
 This function is missing on some platforms:
 HP-UX 11.00, IRIX 6.5, MSVC 14.
+@item
+This function compares the wide characters as if they were unsigned, although
+@code{wchar_t} is signed, on some platforms:
+glibc 2.14.1 on x86 or x86_64, musl libc 1.2.3, NetBSD 9.0, OpenBSD 7.2, Solaris 11.4.
 @end itemize
 
 Portability problems not fixed by Gnulib:
diff --git a/lib/wchar.in.h b/lib/wchar.in.h
index 80b6652e95..6a5b18d39d 100644
--- a/lib/wchar.in.h
+++ b/lib/wchar.in.h
@@ -641,13 +641,25 @@ _GL_WARN_ON_USE (wmemchr, "wmemchr is unportable - "
 
 /* Compare N wide characters of S1 and S2.  */
 #if @GNULIB_WMEMCMP@
-# if !@HAVE_WMEMCMP@
+# if @REPLACE_WMEMCMP@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef wmemcmp
+#   define wmemcmp rpl_wmemcmp
+#  endif
+_GL_FUNCDECL_RPL (wmemcmp, int,
+  (const wchar_t *s1, const wchar_t *s2, size_t n)
+  _GL_ATTRIBUTE_PURE);
+_GL_CXXALIAS_RPL (wmemcmp, int,
+  (const wchar_t *s1, const wchar_t *s2, size_t n));
+# else
+#  if !@HAVE_WMEMCMP@
 _GL_FUNCDECL_SYS (wmemcmp, int,
   (const wchar_t *s1, const wchar_t *s2, size_t n)
   _GL_ATTRIBUTE_PURE);
-# endif
+#  endif
 _GL_CXXALIAS_SYS (wmemcmp, int,
   (const wchar_t *s1, const wchar_t *s2, size_t n));
+# endif
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (wmemcmp);
 # endif
diff --git a/lib/wmemcmp-impl.h b/lib/wmemcmp-impl.h
index 2b8125fe26..6148220de7 100644
--- a/lib/wmemcmp-impl.h
+++ b/lib/wmemcmp-impl.h
@@ -27,8 +27,9 @@ wmemcmp (const wchar_t *s1, const wchar_t 

Re: doc: Clarify list of platforms for year2038 support

2023-04-11 Thread Paul Eggert

On 4/11/23 06:45, Adhemerval Zanella Netto wrote:


It makes difference on all ABIs with has originally 32 bit time_t support:
i686, microblaze, arm, m68k, sh, csky, nios2, and hppa, powerpc32, sparc32,
s390, and mips o32.


Thanks, I installed the attached. It also mentions Android, which still 
supports a 32-bit ABI though rumors are it's going away in Android 14; 
see <https://chromeunboxed.com/pixel-7-series-no-32-bit-apps>.


As I'm not sure about the difference between your "mips o32" and the 
doc's "mips (32-bit or n32 ABI)", I left the doc alone there.From eebb3a74aecc84cc2a316015ca58dc8ba3f35875 Mon Sep 17 00:00:00 2001
From: Paul Eggert 
Date: Tue, 11 Apr 2023 14:54:20 -0700
Subject: [PATCH] doc: update year2038 list further
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Prompted by Adhemerval Zanella Netto’s email in:
https://lists.gnu.org/r/bug-gnulib/2023-04/msg00083.html
Also, mention 32-bit Android.
* doc/year2038.texi: Mention Linux/ork1 and Android.
Append "32" to powerpc and sparc names.
---
 ChangeLog | 9 +
 doc/year2038.texi | 6 --
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index a37429f7f6..c80d5587e8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2023-04-11  Paul Eggert  
+
+	doc: update year2038 list further
+	Prompted by Adhemerval Zanella Netto’s email in:
+	https://lists.gnu.org/r/bug-gnulib/2023-04/msg00083.html
+	Also, mention 32-bit Android.
+	* doc/year2038.texi: Mention Linux/ork1 and Android.
+	Append "32" to powerpc and sparc names.
+
 2023-04-11  Bruno Haible  
 
 	Fix the "make sc_prohibit_AC_LIBOBJ_in_m4" findings.
diff --git a/doc/year2038.texi b/doc/year2038.texi
index 626729578f..4dac00bf56 100644
--- a/doc/year2038.texi
+++ b/doc/year2038.texi
@@ -58,11 +58,11 @@ in bi-arch systems):
 @itemize
 @item
 Linux kernel 5.1 (2019) and later with glibc 2.34 (2021) and later on
-x86, arm, mips (32-bit or n32 ABI), powerpc, sparc, s390, hppa, m68k, sh, csky, microblaze, nios2,
+x86, arm, mips (32-bit or n32 ABI), powerpc32, sparc32, s390, hppa, m68k, sh, csky, microblaze, nios2,
 @item
 Linux kernel 5.1 (2019) and later with musl libc 1.2 (2020) and later on x86,
 @item
-Linux on arc, loong32, riscv32 and x86_64-x32,
+Linux on arc, loong32, ork1, riscv32 and x86_64-x32,
 @item
 NetBSD 6.0 (2012) and later on x86 and sparc,
 @item
@@ -81,6 +81,8 @@ platforms or ABIs:
 
 @itemize
 @item
+Android,
+@item
 Mac OS X 10.6 (2009) and earlier on x86 and powerpc,
 @item
 GNU/Hurd/x86,
-- 
2.39.2



Re: today's Gnulib autoupdate changed quoting style in INSTALL?

2024-01-07 Thread Paul Eggert

On 2024-01-07 15:07, Karl Berry wrote:
I'm using makeinfo 7.1. Maybe that is the difference? 


Yes, thanks, that explains it. I installed the attached patch to work 
around the quoting style glitch. With the patch, things should work fine 
the next time you run autoupdate with a changed doc/install.texi.




Wouldn't it be better for INSTALL to be (entirely) 7-bit ASCII instead
of UTF-8, given the existence of INSTALL.UTF-8? Otherwise, what's the
point of INSTALL.UTF-8?


The idea was that there are two variants, INSTALL.ISO (which is ASCII 
only) and INSTALL.UTF-8 (which uses UTF-8). INSTALL was originally a 
copy of INSTALL.ISO, but in June we changed this because support for 
UTF-8 is now universal and searching for apostrophes is not all that 
common in that file.




it's a lot easier to grep ASCII.


True, but people don't normally use commands like ‘grep "'" INSTALL’.

I also found directed quotes to be an irritation when using Emacs. 
However, there's a partial workaround. Put this into your init file:


(setq search-default-mode 'char-fold-to-regexp)

With this setting, interactive searching for ' will also find directed 
single quotes, and likewise for similar glitches. You can also use M-s ' 
within an interactive search to toggle char-fold-to-regexp. This may 
help to reduce (though of course not eliminate) the irritation. For 
more, see:


https://www.gnu.org/software/emacs/manual/html_node/emacs/Lax-Search.htmlFrom 267184ec9a060c088e1feab717120e43911485e5 Mon Sep 17 00:00:00 2001
From: Paul Eggert 
Date: Sun, 7 Jan 2024 16:54:12 -0800
Subject: [PATCH] doc: adjust to texinfo 7.1

* doc/Makefile (MAKEINFO): Adjust to texinfo 7.1, where makeinfo
by default outputs ASCII approximations to characters.
---
 ChangeLog| 6 ++
 doc/Makefile | 8 +---
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 4e2f4b73fb..8bfff58a1c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2024-01-07  Paul Eggert  
+
+	doc: adjust to texinfo 7.1
+	* doc/Makefile (MAKEINFO): Adjust to texinfo 7.1, where makeinfo
+	by default outputs ASCII approximations to characters.
+
 2024-01-02  Bruno Haible  
 
 	strverscmp: Work around bug in musl libc 1.2.3 and in Cygwin.
diff --git a/doc/Makefile b/doc/Makefile
index 19e3c34dde..2cb1dc2e77 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -9,9 +9,11 @@ doc = gnulib
 
 lang_env = env LANG= LC_MESSAGES= LC_ALL= LANGUAGE=
 makeinfo_prog = makeinfo
-# The customization variable CHECK_NORMAL_MENU_STRUCTURE is necessary with
-# makeinfo versions ≥ 6.8.
-MAKEINFO = $(lang_env) $(makeinfo_prog) -c CHECK_NORMAL_MENU_STRUCTURE=1
+# ASCII_DASHES_AND_QUOTES=0 is needed for makeinfo versions ≥ 7.1.
+# CHECK_NORMAL_MENU_STRUCTURE=1 is needed for makeinfo versions ≥ 6.8.
+MAKEINFO = $(lang_env) $(makeinfo_prog) \
+ -c ASCII_DASHES_AND_QUOTES=0 \
+ -c CHECK_NORMAL_MENU_STRUCTURE=1
 
 manual_opts = --no-split --reference-limit=2000
 TEXI2HTML = $(MAKEINFO) $(manual_opts) --html
-- 
2.40.1



Re: bug#70070: FAIL: test-localtime_r

2024-03-30 Thread Paul Eggert

On 3/29/24 08:15, Andreas Schwab wrote:

On Mär 29 2024, Bruno Haible wrote:


Yes. And make sure that it has a time zone database installed at all.


Why? That doesn't make any sense.


Although Andreas is not clear, perhaps he is alluding to the fact that 
Gnulib's localtime_r tests assume that TZ='Europe/Paris' stands for 
Paris time. POSIX doesn't guarantee this, so the implication is that the 
tests should be skipped when Europe/Paris does not work.


I installed the attached to do that. I don't know whether this will fix 
Andreas's problem, whatever it is.From f130f5426ecd4edd5596797e0a5721b927f80126 Mon Sep 17 00:00:00 2001
From: Paul Eggert 
Date: Sat, 30 Mar 2024 13:28:01 -0600
Subject: [PATCH] time_r-tests: skip French tests if no Europe/Paris

* tests/test-localtime_r.c (main):
* tests/test-localtime_r-mt.c (main):
If TZ='Europe/Paris' does not work, skip these tests.
---
 ChangeLog   |  7 +++
 tests/test-localtime_r-mt.c | 21 +
 tests/test-localtime_r.c| 21 +
 3 files changed, 49 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index eab98607a2..ecb4632196 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2024-03-30  Paul Eggert  
+
+	time_r-tests: skip French tests if no Europe/Paris
+	* tests/test-localtime_r.c (main):
+	* tests/test-localtime_r-mt.c (main):
+	If TZ='Europe/Paris' does not work, skip these tests.
+
 2024-03-29  Paul Eggert  
 
 	intprops: pacify GCC < 10 -Wsign-compare
diff --git a/tests/test-localtime_r-mt.c b/tests/test-localtime_r-mt.c
index ae371a8946..b09e86854f 100644
--- a/tests/test-localtime_r-mt.c
+++ b/tests/test-localtime_r-mt.c
@@ -107,6 +107,27 @@ main (int argc, char *argv[])
 {
   setenv ("TZ", FRENCH_TZ, 1);
 
+  /* Check that this TZ works.  */
+  {
+time_t t = 0; /* 1970-01-01 01:00:00 */
+struct tm *result = localtime ();
+if (! (result
+   && result->tm_sec == 0
+   && result->tm_min == 0
+   && result->tm_hour == 1
+   && result->tm_mday == 1
+   && result->tm_mon == 1 - 1
+   && result->tm_year == 1970 - 1900
+   && result->tm_wday == 4
+   && result->tm_yday == 0
+   && result->tm_isdst == 0))
+  {
+fputs ("Skipping test: TZ='Europe/Paris' is not Paris time\n",
+   stderr);
+return 77;
+  }
+  }
+
   /* Create the threads.  */
   gl_thread_create (thread1_func, NULL);
   gl_thread_create (thread2_func, NULL);
diff --git a/tests/test-localtime_r.c b/tests/test-localtime_r.c
index 70ec3b5d4f..6b3da1af19 100644
--- a/tests/test-localtime_r.c
+++ b/tests/test-localtime_r.c
@@ -43,6 +43,27 @@ main (void)
 {
   setenv ("TZ", FRENCH_TZ, 1);
 
+  /* Check that this TZ works.  */
+  {
+time_t t = 0; /* 1970-01-01 01:00:00 */
+struct tm *result = localtime ();
+if (! (result
+   && result->tm_sec == 0
+   && result->tm_min == 0
+   && result->tm_hour == 1
+   && result->tm_mday == 1
+   && result->tm_mon == 1 - 1
+   && result->tm_year == 1970 - 1900
+   && result->tm_wday == 4
+   && result->tm_yday == 0
+   && result->tm_isdst == 0))
+  {
+fputs ("Skipping test: TZ='Europe/Paris' is not Paris time\n",
+   stderr);
+return 77;
+  }
+  }
+
   /* Note: The result->tm_gmtoff values and the result->tm_zone values are the
  same (3600, "CET" or 7200, "CEST") across all tested platforms:
  glibc, musl, macOS, FreeBSD, NetBSD, OpenBSD, Minix, Cygwin, Android.  */
-- 
2.44.0



Re: quotearg: shell escape issue with single quote

2024-03-31 Thread Bruno Haible
Pádraig Brady wrote:
> > If a string starts with a sequence that requires $'' quoting followed
> > by a \' and then another charactrer requiring $'' quoting, the '$' at
> > the start of the quoted string ends up missing:
> > 
> >  $ env printf '%q\n' $'\1\'\2'
> >  '\001'\'''$'\002'
> 
> Indeed that is a bug.
> I'll be able to have a look at this tomorrow.

The '$' at the beginning is only missing in specific cases:

$ ./printf '%q\n' $'\1\'\2'
'\001'\'''$'\002'
$ ./printf '%q\n' $'a\1\'\2'
'''a'$'\001'\'''$'\002'
$ ./printf '%q\n' $'\1\'\2x'
''$'\001'\'''$'\002''x'

Also, let me apply some documentation improvement to the .h file (attached).

Bruno

>From 4d694d878f8792d510f5d30eaaf9d51c7b48ca10 Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Sun, 31 Mar 2024 22:56:14 +0200
Subject: [PATCH] quotearg: Improve documentation.

* lib/quotearg.h: Refer to specification of $'...' syntax. Document a
limitation of QA_ELIDE_OUTER_QUOTES.
---
 ChangeLog  |  6 ++
 lib/quotearg.h | 12 +---
 2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index ffae5513ae..182a894039 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2024-03-31  Bruno Haible  
+
+	quotearg: Improve documentation.
+	* lib/quotearg.h: Refer to specification of $'...' syntax. Document a
+	limitation of QA_ELIDE_OUTER_QUOTES.
+
 2024-03-31  Bruno Haible  
 
 	canonicalize[-lgpl] tests: Fix test failure on musl libc.
diff --git a/lib/quotearg.h b/lib/quotearg.h
index 4e9099fff4..202b79f33e 100644
--- a/lib/quotearg.h
+++ b/lib/quotearg.h
@@ -80,7 +80,8 @@ enum quoting_style
 
 /* Quote names for the shell if they contain shell metacharacters
or other problematic characters (ls --quoting-style=shell-escape).
-   Non printable characters are quoted using the $'...' syntax,
+   Non printable characters are quoted using the $'...' syntax
+   <https://www.gnu.org/software/bash/manual/html_node/ANSI_002dC-Quoting.html>,
which originated in ksh93 and is widely supported by most shells,
and proposed for inclusion in POSIX.
 
@@ -95,7 +96,8 @@ enum quoting_style
 
 /* Quote names for the shell even if they would normally not
require quoting (ls --quoting-style=shell-escape).
-   Non printable characters are quoted using the $'...' syntax,
+   Non printable characters are quoted using the $'...' syntax
+   <https://www.gnu.org/software/bash/manual/html_node/ANSI_002dC-Quoting.html>,
which originated in ksh93 and is widely supported by most shells,
and proposed for inclusion in POSIX.  Behaves like
shell_escape_quoting_style if QA_ELIDE_OUTER_QUOTES is in effect.
@@ -253,7 +255,11 @@ enum quoting_flags
 
 /* Omit the surrounding quote characters if no escaped characters
are encountered.  Note that if no other character needs
-   escaping, then neither does the escape character.  */
+   escaping, then neither does the escape character.
+   *Attention!*  This flag is unsupported in combination with the styles
+   shell_escape_quoting_style and shell_escape_always_quoting_style
+   (because in this situation it cannot handle strings that start
+   with a non-printable character).  */
 QA_ELIDE_OUTER_QUOTES = 0x02,
 
 /* In the c_quoting_style and c_maybe_quoting_style, split ANSI
-- 
2.34.1



Update HACKING

2024-04-23 Thread Bruno Haible
Let me add a bit more advice to the HACKING file.


2024-04-23  Bruno Haible  

Update HACKING.
* HACKING: Mention the linear git history, how to work with ChangeLog,
how to run a testdir, where to find the gnulib-tool tests, and where are
the continuous integrations.

diff --git a/HACKING b/HACKING
index 74f298081d..7a23a33982 100644
--- a/HACKING
+++ b/HACKING
@@ -14,10 +14,30 @@ Using git
   to update the copyright year of each modified file (since we don't run
   "make update-copyright" on the stable branches).
 
+* We use a linear git history — no merges. To work in this setting, it's
+  recommended that you configure git with 'git config pull.rebase = true'.
+
+* Before pushing a commit, it is highly recommended that you review it in
+  its entirety. The easiest way to do so is to run
+$ gitk
+
 * We update the ChangeLog by hand.  The commit message is usually identical
   to the ChangeLog entry, with the date and author line removed, with
   the leading tabs removed, and with a blank line after the commit's
   summary line.
+  In order to work efficiently with ChangeLog files, it is recommended that
+  you configure git to use the git-merge-changelog driver; see the instructions
+  in the lib/git-merge-changelog.c file.
+  Note: This driver reasonably keeps the ChangeLog entries together; however,
+  it does not always keep them in the order you would desire. For example,
+  when you had prepared a commit, you try to "git push" it but that fails due
+  to someone else's commit that came earlier, what you need to do is:
+1. $ git pull
+2. Verify that your ChangeLog entry is still the top-most one.
+3. If it is not, then edit ChangeLog to move it to the top, and
+   $ git commit --amend ChangeLog
+4. $ gitk
+5. $ git push
 
 * When you commit a contributor's patch, please
   - add a reasonable ChangeLog entry in the usual style (meaningful
@@ -52,6 +72,30 @@ When adding a module, add a unit test module as well.  This 
is our best
 chance to catch portability problems.
 
 
+Maintaining high quality
+
+
+It is a good idea to occasionally create a testdir of all of Gnulib:
+  $ rm -rf ../testdir-all; ./gnulib-tool --create-testdir --dir=../testdir-all 
--with-c++-tests --without-privileged-tests --single-configure `./all-modules`
+and test this directory on various plaforms:
+  - Linux/glibc systems,
+  - Linux/musl systems,
+  - macOS,
+  - FreeBSD,
+  - NetBSD,
+  - OpenBSD,
+  - AIX,
+  - Solaris 10 and 11,
+  - Cygwin,
+  - Haiku,
+  - Android,
+  - and other platforms of your choice.
+
+There is a continuous integration that regularly performs this testing
+on a Linux/glibc system: https://gitlab.com/gnulib/gnulib-ci
+But this will catch only the most blatant mistakes.
+
+
 Warning Options
 ===
 
@@ -519,6 +563,29 @@ Again, use your own judgement to determine whether to fix 
or ignore a
 specific warning.
 
 
+Information for gnulib-tool maintenance
+***
+
+Running the unit tests
+==
+
+The unit tests of gnulib-tool reside in the maint-tools repository, that is a
+satellite repository of the main gnulib repository. Instructions how to obtain
+it are in https://savannah.gnu.org/git/?group=gnulib .
+
+To run the unit tests of gnulib-tool.sh:
+  $ cd maint-tools/gnulib-tool-tests/
+  $ GNULIB_TOOL_IMPL=sh ./test-all.sh
+
+To run the unit tests of gnulib-tool.py:
+  $ cd maint-tools/gnulib-tool-tests/
+  $ GNULIB_TOOL_IMPL=py ./test-all.sh
+
+It is *mandatory* that you run the test suite before pushing any change to
+gnulib-tool.sh or gnulib-tool.py! If you fail to do so, and your change 
contains
+a bug, it will start to affect users immediately.
+
+
 Debugging the Python implementation of gnulib-tool
 ==
 
@@ -571,3 +638,10 @@ With Eclipse and PyDev as IDE
   - Open GLImport.py.
   - On the left-hand border of this editor, do "Add breakpoint".
   - Run > Debug Configurations... > pick the duplicate. Press Debug.
+
+
+Maintaining high quality
+
+
+There is a continuous integration of gnulib-tool.py that runs the unit tests,
+at https://gitlab.com/gnulib/gnulib-tool-ci/ .






*printf-posix: ISO C 23: Add %b directive for binary output of integers

2023-03-17 Thread Bruno Haible
  |  13 +-
 doc/posix-functions/vwprintf.texi|  13 +-
 doc/posix-functions/wprintf.texi |  13 +-
 lib/printf-parse.c   |   2 +-
 lib/printf-parse.h   |   2 +-
 lib/vasnprintf.c | 213 +++
 lib/wprintf-parse.h  |   2 +-
 m4/dprintf-posix.m4  |  32 ++--
 m4/fprintf-posix.m4  |  32 ++--
 m4/obstack-printf-posix.m4   |  32 ++--
 m4/printf.m4 | 186 
 m4/snprintf-posix.m4 |  42 +++--
 m4/sprintf-posix.m4  |  32 ++--
 m4/vasnprintf-posix.m4   |  36 ++--
 m4/vasnprintf.m4 |  18 +-
 m4/vasnwprintf-posix.m4  |   3 +-
 m4/vasprintf-posix.m4|  36 ++--
 m4/vdprintf-posix.m4 |  32 ++--
 m4/vfprintf-posix.m4 |  32 ++--
 m4/vsnprintf-posix.m4|  42 +++--
 m4/vsprintf-posix.m4 |  32 ++--
 tests/test-snprintf-posix.h  |  68 
 tests/test-sprintf-posix.h   |  68 
 tests/test-vasnprintf-posix.c|  93 ++
 tests/test-vasnwprintf-posix.c   |  93 ++
 tests/test-vasprintf-posix.c |  93 ++
 44 files changed, 1166 insertions(+), 256 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 62dd39e17f..173cd45bff 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,56 @@
+2023-03-17  Bruno Haible  
+
+	*printf-posix: ISO C 23: Add %b directive for binary output of integers.
+	* lib/printf-parse.c (PRINTF_PARSE): Recognize the 'b' directive.
+	* lib/printf-parse.h: Update comment.
+	* lib/wprintf-parse.h: Likewise.
+	* lib/vasnprintf.c (MAX_ROOM_NEEDED, VASNPRINTF): Add support for the
+	'b' directive.
+	* m4/printf.m4 (gl_PRINTF_DIRECTIVE_B): New macro.
+	* m4/vasnprintf.m4 (gl_PREREQ_VASNPRINTF_DIRECTIVE_B): New macro.
+	(gl_PREREQ_VASNPRINTF_WITH_EXTRAS): Invoke it.
+	* m4/vasnwprintf-posix.m4 (gl_FUNC_VASNWPRINTF_POSIX): Invoke
+	gl_PREREQ_VASNPRINTF_DIRECTIVE_B.
+	* m4/dprintf-posix.m4 (gl_FUNC_DPRINTF_POSIX): Require
+	gl_PRINTF_DIRECTIVE_B and test its result. Invoke
+	gl_PREREQ_VASNPRINTF_DIRECTIVE_B.
+	* m4/fprintf-posix.m4 (gl_FUNC_FPRINTF_POSIX): Likewise.
+	* m4/obstack-printf-posix.m4 (gl_FUNC_OBSTACK_PRINTF_POSIX): Likewise.
+	* m4/snprintf-posix.m4 (gl_FUNC_SNPRINTF_POSIX): Likewise.
+	* m4/sprintf-posix.m4 (gl_FUNC_SPRINTF_POSIX): Likewise.
+	* m4/vasnprintf-posix.m4 (gl_FUNC_VASNPRINTF_POSIX): Likewise.
+	* m4/vasprintf-posix.m4 (gl_FUNC_VASPRINTF_POSIX): Likewise.
+	* m4/vdprintf-posix.m4 (gl_FUNC_VDPRINTF_POSIX): Likewise.
+	* m4/vfprintf-posix.m4 (gl_FUNC_VFPRINTF_POSIX): Likewise.
+	* m4/vsnprintf-posix.m4 (gl_FUNC_VSNPRINTF_POSIX): Likewise.
+	* m4/vsprintf-posix.m4 (gl_FUNC_VSPRINTF_POSIX): Likewise.
+	* tests/test-snprintf-posix.h (test_function): Add some tests of the %b
+	directive.
+	* tests/test-sprintf-posix.h (test_function): Likewise.
+	* tests/test-vasnprintf-posix.c (test_function): Likewise.
+	* tests/test-vasnwprintf-posix.c (test_function): Likewise.
+	* tests/test-vasprintf-posix.c (test_function): Likewise.
+	* doc/glibc-functions/asprintf.texi: Mention the 'b' directive.
+	* doc/glibc-functions/obstack_printf.texi: Likewise.
+	* doc/glibc-functions/obstack_vprintf.texi: Likewise.
+	* doc/glibc-functions/vasprintf.texi: Likewise.
+	* doc/posix-functions/dprintf.texi: Likewise.
+	* doc/posix-functions/fprintf.texi: Likewise.
+	* doc/posix-functions/fwprintf.texi: Likewise.
+	* doc/posix-functions/printf.texi: Likewise.
+	* doc/posix-functions/snprintf.texi: Likewise.
+	* doc/posix-functions/sprintf.texi: Likewise.
+	* doc/posix-functions/swprintf.texi: Likewise.
+	* doc/posix-functions/vdprintf.texi: Likewise.
+	* doc/posix-functions/vfprintf.texi: Likewise.
+	* doc/posix-functions/vfwprintf.texi: Likewise.
+	* doc/posix-functions/vprintf.texi: Likewise.
+	* doc/posix-functions/vsnprintf.texi: Likewise.
+	* doc/posix-functions/vsprintf.texi: Likewise.
+	* doc/posix-functions/vswprintf.texi: Likewise.
+	* doc/posix-functions/vwprintf.texi: Likewise.
+	* doc/posix-functions/wprintf.texi: Likewise.
+
 2023-03-17  Bruno Haible  
 
 	vasnprintf, vasnwprintf: Simplify code.
diff --git a/doc/glibc-functions/asprintf.texi b/doc/glibc-functions/asprintf.texi
index 93d092d795..47708c40fb 100644
--- a/doc/glibc-functions/asprintf.texi
+++ b/doc/glibc-functions/asprintf.texi
@@ -41,6 +41,11 @@
 platforms:
 glibc-2.3.6, Mac OS X 10.5, NetBSD 9.0, OpenBSD 4.0, Solaris 11.4, Cygwin 1.5.x.
 @item
+This function does not support the @samp{b} directive, required by ISO C23,
+on some platforms:
+glibc 2.34, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
+AIX 7.2, Solaris 11.4, Cygwin 2.9.0.
+@item
 This function does not support the @samp{F} directive on some platforms:
 NetBSD 3.0, Cygwin 1.5.x.
 @item
d

Re: gl_{,SN}PRINTF_DIRECTIVE_N wrongly fail on Ubuntu 18.04

2020-03-08 Thread Bruno Haible
it a/doc/posix-functions/vprintf.texi b/doc/posix-functions/vprintf.texi
index 09d9e2b..0cb573c 100644
--- a/doc/posix-functions/vprintf.texi
+++ b/doc/posix-functions/vprintf.texi
@@ -30,6 +30,7 @@ NetBSD 3.0, AIX 5.1, HP-UX 11.23, IRIX 6.5, Solaris 9,
 Cygwin 1.5.x, mingw, MSVC 14.
 @item
 This function does not support the @samp{n} directive on some platforms:
+glibc when used with @code{_FORTIFY_SOURCE >= 2} (set by default on Ubuntu),
 MSVC 14.
 @item
 This function does not support the @samp{ls} directive on some platforms:
diff --git a/doc/posix-functions/vsnprintf.texi 
b/doc/posix-functions/vsnprintf.texi
index de5258d..8f2f410 100644
--- a/doc/posix-functions/vsnprintf.texi
+++ b/doc/posix-functions/vsnprintf.texi
@@ -75,6 +75,7 @@ This function does not truncate the result as specified in 
C99 on some platforms
 mingw, MSVC 14.
 @item
 This function does not fully support the @samp{n} directive on some platforms:
+glibc when used with @code{_FORTIFY_SOURCE >= 2} (set by default on Ubuntu),
 HP-UX 11, mingw, MSVC 14.
 @item
 This function overwrites memory even when a zero size argument is passed on 
some
diff --git a/doc/posix-functions/vsprintf.texi 
b/doc/posix-functions/vsprintf.texi
index 71da5cc..4e264c7 100644
--- a/doc/posix-functions/vsprintf.texi
+++ b/doc/posix-functions/vsprintf.texi
@@ -30,6 +30,7 @@ NetBSD 3.0, AIX 5.1, HP-UX 11.23, IRIX 6.5, Solaris 9,
 Cygwin 1.5.x, mingw, MSVC 14.
 @item
 This function does not support the @samp{n} directive on some platforms:
+glibc when used with @code{_FORTIFY_SOURCE >= 2} (set by default on Ubuntu),
 MSVC 14.
 @item
 This function does not support the @samp{ls} directive on some platforms:
diff --git a/m4/printf.m4 b/m4/printf.m4
index 9df2153..54a2d71 100644
--- a/m4/printf.m4
+++ b/m4/printf.m4
@@ -1,4 +1,4 @@
-# printf.m4 serial 62
+# printf.m4 serial 63
 dnl Copyright (C) 2003, 2007-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -711,6 +711,16 @@ int main ()
 [gl_cv_func_printf_directive_n=yes],
 [gl_cv_func_printf_directive_n=no],
 [case "$host_os" in
+# Guess no on glibc when _FORTIFY_SOURCE >= 2.
+   *-gnu* | gnu*)   AC_COMPILE_IFELSE(
+  [AC_LANG_SOURCE(
+ [[#if _FORTIFY_SOURCE >= 2
+error fail
+   #endif
+ ]])],
+  [gl_cv_func_printf_directive_n="guessing yes"],
+  [gl_cv_func_printf_directive_n="guessing no"])
+;;
 # Guess no on Android.
linux*-android*) gl_cv_func_printf_directive_n="guessing no";;
 # Guess no on native Windows.
@@ -1414,8 +1424,16 @@ int main ()
 [
 changequote(,)dnl
  case "$host_os" in
- # Guess yes on glibc systems.
-   *-gnu* | gnu*)gl_cv_func_snprintf_directive_n="guessing 
yes";;
+ # Guess no on glibc when _FORTIFY_SOURCE >= 2.
+   *-gnu* | gnu*)AC_COMPILE_IFELSE(
+   [AC_LANG_SOURCE(
+  [[#if _FORTIFY_SOURCE >= 2
+ error fail
+#endif
+  ]])],
+   [gl_cv_func_snprintf_directive_n="guessing 
yes"],
+   [gl_cv_func_snprintf_directive_n="guessing 
no"])
+ ;;
  # Guess yes on musl systems.
*-musl*)  gl_cv_func_snprintf_directive_n="guessing 
yes";;
  # Guess yes on FreeBSD >= 5.




gettimeofday: Remove workaround for Mac OS X 10.0

2020-07-26 Thread Bruno Haible
received a copy of the GNU General Public License
-   along with this program; if not, see <https://www.gnu.org/licenses/>.  */
-
-/* written by Jim Meyering */
-
-#include 
-
-#if GETTIMEOFDAY_CLOBBERS_LOCALTIME
-
-/* The address of the last buffer returned by localtime() or gmtime().  */
-extern struct tm *localtime_buffer_addr;
-
-#endif
diff --git a/lib/localtime.c b/lib/localtime.c
index 9070993..f5e6767 100644
--- a/lib/localtime.c
+++ b/lib/localtime.c
@@ -19,18 +19,15 @@
 /* Specification.  */
 #include 
 
-/* Keep consistent with localtime-buffer.c!  */
-#if !GETTIMEOFDAY_CLOBBERS_LOCALTIME
+#include 
+#include 
 
-# include 
-# include 
-
-# undef localtime
+#undef localtime
 
 struct tm *
 rpl_localtime (const time_t *tp)
 {
-# if defined _WIN32 && ! defined __CYGWIN__
+#if defined _WIN32 && ! defined __CYGWIN__
   /* Rectify the value of the environment variable TZ.
  There are four possible kinds of such values:
- Traditional US time zone names, e.g. "PST8PDT".  Syntax: see
@@ -56,9 +53,7 @@ rpl_localtime (const time_t *tp)
   const char *tz = getenv ("TZ");
   if (tz != NULL && strchr (tz, '/') != NULL)
 _putenv ("TZ=");
-# endif
+#endif
 
   return localtime (tp);
 }
-
-#endif
diff --git a/m4/gettimeofday.m4 b/m4/gettimeofday.m4
index c72b3ea..578ed49 100644
--- a/m4/gettimeofday.m4
+++ b/m4/gettimeofday.m4
@@ -1,4 +1,4 @@
-# serial 27
+# serial 28
 
 # Copyright (C) 2001-2003, 2005, 2007, 2009-2020 Free Software Foundation, Inc.
 # This file is free software; the Free Software Foundation
@@ -19,7 +19,6 @@ AC_DEFUN([gl_FUNC_GETTIMEOFDAY],
   if test $ac_cv_func_gettimeofday != yes; then
 HAVE_GETTIMEOFDAY=0
   else
-gl_FUNC_GETTIMEOFDAY_CLOBBER
 AC_CACHE_CHECK([for gettimeofday with POSIX signature],
   [gl_cv_func_gettimeofday_posix_signature],
   [AC_COMPILE_IFELSE(
@@ -66,63 +65,5 @@ int gettimeofday (struct timeval *restrict, struct timezone 
*restrict);
  declaration of the second argument to gettimeofday.])
 ])
 
-
-dnl See if gettimeofday clobbers the static buffer that localtime uses
-dnl for its return value.  The gettimeofday function from Mac OS X 10.0.4
-dnl (i.e., Darwin 1.3.7) has this problem.
-dnl
-dnl If it does, then arrange to use gettimeofday and localtime only via
-dnl the wrapper functions that work around the problem.
-
-AC_DEFUN([gl_FUNC_GETTIMEOFDAY_CLOBBER],
-[
- AC_REQUIRE([gl_HEADER_SYS_TIME_H])
- AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
- AC_REQUIRE([gl_LOCALTIME_BUFFER_DEFAULTS])
-
- AC_CACHE_CHECK([whether gettimeofday clobbers localtime buffer],
-  [gl_cv_func_gettimeofday_clobber],
-  [AC_RUN_IFELSE(
- [AC_LANG_PROGRAM(
-[[#include 
-  #include 
-  #include 
-  #include 
-]],
-[[
-  time_t t = 0;
-  struct tm *lt;
-  struct tm saved_lt;
-  struct timeval tv;
-  lt = localtime ();
-  saved_lt = *lt;
-  gettimeofday (, NULL);
-  return memcmp (lt, _lt, sizeof (struct tm)) != 0;
-]])],
- [gl_cv_func_gettimeofday_clobber=no],
- [gl_cv_func_gettimeofday_clobber=yes],
- [# When cross-compiling:
-  case "$host_os" in
-   # Guess all is fine on glibc systems.
-*-gnu* | gnu*) gl_cv_func_gettimeofday_clobber="guessing no" ;;
-   # Guess all is fine on musl systems.
-*-musl*)   gl_cv_func_gettimeofday_clobber="guessing no" ;;
-   # Guess no on native Windows.
-mingw*)gl_cv_func_gettimeofday_clobber="guessing no" ;;
-   # If we don't know, obey --enable-cross-guesses.
-*) 
gl_cv_func_gettimeofday_clobber="$gl_cross_guess_inverted" ;;
-  esac
- ])])
-
- case "$gl_cv_func_gettimeofday_clobber" in
-   *yes)
- REPLACE_GETTIMEOFDAY=1
- AC_DEFINE([GETTIMEOFDAY_CLOBBERS_LOCALTIME], [1],
-   [Define if gettimeofday clobbers the localtime buffer.])
- gl_LOCALTIME_BUFFER_NEEDED
- ;;
- esac
-])
-
 # Prerequisites of lib/gettimeofday.c.
 AC_DEFUN([gl_PREREQ_GETTIMEOFDAY], [:])
diff --git a/m4/localtime-buffer.m4 b/m4/localtime-buffer.m4
deleted file mode 100644
index 09df3c9..000
--- a/m4/localtime-buffer.m4
+++ /dev/null
@@ -1,21 +0,0 @@
-# localtime-buffer.m4 serial 1
-dnl Copyright (C) 2017-2020 Free Software Foundation, Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-
-AC_DEFUN([gl_LOCALTIME_BUFFER_DEFAULTS],
-[
-  NEED_LOCALTIME_BUFFER=0
-])
-
-dnl Macro invoked from other modules, to signal that the compilation of
-dnl module 'localtime-buffer' is needed.
-AC_DEFUN([gl_LOCALTIME_BUFFER_NEEDED],
-[
-  AC_REQUIRE([gl_LOCALTIME_BUFFER_DEFAULTS])
-  AC_REQUIRE(

fenv-*: Port to Haiku

2023-11-05 Thread Bruno Haible
On Haiku/x86_64, version hrev57363 or newer, I see this test failure:

FAIL test-fenv-except-state-2 (exit status: 149)

Looking at it in the debugger, it crashes at an 'fld1' instruction, here:

  /* Do a harmless floating-point operation (since on some CPUs, floating-point
 exceptions trigger a trap only at the next floating-point operation).  */
  a = 1.0; b = a + a;  // < HERE

This means, the function fesetexceptflag() triggers a floating-point
exception, although it shouldn't.

This hypothesis can be verified by rebuilding with the configure arguments
  gl_cv_func_fesetexceptflag_works1=no gl_cv_func_fesetexceptflag_works2=no

So, this patch fixes it. Likewise on Haiku/i386 (r1beta4 from 2022).


2023-11-05  Bruno Haible  

fenv-exceptions-trapping: Avoid test failure on Haiku/i386.
* tests/test-fenv-except-trapping-2.c (main): Skip the '4' tests also on
Haiku/i386.

fenv-exceptions-state: Fix test failure on Haiku/i386 and Haiku/x86_64.
* m4/fenv-exceptions-state.m4 (gl_FENV_EXCEPTIONS_STATE): Arrange to
override fesetexceptflag() on Haiku.
* doc/posix-functions/fesetexceptflag.texi: Mention the Haiku bug.



>From 057858a26b333132ec878f21d60ebfee47053d4d Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Sun, 5 Nov 2023 22:16:38 +0100
Subject: [PATCH 1/2] fenv-exceptions-state: Fix test failure on Haiku/i386 and
 Haiku/x86_64.

* m4/fenv-exceptions-state.m4 (gl_FENV_EXCEPTIONS_STATE): Arrange to
override fesetexceptflag() on Haiku.
* doc/posix-functions/fesetexceptflag.texi: Mention the Haiku bug.
---
 ChangeLog| 7 +++
 doc/posix-functions/fesetexceptflag.texi | 2 +-
 m4/fenv-exceptions-state.m4  | 7 ++-
 3 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index dd3661fffd..0f5821ac4d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2023-11-05  Bruno Haible  
+
+	fenv-exceptions-state: Fix test failure on Haiku/i386 and Haiku/x86_64.
+	* m4/fenv-exceptions-state.m4 (gl_FENV_EXCEPTIONS_STATE): Arrange to
+	override fesetexceptflag() on Haiku.
+	* doc/posix-functions/fesetexceptflag.texi: Mention the Haiku bug.
+
 2023-11-05  Bruno Haible  
 
 	fenv: Add C++ tests.
diff --git a/doc/posix-functions/fesetexceptflag.texi b/doc/posix-functions/fesetexceptflag.texi
index 66075be675..3523dbb8f8 100644
--- a/doc/posix-functions/fesetexceptflag.texi
+++ b/doc/posix-functions/fesetexceptflag.texi
@@ -17,7 +17,7 @@
 glibc 2.37/i386, glibc 2.37/x86_64,
 @c https://sourceware.org/bugzilla/show_bug.cgi?id=30988
 glibc 2.37/powerpc,
-musl libc, Mac OS X 10.5, mingw.
+musl libc, Mac OS X 10.5, mingw, Haiku.
 @item
 This function clears too many floating-point exception flags on
 @c https://sourceware.org/bugzilla/show_bug.cgi?id=30998
diff --git a/m4/fenv-exceptions-state.m4 b/m4/fenv-exceptions-state.m4
index bd443be721..3cd09edd11 100644
--- a/m4/fenv-exceptions-state.m4
+++ b/m4/fenv-exceptions-state.m4
@@ -58,7 +58,8 @@ AC_DEFUN([gl_FENV_EXCEPTIONS_STATE]
   AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
   gl_MATHFUNC([feenableexcept], [int], [(int)], [#include ])
   dnl On glibc 2.37 for PowerPC, i386, x86_64, fesetexceptflag may raise
-  dnl traps. Likewise on Mac OS X 10.5.8 on i386, x86_64 and on mingw.
+  dnl traps. Likewise on Mac OS X 10.5.8 on i386, x86_64, on mingw, and
+  dnl on Haiku on i386, x86_64.
   AC_CACHE_CHECK([whether fesetexceptflag is guaranteed non-trapping],
 [gl_cv_func_fesetexceptflag_works1],
 [if test $gl_cv_func_feenableexcept_no_libm = yes \
@@ -129,6 +130,10 @@ AC_DEFUN([gl_FENV_EXCEPTIONS_STATE]
  [gl_cv_func_fesetexceptflag_works1="guessing no"],
  [gl_cv_func_fesetexceptflag_works1="guessing yes"])
;;
+ # Guess no on Haiku.
+ haiku*)
+   gl_cv_func_fesetexceptflag_works1="guessing no"
+   ;;
  *) gl_cv_func_fesetexceptflag_works1="guessing yes" ;;
esac
  fi
-- 
2.34.1

>From e28c0b311c5cc90ef4d441e88ae2e94adc9e3e2e Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Sun, 5 Nov 2023 22:22:35 +0100
Subject: [PATCH 2/2] fenv-exceptions-trapping: Avoid test failure on
 Haiku/i386.

* tests/test-fenv-except-trapping-2.c (main): Skip the '4' tests also on
Haiku/i386.
---
 ChangeLog   | 4 
 tests/test-fenv-except-trapping-2.c | 6 --
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 0f5821ac4d..0648ef3720 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2023-11-05  Bruno Haible  
 
+	fenv-exceptions-trapping: Avoid test failure on Haiku/i386.
+	* tests/test-fenv-except-trapping-2.c (main): Skip the '4' tests also on
+	Haiku/i386.
+
 	fenv-exceptions-state: Fix test failure on Haiku/i386 and Haiku/x86_64.
 	* m4/fenv-except

readutmp: On Cygwin and Windows, return the boot time

2023-08-11 Thread Bruno Haible
Windows has no utmp file. But it's possible to derive the boot time by looking
at the time stamp of a file, namely C:\pagefile.sys. This is the same trick as
used by Emacs (see emacs/nt/inc/ms-w32.h:BOOT_TIME_FILE).

Other ways to determine the boot time, through the event log, would also be
possible: Search for event 6005 [1][2].

[1] https://serverfault.com/questions/702828/
[2] 
https://www.renanrodrigues.com/post/how-to-find-out-the-last-time-windows-rebooted-and-started-up
[3] 
https://www.whatsupgold.com/blog/how-to-find-restart-info-for-machines-on-your-network-using-powershell-and-windows-event-logs


2023-08-11  Bruno Haible  

readutmp: On Cygwin and Windows, return the boot time.
* lib/readutmp.h (READ_UTMP_SUPPORTED): Define also on native Windows.
* lib/readutmp.c (desirable_utmp_entry): Ignore READ_UTMP_CHECK_PIDS on
Windows.
(read_utmp_from_file): Add a BOOT_TIME entry on Windows.

diff --git a/lib/readutmp.c b/lib/readutmp.c
index eabd3e7678..c19ec2f6b1 100644
--- a/lib/readutmp.c
+++ b/lib/readutmp.c
@@ -178,11 +178,13 @@ desirable_utmp_entry (STRUCT_UTMP const *ut, int options)
   bool user_proc = IS_USER_PROCESS (ut);
   if ((options & READ_UTMP_USER_PROCESS) && !user_proc)
 return false;
+# if !(defined __CYGWIN__ || defined _WIN32)
   if ((options & READ_UTMP_CHECK_PIDS)
   && user_proc
   && 0 < UT_PID (ut)
   && (kill (UT_PID (ut), 0) < 0 && errno == ESRCH))
 return false;
+# endif
 
   return true;
 }
@@ -359,7 +361,9 @@ read_utmp_from_file (char const *file, idx_t *n_entries, 
STRUCT_UTMP **utmp_buf,
 
   struct utmp_alloc a = {0};
 
-# if defined UTMP_NAME_FUNCTION /* glibc, musl, macOS, FreeBSD, NetBSD, Minix, 
AIX, IRIX, Solaris, Cygwin, Android */
+# if READUTMP_USE_SYSTEMD || HAVE_UTMPX_H || HAVE_UTMP_H
+
+#  if defined UTMP_NAME_FUNCTION /* glibc, musl, macOS, FreeBSD, NetBSD, 
Minix, AIX, IRIX, Solaris, Cygwin, Android */
 
   /* Ignore the return value for now.
  Solaris' utmpname returns 1 upon success -- which is contrary
@@ -369,17 +373,17 @@ read_utmp_from_file (char const *file, idx_t *n_entries, 
STRUCT_UTMP **utmp_buf,
 
   SET_UTMP_ENT ();
 
-#  if defined __linux__ && !defined __ANDROID__
+#   if defined __linux__ && !defined __ANDROID__
   bool file_is_utmp = (strcmp (file, UTMP_FILE) == 0);
   /* Timestamp of the "runlevel" entry, if any.  */
   struct timespec runlevel_ts = {0};
-#  endif
+#   endif
 
   void const *entry;
 
   while ((entry = GET_UTMP_ENT ()) != NULL)
 {
-#  if __GLIBC__ && _TIME_BITS == 64
+#   if __GLIBC__ && _TIME_BITS == 64
   /* This is a near-copy of glibc's struct utmpx, which stops working
  after the year 2038.  Unlike the glibc version, struct utmpx32
  describes the file format even if time_t is 64 bits.  */
@@ -410,9 +414,9 @@ read_utmp_from_file (char const *file, idx_t *n_entries, 
STRUCT_UTMP **utmp_buf,
 char ut_reserved[20];/* Reserved for future use.  */
   };
   struct utmpx32 const *ut = (struct utmpx32 const *) entry;
-#  else
+#   else
   struct UTMP_STRUCT_NAME const *ut = (struct UTMP_STRUCT_NAME const *) 
entry;
-#  endif
+#   endif
 
   struct timespec ts =
 #if (HAVE_UTMPX_H ? 1 : HAVE_STRUCT_UTMP_UT_TV)
@@ -452,17 +456,17 @@ read_utmp_from_file (char const *file, idx_t *n_entries, 
STRUCT_UTMP **utmp_buf,
 #endif
 UT_EXIT_E_TERMINATION (ut), UT_EXIT_E_EXIT (ut)
);
-#  if defined __linux__ && !defined __ANDROID__
+#   if defined __linux__ && !defined __ANDROID__
   if (file_is_utmp
   && memcmp (UT_USER (ut), "runlevel", strlen ("runlevel") + 1) == 0
   && memcmp (ut->ut_line, "~", strlen ("~") + 1) == 0)
 runlevel_ts = ts;
-#  endif
+#   endif
 }
 
   END_UTMP_ENT ();
 
-#  if defined __linux__ && !defined __ANDROID__
+#   if defined __linux__ && !defined __ANDROID__
   /* On Alpine Linux, UTMP_FILE is not filled.  It is always empty.
  So, fake a BOOT_TIME entry, by getting the time stamp of a file that
  gets touched only during the boot process.
@@ -519,9 +523,9 @@ read_utmp_from_file (char const *file, idx_t *n_entries, 
STRUCT_UTMP **utmp_buf,
 }
 }
 }
-#  endif
+#   endif
 
-#  if defined __ANDROID__
+#   if defined __ANDROID__
   /* On Android, there is no /var, and normal processes don't have access
  to system files.  Therefore use the kernel's uptime counter, although
  it produces wrong values after the date has been bumped in the running
@@ -565,9 +569,9 @@ read_utmp_from_file (char const *file, idx_t *n_entries, 
STRUCT_UTMP **utmp_buf,
 }
 }
 }
-#  endif
+#   endif
 
-# else /* old FreeBSD, OpenBSD, HP-UX */
+#  else /*

new module 'fenv-exceptions-state-c99'

2023-10-30 Thread Bruno Haible
This new module implements the ISO C 99 functions for saving and restoring the
floating-point exception flags.

The unit tests uncovered bugs in glibc, musl libc (*), macOS, AIX, mingw.

(*) The one on musl libc is a documented limitation.


2023-10-30  Bruno Haible  

fenv-exceptions-state-c99: Add tests.
* tests/test-fenv-except-state-1.c: New file.
* tests/test-fenv-except-state-2.c: New file.
* modules/fenv-exceptions-state-c99-tests: New file.

fenv-exceptions-state-c99: New module.
* lib/fenv.in.h (fegetexceptflag, fesetexceptflag): New declarations.
* lib/fenv-except-state-get.c: New file, baed on glibc.
* lib/fenv-except-state-set.c: New file, baed on glibc.
* m4/mathfunc.m4 (gl_MATHFUNC): Handle also the 'fexcept_t *' type.
* m4/fenv-exceptions-state.m4: New file.
* modules/fenv-exceptions-state-c99: New file.
* doc/posix-functions/fegetexceptflag.texi: Mention the new module.
* doc/posix-functions/fesetexceptflag.texi: Mention the new module and
the glibc, musl libc, macOS, AIX, mingw bugs.

From ee6460d256b0ba048ef5ecf39f028b10c9986b12 Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Mon, 30 Oct 2023 16:39:19 +0100
Subject: [PATCH 1/2] fenv-exceptions-state-c99: New module.

* lib/fenv.in.h (fegetexceptflag, fesetexceptflag): New declarations.
* lib/fenv-except-state-get.c: New file, baed on glibc.
* lib/fenv-except-state-set.c: New file, baed on glibc.
* m4/mathfunc.m4 (gl_MATHFUNC): Handle also the 'fexcept_t *' type.
* m4/fenv-exceptions-state.m4: New file.
* modules/fenv-exceptions-state-c99: New file.
* doc/posix-functions/fegetexceptflag.texi: Mention the new module.
* doc/posix-functions/fesetexceptflag.texi: Mention the new module and
the glibc, musl libc, macOS, AIX, mingw bugs.
---
 ChangeLog|  13 +
 doc/posix-functions/fegetexceptflag.texi |   8 +-
 doc/posix-functions/fesetexceptflag.texi |  23 +-
 lib/fenv-except-state-get.c  | 353 ++
 lib/fenv-except-state-set.c  | 597 +++
 lib/fenv.in.h|  49 +-
 m4/fenv-exceptions-state.m4  | 221 +
 m4/mathfunc.m4   |   6 +-
 modules/fenv-exceptions-state-c99|  43 ++
 9 files changed, 1302 insertions(+), 11 deletions(-)
 create mode 100644 lib/fenv-except-state-get.c
 create mode 100644 lib/fenv-except-state-set.c
 create mode 100644 m4/fenv-exceptions-state.m4
 create mode 100644 modules/fenv-exceptions-state-c99

diff --git a/ChangeLog b/ChangeLog
index 1fc40e4ae2..291e89ec60 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2023-10-30  Bruno Haible  
+
+	fenv-exceptions-state-c99: New module.
+	* lib/fenv.in.h (fegetexceptflag, fesetexceptflag): New declarations.
+	* lib/fenv-except-state-get.c: New file, baed on glibc.
+	* lib/fenv-except-state-set.c: New file, baed on glibc.
+	* m4/mathfunc.m4 (gl_MATHFUNC): Handle also the 'fexcept_t *' type.
+	* m4/fenv-exceptions-state.m4: New file.
+	* modules/fenv-exceptions-state-c99: New file.
+	* doc/posix-functions/fegetexceptflag.texi: Mention the new module.
+	* doc/posix-functions/fesetexceptflag.texi: Mention the new module and
+	the glibc, musl libc, macOS, AIX, mingw bugs.
+
 2023-10-30  Bruno Haible  
 
 	fenv-exceptions-tracking-{c99,c23}: Fix the x86_64 and i386 case.
diff --git a/doc/posix-functions/fegetexceptflag.texi b/doc/posix-functions/fegetexceptflag.texi
index 5b45fe8d26..58915e0530 100644
--- a/doc/posix-functions/fegetexceptflag.texi
+++ b/doc/posix-functions/fegetexceptflag.texi
@@ -4,15 +4,15 @@
 
 POSIX specification:@* @url{https://pubs.opengroup.org/onlinepubs/9699919799/functions/fegetexceptflag.html}
 
-Gnulib module: ---
+Gnulib module: fenv-exceptions-state-c99
 
 Portability problems fixed by Gnulib:
 @itemize
+@item
+This function is missing on some platforms:
+FreeBSD 6.0, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 5.1, IRIX 6.5, Solaris 9, Cygwin 1.7.7, MSVC 9, Android 4.4.
 @end itemize
 
 Portability problems not fixed by Gnulib:
 @itemize
-@item
-This function is missing on some platforms:
-FreeBSD 6.0, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 5.1, IRIX 6.5, Solaris 9, Cygwin 1.7.7, MSVC 9, Android 4.4.
 @end itemize
diff --git a/doc/posix-functions/fesetexceptflag.texi b/doc/posix-functions/fesetexceptflag.texi
index 5258d35099..66075be675 100644
--- a/doc/posix-functions/fesetexceptflag.texi
+++ b/doc/posix-functions/fesetexceptflag.texi
@@ -4,15 +4,30 @@
 
 POSIX specification:@* @url{https://pubs.opengroup.org/onlinepubs/9699919799/functions/fesetexceptflag.html}
 
-Gnulib module: ---
+Gnulib module: fenv-exceptions-state-c99
 
 Portability problems fixed by Gnulib:
 @itemize
+@item
+This function is missing on some platforms:
+FreeBSD 5.2.1, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 5.1, IRIX 6.5, Solaris 9, Cygwin 1.7.7, MSVC 9, Android 4.4.
+@item
+This function triggers

Re: free-posix: New module, renamed from 'free'

2020-12-19 Thread Bruno Haible
Paul Eggert wrote:
> > I'm adding a unit test for the "free() preserves errno" feature.
> 
> Thanks. Unfortunately the test fails on Ubuntu 20.10 (and I assume on other 
> GNU/Linux hosts). So I installed the attached patch to port the free-posix 
> module to GNU/Linux (!).

Thanks; I intended to propose this change and ask you whether it's OK with you.

I noted the test failure on:
  Linux 2.4.22 / glibc 2.3.2 (Fedora 1)
  Linux 4.4 / glibc 2.23 (Ubuntu 16.04)
  Linux 4.18 / glibc 2.28 (CentOS 8)
  Linux 5.8 / glibc 2.32 (Ubuntu 20.10)
as well as
  Linux 5.4.43 / musl libc 1.1.24 (Alpine Linux 3.12)

> Perhaps someday we can move the test to m4/free.m4 with AC_RUN_IFELSE, but 
> there's no rush if the problem is ubiquitous.

I don't think we will ever have a reliable AC_RUN_IFELSE test for this
feature, because to get free() on the failure path, often you need to put
the process into a near-out-of-memory state; on Linux this might kill other
processes, whereas on other OSes it may crash the entire machine.

Such a guarantee can only be given through documentation or by a code
inspection.

Also, I don't trust _POSIX_VERSION to be the right indicator, because we
have seen so often that a system has only some traits of a standard, but
not all. Even the glibc people do this, cf.
https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=c70824b9a4645c0ecd049da8cfdb2c28ae7ada23

Inspecting the various implementations of free() — in the source code or
with strace / truss — , here are my findings:

* OpenBSD is good since version 4.5, since they explicitly save errno.
  See
  
https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libc/stdlib/malloc.c.diff?r1=1.100=1.101=h

* Solaris (10, 11, OpenIndiana) is good, since malloc() only ever invokes
  brk(), not mmap(). Therefore free() does not make system calls.

* In various other BSDs, free() invokes munmap() without protecting errno.

* In glibc, there's also another risky code path: an experimental feature,
  where the first free() in a thread invokes malloc(). It should be possible
  to do a malloc() in the main thread, then exhaust nearly all of the ulimit,
  create a thread, and call free() of the block in this thread.

* Also, in glibc, the user can install their custom free() handler. As long
  as it is not documented that this free() handler must preserve errno, glibc
  free() cannot be considered safe either.


2020-12-19  Bruno Haible  

free-posix: Assume future POSIX compliance only on OpenBSD and Solaris.
* m4/free.m4 (gl_FUNC_FREE): Guess yes only on OpenBSD and Solaris.
Don't trust _POSIX_VERSION for this test.

diff --git a/m4/free.m4 b/m4/free.m4
index e7a7203..53df743 100644
--- a/m4/free.m4
+++ b/m4/free.m4
@@ -1,33 +1,43 @@
-# free.m4 serial 3
+# free.m4 serial 4
 # Copyright (C) 2003-2005, 2009-2020 Free Software Foundation, Inc.
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# Written by Paul Eggert.
+# Written by Paul Eggert and Bruno Haible.
 
 AC_DEFUN([gl_FUNC_FREE],
 [
   AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
+  AC_REQUIRE([AC_CANONICAL_HOST])
 
   dnl In the next release of POSIX, free must preserve errno.
   dnl https://www.austingroupbugs.net/view.php?id=385
   dnl https://sourceware.org/bugzilla/show_bug.cgi?id=17924
-  dnl For now, assume implementations other than glibc do not preserve errno
-  dnl unless they set _POSIX_VERSION to the next release number,
-  dnl whatever that happens to be.
+  dnl So far, we know of two platforms that do this:
+  dnl * OpenBSD >= 4.5, thanks to this commit:
+  dnl   
<https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libc/stdlib/malloc.c.diff?r1=1.100=1.101=h>
+  dnl * Solaris, because its malloc() implementation is based on brk(),
+  dnl   not mmap(); hence its free() implementation makes no system calls.
+  dnl For other platforms, you can only be sure if they state it in their
+  dnl documentation, or by code inspection of the free() implementation in 
libc.
   AC_CACHE_CHECK([whether free is known to preserve errno],
 [gl_cv_func_free_preserves_errno],
-[AC_COMPILE_IFELSE(
-   [AC_LANG_PROGRAM(
-  [[#include 
-  ]],
-  [[#if _POSIX_VERSION <= 200809
-  #error "'free' is not known to preserve errno"
-#endif
-  ]])],
-   [gl_cv_func_free_preserves_errno=yes],
-   [gl_cv_func_free_preserves_errno=no])
+[case "$host_os" in
+   # Say yes only if we know it.
+   openbsd* | solaris*)
+ gl_cv_func_free_preserves_errno=yes
+ ;;
+   # It's no on Linux, for implementations that call munmap(), due to
+   # /proc/sys/vm/max_map_count.
+   linux*)
+ gl_cv_func_free_preserves_errno=no
+ ;;
+   # If we don't know, obey --enable-c

Re: How can Autoconf help with the transition to stricter compilation defaults?

2022-11-11 Thread Sam James


> On 10 Nov 2022, at 17:16, Zack Weinberg  wrote:
> 
> I’m the closest thing Autoconf has to a lead maintainer at present.
> 
> It’s come to my attention (via https://lwn.net/Articles/913505/ and
> https://fedoraproject.org/wiki/Changes/PortingToModernC) that GCC and
> Clang both plan to disable several “legacy” C language features by
> default in a near-future release (GCC 14, Clang 16) (see the Fedora
> wiki link for a list).  I understand that this change potentially
> breaks a lot of old dusty code, and in particular that
> Autoconf-generated configure scripts use constructs that may *silently
> give the wrong answer to a probe* when a stricter compiler is in use.

Thank you for asking. The fixes in git get us there, I think, as far
as you can, with the exception of the stuff you (and I) mention below.

> 
> [...]
> 
> The biggest remaining (potential) problem, that I’m aware of, is that
> AC_CHECK_FUNC unconditionally declares the function we’re probing for
> as ‘char NAME (void)’, and asks the compiler to call it with no
> arguments, regardless of what its prototype actually is.  It is not
> clear to me whether this will still work with the planned changes to
> the compilers.  Both GCC 12 and Clang 14 have on-by-default warnings
> triggered by ‘extern char memcpy(void);’ (or any other standard
> library function whose prototype is coded into the compiler) and this
> already causes problems for people who run configure scripts with
> CC='cc -Werror'.  Unfortunately this is very hard to fix — we would
> have to build a comprehensive list of library functions into Autoconf,
> mapping each to either its documented prototype or to a header where
> it ought to be declared; in the latter case we would also have to make
> e.g. AC_CHECK_FUNCS([getaddrinfo]) imply AC_CHECK_HEADERS([sys/types.h
> sys/socket.h netdb.h]) which might mess up configure scripts that
> aren’t expecting headers to be probed at that point.
> 
> How important do you think it is for this to be fixed?
> 
> Are there any other changes you would like to see in a near-future
> Autoconf 2.72 in order to make this transition easier?

This might be a WONTFIX but let me mention it just for
the record:
1. AC_CHECK_FUNCS is, as you've noticed, very noisy.

I would support having a hardcoded list for certain CHOSTs
as Rich suggests to reduce noise, but I don't think we can
do this accurately very quickly.

I think for Gentoo's efforts, I might just build up a set
of cache variables for glibc/musl on each arch to
reduce the noise in logs. But that's time consuming
and brittle still, so I'm not sure.

(Note that Gentoo and Fedora are taking two complementary
but different approaches here:
we're diffing config.logs and other compiler
output, in addition to build logs, while Florian for Fedora
Is building a list of functions which *we know* are available
In a specific environment and patching gcc to spit out
logs when something in said list is missing. This mitigates
noise for things like functions in libbsd, which I'm finding
a bit of a pain.)

I'll see what others say.

2. I often have to set the following cache variables to
reduce noise in logs:
* ac_cv_c_undeclared_builtin_options="none needed"
* ac_cv_header_sys_types_h_makedev=no
* gl_cv_compiler_check_decl_option="-Werror=implicit-function-declaration" 
(obviously this is gnulib)
* gl_cv_minmax_in_limits_h=no

I don't know if we can do anything to make these tests smarter
or just leave it as-is. It's fine if we can't, as exporting the cache
vars is not a bad workaround for us when doing testing.

> 
> zw
> 
> p.s. GCC and Clang folks: As long as you’re changing the defaults out
> from under people, can you please also remove the last few predefined
> user-namespace macros (-Dlinux, -Dunix, -Darm, etc) from all the
> -std=gnuXX modes?

I support this as well. This kind of thing has led to endless
bugs in userland, see https://reviews.llvm.org/D137511.



signature.asc
Description: Message signed with OpenPGP


stdio: ISO C 23: Define _PRINTF_NAN_LEN_MAX

2023-03-25 Thread Bruno Haible
ISO C 23 specifies a new macro, to be defined in : _PRINTF_NAN_LEN_MAX.

This patch implements it.


2023-03-25  Bruno Haible  

stdio: ISO C 23: Define _PRINTF_NAN_LEN_MAX.
* lib/stdio.in.h (_PRINTF_NAN_LEN_MAX): New macro.
* m4/stdio_h.m4 (gl_STDIO_H): Invoke gl_MUSL_LIBC.
* modules/stdio (Files): Add m4/musl.m4.
* tests/test-stdio.c: Check that _PRINTF_NAN_LEN_MAX is defined.
Include nan.h, macros.h.
(main): Check the value of _PRINTF_NAN_LEN_MAX.
* modules/stdio-tests (Files): Add tests/nan.h, tests/macros.h,
m4/exponentd.m4.
(configure.ac): Invoke gl_DOUBLE_EXPONENT_LOCATION.

diff --git a/lib/stdio.in.h b/lib/stdio.in.h
index 098f841738..0ed3e7595c 100644
--- a/lib/stdio.in.h
+++ b/lib/stdio.in.h
@@ -204,6 +204,37 @@
 # undef putc_unlocked
 #endif
 
+
+/* Maximum number of characters produced by printing a NaN value.  */
+#ifndef _PRINTF_NAN_LEN_MAX
+# if defined __FreeBSD__ || defined __DragonFly__ \
+ || defined __NetBSD__ \
+ || defined __OpenBSD__ \
+ || (defined __APPLE__ && defined __MACH__)
+/* On BSD systems, a NaN value prints as just "nan", without a sign.  */
+#  define _PRINTF_NAN_LEN_MAX 3
+# elif (__GLIBC__ >= 2) || MUSL_LIBC || defined __sun || defined __CYGWIN__
+/* glibc, musl libc, Solaris libc, and Cygwin produce "[-]nan".  */
+#  define _PRINTF_NAN_LEN_MAX 4
+# elif defined _AIX
+/* AIX produces "[-]NaNQ".  */
+#  define _PRINTF_NAN_LEN_MAX 5
+# elif defined _WIN32 && !defined __CYGWIN__
+/* On native Windows, the output can be:
+   - with MSVC ucrt: "[-]nan" or "[-]nan(ind)" or "[-]nan(snan)",
+   - with mingw: "[-]1.#IND" or "[-]1.#QNAN".  */
+#  define _PRINTF_NAN_LEN_MAX 10
+# elif defined __sgi
+/* On IRIX, the output typically is "[-]nan0x" with 8 hexadecimal
+   digits.  */
+#  define _PRINTF_NAN_LEN_MAX 14
+# else
+/* We don't know, but 32 should be a safe maximum.  */
+#  define _PRINTF_NAN_LEN_MAX 32
+# endif
+#endif
+
+
 #if @GNULIB_DPRINTF@
 # if @REPLACE_DPRINTF@
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
diff --git a/m4/stdio_h.m4 b/m4/stdio_h.m4
index 07569961f8..342b7d1f20 100644
--- a/m4/stdio_h.m4
+++ b/m4/stdio_h.m4
@@ -1,4 +1,4 @@
-# stdio_h.m4 serial 61
+# stdio_h.m4 serial 62
 dnl Copyright (C) 2007-2023 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -40,6 +40,9 @@ AC_DEFUN_ONCE([gl_STDIO_H]
attribute "__gnu_printf__" instead of "__printf__"])
   fi
 
+  dnl For defining _PRINTF_NAN_LEN_MAX.
+  gl_MUSL_LIBC
+
   dnl This ifdef is an optimization, to avoid performing a configure check 
whose
   dnl result is not used. But it does not make the test of
   dnl GNULIB_STDIO_H_NONBLOCKING or GNULIB_NONBLOCKING redundant.
diff --git a/modules/stdio b/modules/stdio
index b8662ef0a9..b4d866df9d 100644
--- a/modules/stdio
+++ b/modules/stdio
@@ -6,6 +6,7 @@ lib/stdio.in.h
 lib/stdio-read.c
 lib/stdio-write.c
 m4/stdio_h.m4
+m4/musl.m4
 
 Depends-on:
 extensions
diff --git a/modules/stdio-tests b/modules/stdio-tests
index 5368a2c64c..52b753e2f7 100644
--- a/modules/stdio-tests
+++ b/modules/stdio-tests
@@ -1,5 +1,8 @@
 Files:
 tests/test-stdio.c
+tests/nan.h
+tests/macros.h
+m4/exponentd.m4
 
 Depends-on:
 assert-h
@@ -10,6 +13,7 @@ fread-tests
 fwrite-tests
 
 configure.ac:
+gl_DOUBLE_EXPONENT_LOCATION
 
 Makefile.am:
 TESTS += test-stdio
diff --git a/tests/test-stdio.c b/tests/test-stdio.c
index a3b0a3e2ba..9794f4d856 100644
--- a/tests/test-stdio.c
+++ b/tests/test-stdio.c
@@ -23,6 +23,9 @@
 /* Check that the various SEEK_* macros are defined.  */
 int sk[] = { SEEK_CUR, SEEK_END, SEEK_SET };
 
+/* Check that the _PRINTF_NAN_LEN_MAX macro is defined.  */
+int pnlm[] = { _PRINTF_NAN_LEN_MAX };
+
 /* Check that NULL can be passed through varargs as a pointer type,
per POSIX 2008.  */
 static_assert (sizeof NULL == sizeof (void *));
@@ -34,8 +37,37 @@ size_t t3;
 ssize_t t4;
 va_list t5;
 
+#include 
+
+#include "nan.h"
+#include "macros.h"
+
 int
 main (void)
 {
+#if defined DBL_EXPBIT0_WORD && defined DBL_EXPBIT0_BIT
+  /* Check the value of _PRINTF_NAN_LEN_MAX.  */
+  {
+#define NWORDS \
+  ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
+typedef union { double value; unsigned int word[NWORDS]; } memory_double;
+
+double value1;
+memory_double value2;
+char buf[64];
+
+value1 = NaNd();
+sprintf (buf, "%g", value1);
+ASSERT (strlen (buf) <= _PRINTF_NAN_LEN_MAX);
+
+value2.value = NaNd ();
+#if DBL_EXPBIT0_BIT == 20
+value2.word[DBL_EXPBIT0_WORD] ^= 0x54321;
+#endif
+sprintf (buf, "%g", value2.value);
+ASSERT (strlen (buf) <= _PRINTF_NAN_LEN_MAX);
+  }
+#endif
+
   return 0;
 }






Re: vasnwprintf: Fix module dependencies

2023-03-20 Thread Bruno Haible
Yesterday I did:
> 2023-03-19  Bruno Haible  
> 
>   vasnwprintf: Fix module dependencies.
>   * modules/vasnwprintf (Depends-on): Add wmemcpy, wmemset.

Oops, this produces gnulib-tool warnings:

gnulib-tool: warning: module vasnwprintf-posix depends on a module with an 
incompatible license: wmemcpy
gnulib-tool: warning: module vasnwprintf-posix depends on a module with an 
incompatible license: wmemset

Fixed by relicensing these two modules under LGPLv2. (I am the only copyright-
relevant contributor to the files of these two modules.)


2023-03-20  Bruno Haible  

wmemset: Relicense under LGPLv2+.
* modules/wmemset (License): Change to LGPLv2+.
* lib/wmemset.c: Update license notice.
* lib/wmemset-impl.h: Likewise.

2023-03-20  Bruno Haible  

wmemcpy: Relicense under LGPLv2+.
* modules/wmemcpy (License): Change to LGPLv2+.
* lib/wmemcpy.c: Update license notice.
* lib/wmemcpy-impl.h: Likewise.

>From d8f3b7a5aecc81f83c2fb62a7e3e63c0b3998300 Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Mon, 20 Mar 2023 10:09:16 +0100
Subject: [PATCH 1/2] wmemcpy: Relicense under LGPLv2+.

* modules/wmemcpy (License): Change to LGPLv2+.
* lib/wmemcpy.c: Update license notice.
* lib/wmemcpy-impl.h: Likewise.
---
 ChangeLog  | 7 +++
 lib/wmemcpy-impl.h | 2 +-
 lib/wmemcpy.c  | 2 +-
 modules/wmemcpy| 2 +-
 4 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index e83875f2ee..83e9383f40 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2023-03-20  Bruno Haible  
+
+	wmemcpy: Relicense under LGPLv2+.
+	* modules/wmemcpy (License): Change to LGPLv2+.
+	* lib/wmemcpy.c: Update license notice.
+	* lib/wmemcpy-impl.h: Likewise.
+
 2023-03-19  Bruno Haible  
 
 	vasnwprintf: Fix test failures on musl libc.
diff --git a/lib/wmemcpy-impl.h b/lib/wmemcpy-impl.h
index f0a7007506..c243acfa15 100644
--- a/lib/wmemcpy-impl.h
+++ b/lib/wmemcpy-impl.h
@@ -4,7 +4,7 @@
 
This file 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 3 of the
+   published by the Free Software Foundation; either version 2.1 of the
License, or (at your option) any later version.
 
This file is distributed in the hope that it will be useful,
diff --git a/lib/wmemcpy.c b/lib/wmemcpy.c
index 0cfe407a1a..082bfed9ef 100644
--- a/lib/wmemcpy.c
+++ b/lib/wmemcpy.c
@@ -4,7 +4,7 @@
 
This file 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 3 of the
+   published by the Free Software Foundation; either version 2.1 of the
License, or (at your option) any later version.
 
This file is distributed in the hope that it will be useful,
diff --git a/modules/wmemcpy b/modules/wmemcpy
index e45e94fe70..161762304e 100644
--- a/modules/wmemcpy
+++ b/modules/wmemcpy
@@ -23,7 +23,7 @@ Include:
 
 
 License:
-LGPL
+LGPLv2+
 
 Maintainer:
 all
-- 
2.34.1

>From d25f915afb66e63d32f1feec94a0a9bbc87ff8a8 Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Mon, 20 Mar 2023 10:09:57 +0100
Subject: [PATCH 2/2] wmemset: Relicense under LGPLv2+.

* modules/wmemset (License): Change to LGPLv2+.
* lib/wmemset.c: Update license notice.
* lib/wmemset-impl.h: Likewise.
---
 ChangeLog  | 7 +++
 lib/wmemset-impl.h | 2 +-
 lib/wmemset.c  | 2 +-
 modules/wmemset| 2 +-
 4 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 83e9383f40..7320f54be3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2023-03-20  Bruno Haible  
+
+	wmemset: Relicense under LGPLv2+.
+	* modules/wmemset (License): Change to LGPLv2+.
+	* lib/wmemset.c: Update license notice.
+	* lib/wmemset-impl.h: Likewise.
+
 2023-03-20  Bruno Haible  
 
 	wmemcpy: Relicense under LGPLv2+.
diff --git a/lib/wmemset-impl.h b/lib/wmemset-impl.h
index d2cc14ad42..2743469c04 100644
--- a/lib/wmemset-impl.h
+++ b/lib/wmemset-impl.h
@@ -4,7 +4,7 @@
 
This file 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 3 of the
+   published by the Free Software Foundation; either version 2.1 of the
License, or (at your option) any later version.
 
This file is distributed in the hope that it will be useful,
diff --git a/lib/wmemset.c b/lib/wmemset.c
index 72b9eb5f56..d83e07ba64 100644
--- a/lib/wmemset.c
+++ b/lib/wmemset.c
@@ -4,7 +4,7 @@
 
This file 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 3 of the
+   published by the Free Software Foundation; 

wcsncmp: Work around two ISO C compliance bugs on several platforms

2023-04-19 Thread Bruno Haible
Like wcscmp(), wcsncmp() has two ISO C compliance bugs on several platforms.
These two patches provide the workaround.

In particular, the module 'wcsncmp' is no longer obsolete.


2023-04-19  Bruno Haible  

wcsncmp: Add tests.
* tests/test-wcsncmp.c: New file, based on tests/unistr/test-strncmp.h
and tests/test-wcscmp.c.
* modules/wcsncmp-tests: New file.

wcsncmp: Work around two ISO C compliance bugs on several platforms.
* lib/wchar.in.h (wcsncmp): Consider REPLACE_WCSNCMP.
* lib/wcsncmp-impl.h (wcsncmp): Don't assume that the two wide
characters are in the range 0..INT_MAX.
* m4/wcsncmp.m4 (gl_FUNC_WCSNCMP): Test whether wcsncmp works for all
wide characters. Set REPLACE_WCSNCMP.
* m4/wchar_h.m4 (gl_WCHAR_H_DEFAULTS): Initialize REPLACE_WCSNCMP.
* modules/wchar (Makefile.am): Substitute REPLACE_WCSNCMP.
* modules/wcsncmp (Status, Notice): Un-obsolete this module.
(configure.ac): Consider REPLACE_WCSNCMP.
* doc/posix-functions/wcsncmp.texi: Mention the two bugs.

>From ccb59e4c36bea4915303a24ea1c7dec109db97eb Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Wed, 19 Apr 2023 17:59:03 +0200
Subject: [PATCH 1/2] wcsncmp: Work around two ISO C compliance bugs on several
 platforms.

* lib/wchar.in.h (wcsncmp): Consider REPLACE_WCSNCMP.
* lib/wcsncmp-impl.h (wcsncmp): Don't assume that the two wide
characters are in the range 0..INT_MAX.
* m4/wcsncmp.m4 (gl_FUNC_WCSNCMP): Test whether wcsncmp works for all
wide characters. Set REPLACE_WCSNCMP.
* m4/wchar_h.m4 (gl_WCHAR_H_DEFAULTS): Initialize REPLACE_WCSNCMP.
* modules/wchar (Makefile.am): Substitute REPLACE_WCSNCMP.
* modules/wcsncmp (Status, Notice): Un-obsolete this module.
(configure.ac): Consider REPLACE_WCSNCMP.
* doc/posix-functions/wcsncmp.texi: Mention the two bugs.
---
 ChangeLog| 14 
 doc/posix-functions/wcsncmp.texi |  8 +
 lib/wchar.in.h   | 16 +++--
 lib/wcsncmp-impl.h   |  5 +--
 m4/wchar_h.m4|  3 +-
 m4/wcsncmp.m4| 58 +++-
 modules/wchar|  1 +
 modules/wcsncmp  |  9 ++---
 8 files changed, 101 insertions(+), 13 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index a88dfc1d81..46cfb56ea2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2023-04-19  Bruno Haible  
+
+	wcsncmp: Work around two ISO C compliance bugs on several platforms.
+	* lib/wchar.in.h (wcsncmp): Consider REPLACE_WCSNCMP.
+	* lib/wcsncmp-impl.h (wcsncmp): Don't assume that the two wide
+	characters are in the range 0..INT_MAX.
+	* m4/wcsncmp.m4 (gl_FUNC_WCSNCMP): Test whether wcsncmp works for all
+	wide characters. Set REPLACE_WCSNCMP.
+	* m4/wchar_h.m4 (gl_WCHAR_H_DEFAULTS): Initialize REPLACE_WCSNCMP.
+	* modules/wchar (Makefile.am): Substitute REPLACE_WCSNCMP.
+	* modules/wcsncmp (Status, Notice): Un-obsolete this module.
+	(configure.ac): Consider REPLACE_WCSNCMP.
+	* doc/posix-functions/wcsncmp.texi: Mention the two bugs.
+
 2023-04-18  Bruno Haible  
 
 	wcscmp: Add tests.
diff --git a/doc/posix-functions/wcsncmp.texi b/doc/posix-functions/wcsncmp.texi
index b6282606ed..46874af46f 100644
--- a/doc/posix-functions/wcsncmp.texi
+++ b/doc/posix-functions/wcsncmp.texi
@@ -8,6 +8,14 @@
 
 Portability problems fixed by Gnulib:
 @itemize
+@item
+This function compares the wide characters as if they were unsigned, although
+@code{wchar_t} is signed, on some platforms:
+glibc 2.14.1 on x86 or x86_64, musl libc 1.2.3, macOS 12.5, FreeBSD 13.2, NetBSD 9.0, OpenBSD 7.2, Solaris 11.4.
+@item
+This function may return a wrong result if the two arguments are of different
+length, on some platforms:
+AIX 7.2 in 64-bit mode.
 @end itemize
 
 Portability problems not fixed by Gnulib:
diff --git a/lib/wchar.in.h b/lib/wchar.in.h
index c347256368..69fa2f8f59 100644
--- a/lib/wchar.in.h
+++ b/lib/wchar.in.h
@@ -967,13 +967,25 @@ _GL_WARN_ON_USE (wcscmp, "wcscmp is unportable - "
 
 /* Compare no more than N wide characters of S1 and S2.  */
 #if @GNULIB_WCSNCMP@
-# if !@HAVE_WCSNCMP@
+# if @REPLACE_WCSNCMP@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef wcsncmp
+#   define wcsncmp rpl_wcsncmp
+#  endif
+_GL_FUNCDECL_RPL (wcsncmp, int,
+  (const wchar_t *s1, const wchar_t *s2, size_t n)
+  _GL_ATTRIBUTE_PURE);
+_GL_CXXALIAS_RPL (wcsncmp, int,
+  (const wchar_t *s1, const wchar_t *s2, size_t n));
+# else
+#  if !@HAVE_WCSNCMP@
 _GL_FUNCDECL_SYS (wcsncmp, int,
   (const wchar_t *s1, const wchar_t *s2, size_t n)
   _GL_ATTRIBUTE_PURE);
-# endif
+#  endif
 _GL_CXXALIAS_SYS (wcsncmp, int,
   (const wchar_t *s1, const wchar_t *s2, size_t n));
+# endif
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (wcsncmp);
 # endif
diff --git a/lib/wcsncmp-impl.h b/lib/wcsncmp

*c32*: Inline most functions on glibc and musl libc

2023-04-04 Thread Bruno Haible
The type 'char32_t' is a more modern alternative to 'wchar_t', because it
solves the problems mentioned in
<https://www.gnu.org/software/libunistring/manual/html_node/The-wchar_005ft-mess.html>.
To make a migration from 'wchar_t' to 'char32_t' attractive, it is
important that on glibc and musl libc systems the 'char32_t' functions
are not slower than the 'wchar_t' functions.

This is achieved through the patch below, by inlining many functions.

At first, I wanted to use the common idiom for _GL_INLINE.
But it turns out that the idiom with
  #define _GL_UCHAR_INLINE _GL_INLINE
and a uchar.c file that defines
  #define _GL_UCHAR_INLINE _GL_EXTERN_INLINE
works only if all functions marked with _GL_UCHAR_INLINE belong to the
same module. If the .h file makes use of @GNULIB_xxx@ module indicators,
this idiom does not work:
Suppose function A is needed in lib, and function B is only needed in tests.
@GNULIB_A@ expands to 1, @GNULIB_B@ expands to IN_GNULIB_TESTS, i.e.
0 in lib/, 1 in tests/. When uchar.c is compiled, it therefore defines
A but not B in uchar.o. In tests/ uchar.c is not being compiled a second time.
So, we have no global definition of B, and the result is a link error.

The idiom that works is to keep each function in its own compilation unit.


2023-04-04  Bruno Haible  

*c32*: Inline most functions on glibc and musl libc.
* lib/uchar.in.h: Invoke _GL_INLINE_HEADER_BEGIN, _GL_INLINE_HEADER_END.
(btoc32): Inline if _GL_WCHAR_T_IS_UCS4.
(c32isalnum, c32isalpha, c32isblank, c32iscntrl, c32isdigit, c32isgraph,
c32islower, c32isprint, c32ispunct, c32isspace, c32isupper,
c32isxdigit): Inline if
_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t.
(c32snrtombs, c32srtombs, c32stombs, c32tob, mbsnrtoc32s, mbsrtoc32s,
mbstoc32s): Inline if _GL_WCHAR_T_IS_UCS4.
* lib/btoc32.c: Define compilation unit marker.
(btoc32): Conditionally mark as _GL_EXTERN_INLINE.
* lib/c32isalnum.c: Define compilation unit marker.
* lib/c32isalpha.c: Likewise.
* lib/c32isblank.c: Likewise.
* lib/c32iscntrl.c: Likewise.
* lib/c32isdigit.c: Likewise.
* lib/c32isgraph.c: Likewise.
* lib/c32islower.c: Likewise.
* lib/c32isprint.c: Likewise.
* lib/c32ispunct.c: Likewise.
* lib/c32isspace.c: Likewise.
* lib/c32isupper.c: Likewise.
* lib/c32isxdigit.c: Likewise.
* lib/c32is-impl.h (FUNC): Conditionally mark as _GL_EXTERN_INLINE.
* lib/c32snrtombs.c: Define compilation unit marker.
(c32snrtombs): Conditionally mark as _GL_EXTERN_INLINE.
* lib/c32srtombs.c: Define compilation unit marker.
(c32srtombs): Conditionally mark as _GL_EXTERN_INLINE.
* lib/c32stombs.c: Define compilation unit marker.
(c32stombs): Conditionally mark as _GL_EXTERN_INLINE.
* lib/c32tob.c: Define compilation unit marker.
(c32tob): Conditionally mark as _GL_EXTERN_INLINE.
* lib/mbsnrtoc32s.c: Define compilation unit marker.
(mbsnrtoc32s): Conditionally mark as _GL_EXTERN_INLINE.
* lib/mbsrtoc32s.c: Define compilation unit marker.
(mbsrtoc32s): Conditionally mark as _GL_EXTERN_INLINE.
* lib/mbstoc32s.c: Define compilation unit marker.
(mbstoc32s): Conditionally mark as _GL_EXTERN_INLINE.
* modules/uchar (Depends-on): Add extern-inline.

diff --git a/lib/btoc32.c b/lib/btoc32.c
index 9ba8fb5a5e..07fbe194b6 100644
--- a/lib/btoc32.c
+++ b/lib/btoc32.c
@@ -18,12 +18,16 @@
 
 #include 
 
+#define IN_BTOC32
 /* Specification.  */
 #include 
 
 #include 
 #include 
 
+#if _GL_WCHAR_T_IS_UCS4
+_GL_EXTERN_INLINE
+#endif
 wint_t
 btoc32 (int c)
 {
diff --git a/lib/c32is-impl.h b/lib/c32is-impl.h
index d5e5362c0b..8682a6897e 100644
--- a/lib/c32is-impl.h
+++ b/lib/c32is-impl.h
@@ -38,6 +38,9 @@
 
 #include "unictype.h"
 
+#if _GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t
+_GL_EXTERN_INLINE
+#endif
 int
 FUNC (wint_t wc)
 {
diff --git a/lib/c32isalnum.c b/lib/c32isalnum.c
index 6127d99148..c3ab2b8299 100644
--- a/lib/c32isalnum.c
+++ b/lib/c32isalnum.c
@@ -24,6 +24,7 @@
 
 #include 
 
+#define IN_C32ISALNUM
 /* Specification.  */
 #include 
 
diff --git a/lib/c32isalpha.c b/lib/c32isalpha.c
index 4041bed605..1462cf7083 100644
--- a/lib/c32isalpha.c
+++ b/lib/c32isalpha.c
@@ -24,6 +24,7 @@
 
 #include 
 
+#define IN_C32ISALPHA
 /* Specification.  */
 #include 
 
diff --git a/lib/c32isblank.c b/lib/c32isblank.c
index cae38e29f9..edd79e8963 100644
--- a/lib/c32isblank.c
+++ b/lib/c32isblank.c
@@ -24,6 +24,7 @@
 
 #include 
 
+#define IN_C32ISBLANK
 /* Specification.  */
 #include 
 
diff --git a/lib/c32iscntrl.c b/lib/c32iscntrl.c
index 48288eb112..b067aacb1b 100644
--- a/lib/c32iscntrl.c
+++ b/lib/c32iscntrl.c
@@ -24,6 +24,7 @@
 
 #include 
 
+#define IN_C32ISCNTRL
 /* Specification.  */
 #include 
 
diff --git a/lib/c32isdigit.c b/l

unistr/u*strstr tests: Add more tests

2023-04-02 Thread Bruno Haible
In <https://lists.gnu.org/archive/html/bug-gnulib/2018-09/msg00070.html>
and <https://lists.gnu.org/archive/html/bug-gnulib/2023-03/msg00129.html>
I added more tests to tests/test-strstr.c.

With this patch, I'm adding the same tests also to the libunistring *strstr
modules.


2023-04-02  Bruno Haible  

unistr/u*strstr tests: Add more tests.
* tests/unistr/test-u-strstr.h (test_u_strstr): Add the two latest tests
from tests/test-strstr.c.
* tests/unistr/test-u8-strstr.c (U_SET): New macro.
* tests/unistr/test-u16-strstr.c (U_SET): New macro.
* tests/unistr/test-u32-strstr.c (U_SET): New macro.
* modules/unistr/u8-strstr-tests (Depends-on): Add unistr/u8-set.
* modules/unistr/u16-strstr-tests (Depends-on): Add unistr/u16-set.
* modules/unistr/u32-strstr-tests (Depends-on): Add unistr/u32-set.

diff --git a/modules/unistr/u16-strstr-tests b/modules/unistr/u16-strstr-tests
index 5c3cfbff8d..3e77e8af4a 100644
--- a/modules/unistr/u16-strstr-tests
+++ b/modules/unistr/u16-strstr-tests
@@ -4,6 +4,7 @@ tests/unistr/test-u-strstr.h
 tests/macros.h
 
 Depends-on:
+unistr/u16-set
 
 configure.ac:
 AC_CHECK_DECLS_ONCE([alarm])
diff --git a/modules/unistr/u32-strstr-tests b/modules/unistr/u32-strstr-tests
index 8ec3124225..bccd5e602f 100644
--- a/modules/unistr/u32-strstr-tests
+++ b/modules/unistr/u32-strstr-tests
@@ -4,6 +4,7 @@ tests/unistr/test-u-strstr.h
 tests/macros.h
 
 Depends-on:
+unistr/u32-set
 
 configure.ac:
 AC_CHECK_DECLS_ONCE([alarm])
diff --git a/modules/unistr/u8-strstr-tests b/modules/unistr/u8-strstr-tests
index fdc7b76e12..23336d2184 100644
--- a/modules/unistr/u8-strstr-tests
+++ b/modules/unistr/u8-strstr-tests
@@ -4,6 +4,7 @@ tests/unistr/test-u-strstr.h
 tests/macros.h
 
 Depends-on:
+unistr/u8-set
 
 configure.ac:
 AC_CHECK_DECLS_ONCE([alarm])
diff --git a/tests/unistr/test-u-strstr.h b/tests/unistr/test-u-strstr.h
index b97badc005..639b3d9112 100644
--- a/tests/unistr/test-u-strstr.h
+++ b/tests/unistr/test-u-strstr.h
@@ -207,4 +207,42 @@ test_u_strstr (void)
 free (needle);
 free (haystack);
   }
+
+  /* Test case from Yves Bastide.
+ <https://www.openwall.com/lists/musl/2014/04/18/2>  */
+  {
+const UNIT input[] =
+  { 'p', 'l', 'a', 'y', 'i', 'n', 'g', ' ', 'p', 'l', 'a', 'y', ' ', 'p',
+'l', 'a', 'y', ' ', 'p', 'l', 'a', 'y', ' ', 'a', 'l', 'w', 'a', 'y',
+'s', 0
+  };
+const UNIT needle[] =
+  { 'p', 'l', 'a', 'y', ' ', 'p', 'l', 'a', 'y', ' ', 'p', 'l', 'a', 'y',
+0
+  };
+const UNIT *result = U_STRSTR (input, needle);
+ASSERT (result == input + 8);
+  }
+
+  /* Test long needles.  */
+  {
+size_t m = 1024;
+UNIT *haystack = (UNIT *) malloc ((2 * m + 1) * sizeof (UNIT));
+UNIT *needle = (UNIT *) malloc ((m + 1) * sizeof (UNIT));
+if (haystack != NULL && needle != NULL)
+  {
+const UNIT *p;
+haystack[0] = 'x';
+U_SET (haystack + 1, ' ', m - 1);
+U_SET (haystack + m, 'x', m);
+haystack[2 * m] = '\0';
+U_SET (needle, 'x', m);
+needle[m] = '\0';
+p = U_STRSTR (haystack, needle);
+ASSERT (p);
+ASSERT (p - haystack == m);
+  }
+free (needle);
+free (haystack);
+  }
 }
diff --git a/tests/unistr/test-u16-strstr.c b/tests/unistr/test-u16-strstr.c
index b5cd028ff6..9c49aa0496 100644
--- a/tests/unistr/test-u16-strstr.c
+++ b/tests/unistr/test-u16-strstr.c
@@ -29,6 +29,7 @@
 
 #define UNIT uint16_t
 #define U_STRSTR u16_strstr
+#define U_SET u16_set
 #include "test-u-strstr.h"
 
 int
diff --git a/tests/unistr/test-u32-strstr.c b/tests/unistr/test-u32-strstr.c
index 9f388127a5..134a3c5366 100644
--- a/tests/unistr/test-u32-strstr.c
+++ b/tests/unistr/test-u32-strstr.c
@@ -29,6 +29,7 @@
 
 #define UNIT uint32_t
 #define U_STRSTR u32_strstr
+#define U_SET u32_set
 #include "test-u-strstr.h"
 
 int
diff --git a/tests/unistr/test-u8-strstr.c b/tests/unistr/test-u8-strstr.c
index f11d9408c2..39f831b2ea 100644
--- a/tests/unistr/test-u8-strstr.c
+++ b/tests/unistr/test-u8-strstr.c
@@ -29,6 +29,7 @@
 
 #define UNIT uint8_t
 #define U_STRSTR u8_strstr
+#define U_SET u8_set
 #include "test-u-strstr.h"
 
 int






Re: MT-unsafe time modules

2024-02-11 Thread Bruno Haible
e_t t = 150903; /* 2017-10-26 06:40:03 */
+  struct tm tm;
+  struct tm *result = gmtime_r (, );
+  ASSERT (result == );
+  if (!(result->tm_sec == 3
+&& result->tm_min == 40
+&& result->tm_hour == 6
+&& result->tm_mday == 26
+&& result->tm_mon == 10 - 1
+&& result->tm_year == 2017 - 1900
+&& result->tm_wday == 4
+&& result->tm_yday == 298
+&& result->tm_isdst == 0))
+{
+  fprintf (stderr, "thread1 disturbed by thread2!\n"); fflush (stderr);
+  abort ();
+}
+}
+
+  /*NOTREACHED*/
+}
+
+static void *
+thread2_func (void *arg)
+{
+  for (;;)
+{
+  time_t t = 250005; /* 2033-05-18 17:26:45 */
+  struct tm tm;
+  struct tm *result = gmtime_r (, );
+  ASSERT (result == );
+  if (!(result->tm_sec == 45
+&& result->tm_min == 26
+&& result->tm_hour == 17
+&& result->tm_mday == 18
+&& result->tm_mon == 5 - 1
+&& result->tm_year == 2033 - 1900
+&& result->tm_wday == 3
+&& result->tm_yday == 137
+&& result->tm_isdst == 0))
+{
+  fprintf (stderr, "thread2 disturbed by thread1!\n"); fflush (stderr);
+  abort ();
+}
+}
+
+  /*NOTREACHED*/
+}
+
+int
+main (int argc, char *argv[])
+{
+  /* Create the threads.  */
+  gl_thread_create (thread1_func, NULL);
+  gl_thread_create (thread2_func, NULL);
+
+  /* Let them run for 1 second.  */
+  {
+struct timespec duration;
+duration.tv_sec = (argc > 1 ? atoi (argv[1]) : 1);
+duration.tv_nsec = 0;
+
+nanosleep (, NULL);
+  }
+
+  return 0;
+}
+
+#else
+
+/* No multithreading available.  */
+
+#include 
+
+int
+main ()
+{
+  fputs ("Skipping test: multithreading not enabled\n", stderr);
+  return 77;
+}
+
+#endif
diff --git a/tests/test-gmtime_r.c b/tests/test-gmtime_r.c
new file mode 100644
index 00..01eebf3c29
--- /dev/null
+++ b/tests/test-gmtime_r.c
@@ -0,0 +1,56 @@
+/* Test gmtime_r().
+   Copyright (C) 2024 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+/* Written by Bruno Haible , 2024.  */
+
+#include 
+
+/* Specification.  */
+#include 
+
+#include 
+
+#include "macros.h"
+
+int
+main (void)
+{
+  {
+time_t t = 150903; /* 2017-10-26 06:40:03 */
+struct tm tm;
+struct tm *result = gmtime_r (, );
+ASSERT (result == );
+ASSERT (result->tm_sec == 3);
+ASSERT (result->tm_min == 40);
+ASSERT (result->tm_hour == 6);
+ASSERT (result->tm_mday == 26);
+ASSERT (result->tm_mon == 10 - 1);
+ASSERT (result->tm_year == 2017 - 1900);
+ASSERT (result->tm_wday == 4);
+ASSERT (result->tm_yday == 298);
+ASSERT (result->tm_isdst == 0);
+#if HAVE_STRUCT_TM_TM_GMTOFF /* glibc, musl, macOS, FreeBSD, NetBSD, OpenBSD, Minix, Cygwin, Android */
+ASSERT (result->tm_gmtoff == 0);
+#endif
+#if HAVE_STRUCT_TM_TM_ZONE /* glibc, musl, macOS, FreeBSD, NetBSD, OpenBSD, Minix, Cygwin, Android */
+printf ("tm_zone = %s\n", result->tm_zone == NULL ? "(null)" : result->tm_zone);
+ASSERT (strcmp (result->tm_zone, "GMT") == 0 /* glibc, NetBSD, OpenBSD, Minix, Cygwin, Android */
+|| strcmp (result->tm_zone, "UTC") == 0 /* musl, macOS, FreeBSD */);
+#endif
+  }
+
+  return 0;
+}
diff --git a/tests/test-localtime_r-mt.c b/tests/test-localtime_r-mt.c
new file mode 100644
index 00..ae371a8946
--- /dev/null
+++ b/tests/test-localtime_r-mt.c
@@ -0,0 +1,139 @@
+/* Multithread-safety test for localtime_r().
+   Copyright (C) 2024 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FI

Re: autoreconf --force seemingly does not forcibly update everything

2024-04-09 Thread Bruno Haible
Sam James replied to Bruno Haible who cited Nick Bowler:
> >> If I distribute a release package, what I have tested is exactly what is
> >> in that package.  If you start replacing different versions of m4 macros,
> >> or use some distribution-patched autoconf/automake/libtool or whatever,
> >> then this you have invalidated any and all release testing.
> >
> > +1
> >
> > Last month, I spent 2 days on prerelease testing of coreutils. If, after
> > downloading the carefully prepared tarball from ftp.gnu.org, the first
> > thing a distro does is to throw away the *.m4 files and regenerate the
> > configure script with their own one,
> >   * It shows no respect for the QA work that the upstream developers have
> > put in.
> ...
> Nick poses that a specific combination of tools is what is tested and
> anything else invalidates it.

Correct. When an upstream developer/tester has tested a tarball in N
situations, then that tarball is what - he can guarantee - works. The
more changes a distro applies, the more they do so on their own risk.

> But how does this work when building on a
> system that was never tested on, or with different flags, or a different
> toolchain?

The interface of GNU 'configure' [1][2] accommodates for these cases.
In most of these cases, it is not needed to rebuild 'configure'. Just
set CC, CFLAGS, LDFLAGS etc.
  - For other systems: see [3].
  - System that is still in development: Replace config.guess, config.sub,
and potentially config.rpath with modified variants.
  - Different flags: That's what CFLAGS, CXXFLAGS are for.
  - Different compiler: E.g. clang on Ubuntu 22.04
CC="/inst-clang/17.0.4/bin/clang -Wl,-rpath,/inst-clang/17.0.4/lib"
CXX="/inst-clang/17.0.4/bin/clang++ -I/usr/include/c++/11 
-I/usr/include/x86_64-linux-gnu/c++/11 -L/usr/lib/gcc/x86_64-linux-gnu/11 
-Wl,-rpath,/inst-clang/17.0.4/lib"
  - Different linker: E.g. to link with 'mold' instead of 'ld',
create a directory /alternative-ld/with-mold that contains a symlink
ld -> /.../bin/mold
and use CC="gcc -B/alternative-ld/with-mold".

On exotic systems with non-ELF binary format, modifying libtool.m4 is needed.
But most distros are not in this situation; they use the glibc or musl dynamic
loader, hence they don't need libtool.m4 changes.

> It also has value in the context of software which is no longer
> maintained but needs to work on newer systems.

Granted; that's a different category of situation. Here a distro will
probably not only need to change *.m4 files but also *.c files. And
hopefully submit the changes upstream.

> We don't apply this rule to anything else -- you've never rejected a
> report from me because I have a newer version of a library installed
> like openssl or similar. Why is this different?

As an upstream maintainer, I have chosen (or, well, GNU has chosen for me,
even before I was present) to give *tarballs* to my users, not git
repositories. The main differences are that

  - tarballs contain some generated files for which we want to spare
the user the need to install special tools and get familiar with
them (code generators, doc formatters [texlive, doxygen, ...] etc.)

  - tarballs contain source code from other packages (git submodule,
parts of gnulib, etc.)

  - tarballs contain localizations, which are maintained elsewhere than
in the git repository (e.g. in translationproject.org or weblate
instances).

Experience has shown that this interface (tarballs with configure
script) allows for relatively effective support.

There are an entire bunch of questions from users of a git repository
(from "can you please commit the formatted documentation into git?"
over "how to I pull in the submodules?" to "why do I get this error
from flex?") that are obsoleted by this interface.

Also, too often people have reported problems with older versions of
the tools. I mean, we are at Automake 1.16.5, and if someone wants
to rebuild my package with Automake 1.13.4 because that's what his
distro is carrying, and they encounter problems, it is just a waste
of upstream developer's time. Old bugs in old versions of the tools
have been fixed. As an upstream maintainer, I don't want to support
  - different versions of Automake,
  - different versions of Bison,
  - different versions of texinfo,
  - different versionf of groff,
  - etc.
I have enough work supporting
  - different versions of the OS (glibc, Cygwin, etc.),
  - different versions of GNU make,
  - different versions of gcc and clang,
  - different versions of packages with optional support (--with-* options),
  - ...
Keep the test matrix small!

Bruno

[1] https://www.gnu.org/prep/standards/html_node/Configuration.html
[2] 
https://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.72/html_node/Preset-Output-Variables.html
[3] https://gitlab.com/ghwiki/gnow-how/-/wikis/Platforms/Configuration






new module 'fenv-exceptions-trapping'

2023-10-31 Thread Bruno Haible
These patches add a module 'fenv-exceptions-trapping', that portably implement
the GNU functions
  feenableexcept
  fedisableexcept
  fegetexcept   (a terrible misnomer, btw)

Again, the unit tests uncovered several problems on several platforms.


2023-10-31  Bruno Haible  

fenv-exceptions-trapping: Add tests.
* tests/test-fenv-except-trapping-1.c: New file.
* tests/test-fenv-except-trapping-2.sh: New file.
* tests/test-fenv-except-trapping-2.c: New file.
* modules/fenv-exceptions-trapping-tests: New file.

fenv-exceptions-trapping: New module.
* lib/fenv.in.h (feenableexcept, fedisableexcept, fegetexcept): New
declarations.
* lib/fenv-except-trapping.c: New file, based on glibc.
* m4/fenv_h.m4 (gl_FENV_H): Test also whether fegetexcept is declared.
* m4/fenv-exceptions-trapping.m4: New file.
* modules/fenv-exceptions-trapping: New file.
* doc/glibc-functions/fegetexcept.texi: Mention the new module.
* doc/glibc-functions/fedisableexcept.texi: Likewise.
* doc/glibc-functions/feenableexcept.texi: Likewise. Mention the glibc,
macOS, FreeBSD bugs.

From e5a52e29dfa5a292f9f94c56c9ed2f3c9ff189af Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Tue, 31 Oct 2023 21:46:13 +0100
Subject: [PATCH 1/2] fenv-exceptions-trapping: New module.

* lib/fenv.in.h (feenableexcept, fedisableexcept, fegetexcept): New
declarations.
* lib/fenv-except-trapping.c: New file, based on glibc.
* m4/fenv_h.m4 (gl_FENV_H): Test also whether fegetexcept is declared.
* m4/fenv-exceptions-trapping.m4: New file.
* modules/fenv-exceptions-trapping: New file.
* doc/glibc-functions/fegetexcept.texi: Mention the new module.
* doc/glibc-functions/fedisableexcept.texi: Likewise.
* doc/glibc-functions/feenableexcept.texi: Likewise. Mention the glibc,
macOS, FreeBSD bugs.
---
 ChangeLog|  14 +
 doc/glibc-functions/fedisableexcept.texi |   8 +-
 doc/glibc-functions/feenableexcept.texi  |  13 +-
 doc/glibc-functions/fegetexcept.texi |   8 +-
 lib/fenv-except-trapping.c   | 951 +++
 lib/fenv.in.h|  94 +++
 m4/fenv-exceptions-trapping.m4   | 117 +++
 m4/fenv_h.m4 |   3 +-
 modules/fenv-exceptions-trapping |  40 +
 9 files changed, 1236 insertions(+), 12 deletions(-)
 create mode 100644 lib/fenv-except-trapping.c
 create mode 100644 m4/fenv-exceptions-trapping.m4
 create mode 100644 modules/fenv-exceptions-trapping

diff --git a/ChangeLog b/ChangeLog
index 0476828c50..f7d1a2237e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2023-10-31  Bruno Haible  
+
+	fenv-exceptions-trapping: New module.
+	* lib/fenv.in.h (feenableexcept, fedisableexcept, fegetexcept): New
+	declarations.
+	* lib/fenv-except-trapping.c: New file, based on glibc.
+	* m4/fenv_h.m4 (gl_FENV_H): Test also whether fegetexcept is declared.
+	* m4/fenv-exceptions-trapping.m4: New file.
+	* modules/fenv-exceptions-trapping: New file.
+	* doc/glibc-functions/fegetexcept.texi: Mention the new module.
+	* doc/glibc-functions/fedisableexcept.texi: Likewise.
+	* doc/glibc-functions/feenableexcept.texi: Likewise. Mention the glibc,
+	macOS, FreeBSD bugs.
+
 2023-10-30  Bruno Haible  
 
 	fenv-exceptions-state-c99: Fix the x86_64 and i386 case.
diff --git a/doc/glibc-functions/fedisableexcept.texi b/doc/glibc-functions/fedisableexcept.texi
index 8b41ae4d87..d26397f44f 100644
--- a/doc/glibc-functions/fedisableexcept.texi
+++ b/doc/glibc-functions/fedisableexcept.texi
@@ -17,15 +17,15 @@
 @uref{https://www.kernel.org/doc/man-pages/online/pages/man3/fedisableexcept.3.html,,man fedisableexcept}.
 @end itemize
 
-Gnulib module: ---
+Gnulib module: fenv-exceptions-trapping
 
 Portability problems fixed by Gnulib:
 @itemize
+@item
+This function is missing on some platforms:
+macOS 11.1, musl libc, FreeBSD 5.2.1, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 5.1, HP-UX 11, IRIX 6.5, Solaris 11.4, Cygwin 1.7.7, mingw, MSVC 14, Android 4.4.
 @end itemize
 
 Portability problems not fixed by Gnulib:
 @itemize
-@item
-This function is missing on some platforms:
-macOS 11.1, FreeBSD 5.2.1, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 5.1, HP-UX 11, IRIX 6.5, Solaris 11.4, Cygwin 1.7.7, mingw, MSVC 14, Android 4.4.
 @end itemize
diff --git a/doc/glibc-functions/feenableexcept.texi b/doc/glibc-functions/feenableexcept.texi
index dfca91f2a7..a858b4d6c6 100644
--- a/doc/glibc-functions/feenableexcept.texi
+++ b/doc/glibc-functions/feenableexcept.texi
@@ -17,15 +17,22 @@
 @uref{https://www.kernel.org/doc/man-pages/online/pages/man3/feenableexcept.3.html,,man feenableexcept}.
 @end itemize
 
-Gnulib module: ---
+Gnulib module: fenv-exceptions-trapping
 
 Portability problems fixed by Gnulib:
 @itemize
+@item
+This function is missing on some platforms:
+macOS 11.1, musl libc, FreeBSD 5.2.1, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 5.1, HP-UX

getpass: move declaration to

2018-08-19 Thread Bruno Haible
The 'getpass' module provides a replacement for a glibc function.
In glibc the header file for this function is . In gnulib,
so far, the user has to include "getpass.h" instead - simply because
this module predates the 'unistd' module.

This patch moves the declaration into , to match glibc.


2018-08-19  Bruno Haible  

getpass: Move declaration to .
* lib/unistd.in.h (getpass): New declaration.
* lib/getpass.h: Replace with a stub that just includes .
* m4/getpass.m4 (gl_FUNC_GETPASS): Declare through AC_DEFUN_ONCE.
Require gl_UNISTD_H_DEFAULTS. Don't test whether getpass is declared.
(gl_FUNC_GETPASS_GNU): Require gl_UNISTD_H_DEFAULTS and gl_FUNC_GETPASS.
On glibc systems, don't set REPLACE_GETPASS to 1.
* modules/getpass (Depends-on): Add 'unistd'.
(configure.ac): Test also REPLACE_GETPASS. Define a module indicator.
(Include): Specify  instead of "getpass.h".
* modules/getpass-gnu (Depends-on): Merely depend on 'getpass'.
(configure.ac): Sync with the configure.ac section of modules/getpass.
(Include): Specify  instead of "getpass.h".
* m4/unistd_h.m4 (gl_UNISTD_H): Test whether getpass is declared.
(gl_UNISTD_H_DEFAULTS): Initialize GNULIB_GETPASS, HAVE_GETPASS,
REPLACE_GETPASS.
* modules/unistd (Makefile.am): Substitute GNULIB_GETPASS, HAVE_GETPASS,
REPLACE_GETPASS.
* tests/test-unistd-c++.cc: Test also the declaration of 'getpass'.
* doc/glibc-functions/getpass.texi: A length limit exists also on uClibc
and musl.
* NEWS: Mention the change.

diff --git a/NEWS b/NEWS
index 1328e73..e763c91 100644
--- a/NEWS
+++ b/NEWS
@@ -42,6 +42,9 @@ User visible incompatible changes
 
 DateModules Changes
 
+2018-08-18  getpass The include file is changed from "getpass.h" to
+getpass-gnu .
+
 2018-07-17  hard-locale m4/hard-locale.m4 and gl_HARD_LOCALE are removed.
 
 2018-07-05  renameat2   This module is renamed to 'renameatu' and all
diff --git a/doc/glibc-functions/getpass.texi b/doc/glibc-functions/getpass.texi
index 202cf95..932fab7 100644
--- a/doc/glibc-functions/getpass.texi
+++ b/doc/glibc-functions/getpass.texi
@@ -15,7 +15,7 @@ Portability problems fixed by Gnulib module 
@code{getpass-gnu}:
 @itemize
 @item
 The returned password is truncated to PASS_MAX characters on some platforms:
-Mac OS X 10.5 (128), FreeBSD 6.2 (128), NetBSD 3.0 (128), OpenBSD 4.0 (128), 
AIX 5.1 (32), HP-UX 11 (8), IRIX 6.5 (32), OSF/1 5.1 (80), Solaris 11 2010-11 
(8, even less than PASS_MAX), Cygwin (128).
+uClibc (256), musl (128), Mac OS X 10.5 (128), FreeBSD 6.2 (128), NetBSD 3.0 
(128), OpenBSD 4.0 (128), AIX 5.1 (32), HP-UX 11 (8), IRIX 6.5 (32), OSF/1 5.1 
(80), Solaris 11 2010-11 (8, even less than PASS_MAX), Cygwin (128).
 The gnulib implementation returns the password untruncated.
 @end itemize
 
diff --git a/lib/getpass.h b/lib/getpass.h
index e07e73b..3daa1b6 100644
--- a/lib/getpass.h
+++ b/lib/getpass.h
@@ -1,30 +1,4 @@
-/* getpass.h -- Read a password of arbitrary length from /dev/tty or stdin.
-   Copyright (C) 2004, 2009-2018 Free Software Foundation, Inc.
-   Contributed by Simon Josefsson , 2004.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2, or (at your option)
-   any later version.
-
-   This program 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 General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, see <https://www.gnu.org/licenses/>.  */
-
-#ifndef GETPASS_H
-# define GETPASS_H
+/* Obsolete; consider using unistd.h instead.  */
 
 /* Get getpass declaration, if available.  */
-# include 
-
-# if !HAVE_DECL_GETPASS
-/* Read a password of arbitrary length from /dev/tty or stdin.  */
-char *getpass (const char *prompt);
-
-# endif
-
-#endif /* GETPASS_H */
+#include 
diff --git a/lib/unistd.in.h b/lib/unistd.in.h
index 8098291..7a14551 100644
--- a/lib/unistd.in.h
+++ b/lib/unistd.in.h
@@ -935,6 +935,36 @@ _GL_WARN_ON_USE (getpagesize, "getpagesize is unportable - 
"
 #endif
 
 
+#if @GNULIB_GETPASS@
+/* Function getpass() from module 'getpass':
+ Read a password from /dev/tty or stdin.
+   Function getpass() from module 'getpass-gnu':
+ Read a password of arbitrary length from /dev/tty or stdin.  */
+# if @REPLACE_GETPASS@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef getpass
+#   define getpass rpl_getpass
+#  endif
+_GL_FUNCDECL_RPL (getpass, char *, (const char *prompt)
+   

Re: [PATCH] fchmodat, lchmod: port to buggy Linux filesystems

2020-02-16 Thread Bruno Haible
Paul Eggert wrote:
> > 2) Also the discussion what is the "right" behaviour is specific to Linux.
> > The code in the '#else' case
> > 
> >if (S_ISLNK (st.st_mode))
> >  {
> >close (fd);
> >errno = EOPNOTSUPP;
> >return -1;
> >  }
> > 
> > will surely upset users on BSD systems, where symlinks are intended to have
> > permission bits.
> 
> Because of the Autoconf tests, that code should be executed only on 
> platforms where lchmod fails (or does not exist), whould shouldn't occur 
> on BSD systems.

Unfortunately, it doesn't: The line in the module description

lib_SOURCES += lchmod.c

causes lchmod.c to be compiled (to a .o file that defines 'lchmod', not
even 'rpl_lchmod'!) on macOS, FreeBSD, NetBSD, etc.

> Still, I take your point that the code is confusing. 
> Perhaps lchmod.m4 and fchmodat.m4 should define a symbol 
> HAVE_LCHMOD_BUG_WITH_NON_SYMLINKS and the C code could refer to that. 
> The resulting machine code would be the same as now, but the 
> cause-and-effect would be clearer.

Yes, I agree. Let me do this. Also I'm adding more comments. This patch
is tested on all platforms that have an lchown() function.


Before:

   HAVE_LCHMOD  REPLACE_LCHMOD   nm lchmod.o  nm fchmodat.o
glibc/Linux0 0  rpl_fchmodat 
fchmodat,openat,chmod,...
macOS  1 0  rpl_lstat,chmod  
save_cwd,chmod,lchmod,...
HP-UX  1 0  rpl_lstat,chmod  
save_cwd,chmod,lchmod,...
musl/Linux 1 0  fchmodat --
glibc/Hurd 1 0  fchmodat --
glibc/kFreeBSD 1 0  fchmodat --
FreeBSD1 0  fchmodat --
NetBSD 1 0  fchmodat --

After:

   HAVE_LCHMOD  REPLACE_LCHMOD   nm lchmod.o  nm fchmodat.o
glibc/Linux0 0  rpl_fchmodat 
fchmodat,openat,chmod,...
macOS  1 0  --   
save_cwd,chmod,lchmod,...
HP-UX  1 0  --   
save_cwd,chmod,lchmod,...
musl/Linux 1 0  --   --
glibc/Hurd 1 0  --   --
glibc/kFreeBSD 1 0  --   --
FreeBSD1 0  --   --
NetBSD 1 0  --   --


2020-02-16  Bruno Haible  

lchmod: Make more future-proof.
* m4/lchmod.m4 (gl_FUNC_LCHMOD): Define NEED_LCHMOD_NONSYMLINK_FIX.
(gl_PREREQ_LCHMOD): New macro.
* lib/lchmod.c (orig_lchmod): New function.
(lchmod): Test NEED_LCHMOD_NONSYMLINK_FIX. Access /proc only on Linux.
Return EOPNOTSUPP only on Linux and on platforms without lchmod
function.
* modules/lchmod (configure.ac): Invoke gl_PREREQ_LCHMOD.

lchmod: Fix buggy override on macOS, HP-UX (regression from 2020-02-08).
* modules/lchmod (Makefile.am): Don't add lchmod.c to lib_SOURCES.

>From 4efc18c4a2927074bf0653ba8bd79230661b8238 Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Sun, 16 Feb 2020 22:31:34 +0100
Subject: [PATCH 1/2] lchmod: Fix buggy override on macOS, HP-UX (regression
 from 2020-02-08).

* modules/lchmod (Makefile.am): Don't add lchmod.c to lib_SOURCES.
---
 ChangeLog  | 5 +
 modules/lchmod | 1 -
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index beacc09..f7a3959 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2020-02-16  Bruno Haible  
 
+	lchmod: Fix buggy override on macOS, HP-UX (regression from 2020-02-08).
+	* modules/lchmod (Makefile.am): Don't add lchmod.c to lib_SOURCES.
+
+2020-02-16  Bruno Haible  
+
 	lchmod: Improve cross-compilation guess.
 	* m4/lchmod.m4 (gl_FUNC_LCHMOD): Require AC_CANONICAL_HOST. When
 	cross-compiling, guess depending on the platform.
diff --git a/modules/lchmod b/modules/lchmod
index e1054f6..c829910 100644
--- a/modules/lchmod
+++ b/modules/lchmod
@@ -23,7 +23,6 @@ fi
 gl_SYS_STAT_MODULE_INDICATOR([lchmod])
 
 Makefile.am:
-lib_SOURCES += lchmod.c
 
 Include:
 
-- 
2.7.4

>From ea91b32b0719d46354c1d995c1d1b1c36842a2eb Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Sun, 16 Feb 2020 22:37:28 +0100
Subject: [PATCH 2/2] lchmod: Make more future-proof.

* m4/lchmod.m4 (gl_FUNC_LCHMOD): Define NEED_LCHMOD_NONSYMLINK_FIX.
(gl_PREREQ_LCHMOD): New macro.
* lib/lchmod.c (orig_lchmod): New function.
(lchmod): Test NEED_LCHMOD_NONSYMLINK_FIX. Access /proc only on Linux.
Return EOPNOTSUPP only on Linux and on platforms without lchmod
function.
* modules/lchmod (configure.ac): Invoke gl_PREREQ_LCHMOD.
---
 ChangeLo

Re: gnulib / autoconf sync

2020-12-23 Thread Bruno Haible
2.7.4

>From 9e34baba2a6ed10b31de343c25bb28e7ac8f290d Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Mon, 21 Dec 2020 11:19:05 +0100
Subject: [PATCH 2/6] Port AC_FUNC_GETGROUPS fixes from Gnulib.

* lib/autoconf/functions.m4 (AC_FUNC_GETGROUPS): Improve cross-compilation
guesses.
---
 lib/autoconf/functions.m4 | 79 ++-
 1 file changed, 43 insertions(+), 36 deletions(-)

diff --git a/lib/autoconf/functions.m4 b/lib/autoconf/functions.m4
index a86048f..003e9ce 100644
--- a/lib/autoconf/functions.m4
+++ b/lib/autoconf/functions.m4
@@ -689,44 +689,51 @@ fi
 # When cross-compiling, assume getgroups is broken.
 AN_FUNCTION([getgroups], [AC_FUNC_GETGROUPS])
 AC_DEFUN([AC_FUNC_GETGROUPS],
-[AC_REQUIRE([AC_TYPE_GETGROUPS])dnl
-AC_REQUIRE([AC_TYPE_SIZE_T])dnl
-AC_REQUIRE([AC_CANONICAL_HOST])dnl for cross-compiles
-AC_CHECK_FUNC(getgroups)
+[
+  AC_REQUIRE([AC_TYPE_GETGROUPS])dnl
+  AC_REQUIRE([AC_TYPE_SIZE_T])dnl
+  AC_REQUIRE([AC_CANONICAL_HOST])dnl for cross-compiles
+  AC_CHECK_FUNC([getgroups])
 
-# If we don't yet have getgroups, see if it's in -lbsd.
-# This is reported to be necessary on an ITOS 3000WS running SEIUX 3.1.
-ac_save_LIBS=$LIBS
-if test $ac_cv_func_getgroups = no; then
-  AC_CHECK_LIB(bsd, getgroups, [GETGROUPS_LIB=-lbsd])
-fi
+  # If we don't yet have getgroups, see if it's in -lbsd.
+  # This is reported to be necessary on an ITOS 3000WS running SEIUX 3.1.
+  ac_save_LIBS=$LIBS
+  if test $ac_cv_func_getgroups = no; then
+AC_CHECK_LIB(bsd, getgroups, [GETGROUPS_LIB=-lbsd])
+  fi
 
-# Run the program to test the functionality of the system-supplied
-# getgroups function only if there is such a function.
-if test $ac_cv_func_getgroups = yes; then
-  AC_CACHE_CHECK([for working getgroups], ac_cv_func_getgroups_works,
-   [AC_RUN_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT],
-  [[/* On Ultrix 4.3, getgroups (0, 0) always fails.  */
-   return getgroups (0, 0) == -1;]])],
-		  [ac_cv_func_getgroups_works=yes],
-		  [ac_cv_func_getgroups_works=no],
-		  [case "$host_os" in # ((
-			 # Guess yes on glibc systems.
-		 *-gnu*) ac_cv_func_getgroups_works="guessing yes" ;;
-			 # If we don't know, assume the worst.
-		 *)  ac_cv_func_getgroups_works="guessing no" ;;
-		   esac])
-   ])
-else
-  ac_cv_func_getgroups_works=no
-fi
-case "$ac_cv_func_getgroups_works" in
-  *yes)
-AC_DEFINE(HAVE_GETGROUPS, 1,
-	  [Define to 1 if your system has a working `getgroups' function.])
-;;
-esac
-LIBS=$ac_save_LIBS
+  # Run the program to test the functionality of the system-supplied
+  # getgroups function only if there is such a function.
+  if test $ac_cv_func_getgroups = yes; then
+AC_CACHE_CHECK([for working getgroups], [ac_cv_func_getgroups_works],
+  [AC_RUN_IFELSE(
+ [AC_LANG_PROGRAM(
+[AC_INCLUDES_DEFAULT],
+[[/* On NeXTstep 3.2, getgroups (0, 0) always fails.  */
+  return getgroups (0, 0) == -1;]])
+ ],
+ [ac_cv_func_getgroups_works=yes],
+ [ac_cv_func_getgroups_works=no],
+     [case "$host_os" in # ((
+   # Guess yes on glibc systems.
+*-gnu* | gnu*) ac_cv_func_getgroups_works="guessing yes" ;;
+   # Guess yes on musl systems.
+*-musl*)   ac_cv_func_getgroups_works="guessing yes" ;;
+   # If we don't know, assume the worst.
+*) ac_cv_func_getgroups_works="guessing no" ;;
+  esac
+ ])
+  ])
+  else
+ac_cv_func_getgroups_works=no
+  fi
+  case "$ac_cv_func_getgroups_works" in
+*yes)
+  AC_DEFINE([HAVE_GETGROUPS], [1],
+[Define to 1 if your system has a working `getgroups' function.])
+  ;;
+  esac
+  LIBS=$ac_save_LIBS
 ])# AC_FUNC_GETGROUPS
 
 
-- 
2.7.4

>From 15afcdea97a17a48fff9c8c1bf51b9a1264916b1 Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Mon, 21 Dec 2020 11:24:29 +0100
Subject: [PATCH 3/6] Port minor AC_FUNC_MBRTOWC fixes from Gnulib.

* lib/autoconf/functions.m4 (AC_FUNC_MBRTOWC): Quote systematically. Don't use
quadrigraphs.
---
 lib/autoconf/functions.m4 | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/lib/autoconf/functions.m4 b/lib/autoconf/functions.m4
index 003e9ce..a74c6c4 100644
--- a/lib/autoconf/functions.m4
+++ b/lib/autoconf/functions.m4
@@ -1016,19 +1016,19 @@ AN_FUNCTION([mbrtowc], [AC_FUNC_MBRTOWC])
 AC_DEFUN([AC_FUNC_MBRTOWC],
 [
   AC_CACHE_CHECK([whether mbrtowc and mbstate_t are properly declared],
-ac_cv_func_mbrtowc,
+[ac_cv_func_mbrtowc],
 [AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
-	[[@%:@include ]],
+	[[#include ]],
 	[[wchar_t wc;
 	  char const s[] = "";
 	  size_t n = 1;
 	  mbstate_t state;
 	  return ! (sizeof state && (mbrtowc) (, s, n, ));]])],
-   ac_cv_

*printf-posix: Work around bug with %#.0x on Mac OS X 10.6

2023-10-03 Thread Bruno Haible
bc-functions/obstack_vprintf.texi
+++ b/doc/glibc-functions/obstack_vprintf.texi
@@ -73,6 +73,10 @@
 with zeroes) on some platforms:
 Mac OS X 10.5, FreeBSD 13.0, NetBSD 5.0, AIX 5.2, IRIX 6.5, Solaris 11.0, 
Cygwin 1.5.x, mingw, MSVC/clang.
 @item
+printf @code{"%#.0x"} or @code{"%#.0X"} with a zero argument yields an
+incorrect result (non-empty) on some platforms:
+Mac OS X 10.6.
+@item
 This function does not support precisions larger than 512 or 1024 in integer,
 floating-point and pointer output on some platforms:
 Solaris 10/x86, mingw, MSVC/clang.
diff --git a/doc/glibc-functions/vasprintf.texi 
b/doc/glibc-functions/vasprintf.texi
index 91cf7d5635..b33ad91642 100644
--- a/doc/glibc-functions/vasprintf.texi
+++ b/doc/glibc-functions/vasprintf.texi
@@ -71,6 +71,10 @@
 with zeroes) on some platforms:
 Mac OS X 10.5, FreeBSD 6.0, NetBSD 5.0, Solaris 11.0, Cygwin 1.5.x.
 @item
+printf @code{"%#.0x"} or @code{"%#.0X"} with a zero argument yields an
+incorrect result (non-empty) on some platforms:
+Mac OS X 10.6.
+@item
 This function produces wrong output for the @samp{lc} directive with a NUL
 wide character argument on some platforms:
 glibc 2.35, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2, macOS 12.5, AIX 7.2, 
Solaris 11.4, and others.
diff --git a/doc/posix-functions/dprintf.texi b/doc/posix-functions/dprintf.texi
index 92b73a97b5..b109398793 100644
--- a/doc/posix-functions/dprintf.texi
+++ b/doc/posix-functions/dprintf.texi
@@ -47,6 +47,10 @@
 with zeroes, or wrong capitalization) on some platforms:
 Solaris 11.4.
 @item
+printf @code{"%#.0x"} or @code{"%#.0X"} with a zero argument yields an
+incorrect result (non-empty) on some platforms:
+Mac OS X 10.6.
+@item
 This function does not support precisions larger than 512 or 1024 in integer,
 floating-point and pointer output on some platforms:
 AIX 7.1.
diff --git a/doc/posix-functions/fprintf.texi b/doc/posix-functions/fprintf.texi
index e08ece4869..7bd9ff50d8 100644
--- a/doc/posix-functions/fprintf.texi
+++ b/doc/posix-functions/fprintf.texi
@@ -66,6 +66,10 @@
 with zeroes, or wrong capitalization) on some platforms:
 Mac OS X 10.5, FreeBSD 6.0, NetBSD 5.0, AIX 5.2, IRIX 6.5, Solaris 11.4, 
Cygwin 1.5.x, mingw, MSVC/clang.
 @item
+printf @code{"%#.0x"} or @code{"%#.0X"} with a zero argument yields an
+incorrect result (non-empty) on some platforms:
+Mac OS X 10.6.
+@item
 This function does not support precisions larger than 512 or 1024 in integer,
 floating-point and pointer output on some platforms:
 AIX 7.1, Solaris 10/x86, mingw, MSVC/clang.
diff --git a/doc/posix-functions/fwprintf.texi 
b/doc/posix-functions/fwprintf.texi
index db42363cfa..fed553f2b5 100644
--- a/doc/posix-functions/fwprintf.texi
+++ b/doc/posix-functions/fwprintf.texi
@@ -30,6 +30,10 @@
 glibc 2.34, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
 AIX 7.2, HP-UX 11, Solaris 11.4, Cygwin 2.9.0, mingw, MSVC 14.
 @item
+printf @code{"%#.0x"} or @code{"%#.0X"} with a zero argument yields an
+incorrect result (non-empty) on some platforms:
+Mac OS X 10.6.
+@item
 The @code{%m} directive is not portable, use @code{%s} mapped to an
 argument of @code{strerror(errno)} (or a version of @code{strerror_r})
 instead.
diff --git a/doc/posix-functions/printf.texi b/doc/posix-functions/printf.texi
index 4af0105b66..12ba645734 100644
--- a/doc/posix-functions/printf.texi
+++ b/doc/posix-functions/printf.texi
@@ -66,6 +66,10 @@
 with zeroes, or wrong capitalization) on some platforms:
 Mac OS X 10.5, FreeBSD 6.0, NetBSD 5.0, AIX 5.2, IRIX 6.5, Solaris 11.4, 
Cygwin 1.5.x, mingw, MSVC/clang.
 @item
+printf @code{"%#.0x"} or @code{"%#.0X"} with a zero argument yields an
+incorrect result (non-empty) on some platforms:
+Mac OS X 10.6.
+@item
 This function does not support precisions larger than 512 or 1024 in integer,
 floating-point and pointer output on some platforms:
 AIX 7.1, Solaris 10/x86, mingw, MSVC/clang.
diff --git a/doc/posix-functions/snprintf.texi 
b/doc/posix-functions/snprintf.texi
index 7446b88f5f..f907e9cc7f 100644
--- a/doc/posix-functions/snprintf.texi
+++ b/doc/posix-functions/snprintf.texi
@@ -77,6 +77,10 @@
 with zeroes, or wrong capitalization) on some platforms:
 Mac OS X 10.5, FreeBSD 6.0, NetBSD 5.0, AIX 5.2, IRIX 6.5, Solaris 11.4, 
Cygwin 1.5.x, mingw, MSVC/clang.
 @item
+printf @code{"%#.0x"} or @code{"%#.0X"} with a zero argument yields an
+incorrect result (non-empty) on some platforms:
+Mac OS X 10.6.
+@item
 This function does not support precisions larger than 512 or 1024 in integer,
 floating-point and pointer output on some platforms:
 AIX 7.1, Solaris 10/x86, mingw, MSVC/clang.
diff --git a/doc/posix-functions/sprintf.texi b/doc/posix-functions/sprintf.texi
index 8cd5de619f..2652acdebc 100644
--- a/doc/posix-functions/sprintf.texi
+++ b/doc/posix-functions/sprintf.texi
@@ -66,6 +66,10 @@
 with zeroes, or wron

Re: recommending AC_SYS_YEAR2038_REQUIRED ?

2023-04-10 Thread Paul Eggert
{configure} will have an option @option{--enable-year2038}
 that causes @code{configure} to behave as if @samp{year2038} was used.
 This is for packages that have long used @samp{largefile} but have not
-gotten around to upgrade their Gnulib module list to include
-@samp{year2038-required} or @samp{year2038}.
+gotten around to upgrading their Gnulib module list to include
+@samp{year2038} or @samp{year2038-required}.
 @xref{Large File Support}.
-- 
2.37.2

From b4c04569ef149bf658dc387b193cef1c8d3aaf0e Mon Sep 17 00:00:00 2001
From: Paul Eggert 
Date: Mon, 10 Apr 2023 15:18:19 -0700
Subject: [PATCH 2/3] doc: moved year2038 para up
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* doc/year2038.texi: Move a paragraph up,
as it’s lonely at the end.
---
 doc/year2038.texi | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/doc/year2038.texi b/doc/year2038.texi
index 81b212e455..3d58659a43 100644
--- a/doc/year2038.texi
+++ b/doc/year2038.texi
@@ -42,6 +42,15 @@ after the year 2038.  However, if your package needs to support
 32-bit platforms that will not be used after the year 2038,
 you can use the @samp{year2038} module instead.
 
+If the Gnulib module @samp{largefile} is used but neither
+@samp{year2038} nor @samp{year2038-required} is used,
+@command{configure} will have an option @option{--enable-year2038}
+that causes @code{configure} to behave as if @samp{year2038} was used.
+This is for packages that have long used @samp{largefile} but have not
+gotten around to upgrading their Gnulib module list to include
+@samp{year2038} or @samp{year2038-required}.
+@xref{Large File Support}.
+
 With the @samp{year2038-required} module, @command{configure} fails
 on the following 32-bit platforms (or ABIs in bi-arch systems):
 @itemize
@@ -88,12 +97,3 @@ FreeBSD/arm,
 @item
 Minix 3.3.
 @end itemize
-
-If the Gnulib module @samp{largefile} is used but neither
-@samp{year2038} nor @samp{year2038-required} is used,
-@command{configure} will have an option @option{--enable-year2038}
-that causes @code{configure} to behave as if @samp{year2038} was used.
-This is for packages that have long used @samp{largefile} but have not
-gotten around to upgrading their Gnulib module list to include
-@samp{year2038} or @samp{year2038-required}.
-@xref{Large File Support}.
-- 
2.37.2

From be7c3fa0e35b9f11eb3329590426477c6459f7c8 Mon Sep 17 00:00:00 2001
From: Paul Eggert 
Date: Mon, 10 Apr 2023 15:15:37 -0700
Subject: [PATCH 3/3] doc: update list of year2038 platforms

* doc/year2038.texi: Update list of platforms
by adding dates and version numbers and fixing some that
appear to have been misfiled.  Also, list working systems
and versions first, as that helps shorten the list of
failing systems by saying "older versions".
---
 doc/year2038.texi | 58 +--
 1 file changed, 31 insertions(+), 27 deletions(-)

diff --git a/doc/year2038.texi b/doc/year2038.texi
index 3d58659a43..626729578f 100644
--- a/doc/year2038.texi
+++ b/doc/year2038.texi
@@ -51,49 +51,53 @@ gotten around to upgrading their Gnulib module list to include
 @samp{year2038} or @samp{year2038-required}.
 @xref{Large File Support}.
 
-With the @samp{year2038-required} module, @command{configure} fails
-on the following 32-bit platforms (or ABIs in bi-arch systems):
+With the @samp{year2038-required} module, @command{configure} by
+default should work on the following 32-bit platforms (or 32-bit ABIs
+in bi-arch systems):
+
 @itemize
 @item
-Linux with glibc < 2.34 on
+Linux kernel 5.1 (2019) and later with glibc 2.34 (2021) and later on
 x86, arm, mips (32-bit or n32 ABI), powerpc, sparc, s390, hppa, m68k, sh, csky, microblaze, nios2,
 @item
-Linux with musl libc on x86,
-@item
-Linux/riscv32,
-@item
-Mac OS X on x86 and powerpc,
-@item
-GNU/Hurd/x86,
-@item
-GNU/kFreeBSD/x86,
-@item
-FreeBSD/x86,
+Linux kernel 5.1 (2019) and later with musl libc 1.2 (2020) and later on x86,
 @item
-MidnightBSD/x86,
+Linux on arc, loong32, riscv32 and x86_64-x32,
 @item
-AIX/powerpc,
+NetBSD 6.0 (2012) and later on x86 and sparc,
 @item
-Solaris 10 and 11 on x86 and sparc,
+OpenBSD 5.5 (2014) and later on x86,
 @item
-Cygwin/x86,
+FreeBSD/arm,
 @item
-Haiku/x86.
+Minix 3.3.
 @end itemize
 
-Whereas no failure will occur on the following 32-bit platforms or ABIs:
+@noindent
+Whereas @command{configure} with @samp{year2038-required} will fail on
+earlier versions of the abovementioned platforms if a version is listed,
+and it will also fail on all versions of the following older 32-bit
+platforms or ABIs:
+
 @itemize
 @item
-Linux/x86 with glibc >= 2.34 on
-x86, arm, mips (32-bit or n32 ABI), powerpc, sparc, s390, hppa, m68k, sh, csky, microblaze, nios2,
+Mac OS X 10.6 (2009) and earlier on x86 and powerpc,
 @item
-Linux/x86_64-x32,
+GNU/Hurd/x86,
 @item
-NetBSD on x86 and sparc,
+GNU/kFreeBSD/x86,
 @item
-OpenBSD/x86,
+FreeBSD/x86 (this port demoted to Tier

tests for quiet NaNs and signalling NaNs

2023-10-12 Thread Bruno Haible
 part of the mxcsr
+ register.  */
+  /* mingw's _controlfp_s implementation
+ <https://github.com/mingw-w64/mingw-w64/blob/master/mingw-w64-crt/secapi/_controlfp_s.c>
+ is broken.  This code here works.  */
+  {
+unsigned short fctrl, orig_fctrl;
+unsigned int mxcsr, orig_mxcsr;
+
+__asm__ __volatile__ ("fstcw %0" : "=m" (*));
+__asm__ __volatile__ ("stmxcsr %0" : "=m" (*));
+orig_fctrl = fctrl;
+orig_mxcsr = mxcsr;
+fctrl &= ~FE_INVALID;
+mxcsr &= ~(FE_INVALID << 7);
+if (!(fctrl == orig_fctrl && mxcsr == orig_mxcsr))
+  {
+__asm__ __volatile__ ("fldcw %0" : : "m" (*));
+__asm__ __volatile__ ("ldmxcsr %0" : : "m" (*));
+  }
+  }
+
+  return 0;
+}
+
+#elif defined _WIN32 && !defined __CYGWIN__
+/* native Windows */
+
+# include 
+
+static int
+sigfpe_on_invalid ()
+{
+  /* Documentation:
+ <https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/controlfp-s>  */
+  unsigned int control;
+  if (_controlfp_s (, 0, 0) == 0)
+if (_controlfp_s (, control & ~_EM_INVALID, _MCW_EM) == 0)
+  return 0;
+
+  return -1;
+}
+
+#elif MUSL_LIBC && defined __x86_64__
+/* musl libc/x86_64 */
+
+# include 
+
+static int
+sigfpe_on_invalid ()
+{
+  fenv_t env, orig_env;
+  fegetenv ();
+  orig_env = env;
+
+  /* Clear FE_INVALID exceptions from past operations.
+ fstat bits 5..2,0 indicate which floating-point exceptions have occurred
+ since the respective bit was last set to zero, in the 387 compatible
+ floating-point unit.
+ mxcsr bits 5..2,0 indicate which floating-point exceptions have occurred
+ since the respective bit was last set to zero, in the SSE registers
+ floating-point unit.  */
+  env.__status_word &= ~FE_INVALID;
+  env.__mxcsr &= ~FE_INVALID;
+  /* An FE_INVALID exception shall trigger a SIGFPE signal.
+ fctrl bits 5..2,0 indicate which floating-point exceptions shall, when
+ occurring in the 387 compatible floating-point unit, trigger a trap rather
+ than merely set the corresponding bit in the fstat register.
+ mxcsr bits 12..9,7 indicate which floating-point exceptions shall, when
+ occurring in the SSE registers floating-point unit, trigger a trap rather
+ than merely set the corresponding bit in the lower part of the mxcsr
+ register.  */
+  env.__control_word &= ~FE_INVALID;
+  env.__mxcsr &= ~(FE_INVALID << 7);
+
+  if (!(env.__control_word == orig_env.__control_word
+&& env.__status_word == orig_env.__status_word
+&& env.__mxcsr == orig_env.__mxcsr))
+fesetenv ();
+
+  return 0;
+}
+
+#elif MUSL_LIBC && defined __i386__
+/* musl libc/x86 */
+
+# include 
+
+static int
+sigfpe_on_invalid ()
+{
+  fenv_t env, orig_env;
+  fegetenv ();
+  orig_env = env;
+
+  /* The mxcsr register exists, like for x86_64, but only if the CPU supports
+ SSE instructions.  Here it is not part of fenv_t.  Instead, it is
+ transparently handled by the fegetenv and fesetenv functions.  */
+
+  /* Clear FE_INVALID exceptions from past operations.
+ fstat bits 5..2,0 indicate which floating-point exceptions have occurred
+ since the respective bit was last set to zero, in the 387 compatible
+ floating-point unit.  */
+  env.__status_word &= ~FE_INVALID;
+  /* An FE_INVALID exception shall trigger a SIGFPE signal.
+ fctrl bits 5..2,0 indicate which floating-point exceptions shall, when
+ occurring in the 387 compatible floating-point unit, trigger a trap rather
+ than merely set the corresponding bit in the fstat register.  */
+  env.__control_word &= ~FE_INVALID;
+
+  if (!(env.__control_word == orig_env.__control_word
+&& env.__status_word == orig_env.__status_word))
+fesetenv ();
+
+  return 0;
+}
+
+#elif MUSL_LIBC && defined __aarch64__
+/* musl libc/arm64 */
+
+# include 
+
+static int
+sigfpe_on_invalid ()
+{
+  fenv_t env, orig_env;
+  fegetenv ();
+  orig_env = env;
+
+  /* Clear FE_INVALID exceptions from past operations.
+ fpsr bits 4..0 indicate which floating-point exceptions have occurred
+ since the respective bit was last set to zero.  */
+  env.__fpsr &= ~FE_INVALID;
+  /* An FE_INVALID exception shall trigger a SIGFPE signal.
+ fpcr bits 12..8 indicate which floating-point exceptions shall, when
+ occurring, trigger a trap rather than merely set the corresponding bit
+ in the fpsr register.  */
+  env.__fpcr |= (FE_INVALID << 8);
+
+  if (!(env.__fpsr == orig_env.__fpsr && env.__fpcr == orig_env.__fpcr))
+{
+  fesetenv ();
+  /* Test whether __fpcr was actually changed as desired.  */
+  fenv_t new_env;
+  fegetenv (_env);
+  if (new_env.__fpcr != env.__fpcr)
+return -1;
+}
+
+  return 0;
+}
+
+#elif MUSL_LIBC && defined __

more tests against glibc C locale bug

2023-04-03 Thread Bruno Haible
git a/m4/mbrtowc.m4 b/m4/mbrtowc.m4
index 4bf91bec3b..0c7a8bae69 100644
--- a/m4/mbrtowc.m4
+++ b/m4/mbrtowc.m4
@@ -712,6 +712,10 @@ AC_DEFUN([gl_MBRTOWC_EMPTY_INPUT]
 dnl Although POSIX was never intended to allow this, the GNU C Library
 dnl and other implementations do it.  See:
 dnl https://sourceware.org/bugzilla/show_bug.cgi?id=19932
+dnl POSIX has now clarified it:
+dnl <https://pubs.opengroup.org/onlinepubs/9699919799/functions/mbrtowc.html>
+dnl says: "In the POSIX locale an [EILSEQ] error cannot occur since all byte
+dnl values are valid characters."
 
 AC_DEFUN([gl_MBRTOWC_C_LOCALE],
 [
diff --git a/tests/test-mbrtoc32-5.sh b/tests/test-mbrtoc32-5.sh
index cd000fb3c7..4213772272 100755
--- a/tests/test-mbrtoc32-5.sh
+++ b/tests/test-mbrtoc32-5.sh
@@ -1,6 +1,9 @@
 #!/bin/sh
+
 # Test whether the POSIX locale has encoding errors.
 LC_ALL=C \
-${CHECKER} ./test-mbrtoc32${EXEEXT} 5 || exit
+${CHECKER} ./test-mbrtoc32${EXEEXT} 5 || exit 1
 LC_ALL=POSIX \
-${CHECKER} ./test-mbrtoc32${EXEEXT} 5
+${CHECKER} ./test-mbrtoc32${EXEEXT} 5 || exit 1
+
+exit 0
diff --git a/tests/test-mbrtoc32.c b/tests/test-mbrtoc32.c
index 0d75c3db14..a40309004e 100644
--- a/tests/test-mbrtoc32.c
+++ b/tests/test-mbrtoc32.c
@@ -386,6 +386,10 @@ main (int argc, char *argv[])
 
 wc = (char32_t) 0xBADFACE;
 ret = mbrtoc32 (, buf, 1, );
+/* POSIX:2018 says regarding mbrtowc: "In the POSIX locale an
+   [EILSEQ] error cannot occur since all byte values are valid
+   characters."  It is reasonable to expect mbrtoc32 to behave
+   in the same way.  */
 ASSERT (ret == 1);
 if (c < 0x80)
   /* c is an ASCII character.  */
-- 
2.34.1

>From 13679eb960abb41db5557bf364d7b31bc27d6f55 Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Mon, 3 Apr 2023 14:24:39 +0200
Subject: [PATCH 2/6] mbrtoc32 tests: Prefer *c32* functions.

* tests/test-mbrtoc32.c (main): Use btoc32 instead of btowc.
* modules/mbrtoc32-tests (Depends-on): Add btoc32.
---
 ChangeLog  | 6 ++
 modules/mbrtoc32-tests | 1 +
 tests/test-mbrtoc32.c  | 2 +-
 3 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index 7bc1a008f1..901aa4331a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2023-04-03  Bruno Haible  
+
+	mbrtoc32 tests: Prefer *c32* functions.
+	* tests/test-mbrtoc32.c (main): Use btoc32 instead of btowc.
+	* modules/mbrtoc32-tests (Depends-on): Add btoc32.
+
 2023-04-03  Bruno Haible  
 
 	mbrtoc32 tests: Add comment.
diff --git a/modules/mbrtoc32-tests b/modules/mbrtoc32-tests
index e123772a20..95cc4750bd 100644
--- a/modules/mbrtoc32-tests
+++ b/modules/mbrtoc32-tests
@@ -22,6 +22,7 @@ m4/codeset.m4
 
 Depends-on:
 mbsinit
+btoc32
 c32tob
 setlocale
 localcharset
diff --git a/tests/test-mbrtoc32.c b/tests/test-mbrtoc32.c
index a40309004e..ecde031f36 100644
--- a/tests/test-mbrtoc32.c
+++ b/tests/test-mbrtoc32.c
@@ -397,7 +397,7 @@ main (int argc, char *argv[])
 else
   /* On most platforms, the bytes 0x80..0xFF map to U+0080..U+00FF.
  But on musl libc, the bytes 0x80..0xFF map to U+DF80..U+DFFF.  */
-  ASSERT (wc == (btowc (c) == 0xDF00 + c ? btowc (c) : c));
+  ASSERT (wc == (btoc32 (c) == 0xDF00 + c ? btoc32 (c) : c));
 ASSERT (mbsinit ());
 
 ret = mbrtoc32 (NULL, buf, 1, );
-- 
2.34.1

From d36467df509b488bc069a3c247a3ee595874f431 Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Mon, 3 Apr 2023 14:24:42 +0200
Subject: [PATCH 3/6] btoc32 tests: Check behaviour in the C locale.

* tests/test-btoc32.c (main): Test behaviour in the C locale. Based on
tests/test-btowc.c.
* tests/test-btoc32-3.sh: New file, based on tests/test-btowc3.sh.
* modules/btoc32-tests (Files): Add it.
(Makefile.am): Test it.
---
 ChangeLog  |  9 +
 modules/btoc32-tests   |  3 ++-
 tests/test-btoc32-3.sh |  9 +
 tests/test-btoc32.c| 30 ++
 4 files changed, 50 insertions(+), 1 deletion(-)
 create mode 100755 tests/test-btoc32-3.sh

diff --git a/ChangeLog b/ChangeLog
index 901aa4331a..b05eb8f846 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2023-04-03  Bruno Haible  
+
+	btoc32 tests: Check behaviour in the C locale.
+	* tests/test-btoc32.c (main): Test behaviour in the C locale. Based on
+	tests/test-btowc.c.
+	* tests/test-btoc32-3.sh: New file, based on tests/test-btowc3.sh.
+	* modules/btoc32-tests (Files): Add it.
+	(Makefile.am): Test it.
+
 2023-04-03  Bruno Haible  
 
 	mbrtoc32 tests: Prefer *c32* functions.
diff --git a/modules/btoc32-tests b/modules/btoc32-tests
index b3373f3cf8..b9d14eefd1 100644
--- a/modules/btoc32-tests
+++ b/modules/btoc32-tests
@@ -1,6 +1,7 @@
 Files:
 tests/test-btoc32-1.sh
 tests/test-btoc32-2.sh
+tests/test-btoc32-3.sh
 tests/test-btoc32.

improve clang support (9)

2020-08-09 Thread Bruno Haible
EPLACE_HYPOT=0;  AC_SUBST([REPLACE_HYPOT])
+  REPLACE_HYPOTF=0; AC_SUBST([REPLACE_HYPOTF])
+  REPLACE_HYPOTL=0; AC_SUBST([REPLACE_HYPOTL])
+  REPLACE_ILOGB=0;  AC_SUBST([REPLACE_ILOGB])
+  REPLACE_ILOGBF=0; AC_SUBST([REPLACE_ILOGBF])
+  REPLACE_ILOGBL=0; AC_SUBST([REPLACE_ILOGBL])
+  REPLACE_ISFINITE=0;   AC_SUBST([REPLACE_ISFINITE])
+  REPLACE_ISINF=0;  AC_SUBST([REPLACE_ISINF])
+  REPLACE_ISNAN=0;  AC_SUBST([REPLACE_ISNAN])
+  REPLACE_LDEXPL=0; AC_SUBST([REPLACE_LDEXPL])
+  REPLACE_LOG=0;AC_SUBST([REPLACE_LOG])
+  REPLACE_LOGF=0;   AC_SUBST([REPLACE_LOGF])
+  REPLACE_LOGL=0;   AC_SUBST([REPLACE_LOGL])
+  REPLACE_LOG10=0;  AC_SUBST([REPLACE_LOG10])
+  REPLACE_LOG10F=0; AC_SUBST([REPLACE_LOG10F])
+  REPLACE_LOG10L=0; AC_SUBST([REPLACE_LOG10L])
+  REPLACE_LOG1P=0;  AC_SUBST([REPLACE_LOG1P])
+  REPLACE_LOG1PF=0; AC_SUBST([REPLACE_LOG1PF])
+  REPLACE_LOG1PL=0; AC_SUBST([REPLACE_LOG1PL])
+  REPLACE_LOG2=0;   AC_SUBST([REPLACE_LOG2])
+  REPLACE_LOG2F=0;  AC_SUBST([REPLACE_LOG2F])
+  REPLACE_LOG2L=0;  AC_SUBST([REPLACE_LOG2L])
+  REPLACE_LOGB=0;   AC_SUBST([REPLACE_LOGB])
+  REPLACE_LOGBF=0;  AC_SUBST([REPLACE_LOGBF])
+  REPLACE_LOGBL=0;  AC_SUBST([REPLACE_LOGBL])
+  REPLACE_MODF=0;   AC_SUBST([REPLACE_MODF])
+  REPLACE_MODFF=0;  AC_SUBST([REPLACE_MODFF])
+  REPLACE_MODFL=0;  AC_SUBST([REPLACE_MODFL])
+  REPLACE_NAN=0;AC_SUBST([REPLACE_NAN])
+  REPLACE_REMAINDER=0;  AC_SUBST([REPLACE_REMAINDER])
+  REPLACE_REMAINDERF=0; AC_SUBST([REPLACE_REMAINDERF])
+  REPLACE_REMAINDERL=0; AC_SUBST([REPLACE_REMAINDERL])
+  REPLACE_RINTL=0;  AC_SUBST([REPLACE_RINTL])
+  REPLACE_ROUND=0;  AC_SUBST([REPLACE_ROUND])
+  REPLACE_ROUNDF=0; AC_SUBST([REPLACE_ROUNDF])
+  REPLACE_ROUNDL=0; AC_SUBST([REPLACE_ROUNDL])
+  REPLACE_SIGNBIT=0;AC_SUBST([REPLACE_SIGNBIT])
+  REPLACE_SIGNBIT_USING_BUILTINS=0; AC_SUBST([REPLACE_SIGNBIT_USING_BUILTINS])
+  REPLACE_SINF=0;   AC_SUBST([REPLACE_SINF])
+  REPLACE_SINHF=0;  AC_SUBST([REPLACE_SINHF])
+  REPLACE_SQRTF=0;  AC_SUBST([REPLACE_SQRTF])
+  REPLACE_SQRTL=0;  AC_SUBST([REPLACE_SQRTL])
+  REPLACE_TANF=0;   AC_SUBST([REPLACE_TANF])
+  REPLACE_TANHF=0;  AC_SUBST([REPLACE_TANHF])
+  REPLACE_TRUNC=0;  AC_SUBST([REPLACE_TRUNC])
+  REPLACE_TRUNCF=0; AC_SUBST([REPLACE_TRUNCF])
+  REPLACE_TRUNCL=0; AC_SUBST([REPLACE_TRUNCL])
 ])
 
 # gl_LONG_DOUBLE_VS_DOUBLE
diff --git a/m4/signbit.m4 b/m4/signbit.m4
index 73d96ea..05c99ca 100644
--- a/m4/signbit.m4
+++ b/m4/signbit.m4
@@ -1,4 +1,4 @@
-# signbit.m4 serial 19
+# signbit.m4 serial 20
 dnl Copyright (C) 2007-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -40,15 +40,16 @@ AC_DEFUN([gl_SIGNBIT],
  esac
 ])
 ])
-  dnl GCC 4.0 and newer provides three built-ins for signbit.
+  dnl GCC >= 4.0 and clang provide three built-ins for signbit.
   dnl They can be used without warnings, also in C++, regardless of .
   dnl But they may expand to calls to functions, which may or may not be in
   dnl libc.
-  AC_CACHE_CHECK([for signbit compiler built-ins], [gl_cv_func_signbit_gcc],
+  AC_CACHE_CHECK([for signbit compiler built-ins],
+[gl_cv_func_signbit_builtins],
 [
   AC_RUN_IFELSE(
 [AC_LANG_SOURCE([[
-#if __GNUC__ >= 4
+#if (__GNUC__ >= 4) || (__clang_major__ >= 4)
 # define signbit(x) \
(sizeof (x) == sizeof (long double) ? __builtin_signbitl (x) : \
 sizeof (x) == sizeof (double) ? __builtin_signbit (x) : \
@@ -59,30 +60,30 @@ AC_DEFUN([gl_SIGNBIT],
 #include 
 ]gl_SIGNBIT_TEST_PROGRAM
 ])],
-[gl_cv_func_signbit_gcc=yes],
-[gl_cv_func_signbit_gcc=no],
+[gl_cv_func_signbit_builtins=yes],
+[gl_cv_func_signbit_builtins=no],
 [case "$host_os" in
   # Guess yes on glibc systems.
-   *-gnu* | gnu*) gl_cv_func_signbit_gcc="guessing yes" ;;
+   *-gnu* | gnu*) gl_cv_func_signbit_builtins="guessing yes" ;;
   # Guess yes on musl systems.
-   *-musl*)   gl_cv_func_signbit_gcc="guessing yes" ;;
+   *-musl*)   gl_cv_func_signbit_builtins="guessing yes" ;;
   #

fenv-* tests: Add tests of the link dependencies

2023-11-07 Thread Bruno Haible
13 @@
 /* Specification.  */
 #include 
 
-#include 
-
-#include "fpe-trapping.h"
 #include "macros.h"
 
-/* musl libc does not support floating-point exception trapping, even where
-   the hardware supports it.  See
-   <https://wiki.musl-libc.org/functional-differences-from-glibc.html>  */
-#if HAVE_FPE_TRAPPING && (!MUSL_LIBC || GNULIB_FEENABLEEXCEPT)
-
-/* Check that fesetexceptflag() does not trigger a trap.  */
-
-static volatile double a, b;
-static volatile long double al, bl;
-
 int
 main ()
 {
   fexcept_t saved_flags_1;
+  fexcept_t saved_flags_2;
 
   /* Test setting all exception flags.  */
   if (feraiseexcept (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT) != 0)
@@ -53,41 +41,83 @@ main ()
FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT)
   == 0);
 
-  /* Clear exceptions from past operations.  */
-  feclearexcept (FE_ALL_EXCEPT);
-
-  /* An FE_INVALID exception shall trigger a SIGFPE signal, which by default
- terminates the program.  */
-  if (sigfpe_on_invalid () < 0)
-{
-  fputs ("Skipping test: trapping floating-point exceptions are not supported on this machine.\n", stderr);
-  return 77;
-}
-
-  /* Attempt to set the FE_INVALID exception flag.  */
-  _GL_UNUSED int rc = fesetexceptflag (_flags_1, FE_INVALID);
-  /* On older i386 and on PowerPC, there is no way to implement
- fesetexceptflag() such that it does not trigger a trap.  fesetexceptflag()
- is expected to fail in this case.  */
-# if !((defined __i386 || defined _M_IX86) || defined __powerpc__)
-  ASSERT (rc == 0);
-# endif
-
-  /* Do a harmless floating-point operation (since on some CPUs, floating-point
- exceptions trigger a trap only at the next floating-point operation).  */
-  a = 1.0; b = a + a;
-  al = 1.0L; bl = al + al;
+  /* Clear some of the exception flags.  */
+  ASSERT (feclearexcept (FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT) == 0);
+  /* Here, the set exception flags are FE_INVALID | FE_DIVBYZERO.  */
+  ASSERT (fetestexcept (FE_INVALID) == FE_INVALID);
+  ASSERT (fetestexcept (FE_DIVBYZERO) == FE_DIVBYZERO);
+  ASSERT (fetestexcept (FE_OVERFLOW) == 0);
+  ASSERT (fetestexcept (FE_UNDERFLOW) == 0);
+  ASSERT (fetestexcept (FE_INEXACT) == 0);
+
+  /* Fill saved_flags_2.  */
+  ASSERT (fegetexceptflag (_flags_2, FE_INVALID | FE_OVERFLOW) == 0);
+
+  /* Restore some of the exception flags.  */
+  ASSERT (fesetexceptflag (_flags_1,
+   FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW) == 0);
+  /* Here, the set exception flags are FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW.  */
+  ASSERT (fetestexcept (FE_INVALID) == FE_INVALID);
+  ASSERT (fetestexcept (FE_DIVBYZERO) == FE_DIVBYZERO);
+  ASSERT (fetestexcept (FE_OVERFLOW) == FE_OVERFLOW);
+  ASSERT (fetestexcept (FE_UNDERFLOW) == FE_UNDERFLOW);
+  ASSERT (fetestexcept (FE_INEXACT) == 0);
+
+  /* Clear some more exception flags.  */
+  ASSERT (feclearexcept (FE_INVALID) == 0);
+  /* Here, the set exception flags are FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW.  */
+  ASSERT (fetestexcept (FE_INVALID) == 0);
+  ASSERT (fetestexcept (FE_DIVBYZERO) == FE_DIVBYZERO);
+  ASSERT (fetestexcept (FE_OVERFLOW) == FE_OVERFLOW);
+  ASSERT (fetestexcept (FE_UNDERFLOW) == FE_UNDERFLOW);
+  ASSERT (fetestexcept (FE_INEXACT) == 0);
+
+  /* Restore some more exception flags.  */
+  ASSERT (fesetexceptflag (_flags_2, FE_OVERFLOW) == 0);
+  /* Here, the set exception flags are FE_DIVBYZERO | FE_UNDERFLOW.  */
+  ASSERT (fetestexcept (FE_INVALID) == 0);
+  ASSERT (fetestexcept (FE_DIVBYZERO) == FE_DIVBYZERO);
+  ASSERT (fetestexcept (FE_OVERFLOW) == 0);
+  ASSERT (fetestexcept (FE_UNDERFLOW) == FE_UNDERFLOW);
+  ASSERT (fetestexcept (FE_INEXACT) == 0);
+
+  /* Restore some more exception flags.  */
+  ASSERT (fesetexceptflag (_flags_2, FE_INVALID) == 0);
+  /* Here, the set exception flags are FE_INVALID | FE_DIVBYZERO | FE_UNDERFLOW.  */
+  ASSERT (fetestexcept (FE_INVALID) == FE_INVALID);
+  ASSERT (fetestexcept (FE_DIVBYZERO) == FE_DIVBYZERO);
+  ASSERT (fetestexcept (FE_OVERFLOW) == 0);
+  ASSERT (fetestexcept (FE_UNDERFLOW) == FE_UNDERFLOW);
+  ASSERT (fetestexcept (FE_INEXACT) == 0);
+
+  /*  */
+  /* Check that fesetexceptflag clears exception flags in both the 387 unit
+ and the SSE unit, on i386 and x86_64 CPUs.  */
+
+  fexcept_t saved_flags_3;
+
+  ASSERT (feclearexcept (FE_INVALID) == 0);
+
+  ASSERT (fegetexceptflag (_flags_3, FE_INVALID) == 0);
+
+  /* Set the FE_INVALID flag in the SSE unit.  */
+  {
+static volatile double a, b;
+_GL_UNUSED volatile double c;
+a = 0.0; b = 0.0; c = a / b;
+  }
+  /* Set the FE_INVALID flag in the 387 unit.  */
+  {
+static volatile long double al, bl;
+_GL_UNUSED volatile long double cl;
+al = 0.0L; bl = 0.0L; cl = al / bl;
+  }
+

Re: From wchar_t to char32_t, new module mbszero

2023-07-16 Thread Paul Eggert

On 2023-07-16 01:43, Bruno Haible wrote:

Paul Eggert wrote:



However, after implementing mbszero with this data and enabling its use
in many places, I got test failures on NetBSD and Solaris.
   - On NetBSD, the minimum we need to clear is 28 bytes.
   - On Solaris OmniOS and OpenIndiana, the minimum we need to clear is 16 
bytes.
   - On proprietary Solaris, the minimum we need to clear is 20 or 28 bytes
 (depending on 32-bit or 64-bit mode).
So, clearly this is fragile stuff.


Were the test failures for single calls to mbrtoc32, or were they for 
something else? If the former, what went wrong with the source-code 
analysis?


Assuming the problem was not with single calls to mbrtoc32, how about if 
we define another function mbszerotoc32 that is the minimum number of 
bytes to clear so that a single call to mbrtoc32 will work? Such a macro 
would be useful for diffutils, and I expect elsewhere.


 > +/* _GL_MBSTATE_INIT_SIZE describes how mbsinit() behaves: It is the 
number of

+   bytes at the beginning of an mbstate_t that need to be zero, for mbsinit()
+   to return true.


This macro is not used anywhere. How about adding a comment explaining 
why it's defined but not used? Or if it's not needed we can remove it.




+# elif __GLIBC__ >= 2 /* glibc */


Should be glibc 2.2 not glibc 2, if I read the history right. Also 
should check that __GLIBC__ is defined, for the benefit of picky compilers.




# elif defined MUSL_LIBC      /* musl libc */
/* mbstate_t is defined in .
   It is an opaque aligned 8-byte struct, of which at most the first
   4 bytes are used.
   For more details, see src/multibyte/mbrtowc.c.  */
#  define _GL_MBSTATE_INIT_SIZE 4
#  define _GL_MBSTATE_ZERO_SIZE 4


Better to say 'sizeof (unsigned)' instead of '4', as the source code 
uses 'unsigned'. This wouldn't affect the machine code on existing 
platforms, would be better documentation, and would be theoretically 
better on oddball future platforms. Similarly for other parts of wchar.in.h.




+# elif defined __sun  /* Solaris */
+/* On Solaris, mbstate_t is defined in .
+   It is an opaque aligned 24-byte or 32-byte struct, of which at most the 
first
+   20 or 28 bytes are used.
+   For more details, see the *State types in
+   illumos-gate/usr/src/lib/libc/port/locale/
+   {none,euc,mskanji,big5,gb2312,gbk,gb18030,utf8}.c.  */
+/* File   INIT_SIZE  ZERO_SIZE
+   none.c 0  0
+   euc.c 12 12
+   mskanji.c  4  4
+   big5.c 4  4
+   gb2312.c   4  6
+   gbk.c  4  4
+   gb18030.c  4  8
+   utf8.c12 12 */
+/* But 12 is not the correct value: we get test failures
+ - in OpenIndiana and OmniOS: for values < 16,
+ - in Solaris 10 and 11: for values < 20 (in 32-bit mode)
+   or < 28 (in 64-bit mode).  */
+#  if defined _LP64
+#   define _GL_MBSTATE_INIT_SIZE 28
+#   define _GL_MBSTATE_ZERO_SIZE 28
+#  else
+#   define _GL_MBSTATE_INIT_SIZE 20
+#   define _GL_MBSTATE_ZERO_SIZE 20
+#  endif


On 64-bit Solaris 10 sparc with either GCC or Oracle's compiler, it's 
the same number of insns to initialize 28 bytes vs 32 bytes. So if 28 is 
needed let's drop the optimization for Solaris as not worth the 
aggravation of maintaining and worrying about its brittleness. 32-bit 
Solaris is obsolete and will stop working in 2038 and is not worth 
worrying about even if it's one less insn, so let's drop it for that too.



+#  define _GL_MBSTATE_ZERO_SIZE sizeof (mbstate_t)


Might be better to have this sort of thing at the end, as the default, 
rather than sprinkle lots of copies of it elsewhere. Likewise for 
defaulting _GL_MBSTATE_INIT_SIZE to _GL_MBSTATE_ZERO_SIZE, since 
initializing the latter implies initializing the former.


Proposed patch attached; it implements the above suggestions except for 
the comment about _GL_MBSTATE_INIT_SIZE. I haven't installed this.
From 5def9d91a35b3a472577424abc21cda37d21dd35 Mon Sep 17 00:00:00 2001
From: Paul Eggert 
Date: Sun, 16 Jul 2023 15:23:52 -0700
Subject: [PATCH] wchar: new function mbszerotoc32

This is like mbszero, but specialized for when mbrtoc32 is
called once and no other functions are called.
It can be used by diffutils's mbcel code.
* lib/btoc32.c (btoc32):
* lib/localeinfo.c (init_localeinfo):
Prefer mbszerotoc32 to mbszero when either will do.
* lib/localeinfo.c (mbszerotoc32) [GAWK]: New macro.
* lib/wchar.in.h (_GL_MBSTATE_MBRTOC32_SIZE): New macro.
(_GL_MBSTATE_INIT_SIZE, _GL_MBSTATE_ZERO_SIZE):
Simplify defns by relying on defaults.
Don't bother optimizing Solaris.
(mbszerotoc32): New function.
---
 ChangeLog| 16 +
 lib/btoc32.c |  2 +-
 lib/localeinfo.c |  3 +-
 lib/wchar.in.h   | 93 +++-
 4 files changed, 72 insertions(+), 42 deletions(-)

diff --git a/ChangeLog b/

fnmatch, fnmatch-gnu: Document known bugs

2023-07-23 Thread Bruno Haible
With the new unit tests for fnmatch(), I see test failures on several platforms.
(Did anybody expect something else?)

This patch documents the problems. The next patches will then go on to actually
fix the problems.


2023-07-23  Bruno Haible  

fnmatch, fnmatch-gnu: Document known bugs.
* doc/posix-headers/fnmatch.texi: Mention the macros FNM_LEADING_DIR,
FNM_CASEFOLD, FNM_EXTMATCH, FNM_FILE_NAME.
* doc/posix-functions/fnmatch.texi: Reference the glibc documentation
and the Linux man page. Document the effects of the two modules and all
the known bugs in detail.

diff --git a/doc/posix-headers/fnmatch.texi b/doc/posix-headers/fnmatch.texi
index 8e59b764f0..175f5f9886 100644
--- a/doc/posix-headers/fnmatch.texi
+++ b/doc/posix-headers/fnmatch.texi
@@ -3,15 +3,29 @@
 
 POSIX specification:@* 
@url{https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/fnmatch.h.html}
 
-Gnulib module: fnmatch-h
+Gnulib module: fnmatch-h, fnmatch-gnu
 
-Portability problems fixed by Gnulib:
+Portability problems fixed by Gnulib module @code{fnmatch-h}:
 @itemize
 @item
 This header file is missing on some platforms:
 mingw, MSVC 14.
 @end itemize
 
+Portability problems fixed by Gnulib module @code{fnmatch-gnu}, together with 
module @code{fnmatch-h}:
+@itemize
+@item
+The macros @code{FNM_LEADING_DIR} and @code{FNM_CASEFOLD} are not defined
+on some platforms:
+AIX 7.2, HP-UX 11.31, IRIX 6.5, Solaris 10.
+@item
+The macro @code{FNM_EXTMATCH} is not defined on all non-glibc platforms:
+musl libc, macOS 12.5, FreeBSD 13.2, NetBSD 9.3, OpenBSD 7.2, Minix 3.3, AIX 
7.2, HP-UX 11.31, IRIX 6.5, Solaris 11.4, Cygwin 3.4.6, Android 13.
+@item
+The macro @code{FNM_FILE_NAME} is not defined on some platforms:
+NetBSD 9.3, AIX 7.2, HP-UX 11.31, IRIX 6.5, Solaris 10.
+@end itemize
+
 Portability problems not fixed by Gnulib:
 @itemize
 @end itemize
diff --git a/doc/posix-functions/fnmatch.texi b/doc/posix-functions/fnmatch.texi
index 0e239f6c65..3211cc892a 100644
--- a/doc/posix-functions/fnmatch.texi
+++ b/doc/posix-functions/fnmatch.texi
@@ -6,18 +6,192 @@
 
 LSB specification:@* 
@url{https://refspecs.linuxbase.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/baselib-fnmatch-3.html}
 
+Documentation:
+@itemize
+@item
+@ifinfo
+@ref{Wildcard Matching,,Wildcard Matching,libc},
+@end ifinfo
+@ifnotinfo
+@url{https://www.gnu.org/software/libc/manual/html_node/Wildcard-Matching.html},
+@end ifnotinfo
+@item
+@uref{https://www.kernel.org/doc/man-pages/online/pages/man3/fnmatch.3.html,,man
 fnmatch}.
+@end itemize
+
 Gnulib module: fnmatch or fnmatch-gnu
 
-Portability problems fixed by Gnulib:
+Portability problems fixed by either Gnulib module @code{fnmatch} or 
@code{fnmatch-gnu}:
 @itemize
 @item
 This function is missing on some platforms:
 mingw, MSVC 14.
 @item
-This function is broken on some platforms:
-some versions of glibc, NetBSD 7.1, some versions of Solaris.
+Ranges that start or end with a backslash don't work right on some platforms:
+@c https://sourceware.org/bugzilla/show_bug.cgi?id=361
+glibc 2.3.3.
+@item
+In the pattern, an opening bracket without closing bracket does not match
+a literal @code{'['} on some platforms:
+@c https://sourceware.org/bugzilla/show_bug.cgi?id=12378
+@c Failing test cases:
+@c fnmatch ("[[:alpha:]'[:alpha:]\0]", "a", 0) == FNM_NOMATCH
+@c fnmatch ("[a[.\0.]]", "a", 0) == FNM_NOMATCH
+@c fnmatch ("[", "[", 0) == 0
+@c fnmatch ("[/b", "[/b", 0) == 0
+glibc 2.12,
+@c Failing test cases:
+@c fnmatch ("[[:alpha:]'[:alpha:]\0]", "a", 0) == FNM_NOMATCH
+@c fnmatch ("[a[.\0.]]", "a", 0) == FNM_NOMATCH
+@c fnmatch ("[", "[", 0) == 0
+@c fnmatch ("[", "]", 0) == FNM_NOMATCH
+@c fnmatch ("[/b", "[/b", 0) == 0
+macOS 12.5.
+@end itemize
+
+Portability problems fixed by Gnulib module @code{fnmatch-gnu}:
+@itemize
+@item
+This function does not support the flags @code{FNM_LEADING_DIR} and
+@code{FNM_CASEFOLD} on some platforms:
+AIX 7.2, HP-UX 11.31, IRIX 6.5, Solaris 10.
+@item
+The flag @code{FNM_CASEFOLD} does not work in many situations on some 
platforms:
+@c Failing test cases:
+@c fnmatch ("H\366hle", "H\326hLe", FNM_CASEFOLD) == 0
+@c etc.
+@c fnmatch ("\303\266zg\303\274r", "\303\226ZG\303\234R", FNM_CASEFOLD) == 0
+@c etc.
+@c fnmatch ("xy", "Xy", FNM_CASEFOLD) == 0
+@c etc.
+@c fnmatch ("\201\060\213\062zg\250\271r", 
"\201\060\211\060ZG\201\060\211\065R", FNM_CASEFOLD) == 0
+@c etc.
+NetBSD 9.3.
+@item
+The flag @code{FNM_CASEFOLD} does not work for multibyte characters
+consisting of more than one byte on some platforms:
+@c Failing test cases:
+@c fnmatch ("\303\266zg\303\274r", "\303\226ZG\303\234R", FNM_CASEFOLD) == 0
+@c etc.
+Android 13.
+@item
+This func

nstrftime: Add tests of all directives, also in non-trivial locales

2024-02-07 Thread Bruno Haible
The unit tests of module nstrftime, so far, test only a small subset of the
format directives, and only in the "C" locale. Time to extend these tests.


2024-02-07  Bruno Haible  

nstrftime: Add tests of all directives, also in non-trivial locales.
* tests/test-nstrftime.h (language_t): New type.
(locales_test): New function.
* tests/test-nstrftime.c: Include , .
(main): Invoke setlocale and locales_test.
* tests/test-nstrftime-1.sh: New file.
* tests/test-nstrftime-2.sh: New file, based on tests/test-strtod1.sh.
* modules/nstrftime-tests (Files): Add them. Add m4/locale-fr.m4,
m4/codeset.m4, m4/musl.m4.
(configure.ac): Invoke gt_LOCALE_FR, gt_LOCALE_FR_UTF8, gl_MUSL_LIBC.
(Makefile.am): Link test-nstrftime with $(SETLOCALE_LIB). Test
test-nstrftime-*.sh instead of test-nstrftime.

diff --git a/modules/nstrftime-tests b/modules/nstrftime-tests
index b30eae..24212a4f84 100644
--- a/modules/nstrftime-tests
+++ b/modules/nstrftime-tests
@@ -1,7 +1,12 @@
 Files:
+tests/test-nstrftime-1.sh
+tests/test-nstrftime-2.sh
 tests/test-nstrftime.c
 tests/test-nstrftime.h
 tests/macros.h
+m4/locale-fr.m4
+m4/codeset.m4
+m4/musl.m4
 
 Depends-on:
 atoll
@@ -10,7 +15,14 @@ intprops
 strerror
 
 configure.ac:
+gt_LOCALE_FR
+gt_LOCALE_FR_UTF8
+gl_MUSL_LIBC
 
 Makefile.am:
-TESTS += test-nstrftime
+TESTS += test-nstrftime-1.sh test-nstrftime-2.sh
+TESTS_ENVIRONMENT += \
+  LOCALE_FR='@LOCALE_FR@' \
+  LOCALE_FR_UTF8='@LOCALE_FR_UTF8@'
 check_PROGRAMS += test-nstrftime
+test_nstrftime_LDADD = $(LDADD) $(SETLOCALE_LIB)
diff --git a/tests/test-nstrftime-1.sh b/tests/test-nstrftime-1.sh
new file mode 100755
index 00..c0c4665b7e
--- /dev/null
+++ b/tests/test-nstrftime-1.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+LC_ALL=C ${CHECKER} ./test-nstrftime${EXEEXT} || exit 1
+
+exit 0
diff --git a/tests/test-nstrftime-2.sh b/tests/test-nstrftime-2.sh
new file mode 100755
index 00..c0ce75c339
--- /dev/null
+++ b/tests/test-nstrftime-2.sh
@@ -0,0 +1,41 @@
+#!/bin/sh
+
+: "${LOCALE_FR=fr_FR}"
+: "${LOCALE_FR_UTF8=fr_FR.UTF-8}"
+
+if test $LOCALE_FR = none && test $LOCALE_FR_UTF8 = none; then
+  if test -f /usr/bin/localedef; then
+echo "Skipping test: no locale for testing is installed"
+  else
+echo "Skipping test: no locale for testing is supported"
+  fi
+  exit 77
+fi
+
+final_rc=0
+
+if test $LOCALE_FR != none; then
+  LC_ALL=$LOCALE_FR  ${CHECKER} ./test-nstrftime${EXEEXT}
+  rc=$?
+  if test $rc = 77; then
+final_rc=77
+  else
+if test $rc != 0; then
+  exit 1
+fi
+  fi
+fi
+
+if test $LOCALE_FR_UTF8 != none; then
+  LC_ALL=$LOCALE_FR_UTF8 ${CHECKER} ./test-nstrftime${EXEEXT}
+  rc=$?
+  if test $rc = 77; then
+final_rc=77
+  else
+if test $rc != 0; then
+  exit 1
+fi
+  fi
+fi
+
+exit $final_rc
diff --git a/tests/test-nstrftime.c b/tests/test-nstrftime.c
index 3a76298f5e..4074874366 100644
--- a/tests/test-nstrftime.c
+++ b/tests/test-nstrftime.c
@@ -18,8 +18,12 @@
 
 #include 
 
+/* Specification.  */
 #include "strftime.h"
 
+#include 
+#include 
+
 #include "intprops.h"
 
 #include 
@@ -37,10 +41,33 @@
 int
 main (void)
 {
+  /* Try to set the locale by implicitly looking at the LC_ALL environment
+ variable.
+ configure should already have checked that the locale is supported.  */
+  if (setlocale (LC_ALL, "") == NULL)
+return 1;
+
+  bool is_C_locale = STREQ (getenv ("LC_ALL"), "C");
+
   int fail = 0;
   fail |= posixtm_test ();
   fail |= tzalloc_test ();
   fail |= quarter_test ();
   fail |= errno_test ();
+  if (is_C_locale)
+fail |= locales_test (english);
+  else
+{
+#if MUSL_LIBC
+  if (fail == 0)
+{
+  fputs ("Skipping test: musl libc does not come with localizations\n",
+ stderr);
+  return 77;
+}
+#else
+  fail |= locales_test (french);
+#endif
+}
   return fail;
 }
diff --git a/tests/test-nstrftime.h b/tests/test-nstrftime.h
index 97190a6654..5c54266043 100644
--- a/tests/test-nstrftime.h
+++ b/tests/test-nstrftime.h
@@ -1,4 +1,4 @@
-/* Test of nstrftime-like functions in the "C" locale.
+/* Test of nstrftime-like functions.
Copyright (C) 2011-2024 Free Software Foundation, Inc.
 
This program is free software: you can redistribute it and/or modify
@@ -327,6 +327,341 @@ errno_test (void)
 
 /* -- 
*/
 
+/* Test various format directives.  */
+
+typedef enum { english, french } language_t;
+
+static int
+locales_test (language_t language)
+{
+  int fail = 0;
+
+  time_t t = 150903;
+  struct tm *tm = gmtime ();
+  int ns = 123456789;
+  char buf[100];
+  size_t n;
+
+  n = FUNC (buf, sizeof buf, "%+4Y-%m-%d %H:%M:%S.%N", tm, 0, ns);
+  ASSERT (n > 0);
+  printf 

critique of gnulib

2019-08-31 Thread Bruno Haible
Dear Jonas,

Just discovered this critique of gnulib, that you wrote in 2016:
https://gitlab.com/sortix/sortix/wikis/Gnulib

It deserves a discussion.

> Gnulib is a portability layer but ironically fails to be portable,
> as it requires knowledge of implementation details of every supported
> operating system.

Yes, the word "portable" can mean two things:
  (a) a software can be compiled in a different environment without
  modifications,
  (b) a software can easily be modified for the different environment,
  so that it compiles there.

I share the disappointment with you: when I wanted to run "Portable
Common LOOPS" [1] in GNU clisp in 1992, I had to port it myself; it
wasn't portable in the sense (a) but in the sense (b).

For gnulib, sure, when you look into the files lib/mountlist.c or
lib/get_progname_of.c, you will find that often a new OS requires new
code there.

> The gnulib files included [i]n software releases tends to be rarely
> updated and bug fixes in gnulib can take several years to appear
> in most packages.

In which packages have you observed this? We would have to talk with
the maintainers of these packages, in order to understand the cause
of the problem.

> Some parts of gnulib are unnecessary and cause trouble in the modern
> world as it attempts to fix bugs in irrelevant ancient Unix systems.

This may happen, yes, unfortunately, and should be reported to bug-gnulib
when you encounter such trouble.

> Occasionally gnulib wraps standard library interfaces so code can be
> written with glibc assumptions. For instance, whether malloc(0)
> returns NULL or a unique pointer, which can't be detected at compile
> time, and the code should be rewritten to not make such assumptions
> (wrapping malloc might even make it more difficult for code analysis
> tools to detect bugs).

We are assuming that the people who run the code analysis tools do so
on glibc system, where gnulib does not wrap malloc. Developers that
use other OSes as their main OS where they run analysis tools are not
so much in the focus of the GNU project. We do care about them, but not
as much as about developers on glibc systems.

> Gnulib can occasionally cause more trouble than it solves.

These should be rare. When it occurs, feel free to report it.

> Gnulib may even indirectly have exploit mitigation counter-measures,
> as it prevents the standard library with exploit mitigations from
> being used, potentially making vulnerabilities even worse.

I don't understand this argument. Can you back it with some example,
please?

> Gnulib can be especially bad when cross-compiling, as it assumes the
> very worst about the operating system when it can't perform runtime
> tests, which leads to the maximum amount of gnulib being enabled.
> Depending on how much of gnulib is included, in the worst case, gnulib
> might attempt to replace large parts of the standard library.

All autoconf macros in gnulib have cross-compilation support for
glibc / musl systems and for native Windows, because these are the
systems for which cross-compilation is most frequently attempted.
For other platforms, we don't have made this effort, because on these
platforms programs are usually compiled natively, not cross.
And the effect of "replace large parts of the standard library" is not
that bad. Yes, it bloats the libraries and executables a bit. But that
can be afforded.

> The build system tends to assume that if it can't perform a runtime
> test, then you might have a very specific bug that got fixed in
> OpenBSD 1.4, even though you are not OpenBSD, and that OpenBSD 1.4
> is horribly ancient.

Yes, what you describe here is the Autoconf philosophy - test for a
particular bug, not for a particular operating system -, and Gnulib
follows this philosophy for the vast majority of its Autoconf tests.

It's a lesson that people learned in the 1990ies, but that is still
valid today: As e.g. the i18n code from NetBSD ("citrus") gets pulled
into other operating systems, it's no suitable to just test for NetBSD.
Or when you find many BeOS bugs to be also present in Haiku.

> The correct behavior should be assume the very best about unknown
> operating systems, and only assume a bug if the operating system
> is known to have the bug, and require the user to set the applicable
> environment variables with the true answers if gnulib guesses wrong.

No, the practice that you suggest produces more buggy programs,
because
  1. an unknown operating system often pulls in code or design from
 other operating systems,
  2. even in an OS written from scratch, the same mistakes can happen
 as have happened in existing OSes.

> Overall, you will likely find yourself wishing for gnulib to just go away.

>From your perspective as an OS author, yes, the world would be nicer if
all OSes would implement POSIX to t

Re: bug#39236: [musl] coreutils cp mishandles error return from lchmod

2020-02-08 Thread Bruno Haible
Hi Paul,

> similarly for lchmod on non-symlinks.

When I see a new autoconf test that activates an override, in order to
guarantee a certain documented behaviour, I like to add a unit test -
because in the past we several times had an override that would not
have passed the autoconf test either.

So I added a unit test for 'lchown', and found that on HP-UX 11.31 the function
could not be used because it is not declared. Which leads to these patches:


2020-02-08  Bruno Haible  

lchmod: Add tests.
* tests/test-lchmod.c: New file.
* modules/lchmod-tests: New file.

2020-02-08  Bruno Haible  

lchmod: Ensure declaration on HP-UX.
* lib/sys_stat.in.h (lchown): Declare also on HP-UX.
* doc/glibc-functions/lchmod.texi: Mention the HP-UX problem.

>From d863fc54623c497e0ed51fb0d7011415dc943434 Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Sat, 8 Feb 2020 21:22:15 +0100
Subject: [PATCH 1/2] lchmod: Ensure declaration on HP-UX.

* lib/sys_stat.in.h (lchown): Declare also on HP-UX.
* doc/glibc-functions/lchmod.texi: Mention the HP-UX problem.
---
 ChangeLog   | 6 ++
 doc/glibc-functions/lchmod.texi | 3 +++
 lib/sys_stat.in.h   | 2 +-
 3 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index fc07914..ffb2096 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2020-02-08  Bruno Haible  
 
+	lchmod: Ensure declaration on HP-UX.
+	* lib/sys_stat.in.h (lchown): Declare also on HP-UX.
+	* doc/glibc-functions/lchmod.texi: Mention the HP-UX problem.
+
+2020-02-08  Bruno Haible  
+
 	fchmodat: Strengthen tests.
 	* tests/test-fchmodat.c (BASE): New macro.
 	(main): Use it, to avoid conflicts with other unit tests. Verify that
diff --git a/doc/glibc-functions/lchmod.texi b/doc/glibc-functions/lchmod.texi
index 6cc48b4..7a2e9d0 100644
--- a/doc/glibc-functions/lchmod.texi
+++ b/doc/glibc-functions/lchmod.texi
@@ -10,6 +10,9 @@ Portability problems fixed by Gnulib:
 This function is missing on some platforms:
 OpenBSD 3.8, Minix 3.1.8, AIX 5.1, IRIX 6.5, Solaris 11.4, Cygwin, mingw, MSVC 14, Android 9.0.
 @item
+This function is not declared on some platforms:
+HP-UX 11.31.
+@item
 This function always fails with @code{errno} set to @code{ENOSYS},
 even when the file is not a symbolic link:
 GNU/Linux with glibc 2.31.
diff --git a/lib/sys_stat.in.h b/lib/sys_stat.in.h
index 4f9eb59..65661f4 100644
--- a/lib/sys_stat.in.h
+++ b/lib/sys_stat.in.h
@@ -525,7 +525,7 @@ _GL_FUNCDECL_RPL (lchmod, int,
 _GL_CXXALIAS_RPL (lchmod, int,
   (char const *filename, mode_t mode));
 # else
-#  if !@HAVE_LCHMOD@
+#  if !@HAVE_LCHMOD@ || defined __hpux
 _GL_FUNCDECL_SYS (lchmod, int, (const char *filename, mode_t mode)
_GL_ARG_NONNULL ((1)));
 #  endif
-- 
2.7.4

>From 8cc34c349afc79e2728093e109a09f9f0aaa4b50 Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Sat, 8 Feb 2020 21:24:35 +0100
Subject: [PATCH 2/2] lchmod: Add tests.

* tests/test-lchmod.c: New file.
* modules/lchmod-tests: New file.
---
 ChangeLog|  6 +
 modules/lchmod-tests | 13 ++
 tests/test-lchmod.c  | 67 
 3 files changed, 86 insertions(+)
 create mode 100644 modules/lchmod-tests
 create mode 100644 tests/test-lchmod.c

diff --git a/ChangeLog b/ChangeLog
index ffb2096..a4ee3dd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2020-02-08  Bruno Haible  
 
+	lchmod: Add tests.
+	* tests/test-lchmod.c: New file.
+	* modules/lchmod-tests: New file.
+
+2020-02-08  Bruno Haible  
+
 	lchmod: Ensure declaration on HP-UX.
 	* lib/sys_stat.in.h (lchown): Declare also on HP-UX.
 	* doc/glibc-functions/lchmod.texi: Mention the HP-UX problem.
diff --git a/modules/lchmod-tests b/modules/lchmod-tests
new file mode 100644
index 000..cbb2537
--- /dev/null
+++ b/modules/lchmod-tests
@@ -0,0 +1,13 @@
+Files:
+tests/test-lchmod.c
+tests/signature.h
+tests/macros.h
+
+Depends-on:
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-lchmod
+check_PROGRAMS += test-lchmod
+test_lchmod_LDADD = $(LDADD) @LIBINTL@
diff --git a/tests/test-lchmod.c b/tests/test-lchmod.c
new file mode 100644
index 000..783e608
--- /dev/null
+++ b/tests/test-lchmod.c
@@ -0,0 +1,67 @@
+/* Test changing the protections of a file.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along 

Re: configure messages: check for features, not for bugs

2020-08-26 Thread Bruno Haible
Date: Thu, 27 Aug 2020 00:56:09 +0200
Subject: [PATCH 4/9] getcwd: Change configure message.

* m4/getcwd-abort-bug.m4 (gl_FUNC_GETCWD_ABORT_BUG): Say "checking
whether getcwd succeeds when 4k < cwd_length < 16k..." instead of
"checking whether getcwd aborts when 4k < cwd_length < 16k...".
---
 ChangeLog  |  7 +++
 m4/getcwd-abort-bug.m4 | 26 +-
 2 files changed, 20 insertions(+), 13 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 7ac92db..eb7ef9b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
 2020-08-26  Bruno Haible  
 
+	getcwd: Change configure message.
+	* m4/getcwd-abort-bug.m4 (gl_FUNC_GETCWD_ABORT_BUG): Say "checking
+	whether getcwd succeeds when 4k < cwd_length < 16k..." instead of
+	"checking whether getcwd aborts when 4k < cwd_length < 16k...".
+
+2020-08-26  Bruno Haible  
+
 	chdir-long: Change configure message.
 	* m4/chdir-long.m4 (gl_FUNC_CHDIR_LONG): Say "checking whether this
 	system supports file names of any length..." instead of "checking
diff --git a/m4/getcwd-abort-bug.m4 b/m4/getcwd-abort-bug.m4
index 9817912..b5cf86e 100644
--- a/m4/getcwd-abort-bug.m4
+++ b/m4/getcwd-abort-bug.m4
@@ -1,4 +1,4 @@
-# serial 14
+# serial 15
 # Determine whether getcwd aborts when the length of the working directory
 # name is unusually large.  Any length between 4k and 16k trigger the bug
 # when using glibc-2.4.90-9 or older.
@@ -10,7 +10,7 @@
 
 # From Jim Meyering
 
-# gl_FUNC_GETCWD_ABORT_BUG([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+# gl_FUNC_GETCWD_ABORT_BUG([ACTION-IF-BUGGY[, ACTION-IF-WORKS]])
 AC_DEFUN([gl_FUNC_GETCWD_ABORT_BUG],
 [
   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
@@ -24,8 +24,8 @@ AC_DEFUN([gl_FUNC_GETCWD_ABORT_BUG],
   [Define to 1 if the system has the 'getpagesize' function.])
   fi
 
-  AC_CACHE_CHECK([whether getcwd aborts when 4k < cwd_length < 16k],
-[gl_cv_func_getcwd_abort_bug],
+  AC_CACHE_CHECK([whether getcwd succeeds when 4k < cwd_length < 16k],
+[gl_cv_func_getcwd_succeeds_beyond_4k],
 [# Remove any remnants of a previous test.
  rm -rf confdir-14B---
  # Arrange for deletion of the temporary directory this test creates.
@@ -126,7 +126,7 @@ main ()
   return fail;
 }
   ]])],
-   [gl_cv_func_getcwd_abort_bug=no],
+   [gl_cv_func_getcwd_succeeds_beyond_4k=yes],
[dnl An abort will provoke an exit code of something like 134 (128 + 6).
 dnl An exit code of 4 can also occur (in OpenBSD 6.7, NetBSD 5.1 for
 dnl example): getcwd (NULL, 0) fails rather than returning a string
@@ -135,21 +135,21 @@ main ()
 dnl provide a non-NULL value in this case.
 ret=$?
 if test $ret -ge 128 || test $ret = 4; then
-  gl_cv_func_getcwd_abort_bug=yes
+  gl_cv_func_getcwd_succeeds_beyond_4k=no
 else
-  gl_cv_func_getcwd_abort_bug=no
+  gl_cv_func_getcwd_succeeds_beyond_4k=yes
 fi
],
[case "$host_os" in
-   # Guess no on musl systems.
-  *-musl*) gl_cv_func_getcwd_abort_bug="guessing no" ;;
-   # Guess yes otherwise, even on glibc systems.
-  *)   gl_cv_func_getcwd_abort_bug="guessing yes"
+   # Guess yes on musl systems.
+  *-musl*) gl_cv_func_getcwd_succeeds_beyond_4k="guessing yes" ;;
+   # Guess no otherwise, even on glibc systems.
+  *)   gl_cv_func_getcwd_succeeds_beyond_4k="guessing no"
 esac
])
 ])
-  case "$gl_cv_func_getcwd_abort_bug" in
-*yes)
+  case "$gl_cv_func_getcwd_succeeds_beyond_4k" in
+*no)
   $1
   ;;
 *)
-- 
2.7.4

>From a7bdbd1d4cdca3c7f3b951f0ce551040a90cf5cd Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Thu, 27 Aug 2020 01:04:36 +0200
Subject: [PATCH 5/9] include_next: Change configure message.

* m4/include_next.m4 (gl_INCLUDE_NEXT): Say "checking whether source
code line length is unlimited..." instead of "checking whether system
header files limit the line length...".
---
 ChangeLog  |  7 +++
 m4/include_next.m4 | 18 ++
 2 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index eb7ef9b..6f32743 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
 2020-08-26  Bruno Haible  
 
+	include_next: Change configure message.
+	* m4/include_next.m4 (gl_INCLUDE_NEXT): Say "checking whether source
+	code line length is unlimited..." instead of "checking whether system
+	header files limit the line length...".
+
+2020-08-26  Bruno Haible  
+
 	getcwd: Change configure message.
 	* m4/getcwd-abort-bug.m4 (gl_FUNC_GETCWD_ABORT_BUG): Say "checking
 	whether getcwd succeeds when 4k < cwd_length < 16k..." instead of
diff --git a/m4/include_next.m4 

configure messages: check for features, not for bugs

2020-07-26 Thread Bruno Haible
file_name_length = no]
+fcntl-h [test $gl_cv_have_unlimited_file_name_length = no]
+openat  [test $gl_cv_have_unlimited_file_name_length = no]
+memchr  [test $gl_cv_have_unlimited_file_name_length = no]
+mempcpy [test $gl_cv_have_unlimited_file_name_length = no]
+memrchr [test $gl_cv_have_unlimited_file_name_length = no]
+stdbool [test $gl_cv_have_unlimited_file_name_length = no]
+stdlib  [test $gl_cv_have_unlimited_file_name_length = no]
 
 configure.ac:
 gl_FUNC_CHDIR_LONG
-if test $gl_cv_have_arbitrary_file_name_length_limit = yes; then
+if test $gl_cv_have_unlimited_file_name_length = no; then
   AC_LIBOBJ([chdir-long])
   gl_PREREQ_CHDIR_LONG
 fi
-- 
2.7.4

>From 005ad2fba399ed226cfd50abb2136d1d3f7deb9e Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Sun, 26 Jul 2020 14:26:28 +0200
Subject: [PATCH 2/3] getcwd: Change configure message.

* m4/getcwd-abort-bug.m4 (gl_FUNC_GETCWD_ABORT_BUG): Say "checking
whether getcwd succeeds when 4k < cwd_length < 16k..." instead of
"checking whether getcwd aborts when 4k < cwd_length < 16k...".
---
 ChangeLog  |  7 +++
 m4/getcwd-abort-bug.m4 | 26 +-
 2 files changed, 20 insertions(+), 13 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index f31b16a..a4312ff 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
 2020-07-26  Bruno Haible  
 
+	getcwd: Change configure message.
+	* m4/getcwd-abort-bug.m4 (gl_FUNC_GETCWD_ABORT_BUG): Say "checking
+	whether getcwd succeeds when 4k < cwd_length < 16k..." instead of
+	"checking whether getcwd aborts when 4k < cwd_length < 16k...".
+
+2020-07-26  Bruno Haible  
+
 	chdir-long: Change configure message.
 	* m4/chdir-long.m4 (gl_FUNC_CHDIR_LONG): Say "checking whether this
 	system supports file names of any length..." instead of "checking
diff --git a/m4/getcwd-abort-bug.m4 b/m4/getcwd-abort-bug.m4
index 2715f0a..96c1370 100644
--- a/m4/getcwd-abort-bug.m4
+++ b/m4/getcwd-abort-bug.m4
@@ -1,4 +1,4 @@
-# serial 11
+# serial 12
 # Determine whether getcwd aborts when the length of the working directory
 # name is unusually large.  Any length between 4k and 16k trigger the bug
 # when using glibc-2.4.90-9 or older.
@@ -10,7 +10,7 @@
 
 # From Jim Meyering
 
-# gl_FUNC_GETCWD_ABORT_BUG([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+# gl_FUNC_GETCWD_ABORT_BUG([ACTION-IF-BUGGY[, ACTION-IF-WORKS]])
 AC_DEFUN([gl_FUNC_GETCWD_ABORT_BUG],
 [
   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
@@ -24,8 +24,8 @@ AC_DEFUN([gl_FUNC_GETCWD_ABORT_BUG],
   [Define to 1 if the system has the 'getpagesize' function.])
   fi
 
-  AC_CACHE_CHECK([whether getcwd aborts when 4k < cwd_length < 16k],
-[gl_cv_func_getcwd_abort_bug],
+  AC_CACHE_CHECK([whether getcwd succeeds when 4k < cwd_length < 16k],
+[gl_cv_func_getcwd_succeeds_beyond_4k],
 [# Remove any remnants of a previous test.
  rm -rf confdir-14B---
  # Arrange for deletion of the temporary directory this test creates.
@@ -128,7 +128,7 @@ main ()
   return fail;
 }
   ]])],
-   [gl_cv_func_getcwd_abort_bug=no],
+   [gl_cv_func_getcwd_succeeds_beyond_4k=yes],
[dnl An abort will provoke an exit code of something like 134 (128 + 6).
 dnl An exit code of 4 can also occur (in OpenBSD 4.9, NetBSD 5.1 for
     dnl example): getcwd (NULL, 0) fails rather than returning a string
@@ -137,21 +137,21 @@ main ()
 dnl provide a non-NULL value in this case.
 ret=$?
 if test $ret -ge 128 || test $ret = 4; then
-  gl_cv_func_getcwd_abort_bug=yes
+  gl_cv_func_getcwd_succeeds_beyond_4k=no
 else
-  gl_cv_func_getcwd_abort_bug=no
+  gl_cv_func_getcwd_succeeds_beyond_4k=yes
 fi
],
[case "$host_os" in
-   # Guess no on musl systems.
-  *-musl*) gl_cv_func_getcwd_abort_bug="guessing no" ;;
-   # Guess yes otherwise, even on glibc systems.
-  *)   gl_cv_func_getcwd_abort_bug="guessing yes"
+   # Guess yes on musl systems.
+  *-musl*) gl_cv_func_getcwd_succeeds_beyond_4k="guessing yes" ;;
+   # Guess no otherwise, even on glibc systems.
+  *)   gl_cv_func_getcwd_succeeds_beyond_4k="guessing no"
 esac
])
 ])
-  case "$gl_cv_func_getcwd_abort_bug" in
-*yes)
+  case "$gl_cv_func_getcwd_succeeds_beyond_4k" in
+*no)
   $1
   ;;
 *)
-- 
2.7.4

>From 088335c21cc03f0034feec15fb63a2d8cef71625 Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Sun, 26 Jul 2020 14:46:42 +0200
Subject: [PATCH 3/3] include_next: Change configure message.

* m4/include_next.m4 (gl_INCLUDE_NEXT): Say "checking whether source
code line length is unlimited..." instead of &qu

[PATCH] Further improve cross-compilation guesses for midipix

2024-02-02 Thread Ørjan Malde
from running the testsuite:
PASS: test-nanosleep
PASS: test-ftruncate.sh
PASS: test-utime
PASS: test-utimens
PASS: test-utimensat
PASS: test-rename

hopefully this time my contribution is less noisy. :-)

Regards,
Ørjan

>From 3feffaa8b70de4b8bf1491006a871bda63ca31f2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=98rjan=20Malde?= 
Date: Fri, 2 Feb 2024 12:31:55 +0100
Subject: [PATCH] Further improve cross-compilation for midipix.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Ørjan Malde 
---
 ChangeLog   | 11 +++
 m4/nanosleep.m4 |  5 -
 m4/rename.m4|  4 +++-
 m4/truncate.m4  |  4 +++-
 m4/utime.m4 |  4 +++-
 m4/utimens.m4   |  4 +++-
 m4/utimensat.m4 |  5 -
 7 files changed, 31 insertions(+), 6 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 4711be3dd9..1598d17c51 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2024-02-02  Ørjan Malde  
+
+   Further improve cross-compilation for midipix.
+* m4/nanosleep.m4 (gl_FUNC_NANOSLEEP): Guess yes for midipix.
+* m4/rename.m4 (gl_FUNC_RENAME): Treat midipix like Linux with glibc or
+   musl libc.
+* m4/truncate.m4 (gl_FUNC_TRUNCATE): Likewise.
+* m4/utime.m4 (gl_FUNC_UTIME): Likewise.
+* m4/utimens.m4 (gl_UTIMENS): Likewise.
+* m4/utimensat.m4 (gl_FUNC_UTIMENSAT): Likewise.
+
 2024-01-31  Bruno Haible  

Implement 3 new properties, added by Unicode 15.1.0.
diff --git a/m4/nanosleep.m4 b/m4/nanosleep.m4
index c51f590402..df87d856f1 100644
--- a/m4/nanosleep.m4
+++ b/m4/nanosleep.m4
@@ -1,4 +1,4 @@
-# serial 46
+# serial 47

 dnl From Jim Meyering.
 dnl Check for the nanosleep function.
@@ -119,6 +119,9 @@ AC_DEFUN([gl_FUNC_NANOSLEEP],
 # Guess it halfway works when the kernel is Linux.
   linux*)
 gl_cv_func_nanosleep='guessing no (mishandles large arguments)' ;;
+# Guess yes on systems that emulate the Linux system calls.
+  midipix*)
+gl_cv_func_nanosleep'guessing yes' ;;
 # Guess no on native Windows.
   mingw* | windows*)
 gl_cv_func_nanosleep='guessing no' ;;
diff --git a/m4/rename.m4 b/m4/rename.m4
index 5383b3ea52..62f17906d0 100644
--- a/m4/rename.m4
+++ b/m4/rename.m4
@@ -1,4 +1,4 @@
-# serial 36
+# serial 37

 # Copyright (C) 2001, 2003, 2005-2006, 2009-2024 Free Software Foundation, Inc.
 # This file is free software; the Free Software Foundation
@@ -239,6 +239,8 @@ AC_DEFUN([gl_FUNC_RENAME],
   [case "$host_os" in
 # Guess yes on Linux systems.
  linux-* | linux)   gl_cv_func_rename_dest_works="guessing yes" ;;
+# Guess yes on systems that emulate the Linux 
system calls.
+ midipix*)  gl_cv_func_rename_dest_works="guessing yes" ;;
 # Guess yes on glibc systems.
  *-gnu*)gl_cv_func_rename_dest_works="guessing yes" ;;
 # Guess no on native Windows.
diff --git a/m4/truncate.m4 b/m4/truncate.m4
index 727832224a..dd21f4b4ca 100644
--- a/m4/truncate.m4
+++ b/m4/truncate.m4
@@ -1,4 +1,4 @@
-# truncate.m4 serial 6   -*- Autoconf -*-
+# truncate.m4 serial 7   -*- Autoconf -*-
 dnl Copyright (C) 2017-2024 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -50,6 +50,8 @@ AC_DEFUN([gl_FUNC_TRUNCATE],
[case "$host_os" in
# Guess yes on Linux systems.
   linux-* | linux) gl_cv_func_truncate_works="guessing yes" ;;
+   # Guess yes on systems that emulate the Linux 
system calls.
+  midipix*)gl_cv_func_truncate_works="guessing yes" ;;
# Guess yes on glibc systems.
   *-gnu* | gnu*)   gl_cv_func_truncate_works="guessing yes" ;;
# Guess no on AIX systems.
diff --git a/m4/utime.m4 b/m4/utime.m4
index 0009e4f2f9..0ee9bec4ad 100644
--- a/m4/utime.m4
+++ b/m4/utime.m4
@@ -1,4 +1,4 @@
-# utime.m4 serial 5
+# utime.m4 serial 6
 dnl Copyright (C) 2017-2024 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -50,6 +50,8 @@ AC_DEFUN([gl_FUNC_UTIME],
  [case "$host_os" in
  # Guess yes on Linux systems.
 linux-* | linux) gl_cv_func_utime_file_slash="guessing yes" ;;
+ # Guess yes on systems that emulate the Linux 
system calls.
+midipix*)gl_cv_func_utime_file_slash="guessing yes" ;;
  # Guess yes on glibc systems.

physmem: Port better to Linux

2024-04-24 Thread Bruno Haible
physical memory that can be claimed, with a given
+   aggressivity.
+   For AGGRESSIVITY == 0.0, the result is like physmem_available (): the amount
+   of memory the application can use without hindering any other process.
+   For AGGRESSIVITY == 1,0, the result is the amount of memory the application
+   can use, while causing memory shortage to other processes, but without
+   bringing the machine into an out-of-memory state.
+   Values in between, for example AGGRESSIVITY == 0.5, are a reasonable middle
+   ground.  */
+double physmem_claimable (double aggressivity);
+

 #ifdef __cplusplus
 }
diff --git a/lib/physmem.c b/lib/physmem.c
index e6eb26b5f3..5c226b8abf 100644
--- a/lib/physmem.c
+++ b/lib/physmem.c
@@ -22,25 +22,28 @@
 
 #include "physmem.h"
 
+#include 
+#include 
 #include 
 
-#if HAVE_SYS_PSTAT_H
+#if HAVE_SYS_PSTAT_H /* HP-UX */
 # include 
 #endif
 
-#if HAVE_SYS_SYSMP_H
+#if HAVE_SYS_SYSMP_H /* IRIX */
 # include 
 #endif
 
 #if HAVE_SYS_SYSINFO_H
+/* Linux, AIX, HP-UX, IRIX, OSF/1, Solaris, Cygwin, Android */
 # include 
 #endif
 
-#if HAVE_MACHINE_HAL_SYSINFO_H
+#if HAVE_MACHINE_HAL_SYSINFO_H /* OSF/1 */
 # include 
 #endif
 
-#if HAVE_SYS_TABLE_H
+#if HAVE_SYS_TABLE_H /* OSF/1 */
 # include 
 #endif
 
@@ -51,13 +54,16 @@
 #endif
 
 #if HAVE_SYS_SYSCTL_H && !(defined __GLIBC__ && defined __linux__)
+/* Linux/musl, macOS, *BSD, IRIX, Minix */
 # include 
 #endif
 
-#if HAVE_SYS_SYSTEMCFG_H
+#if HAVE_SYS_SYSTEMCFG_H /* AIX */
 # include 
 #endif
 
+#include "full-read.h"
+
 #ifdef _WIN32
 
 # define WIN32_LEAN_AND_MEAN
@@ -203,11 +209,84 @@ physmem_total (void)
   return 64 * 1024 * 1024;
 }
 
-/* Return the amount of physical memory available.  */
+#if defined __linux__
+
+/* Get the amount of free memory and of inactive file cache memory, and
+   return 0.  Upon failure, return -1.  */
+static int
+get_meminfo (unsigned long long *mem_free_p,
+ unsigned long long *mem_inactive_file_p)
+{
+  /* While the sysinfo() system call returns mem_total, mem_free, and a few
+ other numbers, the only way to get mem_inactive_file is by reading
+ /proc/meminfo.  */
+  int fd = open ("/proc/meminfo", O_RDONLY);
+  if (fd >= 0)
+{
+  char buf[4096];
+  size_t buf_size = full_read (fd, buf, sizeof (buf));
+  close (fd);
+  if (buf_size > 0)
+{
+  char *buf_end = buf + buf_size;
+  unsigned long long mem_free = 0;
+  unsigned long long mem_inactive_file = 0;
+
+  /* Iterate through the lines.  */
+  char *line = buf;
+  for (;;)
+{
+  char *p;
+  for (p = line; p < buf_end; p++)
+if (*p == '\n')
+  break;
+  if (p == buf_end)
+break;
+  *p = '\0';
+  if (sscanf (line, "MemFree: %llu kB", _free) == 1)
+{
+  mem_free *= 1024;
+}
+  if (sscanf (line, "Inactive(file): %llu kB", _inactive_file) 
== 1)
+{
+  mem_inactive_file *= 1024;
+}
+  line = p + 1;
+}
+  if (mem_free > 0 && mem_inactive_file > 0)
+{
+  *mem_free_p = mem_free;
+  *mem_inactive_file_p = mem_inactive_file;
+  return 0;
+}
+}
+}
+  return -1;
+}
+
+#endif
+
+/* Return the amount of physical memory that can be claimed, with a given
+   aggressivity.  */
 double
-physmem_available (void)
+physmem_claimable (double aggressivity)
 {
 #if defined _SC_AVPHYS_PAGES && defined _SC_PAGESIZE
+# if defined __linux__
+  /* On Linux, sysconf (_SC_AVPHYS_PAGES) returns the amount of "free" memory.
+ The Linux memory management system attempts to keep only a small amount
+ of memory (something like 5% to 10%) as free, because memory is better
+ used in the file cache.
+ We compute the "claimable" memory as
+   (free memory) + aggressivity * (inactive memory in the file cache).  */
+  if (aggressivity > 0.0)
+{
+  unsigned long long mem_free;
+  unsigned long long mem_inactive_file;
+  if (get_meminfo (_free, _inactive_file) == 0)
+return (double) mem_free + aggressivity * (double) mem_inactive_file;
+}
+# endif
   { /* This works on linux-gnu, kfreebsd-gnu, solaris2, and cygwin.  */
 double pages = sysconf (_SC_AVPHYS_PAGES);
 double pagesize = sysconf (_SC_PAGESIZE);
@@ -312,6 +391,12 @@ physmem_available (void)
   return physmem_total () / 4;
 }
 
+/* Return the amount of physical memory available.  */
+double
+physmem_available (void)
+{
+  return physmem_claimable (0.0);
+}
 
 #if DEBUG
 
diff --git a/modules/physmem b/modules/physmem
index 2cb7e7f64a..e1a4a76700 100644
--- a/modules/physmem
+++ b/modules/physmem
@@ -8,6 +8,7 @@ m4/physmem.m4
 
 Depends-on:
 unistd
+full-read
 
 configure.ac:
 gl_PHYSMEM






*printf-posix: Work around bug with %lc of 0 on many platforms

2023-03-21 Thread Bruno Haible
After adding a few more tests for *printf %c and %lc, I noticed yet another
*printf bug. This time not in musl libc, but in _all_ platforms other than
musl libc.

For glibc, I registered it as
https://sourceware.org/bugzilla/show_bug.cgi?id=30257 .

This patch adds a workaround to the (narrow) *printf-posix modules.


2023-03-21  Bruno Haible  

*printf-posix: Work around bug with %lc of 0 on many platforms.
* lib/vasnprintf.c (local_wctomb): Define also for
NEED_PRINTF_DIRECTIVE_LC.
(VASNPRINTF): Implement %lc handling ourselves if
NEED_PRINTF_DIRECTIVE_LC.
* m4/printf.m4 (gl_PRINTF_DIRECTIVE_LC): New macro.
* m4/vasnprintf.m4 (gl_PREREQ_VASNPRINTF_DIRECTIVE_LC): New macro.
(gl_PREREQ_VASNPRINTF_WITH_EXTRAS): Invoke it.
* m4/dprintf-posix.m4 (gl_FUNC_DPRINTF_POSIX): Require
gl_PRINTF_DIRECTIVE_LC and test its result. Invoke
gl_PREREQ_VASNPRINTF_DIRECTIVE_LC.
* m4/fprintf-posix.m4 (gl_FUNC_FPRINTF_POSIX): Likewise.
* m4/obstack-printf-posix.m4 (gl_FUNC_OBSTACK_PRINTF_POSIX): Likewise.
* m4/snprintf-posix.m4 (gl_FUNC_SNPRINTF_POSIX): Likewise.
* m4/sprintf-posix.m4 (gl_FUNC_SPRINTF_POSIX): Likewise.
* m4/vasnprintf-posix.m4 (gl_FUNC_VASNPRINTF_POSIX): Likewise.
* m4/vasprintf-posix.m4 (gl_FUNC_VASPRINTF_POSIX): Likewise.
* m4/vdprintf-posix.m4 (gl_FUNC_VDPRINTF_POSIX): Likewise.
* m4/vfprintf-posix.m4 (gl_FUNC_VFPRINTF_POSIX): Likewise.
* m4/vsnprintf-posix.m4 (gl_FUNC_VSNPRINTF_POSIX): Likewise.
* m4/vsprintf-posix.m4 (gl_FUNC_VSPRINTF_POSIX): Likewise.
* tests/test-snprintf-posix.h (test_function): Add more tests for the
%c and %lc directives.
* tests/test-sprintf-posix.h (test_function): Likewise.
* tests/test-vasnprintf-posix.c (test_function): Likewise.
* tests/test-vasprintf-posix.c (test_function): Likewise.
* doc/glibc-functions/asprintf.texi: Mention the %lc 0 bug.
* doc/glibc-functions/obstack_printf.texi: Likewise.
* doc/glibc-functions/obstack_vprintf.texi: Likewise.
* doc/glibc-functions/vasprintf.texi: Likewise.
* doc/posix-functions/dprintf.texi: Likewise.
* doc/posix-functions/fprintf.texi: Likewise.
* doc/posix-functions/printf.texi: Likewise.
* doc/posix-functions/snprintf.texi: Likewise.
* doc/posix-functions/sprintf.texi: Likewise.
* doc/posix-functions/vdprintf.texi: Likewise.
* doc/posix-functions/vfprintf.texi: Likewise.
* doc/posix-functions/vprintf.texi: Likewise.
* doc/posix-functions/vsnprintf.texi: Likewise.
* doc/posix-functions/vsprintf.texi: Likewise.

diff --git a/doc/glibc-functions/asprintf.texi 
b/doc/glibc-functions/asprintf.texi
index 47708c40fb..70de08dd1c 100644
--- a/doc/glibc-functions/asprintf.texi
+++ b/doc/glibc-functions/asprintf.texi
@@ -71,6 +71,10 @@
 with zeroes) on some platforms:
 Mac OS X 10.5, FreeBSD 6.0, NetBSD 5.0, Solaris 11.0, Cygwin 1.5.x.
 @item
+This function produces wrong output for the @samp{lc} directive with a NUL
+wide character argument on some platforms:
+glibc 2.35, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2, macOS 12.5, AIX 7.2, 
Solaris 11.4, and others.
+@item
 This function can crash in out-of-memory conditions on some platforms:
 FreeBSD 13.0, NetBSD 5.0.
 @end itemize
diff --git a/doc/glibc-functions/obstack_printf.texi 
b/doc/glibc-functions/obstack_printf.texi
index 7feae78b36..8b13e1296e 100644
--- a/doc/glibc-functions/obstack_printf.texi
+++ b/doc/glibc-functions/obstack_printf.texi
@@ -77,6 +77,10 @@
 floating-point and pointer output on some platforms:
 Solaris 10/x86, mingw, MSVC/clang.
 @item
+This function produces wrong output for the @samp{lc} directive with a NUL
+wide character argument on some platforms:
+glibc 2.35, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2, macOS 12.5, AIX 7.2, 
Solaris 11.4, and others.
+@item
 This function can crash in out-of-memory conditions on some platforms:
 FreeBSD 13.0, NetBSD 5.0.
 @item
diff --git a/doc/glibc-functions/obstack_vprintf.texi 
b/doc/glibc-functions/obstack_vprintf.texi
index cdded10221..2ea59ef4fa 100644
--- a/doc/glibc-functions/obstack_vprintf.texi
+++ b/doc/glibc-functions/obstack_vprintf.texi
@@ -77,6 +77,10 @@
 floating-point and pointer output on some platforms:
 Solaris 10/x86, mingw, MSVC/clang.
 @item
+This function produces wrong output for the @samp{lc} directive with a NUL
+wide character argument on some platforms:
+glibc 2.35, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2, macOS 12.5, AIX 7.2, 
Solaris 11.4, and others.
+@item
 This function can crash in out-of-memory conditions on some platforms:
 FreeBSD 13.0, NetBSD 5.0.
 @item
diff --git a/doc/glibc-functions/vasprintf.texi 
b/doc/glibc-functions/vasprintf.texi
index 2f69df8e78..ef1be6bb88 100644
--- a/doc/glibc-functions/vasprintf.texi
+++ b/doc/glibc-functions/vasprintf.texi
@@ -71,6 +71,10 @@
 with zeroes

striconveha, uniconv/*: avoid test failures on musl libc

2018-02-24 Thread Bruno Haible
On Alpine Linux 3.7.0, which uses musl libc, I see these test failures in
libunistring:

FAIL: test-striconveha
==

../../tests/test-striconveha.c:327: assertion 'retval == 0' failed
FAIL test-striconveha (exit status: 134)

FAIL: test-u16-conv-from-enc


../../tests/uniconv/test-u16-conv-from-enc.c:137: assertion 'result != NULL' 
failed
FAIL test-u16-conv-from-enc (exit status: 134)

FAIL: test-u16-strconv-from-enc
===

../../tests/uniconv/test-u16-strconv-from-enc.c:84: assertion 'result != NULL' 
failed
FAIL test-u16-strconv-from-enc (exit status: 134)

FAIL: test-u32-conv-from-enc


../../tests/uniconv/test-u32-conv-from-enc.c:137: assertion 'result != NULL' 
failed
FAIL test-u32-conv-from-enc (exit status: 134)

FAIL: test-u32-strconv-from-enc
===

../../tests/uniconv/test-u32-strconv-from-enc.c:84: assertion 'result != NULL' 
failed
FAIL test-u32-strconv-from-enc (exit status: 134)

FAIL: test-u8-conv-from-enc
===

../../tests/uniconv/test-u8-conv-from-enc.c:129: assertion 'result != NULL' 
failed
FAIL test-u8-conv-from-enc (exit status: 134)

FAIL: test-u8-strconv-from-enc
==

../../tests/uniconv/test-u8-strconv-from-enc.c:72: assertion 'result != NULL' 
failed
FAIL test-u8-strconv-from-enc (exit status: 134)


The cause is that musl libc does not support the ISO-2022-JP-2 encoding. This
patch fixes it.


Bruno
From 4ce7971770b49e84447e680c823a769240286978 Mon Sep 17 00:00:00 2001
From: Bruno Haible <br...@clisp.org>
Date: Sat, 24 Feb 2018 15:21:11 +0100
Subject: [PATCH] striconveha, uniconv/*: Avoid test failures on musl libc.

* tests/iconvsupport.c: New file.
* tests/test-striconveha.c (main): Skip autodetect_jp tests if iconv()
does not support the ISO-2022-JP-2 encoding.
* tests/uniconv/test-u8-conv-from-enc.c (main): Likewise.
* tests/uniconv/test-u8-strconv-from-enc.c (main): Likewise.
* tests/uniconv/test-u16-conv-from-enc.c (main): Likewise.
* tests/uniconv/test-u16-strconv-from-enc.c (main): Likewise.
* tests/uniconv/test-u32-conv-from-enc.c (main): Likewise.
* tests/uniconv/test-u32-strconv-from-enc.c (main): Likewise.
* modules/striconveha-tests (Files): Add tests/iconvsupport.c.
(Makefile.am): Link test-striconveha with iconvsupport.o.
* modules/uniconv/u8-conv-from-enc-tests (Files): Add
tests/iconvsupport.c.
(Makefile.am): Link test-u8-conv-from-enc with iconvsupport.o.
* modules/uniconv/u8-strconv-from-enc-tests (Files): Add
tests/iconvsupport.c.
(Makefile.am): Link test-u8-strconv-from-enc with iconvsupport.o.
* modules/uniconv/u16-conv-from-enc-tests (Files): Add
tests/iconvsupport.c.
(Makefile.am): Link test-u16-conv-from-enc with iconvsupport.o.
* modules/uniconv/u16-strconv-from-enc-tests (Files): Add
tests/iconvsupport.c.
(Makefile.am): Link test-u16-strconv-from-enc with iconvsupport.o.
* modules/uniconv/u32-conv-from-enc-tests (Files): Add
tests/iconvsupport.c.
(Makefile.am): Link test-u32-conv-from-enc with iconvsupport.o.
* modules/uniconv/u32-strconv-from-enc-tests (Files): Add
tests/iconvsupport.c.
(Makefile.am): Link test-u32-strconv-from-enc with iconvsupport.o.
---
 ChangeLog  |  33 +
 modules/striconveha-tests  |   2 +
 modules/uniconv/u16-conv-from-enc-tests|   3 +-
 modules/uniconv/u16-strconv-from-enc-tests |   3 +-
 modules/uniconv/u32-conv-from-enc-tests|   3 +-
 modules/uniconv/u32-strconv-from-enc-tests |   3 +-
 modules/uniconv/u8-conv-from-enc-tests |   3 +-
 modules/uniconv/u8-strconv-from-enc-tests  |   3 +-
 tests/iconvsupport.c   |  39 +
 tests/test-striconveha.c   | 219 +++--
 tests/uniconv/test-u16-conv-from-enc.c | 164 ++---
 tests/uniconv/test-u16-strconv-from-enc.c  |  74 +-
 tests/uniconv/test-u32-conv-from-enc.c | 164 ++---
 tests/uniconv/test-u32-strconv-from-enc.c  |  74 +-
 tests/uniconv/test-u8-conv-from-enc.c  | 146 +--
 tests/uniconv/test-u8-strconv-from-enc.c   |  62 
 16 files changed, 553 insertions(+), 442 deletions(-)
 create mode 100644 tests/iconvsupport.c

diff --git a/ChangeLog b/ChangeLog
index 58d9971..266b41b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,38 @@
 2018-02-24  Bruno Haible  <br...@clisp.org>
 
+	striconveha, uniconv/*: Avoid test failures on musl libc.
+	* tests/iconvsupport.c: New file.
+	* tests/test-striconveha.c (main): Skip autodetect_jp tests if iconv()
+	does not support the ISO-2022-JP-2 encoding.
+	* tests/uniconv/test-u8-conv-from-enc.c (main): Likewise.
+	* tests/uniconv/test-u8-strconv-from-enc.c (main): Likewise.
+	* tests/uniconv/test-u16-conv-from-enc.c (main): Likewise.
+	* tests/uniconv/test-u16-strconv-from-enc.c (main): Likewise.
+	* tests/uniconv/test-u32-conv-from-enc.c (main): Likewis

nl_langinfo: fix multithread-safety bugs

2019-12-17 Thread Bruno Haible
This series of patches makes gnulib's nl_langinfo replacement multithread-safe.

The nl_langinfo of the various platforms is already multithread-safe (as shown
by the new unit test, which I let run for 30 seconds on each platform) -
nothing to fix on this side.


2019-12-17  Bruno Haible  

langinfo: Document more details.
* doc/posix-headers/langinfo.texi: List platform details.
* doc/posix-functions/nl_langinfo.texi: Likewise.

nl_langinfo: Fix multithread-safety bug on mingw and MSVC.
* lib/nl_langinfo.c (ctype_codeset, rpl_nl_langinfo): Use a
stack-allocated buffer to assemble each result and different static
buffers to return it.
* tests/test-nl_langinfo-mt.c: New file.
* modules/nl_langinfo-tests (Files): Add it.
(Depends-on): Add thread, nanosleep.
(Makefile.am): Build test-nl_langinfo-mt test.

nl_langinfo: Fix multithread-safety bug on OpenBSD 3.8.
* lib/nl_langinfo.c (ctype_codeset): Invoke setlocale_null instead of
setlocale.
* m4/nl_langinfo.m4 (gl_FUNC_NL_LANGINFO): Require
gl_FUNC_SETLOCALE_NULL. Set LIB_NL_LANGINFO.
* modules/nl_langinfo (Depends-on): Add setlocale-null.
From 9accf385430eabe2874a81121d7781943ca7a292 Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Tue, 17 Dec 2019 12:21:07 +0100
Subject: [PATCH 1/3] langinfo: Document more details.

* doc/posix-headers/langinfo.texi: List platform details.
* doc/posix-functions/nl_langinfo.texi: Likewise.
---
 ChangeLog| 6 ++
 doc/posix-functions/nl_langinfo.texi | 2 +-
 doc/posix-headers/langinfo.texi  | 2 +-
 3 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index b8b301d..9027da4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2019-12-17  Bruno Haible  
 
+	langinfo: Document more details.
+	* doc/posix-headers/langinfo.texi: List platform details.
+	* doc/posix-functions/nl_langinfo.texi: Likewise.
+
+2019-12-17  Bruno Haible  
+
 	mbsinit: Fix compilation error in mingw-w64 7.0 with _UCRT defined.
 	Reported by Tom Kacvinsky 
 	and Martin Storsjö 
diff --git a/doc/posix-functions/nl_langinfo.texi b/doc/posix-functions/nl_langinfo.texi
index 058d745..7daaa9e 100644
--- a/doc/posix-functions/nl_langinfo.texi
+++ b/doc/posix-functions/nl_langinfo.texi
@@ -17,7 +17,7 @@ OpenBSD 3.8.
 @item
 The constants @code{ALTMON_1} to @code{ALTMON_12} are not defined on some
 platforms:
-glibc 2.26 and many others.
+glibc 2.26, musl libc, Mac OS X 10.13, NetBSD 8.0, OpenBSD 6.5, AIX 7.2, HP-UX 11.31, IRIX 6.5, Solaris 11.4, Haiku, Cygwin 2.9.
 @item
 The constants @code{ERA}, @code{ERA_D_FMT}, @code{ERA_D_T_FMT},
 @code{ERA_T_FMT}, @code{ALT_DIGITS} are not supported on some platforms:
diff --git a/doc/posix-headers/langinfo.texi b/doc/posix-headers/langinfo.texi
index 3affbd7..d6df4fc 100644
--- a/doc/posix-headers/langinfo.texi
+++ b/doc/posix-headers/langinfo.texi
@@ -16,7 +16,7 @@ OpenBSD 3.8.
 @item
 The constants @code{ALTMON_1} to @code{ALTMON_12} are not defined on some
 platforms:
-glibc 2.26 and many others.
+glibc 2.26, musl libc, Mac OS X 10.13, NetBSD 8.0, OpenBSD 6.5, AIX 7.2, HP-UX 11.31, IRIX 6.5, Solaris 11.4, Haiku, Cygwin 2.9.
 @item
 The constants @code{ERA}, @code{ERA_D_FMT}, @code{ERA_D_T_FMT},
 @code{ERA_T_FMT}, @code{ALT_DIGITS} are not defined on some platforms:
-- 
2.7.4

>From 5dbb9992fe9c872b3fb57b79a8a74161d05ea50b Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Tue, 17 Dec 2019 14:00:59 +0100
Subject: [PATCH 2/3] nl_langinfo: Fix multithread-safety bug on mingw and
 MSVC.

* lib/nl_langinfo.c (ctype_codeset, rpl_nl_langinfo): Use a
stack-allocated buffer to assemble each result and different static
buffers to return it.
* tests/test-nl_langinfo-mt.c: New file.
* modules/nl_langinfo-tests (Files): Add it.
(Depends-on): Add thread, nanosleep.
(Makefile.am): Build test-nl_langinfo-mt test.
---
 ChangeLog   |  11 ++
 lib/nl_langinfo.c   | 101 +--
 modules/nl_langinfo-tests   |   8 +-
 tests/test-nl_langinfo-mt.c | 238 
 4 files changed, 325 insertions(+), 33 deletions(-)
 create mode 100644 tests/test-nl_langinfo-mt.c

diff --git a/ChangeLog b/ChangeLog
index 9027da4..bb6b22b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
 2019-12-17  Bruno Haible  
 
+	nl_langinfo: Fix multithread-safety bug on mingw and MSVC.
+	* lib/nl_langinfo.c (ctype_codeset, rpl_nl_langinfo): Use a
+	stack-allocated buffer to assemble each result and different static
+	buffers to return it.
+	* tests/test-nl_langinfo-mt.c: New file.
+	* modules/nl_langinfo-tests (Files): Add it.
+	(Depends-on): Add thread, nanosleep.
+	(Makefile.am): Build test-nl_langinfo-mt test.
+
+2019-12-17  Bruno Haible  
+
 	langinfo: Document more details.
 	* doc/posix-headers/langinfo.texi: List platform details.
 	* doc/posix-functions/nl_langinfo.texi: Likew

improve clang support (29)

2020-08-15 Thread Bruno Haible
clang on Windows, by default, does not link with '-loldnames' (like mingw and
MSVC 14 do). This means that programs that use open(), close(), etc. will get
link errors by default.

For more than 10 years, Microsoft has been deprecating these function names:

access
chdir
chmod
close
creat
dup
dup2
ecvt
execl
execle
execlp
execv
execve
execvp
execvpe
fcloseall
fcvt
fdopen
fileno
gcvt
getcwd
getpid
getw
isatty
j0
j1
jn
lfind
lsearch
lseek
memccpy
mkdir
mktemp
open
putenv
putw
read
rmdir
strdup
swab
tempnam
tzset
umask
unlink
utime
wcsdup
write
y0
y1
yn

mkdir is special: 2 args in POSIX, 1 arg on Windows.
utime is special: no redirect in the header files, there are variants
_utime32 and _utime64.

Using these function names means that
  * You need to link with -loldnames explicitly. While this can be easy
for executables, I don't think it's worth the trouble when it comes
to creating libraries.
  * With clang, you also need to add '-Wno-deprecated-declarations' to the
CPPFLAGS, or you will get a warning for each reference to these function
names.
  * When looking up the documentation for the functions, you stumble across
stub pages, such as
https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/posix-close
https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/posix-tzset
https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/getcwd

https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strdup-wcsdup
https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/mkdir
  * You are living on the "backward compatibility" edge of the existence.

https://docs.microsoft.com/en-us/cpp/c-runtime-library/backward-compatibility

I'm therefore changing gnulib to use the underscore-prefixed function names
instead on native Windows. Not only with clang, but also with MSVC and with
mingw.

Essentially this means moving the link-time redirection (from oldnames.lib)
to a preprocessor redirection. Gnulib already does plenty of preprocessor
redirection ("#define foo rpl_foo"); therefore we know that it's a technique
that works.

I'm adding these redirections also when the corresponding gnulib module
is not present. Otherwise there would be the need to add many new module
dependencies, leading to the perception of code bloat for many packages
that use Gnulib.

The first patch is a preparation: ensure that gnulib always generates an
'utime.h' from 'utime.in.h', so that the '#define utime _utime' becomes
always visible.

The second patch contains all the preprocessor redirections.


2020-08-15  Bruno Haible  

Support compiling without -loldnames on native Windows.
* m4/gnulib-common.m4 (GL_MDA_DEFINES, _GL_MDA_DEFINES): New macros.
* m4/chown.m4 (AC_FUNC_CHOWN): In the test programs, use GL_MDA_DEFINES.
(gl_FUNC_CHOWN, gl_FUNC_CHOWN_FOLLOWS_SYMLINK): Likewise.
* m4/dup.m4 (gl_FUNC_DUP): Likewise.
* m4/dup2.m4 (gl_FUNC_DUP2): Likewise.
* m4/fchdir.m4 (gl_FUNC_FCHDIR): Likewise.
* m4/fchmodat.m4 (gl_FUNC_FCHMODAT): Likewise.
* m4/fchownat.m4 (gl_FUNC_FCHOWNAT_EMPTY_FILENAME_BUG): Likewise.
* m4/fcntl-o.m4 (gl_FCNTL_O_FLAGS): Likewise.
* m4/fcntl.m4 (gl_FUNC_FCNTL): Likewise.
* m4/fdopen.m4 (gl_FUNC_FDOPEN): Likewise.
* m4/fdopendir.m4 (gl_FUNC_FDOPENDIR): Likewise.
* m4/fflush.m4 (gl_FUNC_FFLUSH_STDIN): Likewise.
* m4/fopen.m4 (gl_FUNC_FOPEN_GNU): Likewise.
* m4/freopen.m4 (gl_FUNC_FREOPEN): Likewise.
* m4/futimens.m4 (gl_FUNC_FUTIMENS): Likewise.
* m4/getcwd-abort-bug.m4 (gl_FUNC_GETCWD_ABORT_BUG): Likewise.
* m4/getcwd-path-max.m4 (gl_FUNC_GETCWD_PATH_MAX): Likewise.
* m4/getcwd.m4 (gl_FUNC_GETCWD_NULL, gl_FUNC_GETCWD_SIGNATURE):
Likewise.
* m4/getdtablesize.m4 (gl_FUNC_GETDTABLESIZE): Likewise.
* m4/linkat.m4 (gl_FUNC_LINKAT): Likewise.
* m4/lseek.m4 (gl_FUNC_LSEEK): Likewise.
* m4/mkdir.m4 (gl_FUNC_MKDIR): Likewise.
* m4/mkstemp.m4 (gl_FUNC_MKSTEMP): Likewise.
* m4/mktime.m4 (gl_FUNC_MKTIME_WORKS): Likewise.
* m4/open-slash.m4 (gl_OPEN_TRAILING_SLASH_BUG): Likewise.
* m4/poll.m4 (gl_FUNC_POLL): Likewise.
* m4/posix_spawn.m4 (gl_POSIX_SPAWN_WORKS): Likewise.
* m4/pread.m4 (gl_FUNC_PREAD): Likewise.
* m4/pselect.m4 (gl_FUNC_PSELECT): Likewise.
* m4/pthread_sigmask.m4 (gl_FUNC_PTHREAD_SIGMASK): Likewise.
* m4/ptsname_r.m4 (gl_PREREQ_PTSNAME_R): Likewise.
* m4/putenv.m4 (gl_FUNC_PUTENV): Likewise.
* m4/pwrite.m4 (gl_FUNC_PWRITE): Likewise.
* m4/rename.m4 (gl_FUNC_RENAME): Likewise.
* m4/rmdir-errno.m4 (gl_FUNC_RMDIR_NOTEMPTY): Likewise.
* m4/rmdir.m4 (gl_FUNC_RMDIR): Likewise.
* m4/select.m4 (gl_FUNC_SELECT): Likewise.
* m4/setenv.m4 (gl_FUNC_UNSETENV): Likewise.
* m4/strncat.m4 (gl_FUNC_STRNCAT): Likewise.
   

Re: fchmodat.c & lchmod.c - O_PATH & AT_EMPTY_PATH on older kernels

2022-06-21 Thread Bruno Haible
OST]) dnl for cross-compiles
+  AC_CACHE_CHECK([whether chmod works],
+[gl_cv_func_chmod_works],
+[AC_RUN_IFELSE(
+   [AC_LANG_PROGRAM(
+  [
+AC_INCLUDES_DEFAULT[
+#if defined _WIN32 && !defined __CYGWIN__
+ #include 
+#endif
+#include 
+#include 
+#ifndef S_IRUSR
+ #define S_IRUSR 0400
+#endif
+#ifndef S_IWUSR
+ #define S_IWUSR 0200
+#endif
+#ifndef S_IRWXU
+ #define S_IRWXU 0700
+#endif
+#ifndef S_IRWXG
+ #define S_IRWXG 0070
+#endif
+#ifndef S_IRWXO
+ #define S_IRWXO 0007
+#endif
+  ]GL_MDA_DEFINES],
+  [[
+int permissive = S_IRWXU | S_IRWXG | S_IRWXO;
+int desired = S_IRUSR | S_IWUSR;
+int result = 0;
+#define file "conftest.chmod"
+if (open (file, O_CREAT | O_WRONLY | O_TRUNC, permissive) < 0)
+  return 1;
+/* Test whether chmod rejects a trailing slash on a non-directory,
+   with error ENOTDIR.
+   This test fails on AIX 7.2, IRIX 6.5 (no error) and
+   native Windows (error EINVAL).  */
+errno = 0;
+if (chmod (file "/", desired) == 0)
+  result |= 2;
+else if (errno != ENOTDIR)
+  result |= 4;
+return result;
+  ]])],
+   [gl_cv_func_chmod_works=yes],
+   [gl_cv_func_chmod_works=no],
+   [case "$host_os" in
+  # Guess no on AIX, IRIX, native Windows.
+  aix* | irix* | mingw*)
+gl_cv_func_chmod_works="guessing no" ;;
+  # Guess yes on glibc, musl libc, macOS, FreeBSD, NetBSD, OpenBSD, Solaris, Haiku, Cygwin.
+  *-gnu* | gnu* | *-musl* | darwin* | freebsd* | midnightbsd* | netbsd* | openbsd* | solaris* | haiku* | cygwin*)
+gl_cv_func_chmod_works="guessing yes" ;;
+  # If we don't know, obey --enable-cross-guesses.
+  *)
+gl_cv_func_chmod_works="$gl_cross_guess_normal" ;;
+esac
+   ])
+ rm -f conftest.chmod
+])
+  case "$gl_cv_func_chmod_works" in
+*yes) ;;
+*) REPLACE_CHMOD=1 ;;
+  esac
+])
+
+# Prerequisites of lib/chmod.c.
+AC_DEFUN([gl_PREREQ_CHMOD],
+[
+  :
+])
diff --git a/m4/sys_stat_h.m4 b/m4/sys_stat_h.m4
index b5a9789b81..2adbfdeef4 100644
--- a/m4/sys_stat_h.m4
+++ b/m4/sys_stat_h.m4
@@ -1,4 +1,4 @@
-# sys_stat_h.m4 serial 41   -*- Autoconf -*-
+# sys_stat_h.m4 serial 42   -*- Autoconf -*-
 dnl Copyright (C) 2006-2022 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -46,7 +46,7 @@ AC_DEFUN_ONCE([gl_SYS_STAT_H],
   dnl Check for declarations of anything we want to poison if the
   dnl corresponding gnulib module is not in use.
   gl_WARN_ON_USE_PREPARE([[#include 
-]], [fchmodat fstat fstatat futimens getumask lchmod lstat
+]], [chmod fchmodat fstat fstatat futimens getumask lchmod lstat
 mkdirat mkfifo mkfifoat mknod mknodat stat utimensat])
 
   AC_REQUIRE([AC_C_RESTRICT])
@@ -72,6 +72,7 @@ AC_DEFUN([gl_SYS_STAT_H_REQUIRE_DEFAULTS],
 [
   m4_defun(GL_MODULE_INDICATOR_PREFIX[_SYS_STAT_H_MODULE_INDICATOR_DEFAULTS], [
 gl_UNISTD_H_REQUIRE_DEFAULTS dnl for REPLACE_FCHDIR
+gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CHMOD])
 gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FCHMODAT])
 gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FSTAT])
 gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FSTATAT])
@@ -112,6 +113,7 @@ AC_DEFUN([gl_SYS_STAT_H_DEFAULTS],
   HAVE_MKNOD=1; AC_SUBST([HAVE_MKNOD])
   HAVE_MKNODAT=1;   AC_SUBST([HAVE_MKNODAT])
   HAVE_UTIMENSAT=1; AC_SUBST([HAVE_UTIMENSAT])
+  REPLACE_CHMOD=0;  AC_SUBST([REPLACE_CHMOD])
   REPLACE_FCHMODAT=0;   AC_SUBST([REPLACE_FCHMODAT])
   REPLACE_FSTAT=0;  AC_SUBST([REPLACE_FSTAT])
   REPLACE_FSTATAT=0;AC_SUBST([REPLACE_FSTATAT])
diff --git a/modules/chmod b/modules/chmod
new file mode 100644
index 00..0efe7b0019
--- /dev/null
+++ b/modules/chmod
@@ -0,0 +1,32 @@
+Description:
+chmod() function: change the permissions of a file
+
+Files:
+lib/chmod.c
+m4/chmod.m4
+
+Depends-on:
+sys_stat
+lstat   [test $REPLACE_CHMOD = 1]
+
+configure.ac:
+gl_FUNC_CHMOD
+gl_CONDITIONAL([GL_COND_OBJ_CHMOD], [test $REPLACE_CHMOD = 1])
+AM_COND_IF([GL_COND_OBJ_CHMOD], [
+  gl_PREREQ_CHMOD
+])
+gl_SYS_STAT_MODULE_INDICATOR([chmod])
+
+Makefile.am:
+if GL_COND_OBJ_CHMOD
+lib_SOURCES += chmod.c
+endif
+
+Include:
+
+
+License:
+GPL
+
+Maintainer:
+Paul Eggert, Bruno Haible
diff --git a/modules/sys_stat b/modules/sys_stat
index 629eac1b41..d5ab154157 100644
--- a/modules/sys_stat
+++ b/modules/sys_stat
@@ -36,6 +36,7 @@ sys/stat.h

new module 'setlocale_null-unlocked'

2024-02-15 Thread Bruno Haible
These patches add a module 'setlocale_null-unlocked', that allows code
to do the equivalent of setlocale(_,NULL) — with platform-specific
workarounds — when we know that it does not need locking.


2024-02-15  Bruno Haible  

setlocale_null-unlocked: Add tests.
* tests/test-setlocale_null-unlocked.c: New file, based on
tests/test-setlocale_null.c.
* modules/setlocale-null-unlocked-tests: New file.

setlocale_null-unlocked: New module.
* lib/setlocale_null.h (setlocale_null_r_unlocked,
setlocale_null_unlocked): New declarations.
* lib/setlocale_null-unlocked.c: New file, based on
lib/setlocale_null.c.
* lib/setlocale_null.c: Don't include .
(setlocale_null_unlocked, setlocale_null_r_unlocked): Remove functions.
* modules/setlocale-null-unlocked: New file.
* modules/setlocale-null (Depends-on): Add setlocale-null-unlocked.

2024-02-15  Bruno Haible  

setlocale-null: Refactor.
* lib/setlocale_null.c
(setlocale_null_r_with_lock): Renamed from setlocale_null_with_lock.
(setlocale_null_r_unlocked): Renamed from setlocale_null_unlocked.
(setlocale_null_unlocked): Renamed from setlocale_null_androidfix.

>From c75f99155342338ae9de19b164fd3e255bf96da4 Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Thu, 15 Feb 2024 09:47:08 +0100
Subject: [PATCH 1/7] setlocale-null: Refactor.

* lib/setlocale_null.c
(setlocale_null_r_with_lock): Renamed from setlocale_null_with_lock.
(setlocale_null_r_unlocked): Renamed from setlocale_null_unlocked.
(setlocale_null_unlocked): Renamed from setlocale_null_androidfix.
---
 ChangeLog|  8 
 lib/setlocale_null.c | 42 +-
 2 files changed, 29 insertions(+), 21 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 05732c7e9d..4ba5cbfc28 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2024-02-15  Bruno Haible  
+
+	setlocale-null: Refactor.
+	* lib/setlocale_null.c
+	(setlocale_null_r_with_lock): Renamed from setlocale_null_with_lock.
+	(setlocale_null_r_unlocked): Renamed from setlocale_null_unlocked.
+	(setlocale_null_unlocked): Renamed from setlocale_null_androidfix.
+
 2024-02-15  Bruno Haible  
 
 	localename-unsafe: New module.
diff --git a/lib/setlocale_null.c b/lib/setlocale_null.c
index 697502fbfe..152452e04f 100644
--- a/lib/setlocale_null.c
+++ b/lib/setlocale_null.c
@@ -63,7 +63,7 @@
 #undef setlocale
 
 static const char *
-setlocale_null_androidfix (int category)
+setlocale_null_unlocked (int category)
 {
   const char *result = setlocale (category, NULL);
 
@@ -94,7 +94,7 @@ setlocale_null_androidfix (int category)
 }
 
 static int
-setlocale_null_unlocked (int category, char *buf, size_t bufsize)
+setlocale_null_r_unlocked (int category, char *buf, size_t bufsize)
 {
 #if defined _WIN32 && !defined __CYGWIN__ && defined _MSC_VER
   /* On native Windows, nowadays, the setlocale() implementation is based
@@ -143,7 +143,7 @@ setlocale_null_unlocked (int category, char *buf, size_t bufsize)
 }
 }
 #else
-  const char *result = setlocale_null_androidfix (category);
+  const char *result = setlocale_null_unlocked (category);
 
   if (result == NULL)
 {
@@ -181,7 +181,7 @@ setlocale_null_unlocked (int category, char *buf, size_t bufsize)
 
 #if !(SETLOCALE_NULL_ALL_MTSAFE && SETLOCALE_NULL_ONE_MTSAFE) /* musl libc, macOS, FreeBSD, NetBSD, OpenBSD, AIX, Haiku, Cygwin < 3.4.6 */
 
-/* Use a lock, so that no two threads can invoke setlocale_null_unlocked
+/* Use a lock, so that no two threads can invoke setlocale_null_r_unlocked
at the same time.  */
 
 /* Prohibit renaming this symbol.  */
@@ -190,20 +190,20 @@ setlocale_null_unlocked (int category, char *buf, size_t bufsize)
 # if AVOID_ANY_THREADS
 
 /* The option '--disable-threads' explicitly requests no locking.  */
-#  define setlocale_null_with_lock setlocale_null_unlocked
+#  define setlocale_null_r_with_lock setlocale_null_r_unlocked
 
 # elif defined _WIN32 && !defined __CYGWIN__
 
 extern __declspec(dllimport) CRITICAL_SECTION *gl_get_setlocale_null_lock (void);
 
 static int
-setlocale_null_with_lock (int category, char *buf, size_t bufsize)
+setlocale_null_r_with_lock (int category, char *buf, size_t bufsize)
 {
   CRITICAL_SECTION *lock = gl_get_setlocale_null_lock ();
   int ret;
 
   EnterCriticalSection (lock);
-  ret = setlocale_null_unlocked (category, buf, bufsize);
+  ret = setlocale_null_r_unlocked (category, buf, bufsize);
   LeaveCriticalSection (lock);
 
   return ret;
@@ -234,7 +234,7 @@ extern
 #  endif
 
 static int
-setlocale_null_with_lock (int category, char *buf, size_t bufsize)
+setlocale_null_r_with_lock (int category, char *buf, size_t bufsize)
 {
   if (pthread_in_use())
 {
@@ -243,14 +243,14 @@ setlocale_null_with_lock (int category, char *buf, size_t bufsize)
 
   if (pthread_mutex_lock (lock))
 abort ()

Resolve conflicts for functions introduced in Android API level 34

2024-01-25 Thread Bruno Haible
At level 34 the added functions are:


__freadahead


memset_explicit


posix_spawn_file_actions_addchdir_np
posix_spawn_file_actions_addfchdir_np


copy_file_range
close_range

Here are the corresponding adjustments in Gnulib.


2024-01-25  Bruno Haible  

Resolve conflicts for functions introduced in Android API level 34.

* m4/copy-file-range.m4 (gl_FUNC_COPY_FILE_RANGE): On platforms without
glibc, test for copy_file_range using gl_CHECK_FUNCS_ANDROID instead of
AC_CHECK_FUNCS_ONCE. Conditionally set REPLACE_COPY_FILE_RANGE.
* doc/glibc-functions/copy_file_range.texi: Mention the Android API
levels.

* m4/posix_spawn.m4 (gl_POSIX_SPAWN_BODY): Test for
posix_spawn_file_actions_addchdir_np and
posix_spawn_file_actions_addfchdir_np using gl_CHECK_FUNCS_ANDROID
instead of AC_CHECK_FUNCS_ONCE.
* m4/posix_spawn_faction_addchdir.m4
(gl_FUNC_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR): Test for
posix_spawn_file_actions_addchdir_np using gl_CHECK_FUNCS_ANDROID
instead of AC_CHECK_FUNCS_ONCE.
* m4/posix_spawn_faction_addfchdir.m4
(gl_FUNC_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR): Test for
posix_spawn_file_actions_addfchdir_np using gl_CHECK_FUNCS_ANDROID
instead of AC_CHECK_FUNCS_ONCE.
* doc/glibc-functions/posix_spawn_file_actions_addchdir_np.texi: Mention
the Android API levels.
* doc/glibc-functions/posix_spawn_file_actions_addfchdir_np.texi:
Likewise.

* lib/string.in.h (memset_explicit): Consider REPLACE_MEMSET_EXPLICIT.
* m4/string_h.m4 (gl_STRING_H_DEFAULTS): Initialize
REPLACE_MEMSET_EXPLICIT.
* modules/string (Makefile.am): Substitute REPLACE_MEMSET_EXPLICIT.
* m4/memset_explicit.m4 (gl_FUNC_MEMSET_EXPLICIT): Test for
memset_explicit using gl_CHECK_FUNCS_ANDROID instead of
AC_CHECK_FUNCS_ONCE. Conditionally set REPLACE_MEMSET_EXPLICIT.
* modules/memset_explicit (configure.ac): Consider
REPLACE_MEMSET_EXPLICIT.
* doc/posix-functions/memset_explicit.texi: Mention the Android API
levels.

* m4/freadahead.m4 (gl_FUNC_FREADAHEAD): Test for __freadahead using
gl_CHECK_FUNCS_ANDROID instead of AC_CHECK_FUNCS_ONCE.
* lib/freadahead.h: Update comment.

From 22c809356688118b5fcc96229788150ed780a747 Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Fri, 26 Jan 2024 00:18:45 +0100
Subject: [PATCH 1/4] Resolve conflicts for functions introduced in Android API
 level 34.

* m4/freadahead.m4 (gl_FUNC_FREADAHEAD): Test for __freadahead using
gl_CHECK_FUNCS_ANDROID instead of AC_CHECK_FUNCS_ONCE.
* lib/freadahead.h: Update comment.
---
 ChangeLog| 8 
 lib/freadahead.h | 2 +-
 m4/freadahead.m4 | 4 ++--
 3 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 46dcdf9c4e..5e7b4d90b4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2024-01-25  Bruno Haible  
+
+	Resolve conflicts for functions introduced in Android API level 34.
+
+	* m4/freadahead.m4 (gl_FUNC_FREADAHEAD): Test for __freadahead using
+	gl_CHECK_FUNCS_ANDROID instead of AC_CHECK_FUNCS_ONCE.
+	* lib/freadahead.h: Update comment.
+
 2024-01-25  Bruno Haible  
 
 	Doc regarding functions introduced in Android API level 33.
diff --git a/lib/freadahead.h b/lib/freadahead.h
index 35052c1c19..f4fc26cbd7 100644
--- a/lib/freadahead.h
+++ b/lib/freadahead.h
@@ -32,7 +32,7 @@
 
STREAM must not be wide-character oriented.  */
 
-#if HAVE___FREADAHEAD /* musl libc */
+#if HAVE___FREADAHEAD /* musl libc, Android API level ≥ 33 */
 
 # include 
 # define freadahead(stream) __freadahead (stream)
diff --git a/m4/freadahead.m4 b/m4/freadahead.m4
index c2352b4616..df7aaa29fe 100644
--- a/m4/freadahead.m4
+++ b/m4/freadahead.m4
@@ -1,4 +1,4 @@
-# freadahead.m4 serial 1
+# freadahead.m4 serial 2
 dnl Copyright (C) 2012-2024 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -6,5 +6,5 @@
 
 AC_DEFUN([gl_FUNC_FREADAHEAD],
 [
-  AC_CHECK_FUNCS_ONCE([__freadahead])
+  gl_CHECK_FUNCS_ANDROID([__freadahead], [[#include ]])
 ])
-- 
2.34.1

>From 2f4edab08c40fa0206d0fca7cee99346a156e1ab Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Fri, 26 Jan 2024 00:18:49 +0100
Subject: [PATCH 2/4] Resolve conflicts for functions introduced in Android API
 level 34.

* lib/string.in.h (memset_explicit): Consider REPLACE_MEMSET_EXPLICIT.
* m4/string_h.m4 (gl_STRING_H_DEFAULTS): Initialize
REPLACE_MEMSET_EXPLICIT.
* modules/string (Makefile.am): Substitute REPLACE_MEMSET_EXPLICIT.
* m4/memset_explicit.m4 (gl_FUNC_MEMSET_EXPLICIT): Test for
memset_explicit using gl_CHECK_FUNCS_ANDROID instead of
AC_CHECK_FUNCS_ONCE. Conditionally set REPLACE_MEMSET_EXPLICIT.
* modules/memset_explicit (configure.ac): Consider
REPLACE_MEMSET_EXPLICIT.
* doc/posix-functi

[PATCH] fflush: be more paranoid about libio.h change

2018-03-08 Thread Paul Eggert
LE as a struct and the necessary bitmask in
  , because they need it for implementing getc() and putc() as
  fast macros.  */
-# if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, 
Linux libc5 */
+# if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1
+  /* GNU libc, BeOS, Haiku, Linux libc5 */
   fp->_IO_read_end = fp->_IO_read_ptr;
   fp->_IO_write_ptr = fp->_IO_write_base;
   /* Avoid memory leak when there is an active ungetc buffer.  */
diff --git a/lib/freadable.c b/lib/freadable.c
index c4ca0b86e..53cdbee08 100644
--- a/lib/freadable.c
+++ b/lib/freadable.c
@@ -31,7 +31,8 @@ freadable (FILE *fp)
   /* Most systems provide FILE as a struct and the necessary bitmask in
  , because they need it for implementing getc() and putc() as
  fast macros.  */
-#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, 
Linux libc5 */
+#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1
+  /* GNU libc, BeOS, Haiku, Linux libc5 */
   return (fp->_flags & _IO_NO_READS) == 0;
 #elif defined __sferror || defined __DragonFly__ || defined __ANDROID__
   /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */
diff --git a/lib/freadahead.c b/lib/freadahead.c
index 23ec76ee5..ed3dd0ebd 100644
--- a/lib/freadahead.c
+++ b/lib/freadahead.c
@@ -30,7 +30,8 @@ extern size_t __sreadahead (FILE *);
 size_t
 freadahead (FILE *fp)
 {
-#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, 
Linux libc5 */
+#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1
+  /* GNU libc, BeOS, Haiku, Linux libc5 */
   if (fp->_IO_write_ptr > fp->_IO_write_base)
 return 0;
   return (fp->_IO_read_end - fp->_IO_read_ptr)
diff --git a/lib/freading.c b/lib/freading.c
index c24d0c88a..790f92ca3 100644
--- a/lib/freading.c
+++ b/lib/freading.c
@@ -31,7 +31,8 @@ freading (FILE *fp)
   /* Most systems provide FILE as a struct and the necessary bitmask in
  , because they need it for implementing getc() and putc() as
  fast macros.  */
-# if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, 
Linux libc5 */
+# if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1
+  /* GNU libc, BeOS, Haiku, Linux libc5 */
   return ((fp->_flags & _IO_NO_WRITES) != 0
   || ((fp->_flags & (_IO_NO_READS | _IO_CURRENTLY_PUTTING)) == 0
   && fp->_IO_read_base != NULL));
diff --git a/lib/freadptr.c b/lib/freadptr.c
index ffb801039..3afa62149 100644
--- a/lib/freadptr.c
+++ b/lib/freadptr.c
@@ -29,7 +29,8 @@ freadptr (FILE *fp, size_t *sizep)
   size_t size;
 
   /* Keep this code in sync with freadahead!  */
-#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, 
Linux libc5 */
+#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1
+  /* GNU libc, BeOS, Haiku, Linux libc5 */
   if (fp->_IO_write_ptr > fp->_IO_write_base)
 return NULL;
   size = fp->_IO_read_end - fp->_IO_read_ptr;
diff --git a/lib/freadseek.c b/lib/freadseek.c
index 5fd2dd7ca..b11845cd5 100644
--- a/lib/freadseek.c
+++ b/lib/freadseek.c
@@ -36,7 +36,8 @@ freadptrinc (FILE *fp, size_t increment)
   /* Keep this code in sync with freadptr!  */
 #if HAVE___FREADPTRINC  /* musl libc */
   __freadptrinc (fp, increment);
-#elif defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, 
Linux libc5 */
+#elif defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1
+  /* GNU libc, BeOS, Haiku, Linux libc5 */
   fp->_IO_read_ptr += increment;
 #elif defined __sferror || defined __DragonFly__ || defined __ANDROID__
   /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */
diff --git a/lib/fseeko.c b/lib/fseeko.c
index 193f4e8ce..e5c5172e7 100644
--- a/lib/fseeko.c
+++ b/lib/fseeko.c
@@ -47,7 +47,8 @@ fseeko (FILE *fp, off_t offset, int whence)
 #endif
 
   /* These tests are based on fpurge.c.  */
-#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, 
Linux libc5 */
+#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1
+  /* GNU libc, BeOS, Haiku, Linux libc5 */
   if (fp->_IO_read_end == fp->_IO_read_ptr
   && fp->_IO_write_ptr == fp->_IO_write_base
   && fp->_IO_save_base == NULL)
@@ -123,7 +124,8 @@ fseeko (FILE *fp, off_t offset, int whence)
   return -1;
 }
 
-#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, 
Linux libc5 */
+#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1
+  /* GNU libc, BeOS, Haiku, Linux libc5 */
   fp->_flags &= ~_IO_EOF_SEEN;
   fp->_offset = pos;
 #elif defined __sferror || defined __DragonFly__ || defined __ANDROID__
diff --git a/lib/fseterr.c b/lib/fseterr.c
index adb637256..fd9da6338 100

random: Fix multithread-safety bug in general

2023-11-10 Thread Bruno Haible
Since CheriBSD is derived from FreeBSD, it sounds likely that FreeBSD's random()
function is equally not multithread-safe.

To verify this hypothesis, I wrote a MT-safety test for random(). The result
(with a REPEAT_COUNT of 100):

glibc OK
musl libc OK
FreeBSD 11.0  Expected value #932913 not found in multithreaded results. (18 
failures among 100 runs)
FreeBSD 13.2  Expected value #712890 not found in multithreaded results. (2 
failures among 100 runs)
NetBSDOK
OpenBSD   Expected value #0 not found in multithreaded results. => SKIP
macOS Expected value #16 not found in multithreaded results.
AIX   OK
Solaris10 Expected value #4 not found in multithreaded results.
Solaris11 Expected value #46 not found in multithreaded results.
Cygwin 2.9.0  Expected value #2499 not found in multithreaded results.
Cygwin 3.4.6  Expected value #367 not found in multithreaded results.
mingw OK (uses gnulib implementation)
MSVC  OK (uses gnulib implementation)
Haiku Expected value #188587 not found in multithreaded results. (1 
failure among 100 runs)
Minix SKIP
Android   OK

So, in general, it requires 100'000'000 repetitions to determine
whether the function is MT-safe. But that's too long for a unit test.
I'm therefore reducing it to 100'000 repetitions and hardcoding the
known platforms in the configure test. Even these 100'000 repetitions
take 3 seconds on Haiku or 1 second on mingw or MSVC.


2023-11-10  Bruno Haible  

doc: Mention an srandom limitation on OpenBSD.
* doc/posix-functions/srandom.texi: Mention the OpenBSD limitation.

2023-11-10  Bruno Haible  

random tests: Add multithread-safety test.
* tests/test-random-mt.c: New file.
* modules/random-tests (Files): Add it.
(Depends-on): Add xalloc, thread, yield.
(Makefile.am): Also build and test test-random-mt.

random: Fix multithread-safety bug in general.
* m4/random.m4 (gl_FUNC_RANDOM): Override also macOS, FreeBSD, Solaris,
Cygwin, Haiku.
* doc/posix-functions/random.texi: Mention the wider scope of the
multithread-safety bug.

>From 53483b103f8d733df604e03f5260486ebf1a4496 Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Fri, 10 Nov 2023 16:46:17 +0100
Subject: [PATCH 1/3] random: Fix multithread-safety bug in general.

* m4/random.m4 (gl_FUNC_RANDOM): Override also macOS, FreeBSD, Solaris,
Cygwin, Haiku.
* doc/posix-functions/random.texi: Mention the wider scope of the
multithread-safety bug.
---
 ChangeLog   |  8 
 doc/posix-functions/random.texi |  4 ++--
 m4/random.m4| 11 +++
 3 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 5c92da54ec..d38e5b5665 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2023-11-10  Bruno Haible  
+
+	random: Fix multithread-safety bug in general.
+	* m4/random.m4 (gl_FUNC_RANDOM): Override also macOS, FreeBSD, Solaris,
+	Cygwin, Haiku.
+	* doc/posix-functions/random.texi: Mention the wider scope of the
+	multithread-safety bug.
+
 2023-11-09  Bruno Haible  
 
 	sigsegv: Improve port to CHERI.
diff --git a/doc/posix-functions/random.texi b/doc/posix-functions/random.texi
index e0bb8e76bc..84cacbe8b5 100644
--- a/doc/posix-functions/random.texi
+++ b/doc/posix-functions/random.texi
@@ -15,8 +15,8 @@
 This function is only defined as an inline function on some platforms:
 Android 4.4.
 @item
-This function crashes when used in multithreaded programs on some platforms:
-CheriBSD.
+This function is not multithread-safe on some platforms:
+macOS 12.5, FreeBSD 13.2, Solaris 11.4, Cygwin 3.4.6, Haiku.
 @end itemize
 
 Portability problems not fixed by Gnulib:
diff --git a/m4/random.m4 b/m4/random.m4
index 69bac2459a..4e4f01b8ed 100644
--- a/m4/random.m4
+++ b/m4/random.m4
@@ -1,4 +1,4 @@
-# random.m4 serial 7
+# random.m4 serial 8
 dnl Copyright (C) 2012-2023 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -44,10 +44,13 @@ AC_DEFUN([gl_FUNC_RANDOM]
   future*) REPLACE_SETSTATE=1 ;;
 esac
   fi
-  dnl On CheriBSD, random() lacks locking, leading to an out-of-bounds read
-  dnl inside random_r.
+  dnl On several platforms, random() is not multithread-safe.
   if test $ac_cv_func_initstate = no || test $ac_cv_func_setstate = no \
- || case "$host" in aarch64c-*-freebsd*) true;; *) false;; esac; then
+ || case "$host_os" in \
+  darwin* | freebsd* | solaris* | cygwin* | haiku*) true ;; \
+  *) false ;; \
+esac
+  then
 dnl In order to define initstate or setstate, we need to define all the
 dnl functions at once.
 REPLACE_RANDOM=1
-- 
2.34.1

>From b5eede6ff76d45112ea1973f12a131228f36a92e Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Fri, 10 Nov 2023 16:48

Re: bug#64937: "who" reports funny dates

2023-08-08 Thread Bruno Haible
!= missing_type)
+  if (type != missing)
 free (type);
   free (tty);
   free (seat);
@@ -441,18 +569,7 @@ read_utmp (char const *file, idx_t *n_entries, STRUCT_UTMP **utmp_buf,
   free (sessions);
 }
 
-  /* Relocate the string pointers back to their natural position.  */
-  {
-char *stringlim = (char *) a.utmp + a.alloc_bytes;
-
-for (idx_t i = 0; i < a.filled; i++)
-  {
-a.utmp[i].ut_user = (intptr_t) a.utmp[i].ut_user + stringlim;
-a.utmp[i].ut_id   = (intptr_t) a.utmp[i].ut_id   + stringlim;
-a.utmp[i].ut_line = (intptr_t) a.utmp[i].ut_line + stringlim;
-a.utmp[i].ut_host = (intptr_t) a.utmp[i].ut_host + stringlim;
-  }
-  }
+  a = finish_utmp (a);
 
   *n_entries = a.filled;
   *utmp_buf = a.utmp;
@@ -460,67 +577,16 @@ read_utmp (char const *file, idx_t *n_entries, STRUCT_UTMP **utmp_buf,
   return 0;
 }
 
-# elif defined UTMP_NAME_FUNCTION
+# elif defined UTMP_NAME_FUNCTION /* glibc, musl, macOS, FreeBSD, NetBSD, Minix, AIX, IRIX, Solaris, Cygwin, Android */
 
-static void
-copy_utmp_entry (STRUCT_UTMP *dst, STRUCT_UTMP *src)
-{
-#  if __GLIBC__ && _TIME_BITS == 64
-  /* Convert from external form in SRC to internal form in DST.
- It is OK to convert now, rather than earlier, before
- desirable_utmp_entry was invoked, because desirable_utmp_entry
- inspects only the leading prefix of the entry, which is the
- same in both external and internal forms.  */
-
-  /* This is a near-copy of glibc's struct utmpx, which stops working
- after the year 2038.  Unlike the glibc version, struct utmpx32
- describes the file format even if time_t is 64 bits.  */
-  struct utmpx32
-  {
-short int ut_type;			/* Type of login.  */
-pid_t ut_pid;			/* Process ID of login process.  */
-char ut_line[sizeof src->ut_line];	/* Devicename.  */
-char ut_id[sizeof src->ut_id];	/* Inittab ID.  */
-char ut_user[sizeof src->ut_user];  /* Username.  */
-char ut_host[sizeof src->ut_host];	/* Hostname for remote login.  */
-struct __exit_status ut_exit;	/* Exit status of a process marked
-   as DEAD_PROCESS.  */
-/* The fields ut_session and ut_tv must be the same size when compiled
-   32- and 64-bit.  This allows files and shared memory to be shared
-   between 32- and 64-bit applications.  */
-int ut_session;			/* Session ID, used for windowing.  */
-struct
-{
-  /* Seconds.  Unsigned not signed, as glibc did not exist before 1970,
- and if the format is still in use after 2038 its timestamps
- will surely have the sign bit on.  This hack stops working
- at 2106-02-07 06:28:16 UTC.  */
-  unsigned int tv_sec;
-
-  int tv_usec;			/* Microseconds.  */
-} ut_tv;/* Time entry was made.  */
-int ut_addr_v6[4];			/* Internet address of remote host.  */
-char ut_reserved[20];		/* Reserved for future use.  */
-  } *s = (struct utmpx32 *) src;
-  memcpy (dst, s, offsetof (struct utmpx32, ut_session));
-  dst->ut_session = s->ut_session;
-  dst->ut_tv.tv_sec = s->ut_tv.tv_sec;
-  dst->ut_tv.tv_usec = s->ut_tv.tv_usec;
-  memcpy (>ut_addr_v6, s->ut_addr_v6, sizeof dst->ut_addr_v6);
-#  else
-  *dst = *src;
+#  if !HAVE_UTMPX_H && HAVE_UTMP_H && !HAVE_DECL_GETUTENT
+struct utmp *getutent (void);
 #  endif
-}
 
 int
 read_utmp (char const *file, idx_t *n_entries, STRUCT_UTMP **utmp_buf,
int options)
 {
-  idx_t n_read = 0;
-  idx_t n_alloc = 0;
-  STRUCT_UTMP *utmp = NULL;
-  STRUCT_UTMP *ut;
-
   /* Ignore the return value for now.
  Solaris' utmpname returns 1 upon success -- which is contrary
  to what the GNU libc version does.  In addition, older GNU libc
@@ -529,59 +595,163 @@ read_utmp (char const *file, idx_t *n_entries, STRUCT_UTMP **utmp_buf,
 
   SET_UTMP_ENT ();
 
-  while ((ut = GET_UTMP_ENT ()) != NULL)
-if (desirable_utmp_entry (ut, options))
+  struct utmp_alloc a = {0};
+  void const *entry;
+
+  while ((entry = GET_UTMP_ENT ()) != NULL)
+{
+#  if __GLIBC__ && _TIME_BITS == 64
+  /* This is a near-copy of glibc's struct utmpx, which stops working
+ after the year 2038.  Unlike the glibc version, struct utmpx32
+ describes the file format even if time_t is 64 bits.  */
+  struct utmpx32
   {
-if (n_read == n_alloc)
-  utmp = xpalloc (utmp, _alloc, 1, -1, sizeof *utmp);
+short int ut_type;   /* Type of login.  */
+pid_t ut_pid;/* Process ID of login process.  */
+char ut_line[UT_LINE_SIZE];  /* Devicename.  */
+char ut_id[UT_ID_SIZE];  /* Inittab ID.  */
+char ut_user[UT_USER_SIZE];  /* Username.  */
+char ut_host[UT_HOST_SIZE];  /* Hostname for remote login. */
+struct __exit_status ut_exit;/* Exit status

asyncsafe-spin: Fix link error on various platforms

2024-01-21 Thread Bruno Haible
   return __sync_val_compare_and_swap (value, comp_val, new_val);
# }
# 
# with option -S, using a (native or cross-) compiler.
#   * The function __sync_bool_compare_and_swap_4 is meant to be included
# in libgcc. And indeed, libgcc contains the source code for this
# function on
#   - arm,  for gcc versions >= 4.7, but only for Linux
#   and (for gcc >= 5) FreeBSD,
#   - hppa, hppa64, for gcc versions >= 4.7, but only for Linux
#   and (for gcc >= 13) NetBSD, OpenBSD, hppa64 HP-UX
#   - i386, never at all
#   - sparc,never at all
#   - m68k, for gcc versions >= 4.7, but only for Linux
#   - mips, never at all
#   * The NetBSD C library provides this function on
#   - arm, arm64,
#   - i386,
#   - sparc,
#   - m68k,
#   - riscv64.
# Other C libraries (e.g. glibc, musl libc) do not provide this function.
# So, the use of these primitives results in a link error on:
#   - arm, with gcc versions >= 4.1, < 4.7 on all systems except NetBSD,
#  with gcc versions >= 4.7, < 5 on FreeBSD, OpenBSD, Android,
#  with gcc versions >= 5 on OpenBSD, Android,
#   - hppa, hppa64, with gcc versions >= 4.1, < 4.7 on all systems,
#   with gcc versions >= 4.7, < 13 on NetBSD, OpenBSD,
#   - i386 (without '-march=i486'), with gcc versions >= 4.1
#   on all systems except NetBSD,
#   - sparc (32-bit, for certain CPU models), with gcc versions >= 4.1
# on all systems except NetBSD,
#   - m68k, with gcc versions >= 4.1, < 4.7 on all systems except NetBSD,
#   - mips, with gcc versions >= 4.1, < 4.3 on all systems.
# Additionally, link errors can occur if - such as on glibc systems - the libgcc
# functions are distributed through glibc, but the glibc version is older than
# the gcc version.
AC_DEFUN([gl_ATOMIC_COMPARE_AND_SWAP],
[
  AC_CACHE_CHECK([for __sync_bool_compare_and_swap],
[gl_cv_builtin_sync_bool_compare_and_swap],
[AC_LINK_IFELSE(
   [AC_LANG_PROGRAM(
  [[int cmpxchg (int* value, int comp_val, int new_val)
{
  return __sync_val_compare_and_swap (value, comp_val, new_val);
}
  ]],
  [[]])
   ],
   [gl_cv_builtin_sync_bool_compare_and_swap=yes],
   [gl_cv_builtin_sync_bool_compare_and_swap=no])
])
  if test $gl_cv_builtin_sync_bool_compare_and_swap = yes; then
AC_DEFINE([HAVE_ATOMIC_COMPARE_AND_SWAP_GCC41], [1],
  [Define to 1 if the GCC 4.1 primitives for atomic compare-and-swap can be 
used.])
  fi
])

diff --git a/lib/asyncsafe-spin.c b/lib/asyncsafe-spin.c
index f16fb54b1c..63352184ae 100644
--- a/lib/asyncsafe-spin.c
+++ b/lib/asyncsafe-spin.c
@@ -134,11 +134,10 @@ do_unlock (asyncsafe_spinlock_t *lock)
 #   endif
 
 #  elif (((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) \
-  && !(defined __sun && defined __sparc__) && !defined __ANDROID__) \
- || __clang_major__ >= 3) \
-&& !defined __ibmxl__
-/* Use GCC built-ins (available in GCC >= 4.1, except on Solaris/SPARC and
-   Android, and clang >= 3.0).
+  || __clang_major__ >= 3) \
+ && HAVE_ATOMIC_COMPARE_AND_SWAP_GCC41)
+/* Use GCC built-ins (available on many platforms with GCC >= 4.1 or
+   clang >= 3.0).
Documentation:
<https://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html>  */
 
diff --git a/lib/pthread-spin.c b/lib/pthread-spin.c
index 32073fbc36..26caa72496 100644
--- a/lib/pthread-spin.c
+++ b/lib/pthread-spin.c
@@ -163,10 +163,10 @@ pthread_spin_destroy (pthread_spinlock_t *lock)
 }
 
 # elif (((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) \
- && !defined __ANDROID__) \
-|| __clang_major__ >= 3) \
-   && !defined __ibmxl__
-/* Use GCC built-ins (available in GCC >= 4.1 and clang >= 3.0).
+ || __clang_major__ >= 3) \
+&& HAVE_ATOMIC_COMPARE_AND_SWAP_GCC41)
+/* Use GCC built-ins (available on many platforms with GCC >= 4.1 or
+   clang >= 3.0).
Documentation:
<https://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html>  */
 
diff --git a/lib/simple-atomic.c b/lib/simple-atomic.c
index 61fc602367..656b4bdc19 100644
--- a/lib/simple-atomic.c
+++ b/lib/simple-atomic.c
@@ -67,11 +67,10 @@ atomic_compare_and_swap_ptr (uintptr_t volatile *vp,
require to link with -latomic.  */
 
 # if (((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) \
-   && !(defined __sun && defined __sparc__) && !defined __ANDROID__) \
-  || __clan

[PATCH] configmake: Avoid namespace pollution issue on mingw.

2019-08-08 Thread Eric Blake
ate
a18f7ce3c term-style-control tests: Fix link error.
4a468b774 term-style-control: Fix typo in comment.
7c4dbc521 term-style-control: Add tests.
993d0646c term-style-control: New module.
092288d12 autoupdate
0d8714b7c _Noreturn: beware of C's _Noreturn in C++ pre C++11
453ff9404 Support cross-compilation to musl libc.
66c3c07e0 posix_spawn_file_actions_*: Document musl libc bugs.
ec766932d autoupdate
407a19c08 futimens: Document musl libc bug.
b6f167d31 Clarify that cross-compilation guesses are guesses.
e0de43c19 strtold: Fix typo.
da77d28dc noreturn: In C++ mode with clang, use _Noreturn as fallback.
5a929250f libtextstyle-optional: Fix compiler warnings
480e356f0 bitset: fix memory leaks
0f3c79720 bitset: minor changes
7b31451e2 bitset: expose bitset_resize
17c967e57 doc: Document the 'stdnoreturn' and 'noreturn' modules.
85e7bcab4 doc: Document how to use 'static inline'.
e4d8618df libtextstyle-optional: Add tests.
c23dae8c0 libtextstyle-optional: New module.
4a7bec233 c-stack: Make signal handlers more reliable.
cf8abf91b Help making signal handlers more reliable.
661f63a41 _Noreturn: clang and MSVC do support [[noreturn]] in C++11 mode.
03eccb2d0 _Noreturn: GCC 4.7 does not support [[noreturn]] in C++11 mode
d6db42193 autoupdate
8bac5eba1 fts: minor simplification
b451121ab autoupdate
4d9813bf6 bitset, timevar: Depend on c99
bca971bd8 bitset: a bit (...) more tests
68cc43e4f bitset: fix overflows
3817922f8 bitset: style changes
3cd207e1d fatal-signal: Pass the signal number to the action.
eac483310 fatal-signal: Add function that lists the fatal signals.
a336be6b8 isatty: Make it return true in Cygwin consoles on native Windows.
050440041 all: Update URLs to msdn.microsoft.com.
7952aabdf gnulib-tool: Clarify the coding style.
de6813ed7 autoupdate
426f44034 autoupdate
3bd82a82c strtod: fix clash with strtold
9a943f694 autoupdate
69c4509f3 alloca-opt: Fix conflict mingw's new  file.
a40779486 autoupdate
fdb2c20b0 tests: Avoid havoc with "gcc -fcheck-pointer-bounds".
011b1a33b uninorm tests: Free allocated memory.
3703dbbe8 di-set: Fix memory leak.
8c96eb80b tests: Free allocated memory.
fcf959577 Fix another test failure introduced by the same commit.
613aa429e Fix test failure introduced by last commit.
4c0df5be8 tests: Prepare for using valgrind.
5db7774f1 get-rusage-as, pthread_sigmask tests: Fix -fsanitize=thread findings.
81d0d262d test-userspec.c: don't print NULL
2ba60a9f1 getloadavg: Write NULL for the null pointer.
fb48c2507 alloca, tsearch-tests: Write NULL for the null pointer.
363bf26b4 strfmon_l: Fix -fsanitize=address finding.
b64bf15ed crypto/des: Fix undefined behaviour.
42254c0a9 Fix undefined behaviour.
fa418ebbd unilbrk/u*-possible-linebreaks: Fix undefined behaviour.
f6f567a94 unistr/*, uniconv/*: Fix undefined behaviour.
7e7501fa2 unistr/u8-cmp: Fix undefined behaviour.
01ec92af9 unictype/numeric: Fix undefined behaviour.
724a59097 autoupdate
9447bd973 git-version-gen: fix --version copyright year
30f4fdcb5 autoupdate
b204bbfc7 relocatable-prog: Use wrapper-free installation on Mac OS X, take 2.
d355f9056 relocatable-prog: Revert "Use wrapper-free installation on Mac OS X."
5c04e7191 autoupdate
788db09a9 autoupdate
188d87b05 nstrftime: support the ‘+’ flag
16e6d93c0 autoupdate
82519af2d relocatable-prog: Improve verbose output.
c3a4785d3 stat, lstat: Fix conflict with relocatable-prog-wrapper module.
e3970fb98 long-options: add parse_gnu_standard_options_only
cc42b8c93 relocatable-prog: Update documentation.
95318be14 relocatable-prog: Update documentation.
7039b8937 relocatable-prog: Use wrapper-free installation also on Mac OS X 10.4.
716fac12c nstrftime: tweak arg order
4fe3afa8f relocatable-prog: Use wrapper-free installation also on Mac OS X.
015c30cac relocatable-prog: Use $ORIGIN trick also on GNU/Hurd.
ddbd29c30 nstrftime: merge glibc strftime changes
35e462817 relocatable-prog: Use $ORIGIN trick on more platforms.
18f4d4133 progreloc: Speed up executable lookup on various platforms.
cd46bf0ca progreloc: Simplify code for Android.
f94c70ae4 autoupdate
314e9b692 autoupdate
dc135c4fd gnulib-tool: Support --import with just a few tests, not --with-tests.
49137e3bc gnulib-tool: Improve handling of multiple --local-dir options.
341723e1b libtextstyle: New module.
30f8dae4c declared.sh: Fix bug with variables of pointer type.
45ed991d6 Add script for running tests under valgrind.
ddba03e40 declared.sh: Fix --version output.
10d0e6a7d Add script for determining the set of symbols to export from a 
library.
3043e43a7 vla: add commentary about VLA_ELEMS
2f6abcc9f dtoastr,ftoastr,ldtoastr: port to c-strtod changes
edacea21c autoupdate
8430fa87e fma: Improve code style.
26201178d *-map tests: Fix compilation error.
b39cc7260 c-strtod, c-strtold: Use the bug fixes for strtod, strtold.
97e23d40a strtod, strtold: Use the locale's decimal point.
cd825c6d5 strtod, strtold tests: Simplify tests.
376b353f9 strtod, strtold: Avoid unnecessary rounding errors.
a908d8969 st

new module 'fenv-exceptions-tracking-c99'

2023-10-28 Thread Bruno Haible
ig_mxcsr);
+  mxcsr = orig_mxcsr & ~exceptions;
+  if (mxcsr != orig_mxcsr)
+_FPU_SETSSECW (mxcsr);
+}
+
+#  endif
+
+  return 0;
+}
+
+# elif defined __aarch64__ /* arm64 */
+
+int
+feclearexcept (int exceptions)
+{
+  exceptions &= FE_ALL_EXCEPT;
+
+  unsigned long fpsr, orig_fpsr;
+  _FPU_GETFPSR (orig_fpsr);
+  fpsr = orig_fpsr & ~exceptions;
+  if (fpsr != orig_fpsr)
+_FPU_SETFPSR (fpsr);
+
+  return 0;
+}
+
+# elif defined __arm__
+
+int
+feclearexcept (int exceptions)
+{
+  exceptions &= FE_ALL_EXCEPT;
+
+#  ifdef __SOFTFP__
+  if (exceptions != 0)
+return -1;
+#  else
+  unsigned int fpscr, orig_fpscr;
+  _FPU_GETCW (orig_fpscr);
+  fpscr = orig_fpscr & ~exceptions;
+  if (fpscr != orig_fpscr)
+_FPU_SETCW (fpscr);
+#  endif
+  return 0;
+}
+
+# elif defined __alpha
+
+int
+feclearexcept (int exceptions)
+{
+  exceptions &= FE_ALL_EXCEPT;
+
+  unsigned long swcr, orig_swcr;
+  orig_swcr = __ieee_get_fp_control ();
+  swcr = orig_swcr & ~exceptions;
+  if (swcr != orig_swcr)
+__ieee_set_fp_control (swcr);
+
+  return 0;
+}
+
+# elif defined __hppa
+
+int
+feclearexcept (int exceptions)
+{
+  exceptions &= FE_ALL_EXCEPT;
+
+  union { unsigned long long fpreg; unsigned int halfreg[2]; } s;
+  /* Get the current status word. */
+  __asm__ __volatile__ ("fstd %%fr0,0(%1)" : "=m" (s.fpreg) : "r" () : "%r0");
+  unsigned int old_halfreg0 = s.halfreg[0];
+  /* Clear all the relevant bits. */
+  s.halfreg[0] &= ~ ((unsigned int) exceptions << 27);
+  if (s.halfreg[0] != old_halfreg0)
+{
+  /* Store the new status word.  */
+  __asm__ __volatile__ ("fldd 0(%0),%%fr0" : : "r" (), "m" (s.fpreg) : "%r0");
+}
+
+  return 0;
+}
+
+# elif defined __ia64__
+
+int
+feclearexcept (int exceptions)
+{
+  exceptions &= FE_ALL_EXCEPT;
+
+  unsigned long fpsr, orig_fpsr;
+  _FPU_GETCW (orig_fpsr);
+  fpsr = orig_fpsr & ~ (unsigned long) (exceptions << 13);
+  if (fpsr != orig_fpsr)
+_FPU_SETCW (fpsr);
+
+  return 0;
+}
+
+# elif defined __m68k__
+
+int
+feclearexcept (int exceptions)
+{
+  exceptions &= FE_ALL_EXCEPT;
+
+  unsigned int fpsr, orig_fpsr;
+  _FPU_GETFPSR (orig_fpsr);
+  fpsr = orig_fpsr & ~ exceptions;
+  if (fpsr != orig_fpsr)
+_FPU_SETFPSR (fpsr);
+
+  return 0;
+}
+
+# elif defined __mips__
+
+int
+feclearexcept (int exceptions)
+{
+  exceptions &= FE_ALL_EXCEPT;
+
+  /* Clear also the cause bits.  If the cause bit is not cleared, the next
+ CTC instruction (just below) will re-generate the exception.  */
+  unsigned int fcsr, orig_fcsr;
+  _FPU_GETCW (orig_fcsr);
+  fcsr = orig_fcsr & ~ ((exceptions << 10) | exceptions);
+  if (fcsr != orig_fcsr)
+_FPU_SETCW (fcsr);
+
+  return 0;
+}
+
+# elif defined __loongarch__
+
+int
+feclearexcept (int exceptions)
+{
+  exceptions &= FE_ALL_EXCEPT;
+
+  /* Clear also the cause bits.  If the cause bit is not cleared, the next
+ CTC instruction (just below) will re-generate the exception.  */
+  unsigned int fcsr, orig_fcsr;
+  _FPU_GETCW (orig_fcsr);
+  fcsr = orig_fcsr & ~ ((exceptions << 8) | exceptions);
+  if (fcsr != orig_fcsr)
+_FPU_SETCW (fcsr);
+
+  return 0;
+}
+
+# elif defined __powerpc__
+
+int
+feclearexcept (int exceptions)
+{
+  exceptions &= FE_ALL_EXCEPT;
+
+  union { unsigned long long u; double f; } memenv, orig_memenv;
+  _FPU_GETCW_AS_DOUBLE (memenv.f);
+  orig_memenv = memenv;
+
+  /* Instead of clearing FE_INVALID (= bit 29), we need to clear the
+ individual bits.  */
+  memenv.u &= ~ (exceptions & FE_INVALID
+ ? (exceptions & ~FE_INVALID) | 0x01F80700U
+ : exceptions);
+
+  if (!(memenv.u == orig_memenv.u))
+_FPU_SETCW_AS_DOUBLE (memenv.f);
+
+  return 0;
+}
+
+# elif defined __riscv
+
+int
+feclearexcept (int exceptions)
+{
+  exceptions &= FE_ALL_EXCEPT;
+  __asm__ __volatile__ ("csrc fflags, %0" : : "r" (exceptions));
+  return 0;
+}
+
+# elif defined __s390__ || defined __s390x__
+
+int
+feclearexcept (int exceptions)
+{
+  exceptions &= FE_ALL_EXCEPT;
+
+  unsigned int fpc, orig_fpc;
+  _FPU_GETCW (orig_fpc);
+#  if FE_INEXACT == 8 /* glibc compatible FE_* values */
+  fpc = orig_fpc & ~(exceptions << 16);
+  if ((fpc & 0x0300) == 0)
+fpc &= ~(exceptions << 8);
+#  else /* musl libc compatible FE_* values */
+  fpc = orig_fpc & ~exceptions;
+  if ((fpc & 0x0300) == 0)
+fpc &= ~(exceptions >> 8);
+#  endif
+  if (fpc != orig_fpc)
+_FPU_SETCW (fpc);
+
+  return 0;
+}
+
+# elif defined __sh__
+
+int
+feclearexcept (int exceptions)
+{
+  exceptions &= FE_ALL_EXCEPT;
+
+  unsigned int fpscr, orig_fpscr;
+  _FPU_GETCW (orig_fpscr);
+  fpscr = orig_fpscr & ~exceptions;
+  if (fpscr != orig_fpscr)
+_FPU_SETCW (fpscr);
+
+  return 0;
+}
+
+# elif def

Re: fseeko broken by Fedora rawhide glibc / git master (ie future 2.28)

2018-03-05 Thread Daniel P . Berrangé
, BeOS, Haiku, 
> Linux libc5 */
>  
>  /* Clear the stream's ungetc buffer, preserving the value of ftello (fp).  */
>  static void
> @@ -72,7 +72,7 @@ clear_ungetc_buffer (FILE *fp)
>  
>  #endif
>  
> -#if ! (defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, 
> Haiku, Linux libc5 */)
> +#if ! (defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, 
> Haiku, Linux libc5 */)
>  
>  # if (defined __sferror || defined __DragonFly__ || defined __ANDROID__) && 
> defined __SNPT
>  /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */
> @@ -148,7 +148,7 @@ rpl_fflush (FILE *stream)
>if (stream == NULL || ! freading (stream))
>  return fflush (stream);
>  
> -#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, 
> Haiku, Linux libc5 */
> +#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, 
> Linux libc5 */
>  
>clear_ungetc_buffer_preserving_position (stream);
>  
> diff --git a/lib/fpending.c b/lib/fpending.c
> index c84e3a5b4..789f50e4e 100644
> --- a/lib/fpending.c
> +++ b/lib/fpending.c
> @@ -32,7 +32,7 @@ __fpending (FILE *fp)
>/* Most systems provide FILE as a struct and the necessary bitmask in
>   , because they need it for implementing getc() and putc() as
>   fast macros.  */
> -#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, 
> Haiku, Linux libc5 */
> +#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, 
> Linux libc5 */
>return fp->_IO_write_ptr - fp->_IO_write_base;
>  #elif defined __sferror || defined __DragonFly__ || defined __ANDROID__
>/* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android 
> */
> diff --git a/lib/fpurge.c b/lib/fpurge.c
> index b1d417c7a..3aedcc373 100644
> --- a/lib/fpurge.c
> +++ b/lib/fpurge.c
> @@ -62,7 +62,7 @@ fpurge (FILE *fp)
>/* Most systems provide FILE as a struct and the necessary bitmask in
>   , because they need it for implementing getc() and putc() as
>   fast macros.  */
> -# if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, 
> Haiku, Linux libc5 */
> +# if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, 
> Linux libc5 */
>fp->_IO_read_end = fp->_IO_read_ptr;
>fp->_IO_write_ptr = fp->_IO_write_base;
>/* Avoid memory leak when there is an active ungetc buffer.  */
> diff --git a/lib/freadable.c b/lib/freadable.c
> index 03b50e186..c4ca0b86e 100644
> --- a/lib/freadable.c
> +++ b/lib/freadable.c
> @@ -31,7 +31,7 @@ freadable (FILE *fp)
>/* Most systems provide FILE as a struct and the necessary bitmask in
>   , because they need it for implementing getc() and putc() as
>   fast macros.  */
> -#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, 
> Haiku, Linux libc5 */
> +#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, 
> Linux libc5 */
>return (fp->_flags & _IO_NO_READS) == 0;
>  #elif defined __sferror || defined __DragonFly__ || defined __ANDROID__
>/* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android 
> */
> diff --git a/lib/freadahead.c b/lib/freadahead.c
> index c2ecb5b28..23ec76ee5 100644
> --- a/lib/freadahead.c
> +++ b/lib/freadahead.c
> @@ -30,7 +30,7 @@ extern size_t __sreadahead (FILE *);
>  size_t
>  freadahead (FILE *fp)
>  {
> -#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, 
> Haiku, Linux libc5 */
> +#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, 
> Linux libc5 */
>if (fp->_IO_write_ptr > fp->_IO_write_base)
>  return 0;
>return (fp->_IO_read_end - fp->_IO_read_ptr)
> diff --git a/lib/freading.c b/lib/freading.c
> index 73c28acdd..c24d0c88a 100644
> --- a/lib/freading.c
> +++ b/lib/freading.c
> @@ -31,7 +31,7 @@ freading (FILE *fp)
>/* Most systems provide FILE as a struct and the necessary bitmask in
>   , because they need it for implementing getc() and putc() as
>   fast macros.  */
> -# if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, 
> Haiku, Linux libc5 */
> +# if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, 
> Linux libc5 */
>return ((fp->_flags & _IO_NO_WRITES) != 0
>|| ((fp->_flags & (_IO_NO_READS | _IO_CURRENTLY_PUTTING)) == 0
>&& fp->_IO_read_base != NULL));
> diff --git a/lib/freadptr.c b/lib/freadptr.c
> index 5aeadf3da..ffb801039 100644
> --- a/lib/freadptr.c
> +++ b/lib/freadptr.c
> @@ -29,7 +29,7 @@ freadptr (FILE *fp, size_t *sizep)
>

Re: fseeko broken by Fedora rawhide glibc / git master (ie future 2.28)

2018-03-05 Thread Paul Eggert
 
Linux libc5 */
+#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, 
Linux libc5 */
 
   clear_ungetc_buffer_preserving_position (stream);
 
diff --git a/lib/fpending.c b/lib/fpending.c
index c84e3a5b4..789f50e4e 100644
--- a/lib/fpending.c
+++ b/lib/fpending.c
@@ -32,7 +32,7 @@ __fpending (FILE *fp)
   /* Most systems provide FILE as a struct and the necessary bitmask in
  , because they need it for implementing getc() and putc() as
  fast macros.  */
-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, 
Linux libc5 */
+#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, 
Linux libc5 */
   return fp->_IO_write_ptr - fp->_IO_write_base;
 #elif defined __sferror || defined __DragonFly__ || defined __ANDROID__
   /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */
diff --git a/lib/fpurge.c b/lib/fpurge.c
index b1d417c7a..3aedcc373 100644
--- a/lib/fpurge.c
+++ b/lib/fpurge.c
@@ -62,7 +62,7 @@ fpurge (FILE *fp)
   /* Most systems provide FILE as a struct and the necessary bitmask in
  , because they need it for implementing getc() and putc() as
  fast macros.  */
-# if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, 
Haiku, Linux libc5 */
+# if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, 
Linux libc5 */
   fp->_IO_read_end = fp->_IO_read_ptr;
   fp->_IO_write_ptr = fp->_IO_write_base;
   /* Avoid memory leak when there is an active ungetc buffer.  */
diff --git a/lib/freadable.c b/lib/freadable.c
index 03b50e186..c4ca0b86e 100644
--- a/lib/freadable.c
+++ b/lib/freadable.c
@@ -31,7 +31,7 @@ freadable (FILE *fp)
   /* Most systems provide FILE as a struct and the necessary bitmask in
  , because they need it for implementing getc() and putc() as
  fast macros.  */
-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, 
Linux libc5 */
+#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, 
Linux libc5 */
   return (fp->_flags & _IO_NO_READS) == 0;
 #elif defined __sferror || defined __DragonFly__ || defined __ANDROID__
   /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */
diff --git a/lib/freadahead.c b/lib/freadahead.c
index c2ecb5b28..23ec76ee5 100644
--- a/lib/freadahead.c
+++ b/lib/freadahead.c
@@ -30,7 +30,7 @@ extern size_t __sreadahead (FILE *);
 size_t
 freadahead (FILE *fp)
 {
-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, 
Linux libc5 */
+#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, 
Linux libc5 */
   if (fp->_IO_write_ptr > fp->_IO_write_base)
 return 0;
   return (fp->_IO_read_end - fp->_IO_read_ptr)
diff --git a/lib/freading.c b/lib/freading.c
index 73c28acdd..c24d0c88a 100644
--- a/lib/freading.c
+++ b/lib/freading.c
@@ -31,7 +31,7 @@ freading (FILE *fp)
   /* Most systems provide FILE as a struct and the necessary bitmask in
  , because they need it for implementing getc() and putc() as
  fast macros.  */
-# if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, 
Haiku, Linux libc5 */
+# if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, 
Linux libc5 */
   return ((fp->_flags & _IO_NO_WRITES) != 0
   || ((fp->_flags & (_IO_NO_READS | _IO_CURRENTLY_PUTTING)) == 0
   && fp->_IO_read_base != NULL));
diff --git a/lib/freadptr.c b/lib/freadptr.c
index 5aeadf3da..ffb801039 100644
--- a/lib/freadptr.c
+++ b/lib/freadptr.c
@@ -29,7 +29,7 @@ freadptr (FILE *fp, size_t *sizep)
   size_t size;
 
   /* Keep this code in sync with freadahead!  */
-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, 
Linux libc5 */
+#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, 
Linux libc5 */
   if (fp->_IO_write_ptr > fp->_IO_write_base)
 return NULL;
   size = fp->_IO_read_end - fp->_IO_read_ptr;
diff --git a/lib/freadseek.c b/lib/freadseek.c
index e7b0c7bdb..5fd2dd7ca 100644
--- a/lib/freadseek.c
+++ b/lib/freadseek.c
@@ -36,7 +36,7 @@ freadptrinc (FILE *fp, size_t increment)
   /* Keep this code in sync with freadptr!  */
 #if HAVE___FREADPTRINC  /* musl libc */
   __freadptrinc (fp, increment);
-#elif defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, 
Haiku, Linux libc5 */
+#elif defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, 
Linux libc5 */
   fp->_IO_read_ptr += increment;
 #elif defined __sferror || defined __DragonFly__ || defined __ANDROID__
   /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */
diff --git a/lib/fseeko.c b/lib/fseeko.c
index 0101ab55f..193f4e8ce 100644
--- a/lib/fseeko.c
+++ b/lib/fseeko.c
@@ -47,7 +47,7 @@ fseeko (FILE *fp, off_t offset, int whence)
 #endif
 
   /* These tests are based on fpurge.c.  */
-#if defi

Re: [PATCH] ISO C 11 threads implementation

2019-06-21 Thread Bruno Haible
This patch makes the 'thread_local' storage class actually usable on
many platforms.

I found that 'thread_local' works on the following platforms:
  * Linux with glibc
on i386/x86_64/x32 (even on "old" systems such as CentOS 5), mips/mips64,
   sparc/sparc64, alpha, arm, arm64, powerpc/powerpc64, ia64, s390/s390x,
   riscv64, m68k, hppa
  * Linux with musl libc
on i386/x86_64
  * GNU/kFreeBSD
on i386/x86_64
  * Hurd
on i386
  * Mac OS X 10.13
on x86_64
  * FreeBSD 11 and MidnightBSD 0.8
on i386/x86_64, arm64
  * NetBSD 7
on i386/x86_64
  * AIX 7 (with 'xlc -qthreaded -qtls')
  * AIX 7.2 (with gcc)
  * HP-UX 11.31 (with gcc)
  * Solaris 10
on i386/x86_64, sparc/sparc64
  * Solaris 11.4
on i386/x86_64
  * illumos (OpenIndiana)
on i386/x86_64
  * Cygwin
on i386/x86_64
  * mingw
on i386/x86_64
  * Haiku
on i386

It does not work (__thread not understood by the compiler and linker)
on the following platforms:
  * Mac OS X 10.5
on i386/x86_64, powerpc
  * OpenBSD 6.5
  * HP-UX 11.31 (with cc)
  * IRIX 6.5 (with gcc)

It does not work (__thread not understood by the compiler and linker
but the test program crashes) on the following platforms:
  * AIX 7.1 (with gcc)
  * Android 4.3


2019-06-21  Bruno Haible  

threads-h: Define 'thread_local' if and only it actually works.
* m4/threads.m4 (gl_THREAD_LOCAL_DEFINITION): New macro.
(gl_THREADS_H): Define _Thread_local to __thread also for ARM C, IBM C,
Oracle Solaris Studio C. Compile a simple program, to see whether
_Thread_local basically works. Set HAVE_THREAD_LOCAL and LIBTHREADLOCAL.
(gl_THREADS_H_DEFAULTS): Initialize HAVE_THREAD_LOCAL.
* lib/threads.in.h (thread_local): Undefine if it does not work.
* modules/threads-h (Makefile.am): Substitute HAVE_THREAD_LOCAL.
(Link): Mention LIBTHREADLOCAL.
* tests/test-threads.c: Don't check that thread_local is defined.
* tests/test-thread_local.c: New file.
* modules/threads-h-tests (Files): Add it and macros.h.
(Depends-on): Add thrd and stdint.
(configure.ac): Test whether 'alarm' is declared.
(Makefile.am): Arrange to build and link test-thread_local.
* doc/posix-headers/threads.texi: Mention the platforms that don't
support 'thread_local'.

diff --git a/doc/posix-headers/threads.texi b/doc/posix-headers/threads.texi
index 71ae43a..d3bc66f 100644
--- a/doc/posix-headers/threads.texi
+++ b/doc/posix-headers/threads.texi
@@ -20,4 +20,20 @@ AIX 7.2.
 
 Portability problems not fixed by Gnulib:
 @itemize
+@item
+There is no way to define a working @code{thread_local} macro on some 
platforms:
+@itemize
+@item
+Mac OS X 10.5,
+@item
+OpenBSD 6.5,
+@item
+AIX 7.1 with gcc (but it works with @samp{xlc -qthreaded -qtls}),
+@item
+HP-UX 11.31 with cc (but it works with gcc),
+@item
+IRIX 6.5,
+@item
+Android 4.3.
+@end itemize
 @end itemize
diff --git a/lib/threads.in.h b/lib/threads.in.h
index a18d64b..b7fed72 100644
--- a/lib/threads.in.h
+++ b/lib/threads.in.h
@@ -67,6 +67,10 @@
 #if !@HAVE_THREADS_H@ || !defined thread_local
 # define thread_local _Thread_local
 #endif
+/* Define the macro thread_local if and only if it actually works.  */
+#if !@HAVE_THREAD_LOCAL@
+# undef thread_local
+#endif
 
 
 /* === ISO C 11 7.26.5 Thread functions === */
diff --git a/m4/threads.m4 b/m4/threads.m4
index 87e97f3..1aebb0a 100644
--- a/m4/threads.m4
+++ b/m4/threads.m4
@@ -1,9 +1,14 @@
-# threads.m4 serial 3
+# threads.m4 serial 4
 dnl Copyright (C) 2019 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
 dnl with or without modifications, as long as this notice is preserved.
 
+dnl Tests whether the  facility is available.
+dnl Sets the variable LIBSTDTHREAD to the linker options for use in a Makefile
+dnl for a program that uses the  functions.
+dnl Sets the variable LIBTHREADLOCAL to the linker options for use in a 
Makefile
+dnl for a program that uses the 'thread_local' macro.
 AC_DEFUN([gl_THREADS_H],
 [
   AC_REQUIRE([gl_THREADS_H_DEFAULTS])
@@ -79,16 +84,54 @@ AC_DEFUN([gl_THREADS_H],
   esac
   AC_SUBST([LIBSTDTHREAD])
 
-  AH_VERBATIM([thread_local],
-[/* The _Thread_local keyword of C11.  */
-#ifndef _Thread_local
-# if defined __GNUC__
-#  define _Thread_local __thread
-# elif defined _MSC_VER
-#  define _Thread_local __declspec (thread)
-# endif
-#endif
-])
+  dnl Define _Thread_local.
+  dnl GCC, for example, supports '__thread' since version 3.3, but it supports
+  dnl '_Thread_local' only starting with version 4.9.
+  AH_VERBATIM([thread_local], gl_THREAD_LOCAL_DEFINITION)
+
+  dnl Test whether _Thread_local is supported in the compiler and linker.
+  AC_CACHE_CHECK([whether _Thread_local works],
+[gl_cv_thread_local_works],
+[dnl On AIX 7.1 with GCC 4.8.1, this test program com

Re: critique of gnulib

2019-09-01 Thread Jonas 'Sortie' Termansen
Hi Bruno & Paul,

Thanks for your interest in my notes on gnulib. I appreciate your desire
to discuss them. Please excuse some of the resources that I'll link
below for overreacting in jest ("screaming in horror", "usual gnulib
infection"), they weren’t really meant for upstream consumption, but
they do refer to true struggles that I've had to go through. I
understand and appreciate that you and I have different goals, but I
think we do have some common ground. I'll give you the context of my
notes below.

My goal is to make a good and clean  POSIX-like operating system, and to
enable other people to do so as well because healthy competition is good.

I have contributed to gnulib in the past. Although my main interest is
my operating systems project and I only work on ports as needed. This
year I am dedicating my time to my game development project, so I don't
have the resources to do OS work these days. Please excuse me if my
information is out of date.

I rather enjoy my operating systems work on Sortix, though, because I've
accomplished something extraordinary: A self-hosting POSIX-like system
made from scratch with key ports of third party software (about 75% of
ports compiles natively, so I rely on cross-compilation). What really
surprised me pleasantly was that I did not have the same backwards
compatibility concerns of a GNU/Linux system. By doing things in a
simple way without historical mistakes, my project got a good baseline
quality.

This really accomplishes the best qualities of a free software platform,
because all the code and ports are integrated and are easy to modify
(you can 'cd /src && make sysmerge' out of the box and the system is
updated to the new sources of everything). I'm free to compete with
other POSIX-like systems by making better implementations of the
standard interfaces and in turn encouraging other systems to improve.
Meanwhile I have encountered technical debt in other projects that I
port, and I sometimes fix those issues and contribute fixes upstream,
improving the health of the free software ecosystem.

My method for porting software is to cross-compile the software to my OS
(see <https://wiki.osdev.org/Cross-Porting_Software>). Sometimes I have
to fix some build system bugs. Then I fix the compile errors and
warnings, if any. That may require implementing some new features in my
OS. Finally it compiles and I run it. It might not work or crash, and I
fix those bugs too. Finally I package up the thing and I might send a
patch to the upstream if I like the software and it's easy and the
upstream seems receptive.

I find BSD software can be easier to port than GNU software, even though
it often does not even attempt to be portable. I can easily deal with it
because it simply fails to compile and I can easily figure out what I
need to provide, or just change the software to use a different feature.
Porting GNU software can be much harder to port because of complexities
in layers like autoconf or gnulib that cause problems that didn't need
to be there.

A big problem with gnulib is that good new operating systems are
unreasonably burdened because of the mistakes of buggy operating systems
(which may have been fixed long ago). A good example is e.g.
cross-compilation. For instance, an old Unix might not have had a broken
fork() system call or something. When cross-compiling, gnulib might be
pessimistic and default to assuming the system call is broken, which may
be handled with a poor or inefficient fallback, disabling functionality
at runtime, or a compile time error. There is usually a whitelist of
systems without the problem and an environment variable to inject the
true answer. That means that it's harder to compete with a new unknown
operating system because I must set the environment variable, while
other operating systems just work, including the buggy one. That means
my good operating system is paying for the complexity caused by a bad
operating system. I'd rather the extra work of cross-compiling is moved
to the buggy operating systems.

Cross-compilation is inherently a bit more difficult when the host
system is buggy, so a more reasonable design would could be to assume
the best about unknown operating systems, and to only invoke the
workarounds for known buggy systems (and forcing them to set the
environment variable instead of me). That means the buggy operating
systems pay the cost instead of the good ones (making it harder for new
systems). Making cross-compilation nice helps the development of new
operating systems, and not just for established things like glibc/musl.

As you saw in my gnulib wiki page, I literally inject 120 environment
variables to make gnulib assume the very best about my operating system.
I'd rather be confronted with bugs up front than have then be secretly
hidden by a portability layer, or be told that it assumed the worst
about my unknown operating system so I have to teach it internals about
my 

<    1   2   3   4   5   >