unofficial mirror of bug-guile@gnu.org 
 help / color / mirror / Atom feed
* bug#52835: [PATCH 0/2] Fix spawning a child not setting standard fds properly
@ 2021-12-27 21:25 Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2021-12-27 21:35 ` bug#52835: [PATCH 1/2] Fix child spawning closing standard fds prematurely Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
                   ` (3 more replies)
  0 siblings, 4 replies; 36+ messages in thread
From: Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language @ 2021-12-27 21:25 UTC (permalink / raw)
  To: 52835; +Cc: Josselin Poiret

Hello,

While working on the Guix installer (that needs to use system* quite a
lot), I've noticed that output/error redirection doesn't behave as
intended when combined with system*.  Here's a test you can try
at home:
--8<---------------cut here---------------start------------->8---
(call-with-output-file "/tmp/test.log"
  (lambda (port) (with-output-to-port port
                   (lambda () (with-error-to-port port
                                (lambda () (system* "bash" "-c" "echo bong >&2")))))))
--8<---------------cut here---------------end--------------->8---

With current Guix, you will notice that /tmp/test.log is empty,
instead of the expected "bong".

Worse even, when testing with
--8<---------------cut here---------------start------------->8---
(with-error-to-port (current-output-port) (lambda () (system* "bash" "-c" "echo $$; sleep 10")))
--8<---------------cut here---------------end--------------->8---
you can actually inspect `/proc/<PID>/fd/` and see that the stderr fd,
2, is actually closed.  This means that the next opened fd will take
its place, to which writes to stderr may end up.

The logic behind the stdin/out/err redirection for child processes
lies in `start_child`, in libguile/posix.c, and doesn't take into
account cases like:
* in/out/err having common values, as the common fd will be closed
before it has been dup2'd to all the std fds (which happens in the
first example);
* in/out/err having values between 0 and 2 which aren't their
corresponding std fd number, as they will not be dup2'd to
the stdin/out/err (which happens in the second example).

The first patch addresses this by:
* moving in/out/err closing logic after they've all been dup2'd;
* removing the check that in/out/err are > the corresponding
stdin/out/err;
* replacing renumber_file_descriptor by simply dup, as the former
closes fds that might be shared.  The closing logic of the first point
is enough here.

The second patch removes renumber_file_descriptor, as it is no longer
used.

Best,
Josselin

Josselin Poiret (2):
  Fix child spawning closing standard fds prematurely
  Remove unused renumber_file_descriptor

 libguile/posix.c | 72 ++++++++++++++----------------------------------
 1 file changed, 20 insertions(+), 52 deletions(-)

-- 
2.34.0






^ permalink raw reply	[flat|nested] 36+ messages in thread

* bug#52835: [PATCH 1/2] Fix child spawning closing standard fds prematurely
  2021-12-27 21:25 bug#52835: [PATCH 0/2] Fix spawning a child not setting standard fds properly Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
@ 2021-12-27 21:35 ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2021-12-27 21:35 ` bug#52835: [PATCH 2/2] Remove unused renumber_file_descriptor Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 36+ messages in thread
From: Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language @ 2021-12-27 21:35 UTC (permalink / raw)
  To: Josselin Poiret; +Cc: 52835

* libguile/posix.c (start_child): Close standard file descriptors only
after all of them have been dup2'd.
---
 libguile/posix.c | 40 +++++++++++++++++++---------------------
 1 file changed, 19 insertions(+), 21 deletions(-)

diff --git a/libguile/posix.c b/libguile/posix.c
index 3ab12b99e..148ebeb3d 100644
--- a/libguile/posix.c
+++ b/libguile/posix.c
@@ -1357,27 +1357,25 @@ start_child (const char *exec_file, char **exec_argv,
   if (err == -1)
     err = open ("/dev/null", O_WRONLY);
 
-  if (in > 0)
-    {
-      if (out == 0)
-        out = renumber_file_descriptor (out, err);
-      if (err == 0)
-        err = renumber_file_descriptor (err, err);
-      do dup2 (in, 0); while (errno == EINTR);
-      close (in);
-    }
-  if (out > 1)
-    {
-      if (err == 1)
-        err = renumber_file_descriptor (err, err);
-      do dup2 (out, 1); while (errno == EINTR);
-      close (out);
-    }
-  if (err > 2)
-    {
-      do dup2 (err, 2); while (errno == EINTR);
-      close (err);
-    }
+  /* Dup each non-yet-dup2'd fd that's in the way to the next available fd,
+     so that we can safely dup2 to 0/1/2 without potentially overwriting
+     in/out/err.  Note that dup2 doesn't do anything if its arguments are
+     equal. */
+  if (out == 0)
+    do out = dup (out); while (errno == EINTR);
+  if (err == 0)
+    do err = dup (err); while (errno == EINTR);
+  do dup2 (in, 0); while (errno == EINTR);
+
+  if (err == 1)
+    do err = dup (err); while (errno == EINTR);
+  do dup2 (out, 1); while (errno == EINTR);
+
+  do dup2 (err, 2); while (errno == EINTR);
+
+  if (in > 2) close (in);
+  if (out > 2) close (out);
+  if (err > 2) close (err);
 
   execvp (exec_file, exec_argv);
 
-- 
2.34.0






^ permalink raw reply related	[flat|nested] 36+ messages in thread

* bug#52835: [PATCH 2/2] Remove unused renumber_file_descriptor
  2021-12-27 21:25 bug#52835: [PATCH 0/2] Fix spawning a child not setting standard fds properly Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2021-12-27 21:35 ` bug#52835: [PATCH 1/2] Fix child spawning closing standard fds prematurely Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
@ 2021-12-27 21:35 ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2021-12-27 21:49   ` bug#52835: [PATCH v2 " Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2021-12-28 15:40 ` bug#52835: [PATCH 0/2] Fix spawning a child not setting standard fds properly Timothy Sample
  2023-01-13  1:11 ` Andrew Whatson via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  3 siblings, 1 reply; 36+ messages in thread
From: Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language @ 2021-12-27 21:35 UTC (permalink / raw)
  To: Josselin Poiret; +Cc: 52835

* libguile/posix.c (renumber_file_descriptor): Remove it.
---
 libguile/posix.c | 32 +-------------------------------
 1 file changed, 1 insertion(+), 31 deletions(-)

diff --git a/libguile/posix.c b/libguile/posix.c
index 148ebeb3d..2624d07c2 100644
--- a/libguile/posix.c
+++ b/libguile/posix.c
@@ -1277,37 +1277,7 @@ SCM_DEFINE (scm_fork, "primitive-fork", 0, 0, 0,
   return scm_from_int (pid);
 }
 #undef FUNC_NAME
-#endif /* HAVE_FORK */
-
-#ifdef HAVE_FORK
-/* 'renumber_file_descriptor' is a helper function for 'start_child'
-   below, and is specialized for that particular environment where it
-   doesn't make sense to report errors via exceptions.  It uses dup(2)
-   to duplicate the file descriptor FD, closes the original FD, and
-   returns the new descriptor.  If dup(2) fails, print an error message
-   to ERR and abort.  */
-static int
-renumber_file_descriptor (int fd, int err)
-{
-  int new_fd;
-
-  do
-    new_fd = dup (fd);
-  while (new_fd == -1 && errno == EINTR);
-
-  if (new_fd == -1)
-    {
-      /* At this point we are in the child process before exec.  We
-         cannot safely raise an exception in this environment.  */
-      const char *msg = strerror (errno);
-      fprintf (fdopen (err, "a"), "start_child: dup failed: %s\n", msg);
-      _exit (127);  /* Use exit status 127, as with other exec errors. */
-    }
-
-  close (fd);
-  return new_fd;
-}
-#endif /* HAVE_FORK */
+#endif /* HAVE_FORK *
 
 #ifdef HAVE_FORK
 #define HAVE_START_CHILD 1
-- 
2.34.0






^ permalink raw reply related	[flat|nested] 36+ messages in thread

* bug#52835: [PATCH v2 2/2] Remove unused renumber_file_descriptor
  2021-12-27 21:35 ` bug#52835: [PATCH 2/2] Remove unused renumber_file_descriptor Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
@ 2021-12-27 21:49   ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  0 siblings, 0 replies; 36+ messages in thread
From: Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language @ 2021-12-27 21:49 UTC (permalink / raw)
  To: Josselin Poiret; +Cc: 52835

* libguile/posix.c (renumber_file_descriptor): Remove it.
---
Sorry for the noise, but I just saw that this patch omitted a closing
*/, here is a fixed version.

 libguile/posix.c | 30 ------------------------------
 1 file changed, 30 deletions(-)

diff --git a/libguile/posix.c b/libguile/posix.c
index 148ebeb3d..1d9996565 100644
--- a/libguile/posix.c
+++ b/libguile/posix.c
@@ -1279,36 +1279,6 @@ SCM_DEFINE (scm_fork, "primitive-fork", 0, 0, 0,
 #undef FUNC_NAME
 #endif /* HAVE_FORK */
 
-#ifdef HAVE_FORK
-/* 'renumber_file_descriptor' is a helper function for 'start_child'
-   below, and is specialized for that particular environment where it
-   doesn't make sense to report errors via exceptions.  It uses dup(2)
-   to duplicate the file descriptor FD, closes the original FD, and
-   returns the new descriptor.  If dup(2) fails, print an error message
-   to ERR and abort.  */
-static int
-renumber_file_descriptor (int fd, int err)
-{
-  int new_fd;
-
-  do
-    new_fd = dup (fd);
-  while (new_fd == -1 && errno == EINTR);
-
-  if (new_fd == -1)
-    {
-      /* At this point we are in the child process before exec.  We
-         cannot safely raise an exception in this environment.  */
-      const char *msg = strerror (errno);
-      fprintf (fdopen (err, "a"), "start_child: dup failed: %s\n", msg);
-      _exit (127);  /* Use exit status 127, as with other exec errors. */
-    }
-
-  close (fd);
-  return new_fd;
-}
-#endif /* HAVE_FORK */
-
 #ifdef HAVE_FORK
 #define HAVE_START_CHILD 1
 /* Since Guile uses threads, we have to be very careful to avoid calling
-- 
2.34.0






^ permalink raw reply related	[flat|nested] 36+ messages in thread

* bug#52835: [PATCH 0/2] Fix spawning a child not setting standard fds properly
  2021-12-27 21:25 bug#52835: [PATCH 0/2] Fix spawning a child not setting standard fds properly Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2021-12-27 21:35 ` bug#52835: [PATCH 1/2] Fix child spawning closing standard fds prematurely Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2021-12-27 21:35 ` bug#52835: [PATCH 2/2] Remove unused renumber_file_descriptor Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
@ 2021-12-28 15:40 ` Timothy Sample
  2021-12-28 17:25   ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2023-01-13  1:11 ` Andrew Whatson via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  3 siblings, 1 reply; 36+ messages in thread
From: Timothy Sample @ 2021-12-28 15:40 UTC (permalink / raw)
  To: 52835; +Cc: dev

Hey Josselin,

Thanks for finding this bug!  I have one concern about your patches:

Josselin Poiret writes:

> The second patch removes renumber_file_descriptor, as it is no longer
> used.

One thing that ‘renumber_file_descriptor’ does that we seem to be losing
here is error checking.  To my eye, the old code will try and warn the
user if they run out of file descriptors, but the new code will not.

The other thing that I like is how ‘renumber_file_descriptor’ checks the
return value of ‘dup’ in addition to checking ‘errno’.  (I realize that
the old code skips that check for ‘dup2’ – I’m kinda just stating a
preference here.)  A quick check of POSIX turns up the following: “the
value of ‘errno’ should only be examined when it is indicated to be
valid by a function’s return value” [1].


-- Tim

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





^ permalink raw reply	[flat|nested] 36+ messages in thread

* bug#52835: [PATCH 0/2] Fix spawning a child not setting standard fds properly
  2021-12-28 15:40 ` bug#52835: [PATCH 0/2] Fix spawning a child not setting standard fds properly Timothy Sample
@ 2021-12-28 17:25   ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2022-02-07 16:55     ` bug#52835: [PATCH v3] Fix child spawning closing standard fds prematurely Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  0 siblings, 1 reply; 36+ messages in thread
From: Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language @ 2021-12-28 17:25 UTC (permalink / raw)
  To: Timothy Sample; +Cc: 52835

Hello Timothy,

Timothy Sample <samplet@ngyro.com> writes:

> One thing that ‘renumber_file_descriptor’ does that we seem to be losing
> here is error checking.  To my eye, the old code will try and warn the
> user if they run out of file descriptors, but the new code will not.

I may have been too hasty on that front, you're right that we should
check for errors when dup'ing.  Note though that we should not run out
of fds, as we close all of them except for in/out/err right before using
it, but still, here are the interesting error codes:
* EINTR, although OpenBSD and Linux will never set that error from my
light research;
* EBUSY, not POSIX though, only Linux, so should we?
* EMFILE, if we run out of fds;
* EBADF if either of the fds are invalid.

As for error reporting, should we keep the parent's stderr fd open while
we do all of this, just to be able to report an error in case it
happens?  The old code used to try reporting the errors to the new `err`
fd instead, but it might be clearer to use stderr.

WDYT?

-- 
Josselin Poiret





^ permalink raw reply	[flat|nested] 36+ messages in thread

* bug#52835: [PATCH v3] Fix child spawning closing standard fds prematurely
  2021-12-28 17:25   ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
@ 2022-02-07 16:55     ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2022-05-28 12:46       ` bug#52835: [PATCH v4 0/4] Improve safety of start_child and piped-process Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  0 siblings, 1 reply; 36+ messages in thread
From: Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language @ 2022-02-07 16:55 UTC (permalink / raw)
  To: Josselin Poiret, Timothy Sample; +Cc: 52835

* libguile/posix.c (renumber_file_descriptor): Refactor it as
dup_handle_error.
(dup_handle_error, dup2_handle_error): New functions that wrap around
dup and dup2 by retrying on EINTR or EBUSY, as well as erroring out on
other errors.
(start_child): Close standard file descriptors only
after all of them have been dup2'd.
---
Hello,

This is a new version of the fix that should now handle possible
dup/dup2 errors properly.

Best,
Josselin
 libguile/posix.c | 82 +++++++++++++++++++++++++++++++-----------------
 1 file changed, 53 insertions(+), 29 deletions(-)

diff --git a/libguile/posix.c b/libguile/posix.c
index 3ab12b99e..dc3080b3c 100644
--- a/libguile/posix.c
+++ b/libguile/posix.c
@@ -1280,14 +1280,14 @@ SCM_DEFINE (scm_fork, "primitive-fork", 0, 0, 0,
 #endif /* HAVE_FORK */
 
 #ifdef HAVE_FORK
-/* 'renumber_file_descriptor' is a helper function for 'start_child'
-   below, and is specialized for that particular environment where it
-   doesn't make sense to report errors via exceptions.  It uses dup(2)
-   to duplicate the file descriptor FD, closes the original FD, and
-   returns the new descriptor.  If dup(2) fails, print an error message
-   to ERR and abort.  */
+/* 'dup_handle_error' is a helper function for 'start_child' below, and
+   is specialized for that particular environment where it doesn't make
+   sense to report errors via exceptions.  It uses dup(2) to duplicate
+   the file descriptor FD, does *not* close the original FD, and returns
+   the new descriptor.  If dup(2) fails, print an error message to ERR
+   and abort.  */
 static int
-renumber_file_descriptor (int fd, int err)
+dup_handle_error (int fd, int err)
 {
   int new_fd;
 
@@ -1304,7 +1304,33 @@ renumber_file_descriptor (int fd, int err)
       _exit (127);  /* Use exit status 127, as with other exec errors. */
     }
 
-  close (fd);
+  return new_fd;
+}
+
+/* 'dup2_handle_error' is a helper function for 'start_child' below, and
+   is specialized for that particular environment where it doesn't make
+   sense to report errors via exceptions.  It uses dup2(2) to duplicate
+   the file descriptor FD, does *not* close the original FD, and returns
+   the new descriptor.  If dup2(2) fails, print an error message to ERR
+   and abort.  */
+static int
+dup2_handle_error (int fd, int to, int err)
+{
+  int new_fd;
+
+  do
+    new_fd = dup2 (fd, to);
+  while (new_fd == -1 && (errno == EINTR || errno == EBUSY));
+
+  if (new_fd == -1)
+    {
+      /* At this point we are in the child process before exec.  We
+         cannot safely raise an exception in this environment.  */
+      const char *msg = strerror (errno);
+      fprintf (fdopen (err, "a"), "start_child: dup failed: %s\n", msg);
+      _exit (127);  /* Use exit status 127, as with other exec errors. */
+    }
+
   return new_fd;
 }
 #endif /* HAVE_FORK */
@@ -1357,27 +1383,25 @@ start_child (const char *exec_file, char **exec_argv,
   if (err == -1)
     err = open ("/dev/null", O_WRONLY);
 
-  if (in > 0)
-    {
-      if (out == 0)
-        out = renumber_file_descriptor (out, err);
-      if (err == 0)
-        err = renumber_file_descriptor (err, err);
-      do dup2 (in, 0); while (errno == EINTR);
-      close (in);
-    }
-  if (out > 1)
-    {
-      if (err == 1)
-        err = renumber_file_descriptor (err, err);
-      do dup2 (out, 1); while (errno == EINTR);
-      close (out);
-    }
-  if (err > 2)
-    {
-      do dup2 (err, 2); while (errno == EINTR);
-      close (err);
-    }
+  /* Dup each non-yet-dup2'd fd that's in the way to the next available fd,
+     so that we can safely dup2 to 0/1/2 without potentially overwriting
+     in/out/err.  Note that dup2 doesn't do anything if its arguments are
+     equal. */
+  if (out == 0)
+    out = dup_handle_error (out, err);
+  if (err == 0)
+    err = dup_handle_error (err, err);
+  dup2_handle_error (in, 0, err);
+
+  if (err == 1)
+    err = dup_handle_error (err, err);
+  dup2_handle_error (out, 1, err);
+
+  dup2_handle_error (err, 2, err);
+
+  if (in > 2) close (in);
+  if (out > 2) close (out);
+  if (err > 2) close (err);
 
   execvp (exec_file, exec_argv);
 
-- 
2.34.0






^ permalink raw reply related	[flat|nested] 36+ messages in thread

* bug#52835: [PATCH v4 0/4] Improve safety of start_child and piped-process.
  2022-02-07 16:55     ` bug#52835: [PATCH v3] Fix child spawning closing standard fds prematurely Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
@ 2022-05-28 12:46       ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2022-05-28 12:46         ` bug#52835: [PATCH v4 1/4] Fix child spawning closing standard fds prematurely Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
                           ` (4 more replies)
  0 siblings, 5 replies; 36+ messages in thread
From: Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language @ 2022-05-28 12:46 UTC (permalink / raw)
  To: Josselin Poiret, Timothy Sample; +Cc: 52835

retitle 52835 Improve safety of start_child and piped-process.
thanks

Hello everyone,

This time, it's another Guix bug [1] that prompted me to have a closer
look at piped-process and start_child, which don't seem to be very
multi-thread safe.  I've ended up with a couple of improvements that
IMO would make all procedures relying on them more robust.  Here's
roughly what I did:

* Fix the fd closing code that was bogus for unusual values for in,
  out, err for start_child.
* Check for double closes and avoid them, so that we don't
  accidentally close an fd that another thread could have opened.
* Remove some closing code in the child, since we're already
  generically closing all fds.
* Add a pipe from the child to the parent that the former uses to
  report its errno to the latter.  This avoids the use of strerror and
  printf in the child after forking, since they are not async-signal
  safe.  As a side effect, this lets piped-error raise the proper
  system exception for the child errno, instead of returning the PID
  of a process that hasn't exec'd successfully.

[1] https://issues.guix.gnu.org/55441

Best,
Josselin Poiret (4):
  Fix child spawning closing standard fds prematurely.
  Avoid double closes in piped-process.
  Remove useless closing code in start_child.
  Make start_child propagate the child errno to the parent.

 configure.ac     |   3 +-
 libguile/posix.c | 187 ++++++++++++++++++++++++++++++++++-------------
 2 files changed, 138 insertions(+), 52 deletions(-)

-- 
2.36.0






^ permalink raw reply	[flat|nested] 36+ messages in thread

* bug#52835: [PATCH v4 1/4] Fix child spawning closing standard fds prematurely.
  2022-05-28 12:46       ` bug#52835: [PATCH v4 0/4] Improve safety of start_child and piped-process Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
@ 2022-05-28 12:46         ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2022-05-28 12:46         ` bug#52835: [PATCH v4 2/4] Avoid double closes in piped-process Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
                           ` (3 subsequent siblings)
  4 siblings, 0 replies; 36+ messages in thread
From: Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language @ 2022-05-28 12:46 UTC (permalink / raw)
  To: Josselin Poiret, Timothy Sample; +Cc: 52835

* libguile/posix.c (renumber_file_descriptor): Refactor it as
dup_handle_error.
(dup_handle_error, dup2_handle_error): New functions that wrap around
dup and dup2 by retrying on EINTR or EBUSY, as well as erroring out on
other errors.
(start_child): Close standard file descriptors only after all of them
have been dup2'd.
---
 libguile/posix.c | 84 +++++++++++++++++++++++++++++++-----------------
 1 file changed, 54 insertions(+), 30 deletions(-)

diff --git a/libguile/posix.c b/libguile/posix.c
index 3ab12b99e..e9f49fa27 100644
--- a/libguile/posix.c
+++ b/libguile/posix.c
@@ -1280,14 +1280,14 @@ SCM_DEFINE (scm_fork, "primitive-fork", 0, 0, 0,
 #endif /* HAVE_FORK */
 
 #ifdef HAVE_FORK
-/* 'renumber_file_descriptor' is a helper function for 'start_child'
-   below, and is specialized for that particular environment where it
-   doesn't make sense to report errors via exceptions.  It uses dup(2)
-   to duplicate the file descriptor FD, closes the original FD, and
-   returns the new descriptor.  If dup(2) fails, print an error message
-   to ERR and abort.  */
+/* 'dup_handle_error' is a helper function for 'start_child' below, and
+   is specialized for that particular environment where it doesn't make
+   sense to report errors via exceptions.  It uses dup(2) to duplicate
+   the file descriptor FD, does *not* close the original FD, and returns
+   the new descriptor.  If dup(2) fails, print an error message to ERR
+   and abort.  */
 static int
-renumber_file_descriptor (int fd, int err)
+dup_handle_error (int fd, int err)
 {
   int new_fd;
 
@@ -1304,7 +1304,33 @@ renumber_file_descriptor (int fd, int err)
       _exit (127);  /* Use exit status 127, as with other exec errors. */
     }
 
-  close (fd);
+  return new_fd;
+}
+
+/* 'dup2_handle_error' is a helper function for 'start_child' below, and
+   is specialized for that particular environment where it doesn't make
+   sense to report errors via exceptions.  It uses dup2(2) to duplicate
+   the file descriptor FD, does *not* close the original FD, and returns
+   the new descriptor.  If dup2(2) fails, print an error message to ERR
+   and abort.  */
+static int
+dup2_handle_error (int fd, int to, int err)
+{
+  int new_fd;
+
+  do
+    new_fd = dup2 (fd, to);
+  while (new_fd == -1 && (errno == EINTR || errno == EBUSY));
+
+  if (new_fd == -1)
+    {
+      /* At this point we are in the child process before exec.  We
+         cannot safely raise an exception in this environment.  */
+      const char *msg = strerror (errno);
+      fprintf (fdopen (err, "a"), "start_child: dup failed: %s\n", msg);
+      _exit (127);  /* Use exit status 127, as with other exec errors. */
+    }
+
   return new_fd;
 }
 #endif /* HAVE_FORK */
@@ -1357,34 +1383,32 @@ start_child (const char *exec_file, char **exec_argv,
   if (err == -1)
     err = open ("/dev/null", O_WRONLY);
 
-  if (in > 0)
-    {
-      if (out == 0)
-        out = renumber_file_descriptor (out, err);
-      if (err == 0)
-        err = renumber_file_descriptor (err, err);
-      do dup2 (in, 0); while (errno == EINTR);
-      close (in);
-    }
-  if (out > 1)
-    {
-      if (err == 1)
-        err = renumber_file_descriptor (err, err);
-      do dup2 (out, 1); while (errno == EINTR);
-      close (out);
-    }
-  if (err > 2)
-    {
-      do dup2 (err, 2); while (errno == EINTR);
-      close (err);
-    }
+  /* Dup each non-yet-dup2'd fd that's in the way to the next available fd,
+     so that we can safely dup2 to 0/1/2 without potentially overwriting
+     in/out/err.  Note that dup2 doesn't do anything if its arguments are
+     equal. */
+  if (out == 0)
+    out = dup_handle_error (out, err);
+  if (err == 0)
+    err = dup_handle_error (err, err);
+  dup2_handle_error (in, 0, err);
+
+  if (err == 1)
+    err = dup_handle_error (err, err);
+  dup2_handle_error (out, 1, err);
+
+  dup2_handle_error (err, 2, err);
+
+  if (in > 2) close (in);
+  if (out > 2) close (out);
+  if (err > 2) close (err);
 
   execvp (exec_file, exec_argv);
 
   /* The exec failed!  There is nothing sensible to do.  */
   {
     const char *msg = strerror (errno);
-    fprintf (fdopen (2, "a"), "In execvp of %s: %s\n",
+    dprintf (2, "In execvp of %s: %s\n",
              exec_file, msg);
   }
 
-- 
2.36.0






^ permalink raw reply related	[flat|nested] 36+ messages in thread

* bug#52835: [PATCH v4 2/4] Avoid double closes in piped-process.
  2022-05-28 12:46       ` bug#52835: [PATCH v4 0/4] Improve safety of start_child and piped-process Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2022-05-28 12:46         ` bug#52835: [PATCH v4 1/4] Fix child spawning closing standard fds prematurely Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
@ 2022-05-28 12:46         ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2022-05-28 12:46         ` bug#52835: [PATCH v4 3/4] Remove useless closing code in start_child Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
                           ` (2 subsequent siblings)
  4 siblings, 0 replies; 36+ messages in thread
From: Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language @ 2022-05-28 12:46 UTC (permalink / raw)
  To: Josselin Poiret, Timothy Sample; +Cc: 52835

* libguile/posix.c (scm_piped_process): Avoid double closes.
---
 libguile/posix.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/libguile/posix.c b/libguile/posix.c
index e9f49fa27..155ad09b7 100644
--- a/libguile/posix.c
+++ b/libguile/posix.c
@@ -1475,12 +1475,18 @@ scm_piped_process (SCM prog, SCM args, SCM from, SCM to)
       if (reading)
         {
           close (c2p[0]);
-          close (c2p[1]);
+          if (c2p[1] != c2p[0])
+            close (c2p[1]);
         }
       if (writing)
         {
-          close (p2c[0]);
-          close (p2c[1]);
+          if (!(reading && (c2p[0] == p2c[0] ||
+                            c2p[1] == p2c[0])))
+            close (p2c[0]);
+          if (p2c[0] != p2c[1] &&
+              !(reading && (c2p[0] == p2c[1] ||
+                            c2p[1] == p2c[1])))
+            close (p2c[1]);
         }
       errno = errno_save;
       SCM_SYSERROR;
@@ -1488,7 +1494,7 @@ scm_piped_process (SCM prog, SCM args, SCM from, SCM to)
 
   if (reading)
     close (c2p[1]);
-  if (writing)
+  if (writing && !(reading && c2p[1] == p2c[0]))
     close (p2c[0]);
 
   return scm_from_int (pid);
-- 
2.36.0






^ permalink raw reply related	[flat|nested] 36+ messages in thread

* bug#52835: [PATCH v4 3/4] Remove useless closing code in start_child.
  2022-05-28 12:46       ` bug#52835: [PATCH v4 0/4] Improve safety of start_child and piped-process Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2022-05-28 12:46         ` bug#52835: [PATCH v4 1/4] Fix child spawning closing standard fds prematurely Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2022-05-28 12:46         ` bug#52835: [PATCH v4 2/4] Avoid double closes in piped-process Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
@ 2022-05-28 12:46         ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2022-05-28 12:46         ` bug#52835: [PATCH v4 4/4] Make start_child propagate the child errno to the parent Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2022-09-05  6:48         ` bug#52835: [PATCH v5 0/3] Move spawning procedures to posix_spawn Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  4 siblings, 0 replies; 36+ messages in thread
From: Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language @ 2022-05-28 12:46 UTC (permalink / raw)
  To: Josselin Poiret, Timothy Sample; +Cc: 52835

* libguile/posix.c (start_child): We're closing all fds anyway, no need
to try to close some specific ones beforehand.
---
 libguile/posix.c | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/libguile/posix.c b/libguile/posix.c
index 155ad09b7..94a043cca 100644
--- a/libguile/posix.c
+++ b/libguile/posix.c
@@ -1363,12 +1363,6 @@ start_child (const char *exec_file, char **exec_argv,
        child.  Return directly in either case.  */
     return pid;
 
-  /* The child.  */
-  if (reading)
-    close (c2p[0]);
-  if (writing)
-    close (p2c[1]);
-
   /* Close all file descriptors in ports inherited from the parent
      except for in, out, and err.  Heavy-handed, but robust.  */
   while (max_fd--)
-- 
2.36.0






^ permalink raw reply related	[flat|nested] 36+ messages in thread

* bug#52835: [PATCH v4 4/4] Make start_child propagate the child errno to the parent.
  2022-05-28 12:46       ` bug#52835: [PATCH v4 0/4] Improve safety of start_child and piped-process Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
                           ` (2 preceding siblings ...)
  2022-05-28 12:46         ` bug#52835: [PATCH v4 3/4] Remove useless closing code in start_child Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
@ 2022-05-28 12:46         ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2022-09-05  6:48         ` bug#52835: [PATCH v5 0/3] Move spawning procedures to posix_spawn Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  4 siblings, 0 replies; 36+ messages in thread
From: Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language @ 2022-05-28 12:46 UTC (permalink / raw)
  To: Josselin Poiret, Timothy Sample; +Cc: 52835

* configure.ac: Add AC_CHECK_FUNCS for pipe2.
* libguile/posix.c (start_child): Use a pipe to transmit the child's
errno to the parent, which can then use it to signal an error instead of
writing to its error file descriptor.  This also avoids the use of
async-signal unsafe functions inside the child before exec.  Use pipe2
when available.
(dup_handle_error,dup2_handle_error): Ditto.
---
 configure.ac     |   3 +-
 libguile/posix.c | 113 ++++++++++++++++++++++++++++++++++++-----------
 2 files changed, 89 insertions(+), 27 deletions(-)

diff --git a/configure.ac b/configure.ac
index 827e1c09d..19441a52e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -525,6 +525,7 @@ AC_CHECK_HEADERS([assert.h crt_externs.h])
 #   fork - unavailable on Windows
 #   sched_getaffinity, sched_setaffinity - GNU extensions (glibc)
 #   sendfile - non-POSIX, found in glibc
+#   pipe2 - non-POSIX, found on Linux
 #
 AC_CHECK_FUNCS([DINFINITY DQNAN cexp chsize clog clog10 ctermid         \
   fesetround ftime ftruncate fchown fchmod getcwd geteuid getsid        \
@@ -536,7 +537,7 @@ AC_CHECK_FUNCS([DINFINITY DQNAN cexp chsize clog clog10 ctermid         \
   getgrent kill getppid getpgrp fork setitimer getitimer strchr strcmp  \
   index bcopy memcpy rindex truncate isblank _NSGetEnviron              \
   strcoll strcoll_l strtod_l strtol_l newlocale uselocale utimensat     \
-  sched_getaffinity sched_setaffinity sendfile])
+  sched_getaffinity sched_setaffinity sendfile pipe2])
 
 # The newlib C library uses _NL_ prefixed locale langinfo constants.
 AC_CHECK_DECLS([_NL_NUMERIC_GROUPING], [], [], [[#include <langinfo.h>]])
diff --git a/libguile/posix.c b/libguile/posix.c
index 94a043cca..79f097756 100644
--- a/libguile/posix.c
+++ b/libguile/posix.c
@@ -1284,8 +1284,7 @@ SCM_DEFINE (scm_fork, "primitive-fork", 0, 0, 0,
    is specialized for that particular environment where it doesn't make
    sense to report errors via exceptions.  It uses dup(2) to duplicate
    the file descriptor FD, does *not* close the original FD, and returns
-   the new descriptor.  If dup(2) fails, print an error message to ERR
-   and abort.  */
+   the new descriptor.  If dup(2) fails, send errno to ERR and abort.  */
 static int
 dup_handle_error (int fd, int err)
 {
@@ -1299,9 +1298,12 @@ dup_handle_error (int fd, int err)
     {
       /* At this point we are in the child process before exec.  We
          cannot safely raise an exception in this environment.  */
-      const char *msg = strerror (errno);
-      fprintf (fdopen (err, "a"), "start_child: dup failed: %s\n", msg);
-      _exit (127);  /* Use exit status 127, as with other exec errors. */
+      int errno_save = errno;
+      while (write (err, &errno_save, sizeof (errno)) == -1)
+        if (errno != EINTR)
+          break;
+
+      _exit (127);
     }
 
   return new_fd;
@@ -1311,8 +1313,8 @@ dup_handle_error (int fd, int err)
    is specialized for that particular environment where it doesn't make
    sense to report errors via exceptions.  It uses dup2(2) to duplicate
    the file descriptor FD, does *not* close the original FD, and returns
-   the new descriptor.  If dup2(2) fails, print an error message to ERR
-   and abort.  */
+   the new descriptor.  If dup2(2) fails, send errno to ERR and
+   abort.  */
 static int
 dup2_handle_error (int fd, int to, int err)
 {
@@ -1326,9 +1328,11 @@ dup2_handle_error (int fd, int to, int err)
     {
       /* At this point we are in the child process before exec.  We
          cannot safely raise an exception in this environment.  */
-      const char *msg = strerror (errno);
-      fprintf (fdopen (err, "a"), "start_child: dup failed: %s\n", msg);
-      _exit (127);  /* Use exit status 127, as with other exec errors. */
+      int errno_save = errno;
+      while (write (err, &errno_save, sizeof (errno)) == -1)
+        if (errno != EINTR)
+          break;
+      _exit (127);
     }
 
   return new_fd;
@@ -1347,6 +1351,8 @@ start_child (const char *exec_file, char **exec_argv,
 {
   int pid;
   int max_fd = 1024;
+  int errno_save;
+  int errpipefds[2];
 
 #if defined (HAVE_GETRLIMIT) && defined (RLIMIT_NOFILE)
   {
@@ -1356,17 +1362,73 @@ start_child (const char *exec_file, char **exec_argv,
   }
 #endif
 
+/* Setup a pipe to receive the errno of the child, which can't call
+   async-signal unsafe functions such as strerror or the printf family. */
+#ifdef HAVE_PIPE2
+  if (pipe2 (errpipefds, O_CLOEXEC))
+    return -1;
+#else
+  if (pipe (errpipefds))
+    return -1;
+  /* Set the writer end as close-on-exec, so that it automatically
+     closes on successful exec, and so that other threads that fork+exec
+     will not block it.
+
+     XXX: There can potentially be a race issue between the pipe and
+     fcntl calls, such that another thread that forks in between
+     inherits the fd without CLOEXEC.  There is no POSIXy way to make
+     the combination atomic, so just hope that any other fork would
+     release resources it doesn't need, like we do. */
+  if (fcntl (errpipefds[1], F_SETFD, fcntl (errpipefds[1], F_GETFD) | FD_CLOEXEC))
+    {
+      errno_save = errno;
+      close (errpipefds[0]);
+      close (errpipefds[1]);
+      errno = errno_save;
+      return -1;
+    }
+#endif
+
   pid = fork ();
 
   if (pid != 0)
-    /* The parent, with either and error (pid == -1), or the PID of the
-       child.  Return directly in either case.  */
-    return pid;
+    {
+      /* We're in the parent process. */
+      int read_count;
+      close (errpipefds[1]);
+      if (pid == -1)
+        {
+          /* Fork failed. */
+          errno_save = errno;
+          close (errpipefds[0]);
+          errno = errno_save;
+          return -1;
+        }
+
+      /* Fork successful, try to read a potential child errno from the pipe. */
+      while ((read_count = read(errpipefds[0], &errno_save, sizeof (errno))) == -1)
+        if (errno != EAGAIN && errno != EINTR)
+          break;
+      if (read_count == -1)
+        errno_save = errno;
+      close (errpipefds[0]);
+      if (read_count != 0)
+        {
+          /* Either the read failed (-1) or the child sent us an errno (> 0) */
+          errno = errno_save;
+          return -1;
+        }
+      return pid;
+    }
+
+  /* From now on, we are single threaded because of fork, so double
+     closes should be a no-op. */
 
   /* Close all file descriptors in ports inherited from the parent
-     except for in, out, and err.  Heavy-handed, but robust.  */
+     except for in, out, err and the error pipe back to the parent.
+     Heavy-handed, but robust.  */
   while (max_fd--)
-    if (max_fd != in && max_fd != out && max_fd != err)
+    if (max_fd != in && max_fd != out && max_fd != err && max_fd != errpipefds[1])
       close (max_fd);
 
   /* Ignore errors on these open() calls.  */
@@ -1382,16 +1444,16 @@ start_child (const char *exec_file, char **exec_argv,
      in/out/err.  Note that dup2 doesn't do anything if its arguments are
      equal. */
   if (out == 0)
-    out = dup_handle_error (out, err);
+    out = dup_handle_error (out, errpipefds[1]);
   if (err == 0)
-    err = dup_handle_error (err, err);
-  dup2_handle_error (in, 0, err);
+    err = dup_handle_error (err, errpipefds[1]);
+  dup2_handle_error (in, 0, errpipefds[1]);
 
   if (err == 1)
-    err = dup_handle_error (err, err);
-  dup2_handle_error (out, 1, err);
+    err = dup_handle_error (err, errpipefds[1]);
+  dup2_handle_error (out, 1, errpipefds[1]);
 
-  dup2_handle_error (err, 2, err);
+  dup2_handle_error (err, 2, errpipefds[1]);
 
   if (in > 2) close (in);
   if (out > 2) close (out);
@@ -1400,11 +1462,10 @@ start_child (const char *exec_file, char **exec_argv,
   execvp (exec_file, exec_argv);
 
   /* The exec failed!  There is nothing sensible to do.  */
-  {
-    const char *msg = strerror (errno);
-    dprintf (2, "In execvp of %s: %s\n",
-             exec_file, msg);
-  }
+  errno_save = errno;
+  while (write (errpipefds[1], &errno_save, sizeof (errno)) == -1)
+    if (errno != EINTR)
+      break;
 
   /* Use exit status 127, like shells in this case, as per POSIX
      <http://pubs.opengroup.org/onlinepubs/007904875/utilities/xcu_chap02.html#tag_02_09_01_01>.  */
-- 
2.36.0






^ permalink raw reply related	[flat|nested] 36+ messages in thread

* bug#52835: [PATCH v5 0/3] Move spawning procedures to posix_spawn.
  2022-05-28 12:46       ` bug#52835: [PATCH v4 0/4] Improve safety of start_child and piped-process Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
                           ` (3 preceding siblings ...)
  2022-05-28 12:46         ` bug#52835: [PATCH v4 4/4] Make start_child propagate the child errno to the parent Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
@ 2022-09-05  6:48         ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2022-09-05  6:48           ` bug#52835: [PATCH v5 1/3] Update gnulib to 0.1.5414-8204d and add posix_spawn, posix_spawnp Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
                             ` (2 more replies)
  4 siblings, 3 replies; 36+ messages in thread
From: Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language @ 2022-09-05  6:48 UTC (permalink / raw)
  To: 52835; +Cc: Timothy Sample, Josselin Poiret

Hi everyone,

As was discussed on IRC, if we're going to rewrite a non-negligible part of
posix.c, let's at least do it right and use posix_spawn to handle the process
spawning side of things.  This is quite complex to get right in general
(highlighted by this very bug) and so people have already done the hard work for
us.  Additionally, we use Gnulib's posix_spawn, so that it is available on all
supported systems.  I then adjusted all the procedures to use posix_spawn
instead of scm_piped_process and removed the latter, and the tests in
popen.test, posix.test.

There are two inderminates here:

* I don't have anything other than a Linux system to test.  This would need some
feedback for at least Mach and win32.

* This changes the interfaces (for the better, in my opinion): whenever
possible, posix_spawn reports child starting failures as a parent errno, meaning
that for eg. non- existing binaries, system* now throws an exception instead of
returning a pid that will have an exit status code of 127.  This means that
existing code that relies on that behavior will need to be changed, the first
example being the test suite which I adapted to actually check for exceptions
instead.  Some tests were removed because they no longer make sense: in
posix.test, https://bugs.gnu.org/13166, exit code for nonexistent file and
https://bugs.gnu.org/55596 are superseded by "exception for nonexistent file".

Also, I have no experience in using Gnulib so I'm not 100% sure I committed
exactly the right files, I'd love it if someone could check this is ok.

What do you all think about this approach?

Josselin Poiret (3):
  Update gnulib to 0.1.5414-8204d and add posix_spawn, posix_spawnp.
  Add spawn*.
  Move popen and posix procedures to spawn*.

 GNUmakefile                                |    2 +-
 build-aux/announce-gen                     |   69 +-
 build-aux/gendocs.sh                       |   50 +-
 build-aux/git-version-gen                  |   13 +-
 build-aux/gitlog-to-changelog              |    4 +-
 build-aux/gnu-web-doc-update               |    4 +-
 build-aux/gnupload                         |    4 +-
 build-aux/useless-if-before-free           |    6 +-
 build-aux/vc-list-files                    |    2 +-
 doc/gendocs_template                       |    4 +-
 doc/gendocs_template_min                   |    2 +-
 gnulib-local/m4/clock_time.m4.diff         |   12 +-
 lib/Makefile.am                            | 1252 +++++++++-------
 lib/_Noreturn.h                            |    2 +-
 lib/accept.c                               |    2 +-
 lib/accept4.c                              |    4 +-
 lib/access.c                               |   31 +
 lib/alignof.h                              |    2 +-
 lib/alloca.c                               |   35 -
 lib/alloca.in.h                            |    2 +-
 lib/arg-nonnull.h                          |    2 +-
 lib/arpa_inet.in.h                         |    2 +-
 lib/asnprintf.c                            |    2 +-
 lib/assure.h                               |    2 +-
 lib/attribute.h                            |   10 +-
 lib/basename-lgpl.c                        |    2 +-
 lib/basename-lgpl.h                        |    2 +-
 lib/binary-io.c                            |    2 +-
 lib/binary-io.h                            |    4 +-
 lib/bind.c                                 |    2 +-
 lib/btowc.c                                |    2 +-
 lib/byteswap.in.h                          |    2 +-
 lib/c++defs.h                              |    2 +-
 lib/c-ctype.c                              |    2 +-
 lib/c-ctype.h                              |    2 +-
 lib/c-strcase.h                            |    2 +-
 lib/c-strcasecmp.c                         |    2 +-
 lib/c-strcaseeq.h                          |    2 +-
 lib/c-strncasecmp.c                        |    2 +-
 lib/canonicalize-lgpl.c                    |    2 +-
 lib/cdefs.h                                |   76 +-
 lib/ceil.c                                 |    4 +-
 lib/cloexec.c                              |    2 +-
 lib/cloexec.h                              |    2 +-
 lib/close.c                                |    2 +-
 lib/concat-filename.c                      |   73 +
 lib/concat-filename.h                      |   46 +
 lib/connect.c                              |    2 +-
 lib/copysign.c                             |    4 +-
 lib/dirent.in.h                            |   24 +-
 lib/dirfd.c                                |    2 +-
 lib/dirname-lgpl.c                         |    2 +-
 lib/dirname.h                              |    2 +-
 lib/dup2.c                                 |    2 +-
 lib/duplocale.c                            |    4 +-
 lib/dynarray.h                             |    2 +-
 lib/eloop-threshold.h                      |    2 +-
 lib/errno.in.h                             |    2 +-
 lib/fcntl.c                                |    2 +-
 lib/fcntl.in.h                             |    6 +-
 lib/fd-hook.c                              |    2 +-
 lib/fd-hook.h                              |    2 +-
 lib/filename.h                             |    2 +-
 lib/findprog-in.c                          |  399 ++++++
 lib/findprog.h                             |   77 +
 lib/flexmember.h                           |    2 +-
 lib/float+.h                               |    2 +-
 lib/float.c                                |    2 +-
 lib/float.in.h                             |    2 +-
 lib/flock.c                                |    2 +-
 lib/floor.c                                |    4 +-
 lib/free.c                                 |    2 +-
 lib/frexp.c                                |    2 +-
 lib/fstat.c                                |    2 +-
 lib/fsync.c                                |    2 +-
 lib/full-read.c                            |    2 +-
 lib/full-read.h                            |    2 +-
 lib/full-write.c                           |    2 +-
 lib/full-write.h                           |    2 +-
 lib/gai_strerror.c                         |    2 +-
 lib/getaddrinfo.c                          |    2 +-
 lib/getdtablesize.c                        |    2 +-
 lib/getlogin.c                             |    2 +-
 lib/getpeername.c                          |    2 +-
 lib/getrandom.c                            |    2 +-
 lib/getsockname.c                          |    2 +-
 lib/getsockopt.c                           |    2 +-
 lib/gettext.h                              |   15 +-
 lib/hard-locale.c                          |    2 +-
 lib/hard-locale.h                          |    2 +-
 lib/iconv.c                                |    2 +-
 lib/iconv.in.h                             |    2 +-
 lib/iconv_close.c                          |    2 +-
 lib/iconv_open-aix.gperf                   |    2 +-
 lib/iconv_open-hpux.gperf                  |    2 +-
 lib/iconv_open-irix.gperf                  |    2 +-
 lib/iconv_open-osf.gperf                   |    2 +-
 lib/iconv_open-solaris.gperf               |    2 +-
 lib/iconv_open-zos.gperf                   |    2 +-
 lib/iconv_open-zos.h                       |  329 +++++
 lib/iconv_open.c                           |    2 +-
 lib/iconveh.h                              |    7 +-
 lib/idx.h                                  |   22 +-
 lib/inet_ntop.c                            |    2 +-
 lib/inet_pton.c                            |    2 +-
 lib/intprops-internal.h                    |  392 +++++
 lib/intprops.h                             |  359 +----
 lib/inttypes.h                             | 1509 ++++++++++++++++++++
 lib/inttypes.in.h                          |    2 +-
 lib/isfinite.c                             |    4 +-
 lib/isinf.c                                |    4 +-
 lib/isnan.c                                |    2 +-
 lib/isnand-nolibm.h                        |    2 +-
 lib/isnand.c                               |    2 +-
 lib/isnanf-nolibm.h                        |    2 +-
 lib/isnanf.c                               |    2 +-
 lib/isnanl-nolibm.h                        |    2 +-
 lib/isnanl.c                               |    2 +-
 lib/itold.c                                |    2 +-
 lib/langinfo.in.h                          |    2 +-
 lib/lc-charset-dispatch.c                  |    2 +-
 lib/lc-charset-dispatch.h                  |    2 +-
 lib/libc-config.h                          |   13 +-
 lib/libunistring.valgrind                  |    4 +-
 lib/limits.in.h                            |    2 +-
 lib/link.c                                 |    2 +-
 lib/listen.c                               |    2 +-
 lib/localcharset.c                         |    2 +-
 lib/localcharset.h                         |    2 +-
 lib/locale.in.h                            |    2 +-
 lib/localeconv.c                           |    2 +-
 lib/log.c                                  |    4 +-
 lib/log1p.c                                |    4 +-
 lib/lstat.c                                |    2 +-
 lib/malloc.c                               |    2 +-
 lib/malloc/.dirstamp                       |    0
 lib/malloc/dynarray-skeleton.c             |    2 +-
 lib/malloc/dynarray-skeleton.gl.h          |  529 +++++++
 lib/malloc/dynarray.gl.h                   |  174 +++
 lib/malloc/dynarray.h                      |    2 +-
 lib/malloc/dynarray_at_failure.c           |    2 +-
 lib/malloc/dynarray_emplace_enlarge.c      |    2 +-
 lib/malloc/dynarray_finalize.c             |    2 +-
 lib/malloc/dynarray_resize.c               |    2 +-
 lib/malloc/dynarray_resize_clear.c         |    2 +-
 lib/malloc/scratch_buffer.h                |    2 +-
 lib/malloc/scratch_buffer_dupfree.c        |    2 +-
 lib/malloc/scratch_buffer_grow.c           |    2 +-
 lib/malloc/scratch_buffer_grow_preserve.c  |    2 +-
 lib/malloc/scratch_buffer_set_array_size.c |    2 +-
 lib/malloca.c                              |   12 +-
 lib/malloca.h                              |    2 +-
 lib/math.c                                 |    2 +-
 lib/math.in.h                              |   16 +-
 lib/mbrtowc-impl-utf8.h                    |    2 +-
 lib/mbrtowc-impl.h                         |    2 +-
 lib/mbrtowc.c                              |    2 +-
 lib/mbsinit.c                              |    2 +-
 lib/mbtowc-impl.h                          |    2 +-
 lib/mbtowc-lock.c                          |    2 +-
 lib/mbtowc-lock.h                          |    2 +-
 lib/mbtowc.c                               |    2 +-
 lib/memchr.c                               |    2 +-
 lib/memchr.valgrind                        |    2 +-
 lib/mempcpy.c                              |    2 +-
 lib/minmax.h                               |    2 +-
 lib/mkdir.c                                |    4 +-
 lib/mkostemp.c                             |    2 +-
 lib/mktime-internal.h                      |    2 +-
 lib/mktime.c                               |   30 +-
 lib/msvc-inval.c                           |    2 +-
 lib/msvc-inval.h                           |    2 +-
 lib/msvc-nothrow.c                         |    2 +-
 lib/msvc-nothrow.h                         |    2 +-
 lib/netdb.in.h                             |    2 +-
 lib/netinet_in.in.h                        |    2 +-
 lib/nl_langinfo-lock.c                     |    2 +-
 lib/nl_langinfo.c                          |    2 +-
 lib/nproc.c                                |   24 +-
 lib/nproc.h                                |    2 +-
 lib/nstrftime.c                            |   28 +-
 lib/open.c                                 |    2 +-
 lib/pathmax.h                              |    2 +-
 lib/pipe.c                                 |    2 +-
 lib/pipe2.c                                |    2 +-
 lib/poll.c                                 |    2 +-
 lib/poll.in.h                              |    2 +-
 lib/printf-args.c                          |    2 +-
 lib/printf-args.h                          |    2 +-
 lib/printf-parse.c                         |    2 +-
 lib/printf-parse.h                         |    2 +-
 lib/putenv.c                               |    4 +-
 lib/raise.c                                |    2 +-
 lib/rawmemchr.c                            |   78 +-
 lib/rawmemchr.valgrind                     |    2 +-
 lib/read.c                                 |    2 +-
 lib/readlink.c                             |    6 +-
 lib/realloc.c                              |    2 +-
 lib/recv.c                                 |    2 +-
 lib/recvfrom.c                             |    2 +-
 lib/regcomp.c                              |  831 +++++------
 lib/regex.c                                |    3 +-
 lib/regex.h                                |   52 +-
 lib/regex_internal.c                       |   64 +-
 lib/regex_internal.h                       |   51 +-
 lib/regexec.c                              |   95 +-
 lib/rename.c                               |    4 +-
 lib/rmdir.c                                |    2 +-
 lib/round.c                                |    4 +-
 lib/safe-read.c                            |    2 +-
 lib/safe-read.h                            |    2 +-
 lib/safe-write.c                           |    2 +-
 lib/safe-write.h                           |    2 +-
 lib/same-inode.h                           |    2 +-
 lib/sched.h                                |  580 ++++++++
 lib/sched.in.h                             |   99 ++
 lib/scratch_buffer.h                       |    2 +-
 lib/select.c                               |    2 +-
 lib/send.c                                 |    2 +-
 lib/sendto.c                               |    2 +-
 lib/setenv.c                               |    2 +-
 lib/setlocale-lock.c                       |    2 +-
 lib/setlocale_null.c                       |    2 +-
 lib/setlocale_null.h                       |    2 +-
 lib/setsockopt.c                           |    2 +-
 lib/shutdown.c                             |    2 +-
 lib/signal.in.h                            |    2 +-
 lib/signbitd.c                             |    2 +-
 lib/signbitf.c                             |    2 +-
 lib/signbitl.c                             |    2 +-
 lib/size_max.h                             |    2 +-
 lib/snprintf.c                             |    2 +-
 lib/socket.c                               |    2 +-
 lib/sockets.c                              |    4 +-
 lib/sockets.h                              |    2 +-
 lib/spawn.c                                |   34 +
 lib/spawn.h                                | 1499 +++++++++++++++++++
 lib/spawn.in.h                             |  992 +++++++++++++
 lib/spawn_int.h                            |   72 +
 lib/spawni.c                               |  965 +++++++++++++
 lib/spawnp.c                               |   34 +
 lib/stat-time.c                            |    2 +-
 lib/stat-time.h                            |    8 +-
 lib/stat-w32.c                             |    2 +-
 lib/stat-w32.h                             |    2 +-
 lib/stat.c                                 |    2 +-
 lib/stdalign.in.h                          |    2 +-
 lib/stdbool.h                              |  116 ++
 lib/stdbool.in.h                           |   27 +-
 lib/stdckdint.h                            |   38 +
 lib/stdckdint.in.h                         |   37 +
 lib/stddef.in.h                            |    2 +-
 lib/stdint.in.h                            |    2 +-
 lib/stdio-read.c                           |  168 +++
 lib/stdio-write.c                          |  206 +++
 lib/stdio.in.h                             |   86 +-
 lib/stdlib.in.h                            |   66 +-
 lib/stpcpy.c                               |   49 +
 lib/strchrnul.c                            |  142 ++
 lib/strchrnul.valgrind                     |   28 +
 lib/strdup.c                               |    2 +-
 lib/streq.h                                |    2 +-
 lib/strftime.h                             |    4 +-
 lib/striconveh.c                           |  106 +-
 lib/striconveh.h                           |    2 +-
 lib/string.in.h                            |  175 ++-
 lib/stripslash.c                           |    2 +-
 lib/sys-limits.h                           |    2 +-
 lib/sys_file.in.h                          |    2 +-
 lib/sys_random.in.h                        |    8 +-
 lib/sys_select.in.h                        |   15 +-
 lib/sys_socket.c                           |    2 +-
 lib/sys_socket.in.h                        |    2 +-
 lib/sys_stat.in.h                          |   30 +-
 lib/sys_time.in.h                          |    2 +-
 lib/sys_times.in.h                         |    2 +-
 lib/sys_types.in.h                         |    2 +-
 lib/sys_uio.in.h                           |    2 +-
 lib/tempname.c                             |  176 +--
 lib/tempname.h                             |    4 +-
 lib/time-internal.h                        |    4 +-
 lib/time.in.h                              |   13 +-
 lib/time_r.c                               |    2 +-
 lib/time_rz.c                              |    4 +-
 lib/timegm.c                               |    2 +-
 lib/times.c                                |    2 +-
 lib/trunc.c                                |    4 +-
 lib/tzset.c                                |    4 +-
 lib/unistd.c                               |    2 +-
 lib/unistd.in.h                            |   21 +-
 lib/unsetenv.c                             |    2 +-
 lib/vasnprintf.c                           |  241 +---
 lib/vasnprintf.h                           |    2 +-
 lib/verify.h                               |   14 +-
 lib/vsnprintf.c                            |    2 +-
 lib/w32sock.h                              |    2 +-
 lib/warn-on-use.h                          |    8 +-
 lib/wchar.in.h                             |   73 +-
 lib/wcrtomb.c                              |    2 +-
 lib/wctype-h.c                             |    2 +-
 lib/wctype.in.h                            |    2 +-
 lib/windows-initguard.h                    |    2 +-
 lib/windows-spawn.c                        |  727 ++++++++++
 lib/windows-spawn.h                        |  157 ++
 lib/write.c                                |    2 +-
 lib/xalloc-oversized.h                     |    2 +-
 lib/xsize.c                                |    2 +-
 lib/xsize.h                                |    2 +-
 libguile/posix.c                           |  221 +--
 m4/00gnulib.m4                             |    2 +-
 m4/__inline.m4                             |    2 +-
 m4/absolute-header.m4                      |    2 +-
 m4/accept4.m4                              |    2 +-
 m4/access.m4                               |   16 +
 m4/alloca.m4                               |   12 +-
 m4/arpa_inet_h.m4                          |    2 +-
 m4/autobuild.m4                            |    2 +-
 m4/btowc.m4                                |    2 +-
 m4/builtin-expect.m4                       |    2 +-
 m4/byteswap.m4                             |   10 +-
 m4/canonicalize.m4                         |    2 +-
 m4/ceil.m4                                 |    2 +-
 m4/check-math-lib.m4                       |    2 +-
 m4/clock_time.m4                           |   20 +-
 m4/close.m4                                |    2 +-
 m4/codeset.m4                              |    2 +-
 m4/copysign.m4                             |    2 +-
 m4/dirent_h.m4                             |    2 +-
 m4/dirfd.m4                                |    2 +-
 m4/double-slash-root.m4                    |    2 +-
 m4/dup2.m4                                 |    2 +-
 m4/duplocale.m4                            |    2 +-
 m4/eaccess.m4                              |   12 +
 m4/eealloc.m4                              |    2 +-
 m4/environ.m4                              |    2 +-
 m4/errno_h.m4                              |   12 +-
 m4/exponentd.m4                            |    2 +-
 m4/exponentf.m4                            |    2 +-
 m4/exponentl.m4                            |    2 +-
 m4/extensions.m4                           |    2 +-
 m4/extern-inline.m4                        |   28 +-
 m4/fcntl-o.m4                              |    2 +-
 m4/fcntl.m4                                |    2 +-
 m4/fcntl_h.m4                              |    2 +-
 m4/findprog-in.m4                          |   11 +
 m4/flexmember.m4                           |    2 +-
 m4/float_h.m4                              |   22 +-
 m4/flock.m4                                |    2 +-
 m4/floor.m4                                |    2 +-
 m4/fpieee.m4                               |    2 +-
 m4/free.m4                                 |    2 +-
 m4/frexp.m4                                |    2 +-
 m4/fstat.m4                                |    2 +-
 m4/fsync.m4                                |    2 +-
 m4/func.m4                                 |    2 +-
 m4/getaddrinfo.m4                          |    2 +-
 m4/getdtablesize.m4                        |    2 +-
 m4/getlogin.m4                             |    2 +-
 m4/getrandom.m4                            |    2 +-
 m4/gettext.m4                              |  383 +++++
 m4/glibc2.m4                               |   30 +
 m4/glibc21.m4                              |   30 +
 m4/gnulib-cache.m4                         |    8 +-
 m4/gnulib-common.m4                        |  277 +++-
 m4/gnulib-comp.m4                          |  743 ++++++----
 m4/gnulib-tool.m4                          |   10 +-
 m4/host-cpu-c-abi.m4                       |    7 +-
 m4/hostent.m4                              |    2 +-
 m4/iconv.m4                                |   26 +-
 m4/iconv_h.m4                              |   18 +-
 m4/iconv_open-utf.m4                       |    2 +-
 m4/iconv_open.m4                           |    2 +-
 m4/include_next.m4                         |    8 +-
 m4/inet_ntop.m4                            |    2 +-
 m4/inet_pton.m4                            |    2 +-
 m4/intdiv0.m4                              |   84 ++
 m4/intl.m4                                 |  294 ++++
 m4/intldir.m4                              |   19 +
 m4/intlmacosx.m4                           |   51 +
 m4/intmax.m4                               |   33 +
 m4/intmax_t.m4                             |    2 +-
 m4/inttypes-pri.m4                         |   36 +
 m4/inttypes.m4                             |    6 +-
 m4/inttypes_h.m4                           |    2 +-
 m4/isfinite.m4                             |    2 +-
 m4/isinf.m4                                |    2 +-
 m4/isnan.m4                                |    2 +-
 m4/isnand.m4                               |    2 +-
 m4/isnanf.m4                               |    2 +-
 m4/isnanl.m4                               |    2 +-
 m4/langinfo_h.m4                           |    2 +-
 m4/largefile.m4                            |    9 +-
 m4/lcmessage.m4                            |   31 +
 m4/ld-version-script.m4                    |    2 +-
 m4/ldexp.m4                                |    2 +-
 m4/lib-ld.m4                               |    2 +-
 m4/lib-link.m4                             |    8 +-
 m4/lib-prefix.m4                           |    6 +-
 m4/libunistring.m4                         |    2 +-
 m4/limits-h.m4                             |   11 +-
 m4/link.m4                                 |    2 +-
 m4/localcharset.m4                         |    2 +-
 m4/locale-fr.m4                            |    2 +-
 m4/locale-ja.m4                            |    2 +-
 m4/locale-zh.m4                            |    2 +-
 m4/locale_h.m4                             |    2 +-
 m4/localeconv.m4                           |    2 +-
 m4/lock.m4                                 |   37 +
 m4/log.m4                                  |    2 +-
 m4/log1p.m4                                |    2 +-
 m4/longlong.m4                             |  106 ++
 m4/lstat.m4                                |    2 +-
 m4/malloc.m4                               |   13 +-
 m4/malloca.m4                              |    2 +-
 m4/math_h.m4                               |    2 +-
 m4/mathfunc.m4                             |    2 +-
 m4/mbrtowc.m4                              |    2 +-
 m4/mbsinit.m4                              |    2 +-
 m4/mbstate_t.m4                            |    2 +-
 m4/mbtowc.m4                               |    2 +-
 m4/memchr.m4                               |    2 +-
 m4/mempcpy.m4                              |    2 +-
 m4/minmax.m4                               |    2 +-
 m4/mkdir.m4                                |    2 +-
 m4/mkostemp.m4                             |    2 +-
 m4/mktime.m4                               |   31 +-
 m4/mmap-anon.m4                            |    2 +-
 m4/mode_t.m4                               |    2 +-
 m4/msvc-inval.m4                           |    2 +-
 m4/msvc-nothrow.m4                         |    2 +-
 m4/multiarch.m4                            |    2 +-
 m4/netdb_h.m4                              |    2 +-
 m4/netinet_in_h.m4                         |   10 +-
 m4/nl_langinfo.m4                          |    2 +-
 m4/nls.m4                                  |   32 +
 m4/nocrash.m4                              |    2 +-
 m4/nproc.m4                                |    2 +-
 m4/nstrftime.m4                            |    2 +-
 m4/off_t.m4                                |    2 +-
 m4/open-cloexec.m4                         |    2 +-
 m4/open-slash.m4                           |    2 +-
 m4/open.m4                                 |    2 +-
 m4/pathmax.m4                              |    2 +-
 m4/pid_t.m4                                |    2 +-
 m4/pipe.m4                                 |    2 +-
 m4/pipe2.m4                                |    2 +-
 m4/po.m4                                   |  449 ++++++
 m4/poll.m4                                 |    2 +-
 m4/poll_h.m4                               |    2 +-
 m4/posix_spawn.m4                          |  691 +++++++++
 m4/printf-posix.m4                         |   45 +
 m4/printf.m4                               |    2 +-
 m4/progtest.m4                             |   92 ++
 m4/putenv.m4                               |    2 +-
 m4/raise.m4                                |    2 +-
 m4/rawmemchr.m4                            |    2 +-
 m4/read.m4                                 |    2 +-
 m4/readlink.m4                             |    2 +-
 m4/realloc.m4                              |   12 +-
 m4/regex.m4                                |    2 +-
 m4/rename.m4                               |    2 +-
 m4/rmdir.m4                                |    2 +-
 m4/round.m4                                |    2 +-
 m4/safe-read.m4                            |    2 +-
 m4/safe-write.m4                           |    2 +-
 m4/sched_h.m4                              |  106 ++
 m4/select.m4                               |    2 +-
 m4/servent.m4                              |    2 +-
 m4/setenv.m4                               |    2 +-
 m4/setlocale_null.m4                       |    2 +-
 m4/sh-filename.m4                          |   24 +
 m4/signal_h.m4                             |    2 +-
 m4/signbit.m4                              |    2 +-
 m4/size_max.m4                             |    2 +-
 m4/snprintf.m4                             |    2 +-
 m4/socketlib.m4                            |    2 +-
 m4/sockets.m4                              |    2 +-
 m4/socklen.m4                              |    2 +-
 m4/sockpfaf.m4                             |    2 +-
 m4/spawn_h.m4                              |  151 ++
 m4/ssize_t.m4                              |    2 +-
 m4/stat-time.m4                            |    2 +-
 m4/stat.m4                                 |    2 +-
 m4/std-gnu11.m4                            |    2 +-
 m4/stdalign.m4                             |    9 +-
 m4/stdbool.m4                              |  124 +-
 m4/stddef_h.m4                             |   16 +-
 m4/stdint.m4                               |   10 +-
 m4/stdint_h.m4                             |    2 +-
 m4/stdio_h.m4                              |   33 +-
 m4/stdlib_h.m4                             |   16 +-
 m4/stpcpy.m4                               |   25 +
 m4/strchrnul.m4                            |   50 +
 m4/strdup.m4                               |    2 +-
 m4/string_h.m4                             |    6 +-
 m4/sys_file_h.m4                           |    2 +-
 m4/sys_random_h.m4                         |    2 +-
 m4/sys_select_h.m4                         |    2 +-
 m4/sys_socket_h.m4                         |    9 +-
 m4/sys_stat_h.m4                           |    8 +-
 m4/sys_time_h.m4                           |    2 +-
 m4/sys_times_h.m4                          |    2 +-
 m4/sys_types_h.m4                          |    2 +-
 m4/sys_uio_h.m4                            |    2 +-
 m4/tempname.m4                             |    2 +-
 m4/threadlib.m4                            |   64 +-
 m4/time_h.m4                               |    6 +-
 m4/time_r.m4                               |    2 +-
 m4/time_rz.m4                              |    2 +-
 m4/timegm.m4                               |    2 +-
 m4/times.m4                                |    2 +-
 m4/tm_gmtoff.m4                            |    2 +-
 m4/trunc.m4                                |    2 +-
 m4/tzset.m4                                |    2 +-
 m4/uintmax_t.m4                            |   30 +
 m4/unistd_h.m4                             |  191 +--
 m4/vararrays.m4                            |   72 +
 m4/vasnprintf.m4                           |    2 +-
 m4/visibility.m4                           |    2 +-
 m4/vsnprintf.m4                            |    2 +-
 m4/warn-on-use.m4                          |    2 +-
 m4/warnings.m4                             |    2 +-
 m4/wchar_h.m4                              |    6 +-
 m4/wchar_t.m4                              |    2 +-
 m4/wcrtomb.m4                              |    2 +-
 m4/wctype_h.m4                             |    2 +-
 m4/wint_t.m4                               |    2 +-
 m4/write.m4                                |    2 +-
 m4/xsize.m4                                |    2 +-
 m4/year2038.m4                             |   12 +-
 m4/zzgnulib.m4                             |    2 +-
 maint.mk                                   |   68 +-
 module/ice-9/popen.scm                     |   83 +-
 test-suite/tests/popen.test                |   14 +-
 test-suite/tests/posix.test                |   36 +-
 535 files changed, 16353 insertions(+), 3490 deletions(-)
 create mode 100644 lib/access.c
 create mode 100644 lib/concat-filename.c
 create mode 100644 lib/concat-filename.h
 create mode 100644 lib/findprog-in.c
 create mode 100644 lib/findprog.h
 create mode 100644 lib/iconv_open-zos.h
 create mode 100644 lib/intprops-internal.h
 create mode 100644 lib/inttypes.h
 create mode 100644 lib/malloc/.dirstamp
 create mode 100644 lib/malloc/dynarray-skeleton.gl.h
 create mode 100644 lib/malloc/dynarray.gl.h
 create mode 100644 lib/sched.h
 create mode 100644 lib/sched.in.h
 create mode 100644 lib/spawn.c
 create mode 100644 lib/spawn.h
 create mode 100644 lib/spawn.in.h
 create mode 100644 lib/spawn_int.h
 create mode 100644 lib/spawni.c
 create mode 100644 lib/spawnp.c
 create mode 100644 lib/stdbool.h
 create mode 100644 lib/stdckdint.h
 create mode 100644 lib/stdckdint.in.h
 create mode 100644 lib/stdio-read.c
 create mode 100644 lib/stdio-write.c
 create mode 100644 lib/stpcpy.c
 create mode 100644 lib/strchrnul.c
 create mode 100644 lib/strchrnul.valgrind
 create mode 100644 lib/windows-spawn.c
 create mode 100644 lib/windows-spawn.h
 create mode 100644 m4/access.m4
 create mode 100644 m4/eaccess.m4
 create mode 100644 m4/findprog-in.m4
 create mode 100644 m4/gettext.m4
 create mode 100644 m4/glibc2.m4
 create mode 100644 m4/glibc21.m4
 create mode 100644 m4/intdiv0.m4
 create mode 100644 m4/intl.m4
 create mode 100644 m4/intldir.m4
 create mode 100644 m4/intlmacosx.m4
 create mode 100644 m4/intmax.m4
 create mode 100644 m4/inttypes-pri.m4
 create mode 100644 m4/lcmessage.m4
 create mode 100644 m4/lock.m4
 create mode 100644 m4/longlong.m4
 create mode 100644 m4/nls.m4
 create mode 100644 m4/po.m4
 create mode 100644 m4/posix_spawn.m4
 create mode 100644 m4/printf-posix.m4
 create mode 100644 m4/progtest.m4
 create mode 100644 m4/sched_h.m4
 create mode 100644 m4/sh-filename.m4
 create mode 100644 m4/spawn_h.m4
 create mode 100644 m4/stpcpy.m4
 create mode 100644 m4/strchrnul.m4
 create mode 100644 m4/uintmax_t.m4
 create mode 100644 m4/vararrays.m4


base-commit: 61d8dab8eafd498306ce618582aab37497df77b4
-- 
2.37.2






^ permalink raw reply	[flat|nested] 36+ messages in thread

* bug#52835: [PATCH v5 1/3] Update gnulib to 0.1.5414-8204d and add posix_spawn, posix_spawnp.
  2022-09-05  6:48         ` bug#52835: [PATCH v5 0/3] Move spawning procedures to posix_spawn Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
@ 2022-09-05  6:48           ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2022-09-05  6:48           ` bug#52835: [PATCH v5 2/3] Add spawn* Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2022-09-05  6:48           ` bug#52835: [PATCH v5 3/3] Move popen and posix procedures to spawn* Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2 siblings, 0 replies; 36+ messages in thread
From: Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language @ 2022-09-05  6:48 UTC (permalink / raw)
  To: 52835; +Cc: Timothy Sample, Josselin Poiret

---
 GNUmakefile                                |    2 +-
 build-aux/announce-gen                     |   69 +-
 build-aux/gendocs.sh                       |   50 +-
 build-aux/git-version-gen                  |   13 +-
 build-aux/gitlog-to-changelog              |    4 +-
 build-aux/gnu-web-doc-update               |    4 +-
 build-aux/gnupload                         |    4 +-
 build-aux/useless-if-before-free           |    6 +-
 build-aux/vc-list-files                    |    2 +-
 doc/gendocs_template                       |    4 +-
 doc/gendocs_template_min                   |    2 +-
 gnulib-local/m4/clock_time.m4.diff         |   12 +-
 lib/Makefile.am                            | 1252 +++++++++-------
 lib/_Noreturn.h                            |    2 +-
 lib/accept.c                               |    2 +-
 lib/accept4.c                              |    4 +-
 lib/access.c                               |   31 +
 lib/alignof.h                              |    2 +-
 lib/alloca.c                               |   35 -
 lib/alloca.in.h                            |    2 +-
 lib/arg-nonnull.h                          |    2 +-
 lib/arpa_inet.in.h                         |    2 +-
 lib/asnprintf.c                            |    2 +-
 lib/assure.h                               |    2 +-
 lib/attribute.h                            |   10 +-
 lib/basename-lgpl.c                        |    2 +-
 lib/basename-lgpl.h                        |    2 +-
 lib/binary-io.c                            |    2 +-
 lib/binary-io.h                            |    4 +-
 lib/bind.c                                 |    2 +-
 lib/btowc.c                                |    2 +-
 lib/byteswap.in.h                          |    2 +-
 lib/c++defs.h                              |    2 +-
 lib/c-ctype.c                              |    2 +-
 lib/c-ctype.h                              |    2 +-
 lib/c-strcase.h                            |    2 +-
 lib/c-strcasecmp.c                         |    2 +-
 lib/c-strcaseeq.h                          |    2 +-
 lib/c-strncasecmp.c                        |    2 +-
 lib/canonicalize-lgpl.c                    |    2 +-
 lib/cdefs.h                                |   76 +-
 lib/ceil.c                                 |    4 +-
 lib/cloexec.c                              |    2 +-
 lib/cloexec.h                              |    2 +-
 lib/close.c                                |    2 +-
 lib/concat-filename.c                      |   73 +
 lib/concat-filename.h                      |   46 +
 lib/connect.c                              |    2 +-
 lib/copysign.c                             |    4 +-
 lib/dirent.in.h                            |   24 +-
 lib/dirfd.c                                |    2 +-
 lib/dirname-lgpl.c                         |    2 +-
 lib/dirname.h                              |    2 +-
 lib/dup2.c                                 |    2 +-
 lib/duplocale.c                            |    4 +-
 lib/dynarray.h                             |    2 +-
 lib/eloop-threshold.h                      |    2 +-
 lib/errno.in.h                             |    2 +-
 lib/fcntl.c                                |    2 +-
 lib/fcntl.in.h                             |    6 +-
 lib/fd-hook.c                              |    2 +-
 lib/fd-hook.h                              |    2 +-
 lib/filename.h                             |    2 +-
 lib/findprog-in.c                          |  399 ++++++
 lib/findprog.h                             |   77 +
 lib/flexmember.h                           |    2 +-
 lib/float+.h                               |    2 +-
 lib/float.c                                |    2 +-
 lib/float.in.h                             |    2 +-
 lib/flock.c                                |    2 +-
 lib/floor.c                                |    4 +-
 lib/free.c                                 |    2 +-
 lib/frexp.c                                |    2 +-
 lib/fstat.c                                |    2 +-
 lib/fsync.c                                |    2 +-
 lib/full-read.c                            |    2 +-
 lib/full-read.h                            |    2 +-
 lib/full-write.c                           |    2 +-
 lib/full-write.h                           |    2 +-
 lib/gai_strerror.c                         |    2 +-
 lib/getaddrinfo.c                          |    2 +-
 lib/getdtablesize.c                        |    2 +-
 lib/getlogin.c                             |    2 +-
 lib/getpeername.c                          |    2 +-
 lib/getrandom.c                            |    2 +-
 lib/getsockname.c                          |    2 +-
 lib/getsockopt.c                           |    2 +-
 lib/gettext.h                              |   15 +-
 lib/hard-locale.c                          |    2 +-
 lib/hard-locale.h                          |    2 +-
 lib/iconv.c                                |    2 +-
 lib/iconv.in.h                             |    2 +-
 lib/iconv_close.c                          |    2 +-
 lib/iconv_open-aix.gperf                   |    2 +-
 lib/iconv_open-hpux.gperf                  |    2 +-
 lib/iconv_open-irix.gperf                  |    2 +-
 lib/iconv_open-osf.gperf                   |    2 +-
 lib/iconv_open-solaris.gperf               |    2 +-
 lib/iconv_open-zos.gperf                   |    2 +-
 lib/iconv_open-zos.h                       |  329 +++++
 lib/iconv_open.c                           |    2 +-
 lib/iconveh.h                              |    7 +-
 lib/idx.h                                  |   22 +-
 lib/inet_ntop.c                            |    2 +-
 lib/inet_pton.c                            |    2 +-
 lib/intprops-internal.h                    |  392 +++++
 lib/intprops.h                             |  359 +----
 lib/inttypes.h                             | 1509 ++++++++++++++++++++
 lib/inttypes.in.h                          |    2 +-
 lib/isfinite.c                             |    4 +-
 lib/isinf.c                                |    4 +-
 lib/isnan.c                                |    2 +-
 lib/isnand-nolibm.h                        |    2 +-
 lib/isnand.c                               |    2 +-
 lib/isnanf-nolibm.h                        |    2 +-
 lib/isnanf.c                               |    2 +-
 lib/isnanl-nolibm.h                        |    2 +-
 lib/isnanl.c                               |    2 +-
 lib/itold.c                                |    2 +-
 lib/langinfo.in.h                          |    2 +-
 lib/lc-charset-dispatch.c                  |    2 +-
 lib/lc-charset-dispatch.h                  |    2 +-
 lib/libc-config.h                          |   13 +-
 lib/libunistring.valgrind                  |    4 +-
 lib/limits.in.h                            |    2 +-
 lib/link.c                                 |    2 +-
 lib/listen.c                               |    2 +-
 lib/localcharset.c                         |    2 +-
 lib/localcharset.h                         |    2 +-
 lib/locale.in.h                            |    2 +-
 lib/localeconv.c                           |    2 +-
 lib/log.c                                  |    4 +-
 lib/log1p.c                                |    4 +-
 lib/lstat.c                                |    2 +-
 lib/malloc.c                               |    2 +-
 lib/malloc/.dirstamp                       |    0
 lib/malloc/dynarray-skeleton.c             |    2 +-
 lib/malloc/dynarray-skeleton.gl.h          |  529 +++++++
 lib/malloc/dynarray.gl.h                   |  174 +++
 lib/malloc/dynarray.h                      |    2 +-
 lib/malloc/dynarray_at_failure.c           |    2 +-
 lib/malloc/dynarray_emplace_enlarge.c      |    2 +-
 lib/malloc/dynarray_finalize.c             |    2 +-
 lib/malloc/dynarray_resize.c               |    2 +-
 lib/malloc/dynarray_resize_clear.c         |    2 +-
 lib/malloc/scratch_buffer.h                |    2 +-
 lib/malloc/scratch_buffer_dupfree.c        |    2 +-
 lib/malloc/scratch_buffer_grow.c           |    2 +-
 lib/malloc/scratch_buffer_grow_preserve.c  |    2 +-
 lib/malloc/scratch_buffer_set_array_size.c |    2 +-
 lib/malloca.c                              |   12 +-
 lib/malloca.h                              |    2 +-
 lib/math.c                                 |    2 +-
 lib/math.in.h                              |   16 +-
 lib/mbrtowc-impl-utf8.h                    |    2 +-
 lib/mbrtowc-impl.h                         |    2 +-
 lib/mbrtowc.c                              |    2 +-
 lib/mbsinit.c                              |    2 +-
 lib/mbtowc-impl.h                          |    2 +-
 lib/mbtowc-lock.c                          |    2 +-
 lib/mbtowc-lock.h                          |    2 +-
 lib/mbtowc.c                               |    2 +-
 lib/memchr.c                               |    2 +-
 lib/memchr.valgrind                        |    2 +-
 lib/mempcpy.c                              |    2 +-
 lib/minmax.h                               |    2 +-
 lib/mkdir.c                                |    4 +-
 lib/mkostemp.c                             |    2 +-
 lib/mktime-internal.h                      |    2 +-
 lib/mktime.c                               |   30 +-
 lib/msvc-inval.c                           |    2 +-
 lib/msvc-inval.h                           |    2 +-
 lib/msvc-nothrow.c                         |    2 +-
 lib/msvc-nothrow.h                         |    2 +-
 lib/netdb.in.h                             |    2 +-
 lib/netinet_in.in.h                        |    2 +-
 lib/nl_langinfo-lock.c                     |    2 +-
 lib/nl_langinfo.c                          |    2 +-
 lib/nproc.c                                |   24 +-
 lib/nproc.h                                |    2 +-
 lib/nstrftime.c                            |   28 +-
 lib/open.c                                 |    2 +-
 lib/pathmax.h                              |    2 +-
 lib/pipe.c                                 |    2 +-
 lib/pipe2.c                                |    2 +-
 lib/poll.c                                 |    2 +-
 lib/poll.in.h                              |    2 +-
 lib/printf-args.c                          |    2 +-
 lib/printf-args.h                          |    2 +-
 lib/printf-parse.c                         |    2 +-
 lib/printf-parse.h                         |    2 +-
 lib/putenv.c                               |    4 +-
 lib/raise.c                                |    2 +-
 lib/rawmemchr.c                            |   78 +-
 lib/rawmemchr.valgrind                     |    2 +-
 lib/read.c                                 |    2 +-
 lib/readlink.c                             |    6 +-
 lib/realloc.c                              |    2 +-
 lib/recv.c                                 |    2 +-
 lib/recvfrom.c                             |    2 +-
 lib/regcomp.c                              |  831 +++++------
 lib/regex.c                                |    3 +-
 lib/regex.h                                |   52 +-
 lib/regex_internal.c                       |   64 +-
 lib/regex_internal.h                       |   51 +-
 lib/regexec.c                              |   95 +-
 lib/rename.c                               |    4 +-
 lib/rmdir.c                                |    2 +-
 lib/round.c                                |    4 +-
 lib/safe-read.c                            |    2 +-
 lib/safe-read.h                            |    2 +-
 lib/safe-write.c                           |    2 +-
 lib/safe-write.h                           |    2 +-
 lib/same-inode.h                           |    2 +-
 lib/sched.h                                |  580 ++++++++
 lib/sched.in.h                             |   99 ++
 lib/scratch_buffer.h                       |    2 +-
 lib/select.c                               |    2 +-
 lib/send.c                                 |    2 +-
 lib/sendto.c                               |    2 +-
 lib/setenv.c                               |    2 +-
 lib/setlocale-lock.c                       |    2 +-
 lib/setlocale_null.c                       |    2 +-
 lib/setlocale_null.h                       |    2 +-
 lib/setsockopt.c                           |    2 +-
 lib/shutdown.c                             |    2 +-
 lib/signal.in.h                            |    2 +-
 lib/signbitd.c                             |    2 +-
 lib/signbitf.c                             |    2 +-
 lib/signbitl.c                             |    2 +-
 lib/size_max.h                             |    2 +-
 lib/snprintf.c                             |    2 +-
 lib/socket.c                               |    2 +-
 lib/sockets.c                              |    4 +-
 lib/sockets.h                              |    2 +-
 lib/spawn.c                                |   34 +
 lib/spawn.h                                | 1499 +++++++++++++++++++
 lib/spawn.in.h                             |  992 +++++++++++++
 lib/spawn_int.h                            |   72 +
 lib/spawni.c                               |  965 +++++++++++++
 lib/spawnp.c                               |   34 +
 lib/stat-time.c                            |    2 +-
 lib/stat-time.h                            |    8 +-
 lib/stat-w32.c                             |    2 +-
 lib/stat-w32.h                             |    2 +-
 lib/stat.c                                 |    2 +-
 lib/stdalign.in.h                          |    2 +-
 lib/stdbool.h                              |  116 ++
 lib/stdbool.in.h                           |   27 +-
 lib/stdckdint.h                            |   38 +
 lib/stdckdint.in.h                         |   37 +
 lib/stddef.in.h                            |    2 +-
 lib/stdint.in.h                            |    2 +-
 lib/stdio-read.c                           |  168 +++
 lib/stdio-write.c                          |  206 +++
 lib/stdio.in.h                             |   86 +-
 lib/stdlib.in.h                            |   66 +-
 lib/stpcpy.c                               |   49 +
 lib/strchrnul.c                            |  142 ++
 lib/strchrnul.valgrind                     |   28 +
 lib/strdup.c                               |    2 +-
 lib/streq.h                                |    2 +-
 lib/strftime.h                             |    4 +-
 lib/striconveh.c                           |  106 +-
 lib/striconveh.h                           |    2 +-
 lib/string.in.h                            |  175 ++-
 lib/stripslash.c                           |    2 +-
 lib/sys-limits.h                           |    2 +-
 lib/sys_file.in.h                          |    2 +-
 lib/sys_random.in.h                        |    8 +-
 lib/sys_select.in.h                        |   15 +-
 lib/sys_socket.c                           |    2 +-
 lib/sys_socket.in.h                        |    2 +-
 lib/sys_stat.in.h                          |   30 +-
 lib/sys_time.in.h                          |    2 +-
 lib/sys_times.in.h                         |    2 +-
 lib/sys_types.in.h                         |    2 +-
 lib/sys_uio.in.h                           |    2 +-
 lib/tempname.c                             |  176 +--
 lib/tempname.h                             |    4 +-
 lib/time-internal.h                        |    4 +-
 lib/time.in.h                              |   13 +-
 lib/time_r.c                               |    2 +-
 lib/time_rz.c                              |    4 +-
 lib/timegm.c                               |    2 +-
 lib/times.c                                |    2 +-
 lib/trunc.c                                |    4 +-
 lib/tzset.c                                |    4 +-
 lib/unistd.c                               |    2 +-
 lib/unistd.in.h                            |   21 +-
 lib/unsetenv.c                             |    2 +-
 lib/vasnprintf.c                           |  241 +---
 lib/vasnprintf.h                           |    2 +-
 lib/verify.h                               |   14 +-
 lib/vsnprintf.c                            |    2 +-
 lib/w32sock.h                              |    2 +-
 lib/warn-on-use.h                          |    8 +-
 lib/wchar.in.h                             |   73 +-
 lib/wcrtomb.c                              |    2 +-
 lib/wctype-h.c                             |    2 +-
 lib/wctype.in.h                            |    2 +-
 lib/windows-initguard.h                    |    2 +-
 lib/windows-spawn.c                        |  727 ++++++++++
 lib/windows-spawn.h                        |  157 ++
 lib/write.c                                |    2 +-
 lib/xalloc-oversized.h                     |    2 +-
 lib/xsize.c                                |    2 +-
 lib/xsize.h                                |    2 +-
 m4/00gnulib.m4                             |    2 +-
 m4/__inline.m4                             |    2 +-
 m4/absolute-header.m4                      |    2 +-
 m4/accept4.m4                              |    2 +-
 m4/access.m4                               |   16 +
 m4/alloca.m4                               |   12 +-
 m4/arpa_inet_h.m4                          |    2 +-
 m4/autobuild.m4                            |    2 +-
 m4/btowc.m4                                |    2 +-
 m4/builtin-expect.m4                       |    2 +-
 m4/byteswap.m4                             |   10 +-
 m4/canonicalize.m4                         |    2 +-
 m4/ceil.m4                                 |    2 +-
 m4/check-math-lib.m4                       |    2 +-
 m4/clock_time.m4                           |   20 +-
 m4/close.m4                                |    2 +-
 m4/codeset.m4                              |    2 +-
 m4/copysign.m4                             |    2 +-
 m4/dirent_h.m4                             |    2 +-
 m4/dirfd.m4                                |    2 +-
 m4/double-slash-root.m4                    |    2 +-
 m4/dup2.m4                                 |    2 +-
 m4/duplocale.m4                            |    2 +-
 m4/eaccess.m4                              |   12 +
 m4/eealloc.m4                              |    2 +-
 m4/environ.m4                              |    2 +-
 m4/errno_h.m4                              |   12 +-
 m4/exponentd.m4                            |    2 +-
 m4/exponentf.m4                            |    2 +-
 m4/exponentl.m4                            |    2 +-
 m4/extensions.m4                           |    2 +-
 m4/extern-inline.m4                        |   28 +-
 m4/fcntl-o.m4                              |    2 +-
 m4/fcntl.m4                                |    2 +-
 m4/fcntl_h.m4                              |    2 +-
 m4/findprog-in.m4                          |   11 +
 m4/flexmember.m4                           |    2 +-
 m4/float_h.m4                              |   22 +-
 m4/flock.m4                                |    2 +-
 m4/floor.m4                                |    2 +-
 m4/fpieee.m4                               |    2 +-
 m4/free.m4                                 |    2 +-
 m4/frexp.m4                                |    2 +-
 m4/fstat.m4                                |    2 +-
 m4/fsync.m4                                |    2 +-
 m4/func.m4                                 |    2 +-
 m4/getaddrinfo.m4                          |    2 +-
 m4/getdtablesize.m4                        |    2 +-
 m4/getlogin.m4                             |    2 +-
 m4/getrandom.m4                            |    2 +-
 m4/gettext.m4                              |  383 +++++
 m4/glibc2.m4                               |   30 +
 m4/glibc21.m4                              |   30 +
 m4/gnulib-cache.m4                         |    8 +-
 m4/gnulib-common.m4                        |  277 +++-
 m4/gnulib-comp.m4                          |  743 ++++++----
 m4/gnulib-tool.m4                          |   10 +-
 m4/host-cpu-c-abi.m4                       |    7 +-
 m4/hostent.m4                              |    2 +-
 m4/iconv.m4                                |   26 +-
 m4/iconv_h.m4                              |   18 +-
 m4/iconv_open-utf.m4                       |    2 +-
 m4/iconv_open.m4                           |    2 +-
 m4/include_next.m4                         |    8 +-
 m4/inet_ntop.m4                            |    2 +-
 m4/inet_pton.m4                            |    2 +-
 m4/intdiv0.m4                              |   84 ++
 m4/intl.m4                                 |  294 ++++
 m4/intldir.m4                              |   19 +
 m4/intlmacosx.m4                           |   51 +
 m4/intmax.m4                               |   33 +
 m4/intmax_t.m4                             |    2 +-
 m4/inttypes-pri.m4                         |   36 +
 m4/inttypes.m4                             |    6 +-
 m4/inttypes_h.m4                           |    2 +-
 m4/isfinite.m4                             |    2 +-
 m4/isinf.m4                                |    2 +-
 m4/isnan.m4                                |    2 +-
 m4/isnand.m4                               |    2 +-
 m4/isnanf.m4                               |    2 +-
 m4/isnanl.m4                               |    2 +-
 m4/langinfo_h.m4                           |    2 +-
 m4/largefile.m4                            |    9 +-
 m4/lcmessage.m4                            |   31 +
 m4/ld-version-script.m4                    |    2 +-
 m4/ldexp.m4                                |    2 +-
 m4/lib-ld.m4                               |    2 +-
 m4/lib-link.m4                             |    8 +-
 m4/lib-prefix.m4                           |    6 +-
 m4/libunistring.m4                         |    2 +-
 m4/limits-h.m4                             |   11 +-
 m4/link.m4                                 |    2 +-
 m4/localcharset.m4                         |    2 +-
 m4/locale-fr.m4                            |    2 +-
 m4/locale-ja.m4                            |    2 +-
 m4/locale-zh.m4                            |    2 +-
 m4/locale_h.m4                             |    2 +-
 m4/localeconv.m4                           |    2 +-
 m4/lock.m4                                 |   37 +
 m4/log.m4                                  |    2 +-
 m4/log1p.m4                                |    2 +-
 m4/longlong.m4                             |  106 ++
 m4/lstat.m4                                |    2 +-
 m4/malloc.m4                               |   13 +-
 m4/malloca.m4                              |    2 +-
 m4/math_h.m4                               |    2 +-
 m4/mathfunc.m4                             |    2 +-
 m4/mbrtowc.m4                              |    2 +-
 m4/mbsinit.m4                              |    2 +-
 m4/mbstate_t.m4                            |    2 +-
 m4/mbtowc.m4                               |    2 +-
 m4/memchr.m4                               |    2 +-
 m4/mempcpy.m4                              |    2 +-
 m4/minmax.m4                               |    2 +-
 m4/mkdir.m4                                |    2 +-
 m4/mkostemp.m4                             |    2 +-
 m4/mktime.m4                               |   31 +-
 m4/mmap-anon.m4                            |    2 +-
 m4/mode_t.m4                               |    2 +-
 m4/msvc-inval.m4                           |    2 +-
 m4/msvc-nothrow.m4                         |    2 +-
 m4/multiarch.m4                            |    2 +-
 m4/netdb_h.m4                              |    2 +-
 m4/netinet_in_h.m4                         |   10 +-
 m4/nl_langinfo.m4                          |    2 +-
 m4/nls.m4                                  |   32 +
 m4/nocrash.m4                              |    2 +-
 m4/nproc.m4                                |    2 +-
 m4/nstrftime.m4                            |    2 +-
 m4/off_t.m4                                |    2 +-
 m4/open-cloexec.m4                         |    2 +-
 m4/open-slash.m4                           |    2 +-
 m4/open.m4                                 |    2 +-
 m4/pathmax.m4                              |    2 +-
 m4/pid_t.m4                                |    2 +-
 m4/pipe.m4                                 |    2 +-
 m4/pipe2.m4                                |    2 +-
 m4/po.m4                                   |  449 ++++++
 m4/poll.m4                                 |    2 +-
 m4/poll_h.m4                               |    2 +-
 m4/posix_spawn.m4                          |  691 +++++++++
 m4/printf-posix.m4                         |   45 +
 m4/printf.m4                               |    2 +-
 m4/progtest.m4                             |   92 ++
 m4/putenv.m4                               |    2 +-
 m4/raise.m4                                |    2 +-
 m4/rawmemchr.m4                            |    2 +-
 m4/read.m4                                 |    2 +-
 m4/readlink.m4                             |    2 +-
 m4/realloc.m4                              |   12 +-
 m4/regex.m4                                |    2 +-
 m4/rename.m4                               |    2 +-
 m4/rmdir.m4                                |    2 +-
 m4/round.m4                                |    2 +-
 m4/safe-read.m4                            |    2 +-
 m4/safe-write.m4                           |    2 +-
 m4/sched_h.m4                              |  106 ++
 m4/select.m4                               |    2 +-
 m4/servent.m4                              |    2 +-
 m4/setenv.m4                               |    2 +-
 m4/setlocale_null.m4                       |    2 +-
 m4/sh-filename.m4                          |   24 +
 m4/signal_h.m4                             |    2 +-
 m4/signbit.m4                              |    2 +-
 m4/size_max.m4                             |    2 +-
 m4/snprintf.m4                             |    2 +-
 m4/socketlib.m4                            |    2 +-
 m4/sockets.m4                              |    2 +-
 m4/socklen.m4                              |    2 +-
 m4/sockpfaf.m4                             |    2 +-
 m4/spawn_h.m4                              |  151 ++
 m4/ssize_t.m4                              |    2 +-
 m4/stat-time.m4                            |    2 +-
 m4/stat.m4                                 |    2 +-
 m4/std-gnu11.m4                            |    2 +-
 m4/stdalign.m4                             |    9 +-
 m4/stdbool.m4                              |  124 +-
 m4/stddef_h.m4                             |   16 +-
 m4/stdint.m4                               |   10 +-
 m4/stdint_h.m4                             |    2 +-
 m4/stdio_h.m4                              |   33 +-
 m4/stdlib_h.m4                             |   16 +-
 m4/stpcpy.m4                               |   25 +
 m4/strchrnul.m4                            |   50 +
 m4/strdup.m4                               |    2 +-
 m4/string_h.m4                             |    6 +-
 m4/sys_file_h.m4                           |    2 +-
 m4/sys_random_h.m4                         |    2 +-
 m4/sys_select_h.m4                         |    2 +-
 m4/sys_socket_h.m4                         |    9 +-
 m4/sys_stat_h.m4                           |    8 +-
 m4/sys_time_h.m4                           |    2 +-
 m4/sys_times_h.m4                          |    2 +-
 m4/sys_types_h.m4                          |    2 +-
 m4/sys_uio_h.m4                            |    2 +-
 m4/tempname.m4                             |    2 +-
 m4/threadlib.m4                            |   64 +-
 m4/time_h.m4                               |    6 +-
 m4/time_r.m4                               |    2 +-
 m4/time_rz.m4                              |    2 +-
 m4/timegm.m4                               |    2 +-
 m4/times.m4                                |    2 +-
 m4/tm_gmtoff.m4                            |    2 +-
 m4/trunc.m4                                |    2 +-
 m4/tzset.m4                                |    2 +-
 m4/uintmax_t.m4                            |   30 +
 m4/unistd_h.m4                             |  191 +--
 m4/vararrays.m4                            |   72 +
 m4/vasnprintf.m4                           |    2 +-
 m4/visibility.m4                           |    2 +-
 m4/vsnprintf.m4                            |    2 +-
 m4/warn-on-use.m4                          |    2 +-
 m4/warnings.m4                             |    2 +-
 m4/wchar_h.m4                              |    6 +-
 m4/wchar_t.m4                              |    2 +-
 m4/wcrtomb.m4                              |    2 +-
 m4/wctype_h.m4                             |    2 +-
 m4/wint_t.m4                               |    2 +-
 m4/write.m4                                |    2 +-
 m4/xsize.m4                                |    2 +-
 m4/year2038.m4                             |   12 +-
 m4/zzgnulib.m4                             |    2 +-
 maint.mk                                   |   68 +-
 531 files changed, 16214 insertions(+), 3275 deletions(-)
 create mode 100644 lib/access.c
 create mode 100644 lib/concat-filename.c
 create mode 100644 lib/concat-filename.h
 create mode 100644 lib/findprog-in.c
 create mode 100644 lib/findprog.h
 create mode 100644 lib/iconv_open-zos.h
 create mode 100644 lib/intprops-internal.h
 create mode 100644 lib/inttypes.h
 create mode 100644 lib/malloc/.dirstamp
 create mode 100644 lib/malloc/dynarray-skeleton.gl.h
 create mode 100644 lib/malloc/dynarray.gl.h
 create mode 100644 lib/sched.h
 create mode 100644 lib/sched.in.h
 create mode 100644 lib/spawn.c
 create mode 100644 lib/spawn.h
 create mode 100644 lib/spawn.in.h
 create mode 100644 lib/spawn_int.h
 create mode 100644 lib/spawni.c
 create mode 100644 lib/spawnp.c
 create mode 100644 lib/stdbool.h
 create mode 100644 lib/stdckdint.h
 create mode 100644 lib/stdckdint.in.h
 create mode 100644 lib/stdio-read.c
 create mode 100644 lib/stdio-write.c
 create mode 100644 lib/stpcpy.c
 create mode 100644 lib/strchrnul.c
 create mode 100644 lib/strchrnul.valgrind
 create mode 100644 lib/windows-spawn.c
 create mode 100644 lib/windows-spawn.h
 create mode 100644 m4/access.m4
 create mode 100644 m4/eaccess.m4
 create mode 100644 m4/findprog-in.m4
 create mode 100644 m4/gettext.m4
 create mode 100644 m4/glibc2.m4
 create mode 100644 m4/glibc21.m4
 create mode 100644 m4/intdiv0.m4
 create mode 100644 m4/intl.m4
 create mode 100644 m4/intldir.m4
 create mode 100644 m4/intlmacosx.m4
 create mode 100644 m4/intmax.m4
 create mode 100644 m4/inttypes-pri.m4
 create mode 100644 m4/lcmessage.m4
 create mode 100644 m4/lock.m4
 create mode 100644 m4/longlong.m4
 create mode 100644 m4/nls.m4
 create mode 100644 m4/po.m4
 create mode 100644 m4/posix_spawn.m4
 create mode 100644 m4/printf-posix.m4
 create mode 100644 m4/progtest.m4
 create mode 100644 m4/sched_h.m4
 create mode 100644 m4/sh-filename.m4
 create mode 100644 m4/spawn_h.m4
 create mode 100644 m4/stpcpy.m4
 create mode 100644 m4/strchrnul.m4
 create mode 100644 m4/uintmax_t.m4
 create mode 100644 m4/vararrays.m4

diff --git a/GNUmakefile b/GNUmakefile
index 0c99d5842..7a08c9d55 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -5,7 +5,7 @@
 # It is necessary if you want to build targets usually of interest
 # only to the maintainer.
 
-# Copyright (C) 2001, 2003, 2006-2021 Free Software Foundation, Inc.
+# Copyright (C) 2001, 2003, 2006-2022 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
diff --git a/build-aux/announce-gen b/build-aux/announce-gen
index f3b5461ae..3847a568d 100755
--- a/build-aux/announce-gen
+++ b/build-aux/announce-gen
@@ -3,7 +3,7 @@
 
 # Generate a release announcement message.
 
-# Copyright (C) 2002-2021 Free Software Foundation, Inc.
+# Copyright (C) 2002-2022 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
@@ -35,13 +35,13 @@
 eval 'exec perl -wSx "$0" "$@"'
      if 0;
 
-my $VERSION = '2021-08-04 09:17'; # UTC
+my $VERSION = '2022-07-10 01:47'; # UTC
 # The definition above must lie within the first 8 lines in order
 # for the Emacs time-stamp write hook (at end) to update it.
 # If you change this file with Emacs, please let the write hook
 # do its job.  Otherwise, update this string manually.
 
-my $copyright_year = '2021';
+my $copyright_year = '2022';
 
 use strict;
 use Getopt::Long;
@@ -90,6 +90,10 @@ The following are optional:
                                 VERSION is the result of running git describe
                                 in the gnulib source directory.
                                 required if gnulib is in TOOL_LIST.
+   --gpg-key-email=EMAIL        The email address of the key used to
+                                sign the tarballs
+   --gpg-keyring-url=URL        URL pointing to keyring containing the key used
+                                to sign the tarballs
    --no-print-checksums         do not emit SHA1 or SHA256 checksums
    --archive-suffix=SUF         add SUF to the list of archive suffixes
    --mail-headers=HEADERS       a space-separated list of mail headers, e.g.,
@@ -377,6 +381,8 @@ sub get_tool_versions ($$)
   my $bootstrap_tools;
   my $gnulib_version;
   my $print_checksums_p = 1;
+  my $gpg_key_email;
+  my $gpg_keyring_url;
 
   # Reformat the warnings before displaying them.
   local $SIG{__WARN__} = sub
@@ -395,6 +401,8 @@ sub get_tool_versions ($$)
      'previous-version=s' => \$prev_version,
      'current-version=s'  => \$curr_version,
      'gpg-key-id=s'       => \$gpg_key_id,
+     'gpg-key-email=s'    => \$gpg_key_email,
+     'gpg-keyring-url=s'  => \$gpg_keyring_url,
      'url-directory=s'    => \@url_dir_list,
      'news=s'             => \@news_file,
      'srcdir=s'           => \$srcdir,
@@ -437,11 +445,15 @@ sub get_tool_versions ($$)
   my @tool_list = split ',', $bootstrap_tools
     if $bootstrap_tools;
 
-  grep (/^gnulib$/, @tool_list) ^ defined $gnulib_version
+  grep (/^gnulib$/, @tool_list) && ! defined $gnulib_version
     and (warn "when specifying gnulib as a tool, you must also specify\n"
         . "--gnulib-version=V, where V is the result of running git describe\n"
         . "in the gnulib source directory.\n"), $fail = 1;
 
+  ! grep (/^gnulib$/, @tool_list) && defined $gnulib_version
+    and (warn "with --gnulib-version=V you must use --bootstrap-tools=...\n"
+         . "including gnulib in that list"), $fail = 1;
+
   !$release_type || exists $valid_release_types{$release_type}
     or (warn "'$release_type': invalid release type\n"), $fail = 1;
 
@@ -490,7 +502,7 @@ EOF
     {
       # When there's only one tarball and one URL, use a more concise form.
       my $m = "$url_dir_list[0]/$tarballs[0]";
-      print "Here are the compressed sources and a GPG detached signature[*]:\n"
+      print "Here are the compressed sources and a GPG detached signature:\n"
         . "  $m\n"
         . "  $m.sig\n\n";
     }
@@ -502,7 +514,7 @@ EOF
                              . "please tell bug-gnulib\@gnu.org)",
                              @url_dir_list, %size, $xd);
       my @sig_files = map { "$_.sig" } @tarballs;
-      print_locations ("GPG detached signatures[*]", @url_dir_list, %size,
+      print_locations ("GPG detached signatures", @url_dir_list, %size,
                        @sig_files);
     }
 
@@ -527,18 +539,55 @@ EOF
     and print_checksums (@sizable);
 
   print <<EOF;
-[*] Use a .sig file to verify that the corresponding file (without the
+Use a .sig file to verify that the corresponding file (without the
 .sig suffix) is intact.  First, be sure to download both the .sig file
 and the corresponding tarball.  Then, run a command like this:
 
   gpg --verify $tarballs[0].sig
 
+EOF
+  my $gpg_fingerprint = `LC_ALL=C gpg --fingerprint $gpg_key_id | grep -v ^sub`;
+  if ($gpg_fingerprint =~ /^pub/)
+    {
+      chop $gpg_fingerprint;
+      $gpg_fingerprint =~ s/ \[expires:.*//mg;
+      $gpg_fingerprint =~ s/^uid           \[ultimate\]/uid  /mg;
+      $gpg_fingerprint =~ s/^/  /mg;
+      print<<EOF
+The signature should match the fingerprint of the following key:
+
+$gpg_fingerprint
+EOF
+    }
+  print <<EOF;
 If that command fails because you don't have the required public key,
-then run this command to import it:
+or that public key has expired, try the following commands to retrieve
+or refresh it, and then rerun the 'gpg --verify' command.
+EOF
+  if ($gpg_key_email) {
+    print <<EOF;
+
+  gpg --locate-external-key $gpg_key_email
+EOF
+    }
+  print <<EOF;
+
+  gpg --recv-keys $gpg_key_id
+EOF
+    if ($gpg_keyring_url) {
+      print <<EOF;
+
+  wget -q -O- '$gpg_keyring_url' | gpg --import -
+EOF
+      }
+  print <<EOF;
+
+As a last resort to find the key, you can try the official GNU
+keyring:
 
-  gpg --keyserver keys.gnupg.net --recv-keys $gpg_key_id
+  wget -q https://ftp.gnu.org/gnu/gnu-keyring.gpg
+  gpg --keyring gnu-keyring.gpg --verify $tarballs[0].sig
 
-and rerun the 'gpg --verify' command.
 EOF
 
   my @tool_versions = get_tool_versions (\@tool_list, $gnulib_version);
diff --git a/build-aux/gendocs.sh b/build-aux/gendocs.sh
index 1241ee35a..f6811eea4 100755
--- a/build-aux/gendocs.sh
+++ b/build-aux/gendocs.sh
@@ -2,13 +2,13 @@
 # gendocs.sh -- generate a GNU manual in many formats.  This script is
 #   mentioned in maintain.texi.  See the help message below for usage details.
 
-scriptversion=2021-07-19.18
+scriptversion=2022-01-01.00
 
-# Copyright 2003-2021 Free Software Foundation, Inc.
+# Copyright 2003-2022 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
+# 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,
@@ -40,15 +40,15 @@ srcdir=`pwd`
 scripturl="https://git.savannah.gnu.org/cgit/gnulib.git/plain/build-aux/gendocs.sh"
 templateurl="https://git.savannah.gnu.org/cgit/gnulib.git/plain/doc/gendocs_template"
 
-: ${SETLANG="env LANG= LC_MESSAGES= LC_ALL= LANGUAGE="}
-: ${MAKEINFO="makeinfo"}
-: ${TEXI2DVI="texi2dvi"}
-: ${DOCBOOK2HTML="docbook2html"}
-: ${DOCBOOK2PDF="docbook2pdf"}
-: ${DOCBOOK2TXT="docbook2txt"}
-: ${GENDOCS_TEMPLATE_DIR="."}
-: ${PERL='perl'}
-: ${TEXI2HTML="texi2html"}
+: "${SETLANG="env LANG= LC_MESSAGES= LC_ALL= LANGUAGE="}"
+: "${MAKEINFO="makeinfo"}"
+: "${TEXI2DVI="texi2dvi"}"
+: "${DOCBOOK2HTML="docbook2html"}"
+: "${DOCBOOK2PDF="docbook2pdf"}"
+: "${DOCBOOK2TXT="docbook2txt"}"
+: "${GENDOCS_TEMPLATE_DIR="."}"
+: "${PERL="perl"}"
+: "${TEXI2HTML="texi2html"}"
 unset CDPATH
 unset use_texi2html
 
@@ -73,7 +73,7 @@ texarg="-t @finalout"
 
 version="gendocs.sh $scriptversion
 
-Copyright 2021 Free Software Foundation, Inc.
+Copyright 2022 Free Software Foundation, Inc.
 There is NO warranty.  You may redistribute this software
 under the terms of the GNU General Public License.
 For more information about these matters, see the files named COPYING."
@@ -304,7 +304,7 @@ fi  # end info
 # \f
 if $generate_tex; then
   cmd="$SETLANG $TEXI2DVI $dirargs $texarg \"$srcfile\""
-  printf "\nGenerating dvi... ($cmd)\n"
+  printf "\nGenerating dvi... (%s)\n" "$cmd"
   eval "$cmd"
   # compress/finish dvi:
   gzip -f -9 $PACKAGE.dvi
@@ -313,7 +313,7 @@ if $generate_tex; then
   ls -l "$outdir/$PACKAGE.dvi.gz"
 
   cmd="$SETLANG $TEXI2DVI --pdf $dirargs $texarg \"$srcfile\""
-  printf "\nGenerating pdf... ($cmd)\n"
+  printf "\nGenerating pdf... (%s)\n" "$cmd"
   eval "$cmd"
   pdf_size=`calcsize $PACKAGE.pdf`
   mv $PACKAGE.pdf "$outdir/"
@@ -324,7 +324,7 @@ fi # end tex (dvi + pdf)
 if $generate_ascii; then
   opt="-o $PACKAGE.txt --no-split --no-headers $commonarg"
   cmd="$SETLANG $MAKEINFO $opt \"$srcfile\""
-  printf "\nGenerating ascii... ($cmd)\n"
+  printf "\nGenerating ascii... (%s)\n" "$cmd"
   eval "$cmd"
   ascii_size=`calcsize $PACKAGE.txt`
   gzip -f -9 -c $PACKAGE.txt >"$outdir/$PACKAGE.txt.gz"
@@ -341,7 +341,7 @@ html_split()
 {
   opt="--split=$1 --node-files $commonarg $htmlarg"
   cmd="$SETLANG $TEXI2HTML --output $PACKAGE.html $opt \"$srcfile\""
-  printf "\nGenerating html by $1... ($cmd)\n"
+  printf "\nGenerating html by %s... (%s)\n" "$1" "$cmd"
   eval "$cmd"
   split_html_dir=$PACKAGE.html
   (
@@ -359,7 +359,7 @@ html_split()
 if test -z "$use_texi2html"; then
   opt="--no-split --html -o $PACKAGE.html $commonarg $htmlarg"
   cmd="$SETLANG $MAKEINFO $opt \"$srcfile\""
-  printf "\nGenerating monolithic html... ($cmd)\n"
+  printf "\nGenerating monolithic html... (%s)\n" "$cmd"
   rm -rf $PACKAGE.html  # in case a directory is left over
   eval "$cmd"
   html_mono_size=`calcsize $PACKAGE.html`
@@ -380,7 +380,7 @@ if test -z "$use_texi2html"; then
   #
   opt="--html -o $PACKAGE.html $split_arg $commonarg $htmlarg"
   cmd="$SETLANG $MAKEINFO $opt \"$srcfile\""
-  printf "\nGenerating html by $split... ($cmd)\n"
+  printf "\nGenerating html by %s... (%s)\n" "$split" "$cmd"
   eval "$cmd"
   split_html_dir=$PACKAGE.html
   copy_images $split_html_dir/ $split_html_dir/*.html
@@ -398,7 +398,7 @@ if test -z "$use_texi2html"; then
 else # use texi2html:
   opt="--output $PACKAGE.html $commonarg $htmlarg"
   cmd="$SETLANG $TEXI2HTML $opt \"$srcfile\""
-  printf "\nGenerating monolithic html with texi2html... ($cmd)\n"
+  printf "\nGenerating monolithic html with texi2html... (%s)\n" "$cmd"
   rm -rf $PACKAGE.html  # in case a directory is left over
   eval "$cmd"
   html_mono_size=`calcsize $PACKAGE.html`
@@ -428,7 +428,7 @@ texi_tgz_size=`calcsize "$outdir/$PACKAGE.texi.tar.gz"`
 if test -n "$docbook"; then
   opt="-o - --docbook $commonarg"
   cmd="$SETLANG $MAKEINFO $opt \"$srcfile\" >${srcdir}/$PACKAGE-db.xml"
-  printf "\nGenerating docbook XML... ($cmd)\n"
+  printf "\nGenerating docbook XML... (%s)\n" "$cmd"
   eval "$cmd"
   docbook_xml_size=`calcsize $PACKAGE-db.xml`
   gzip -f -9 -c $PACKAGE-db.xml >"$outdir/$PACKAGE-db.xml.gz"
@@ -438,7 +438,7 @@ if test -n "$docbook"; then
   split_html_db_dir=html_node_db
   opt="$commonarg -o $split_html_db_dir"
   cmd="$DOCBOOK2HTML $opt \"${outdir}/$PACKAGE-db.xml\""
-  printf "\nGenerating docbook HTML... ($cmd)\n"
+  printf "\nGenerating docbook HTML... (%s)\n" "$cmd"
   eval "$cmd"
   (
     cd ${split_html_db_dir} || exit 1
@@ -451,20 +451,20 @@ if test -n "$docbook"; then
   rmdir ${split_html_db_dir}
 
   cmd="$DOCBOOK2TXT \"${outdir}/$PACKAGE-db.xml\""
-  printf "\nGenerating docbook ASCII... ($cmd)\n"
+  printf "\nGenerating docbook ASCII... (%s)\n" "$cmd"
   eval "$cmd"
   docbook_ascii_size=`calcsize $PACKAGE-db.txt`
   mv $PACKAGE-db.txt "$outdir/"
 
   cmd="$DOCBOOK2PDF \"${outdir}/$PACKAGE-db.xml\""
-  printf "\nGenerating docbook PDF... ($cmd)\n"
+  printf "\nGenerating docbook PDF... (%s)\n" "$cmd"
   eval "$cmd"
   docbook_pdf_size=`calcsize $PACKAGE-db.pdf`
   mv $PACKAGE-db.pdf "$outdir/"
 fi
 
 # \f
-printf "\nMaking index.html for $PACKAGE...\n"
+printf "\nMaking index.html for %s...\n" "$PACKAGE"
 if test -z "$use_texi2html"; then
   CONDS="/%%IF  *HTML_SECTION%%/,/%%ENDIF  *HTML_SECTION%%/d;\
          /%%IF  *HTML_CHAPTER%%/,/%%ENDIF  *HTML_CHAPTER%%/d"
diff --git a/build-aux/git-version-gen b/build-aux/git-version-gen
index 5e42afb2c..36c1abaf7 100755
--- a/build-aux/git-version-gen
+++ b/build-aux/git-version-gen
@@ -1,12 +1,12 @@
 #!/bin/sh
 # Print a version string.
-scriptversion=2019-10-13.15; # UTC
+scriptversion=2022-07-09.08; # UTC
 
-# Copyright (C) 2007-2021 Free Software Foundation, Inc.
+# Copyright (C) 2007-2022 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
+# 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,
@@ -65,9 +65,10 @@ scriptversion=2019-10-13.15; # UTC
 # EXTRA_DIST = $(top_srcdir)/.version
 # BUILT_SOURCES = $(top_srcdir)/.version
 # $(top_srcdir)/.version:
-#	echo $(VERSION) > $@-t && mv $@-t $@
+#	echo '$(VERSION)' > $@-t
+#	mv $@-t $@
 # dist-hook:
-#	echo $(VERSION) > $(distdir)/.tarball-version
+#	echo '$(VERSION)' > $(distdir)/.tarball-version
 
 
 me=$0
@@ -94,7 +95,7 @@ Options:
    --help             display this help and exit
    --version          output version information and exit
 
-Running without arguments will suffice in most cases."
+Send patches and bug reports to <bug-gnulib@gnu.org>."
 
 prefix=v
 fallback=
diff --git a/build-aux/gitlog-to-changelog b/build-aux/gitlog-to-changelog
index 9ff15f601..82d9f9733 100755
--- a/build-aux/gitlog-to-changelog
+++ b/build-aux/gitlog-to-changelog
@@ -3,7 +3,7 @@
 
 # Convert git log output to ChangeLog format.
 
-# Copyright (C) 2008-2021 Free Software Foundation, Inc.
+# Copyright (C) 2008-2022 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
@@ -35,7 +35,7 @@
 eval 'exec perl -wSx "$0" "$@"'
      if 0;
 
-my $VERSION = '2021-02-24 23:42'; # UTC
+my $VERSION = '2022-01-27 18:49'; # UTC
 # The definition above must lie within the first 8 lines in order
 # for the Emacs time-stamp write hook (at end) to update it.
 # If you change this file with Emacs, please let the write hook
diff --git a/build-aux/gnu-web-doc-update b/build-aux/gnu-web-doc-update
index cc553f9a3..c041364fb 100755
--- a/build-aux/gnu-web-doc-update
+++ b/build-aux/gnu-web-doc-update
@@ -2,9 +2,9 @@
 # Run this after each non-alpha release, to update the web documentation at
 # https://www.gnu.org/software/$pkg/manual/
 
-VERSION=2021-01-09.09; # UTC
+VERSION=2022-01-27.18; # UTC
 
-# Copyright (C) 2009-2021 Free Software Foundation, Inc.
+# Copyright (C) 2009-2022 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
diff --git a/build-aux/gnupload b/build-aux/gnupload
index e7822aed7..b97e566f9 100755
--- a/build-aux/gnupload
+++ b/build-aux/gnupload
@@ -1,9 +1,9 @@
 #!/bin/sh
 # Sign files and upload them.
 
-scriptversion=2021-04-11.09; # UTC
+scriptversion=2022-01-27.18; # UTC
 
-# Copyright (C) 2004-2021 Free Software Foundation, Inc.
+# Copyright (C) 2004-2022 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
diff --git a/build-aux/useless-if-before-free b/build-aux/useless-if-before-free
index 5bbbc44c5..1a027a5d5 100755
--- a/build-aux/useless-if-before-free
+++ b/build-aux/useless-if-before-free
@@ -4,7 +4,7 @@
 # Detect instances of "if (p) free (p);".
 # Likewise "if (p != 0)", "if (0 != p)", or with NULL; and with braces.
 
-# Copyright (C) 2008-2021 Free Software Foundation, Inc.
+# Copyright (C) 2008-2022 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
@@ -36,13 +36,13 @@
 eval 'exec perl -wSx "$0" "$@"'
      if 0;
 
-my $VERSION = '2021-04-11 10:11'; # UTC
+my $VERSION = '2022-01-27 18:51'; # UTC
 # The definition above must lie within the first 8 lines in order
 # for the Emacs time-stamp write hook (at end) to update it.
 # If you change this file with Emacs, please let the write hook
 # do its job.  Otherwise, update this string manually.
 
-my $copyright_year = '2021';
+my $copyright_year = '2022';
 
 use strict;
 use warnings;
diff --git a/build-aux/vc-list-files b/build-aux/vc-list-files
index cf168ea83..77750b9f8 100755
--- a/build-aux/vc-list-files
+++ b/build-aux/vc-list-files
@@ -4,7 +4,7 @@
 # Print a version string.
 scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 2006-2021 Free Software Foundation, Inc.
+# Copyright (C) 2006-2022 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
diff --git a/doc/gendocs_template b/doc/gendocs_template
index cd9ac3831..0415d947b 100644
--- a/doc/gendocs_template
+++ b/doc/gendocs_template
@@ -2,7 +2,7 @@
 <!-- Parent-Version: 1.78 -->
 
 <!--
-Copyright (C) 2006-2021 Free Software Foundation, Inc.
+Copyright (C) 2006-2022 Free Software Foundation, Inc.
 
 Copying and distribution of this file, with or without modification,
 are permitted in any medium without royalty provided the copyright
@@ -87,7 +87,7 @@ the FSF.  Broken links and other corrections or suggestions can be sent
 to <a href="mailto:%%EMAIL%%">&lt;%%EMAIL%%&gt;</a>.</p>
 </div>
 
-<p>Copyright &copy; 2020 Free Software Foundation, Inc.</p>
+<p>Copyright &copy; 2022 Free Software Foundation, Inc.</p>
 
 <p>This page is licensed under a <a rel="license"
 href="https://creativecommons.org/licenses/by-nd/3.0/us/">Creative
diff --git a/doc/gendocs_template_min b/doc/gendocs_template_min
index 36e60ff79..369f49447 100644
--- a/doc/gendocs_template_min
+++ b/doc/gendocs_template_min
@@ -4,7 +4,7 @@
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
 
 <!--
-Copyright (C) 2007-2021 Free Software Foundation, Inc.
+Copyright (C) 2007-2022 Free Software Foundation, Inc.
 
 Copying and distribution of this file, with or without modification,
 are permitted in any medium without royalty provided the copyright
diff --git a/gnulib-local/m4/clock_time.m4.diff b/gnulib-local/m4/clock_time.m4.diff
index 57d34e19c..c144d51c2 100644
--- a/gnulib-local/m4/clock_time.m4.diff
+++ b/gnulib-local/m4/clock_time.m4.diff
@@ -4,16 +4,13 @@ See <http://lists.gnu.org/archive/html/bug-gnulib/2011-06/msg00227.html>
 for details.
 
 diff --git a/m4/clock_time.m4 b/m4/clock_time.m4
-index 0bec0ef..fb3a17a 100644
+index 225355331..61373c4b7 100644
 --- a/m4/clock_time.m4
 +++ b/m4/clock_time.m4
-@@ -24,8 +24,15 @@ AC_DEFUN([gl_CLOCK_TIME],
+@@ -25,8 +25,17 @@ AC_DEFUN([gl_CLOCK_TIME],
    AC_SUBST([LIB_CLOCK_GETTIME])
    gl_saved_libs=$LIBS
      AC_SEARCH_LIBS([clock_gettime], [rt posix4],
--                   [test "$ac_cv_search_clock_gettime" = "none required" ||
--                    LIB_CLOCK_GETTIME=$ac_cv_search_clock_gettime])
--    AC_CHECK_FUNCS([clock_gettime clock_settime])
 +                   [if test "$ac_cv_search_clock_gettime" = "none required"; then
 +                      AC_SEARCH_LIBS([clock_getcpuclockid], [rt posix4],
 +                                     [test "$ac_cv_search_clock_getcpuclockid" = "none required" \
@@ -23,6 +20,9 @@ index 0bec0ef..fb3a17a 100644
 +                    else
 +                      LIB_CLOCK_GETTIME=$ac_cv_search_clock_gettime
 +                    fi])
-+    AC_CHECK_FUNCS([clock_gettime clock_settime clock_getcpuclockid])
+                    [test "$ac_cv_search_clock_gettime" = "none required" ||
+                     LIB_CLOCK_GETTIME=$ac_cv_search_clock_gettime])
+-    AC_CHECK_FUNCS([clock_getres clock_gettime clock_settime])
++    AC_CHECK_FUNCS([clock_getres clock_gettime clock_settime clock_getcpuclockid])
    LIBS=$gl_saved_libs
  ])
diff --git a/lib/Makefile.am b/lib/Makefile.am
index cb29c3136..0e7ed9b91 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -1,10 +1,10 @@
 ## DO NOT EDIT! GENERATED AUTOMATICALLY!
 ## Process this file with automake to produce Makefile.in.
-# Copyright (C) 2002-2021 Free Software Foundation, Inc.
+# Copyright (C) 2002-2022 Free Software Foundation, Inc.
 #
 # This file 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
+# the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
 #
 # This file is distributed in the hope that it will be useful,
@@ -110,6 +110,7 @@
 #  pipe-posix \
 #  pipe2 \
 #  poll \
+#  posix_spawnp \
 #  putenv \
 #  readlink \
 #  recv \
@@ -138,7 +139,7 @@
 #  warnings \
 #  wchar
 
-AUTOMAKE_OPTIONS = 1.11 gnits subdir-objects
+AUTOMAKE_OPTIONS = 1.14 gnits subdir-objects
 
 SUBDIRS =
 noinst_HEADERS =
@@ -160,6 +161,7 @@ AM_CFLAGS =
 noinst_LTLIBRARIES += libgnu.la
 
 libgnu_la_SOURCES =
+libgnu_la_CFLAGS = $(AM_CFLAGS) $(GL_CFLAG_GNULIB_WARNINGS)
 libgnu_la_LIBADD = $(gl_LTLIBOBJS)
 libgnu_la_DEPENDENCIES = $(gl_LTLIBOBJS)
 EXTRA_libgnu_la_SOURCES =
@@ -208,10 +210,11 @@ HAVE_INCLUDE_NEXT = (__GNUC__ || __clang__ || 60000000 <= __DECC_VER)
 
 ## begin gnulib module accept
 
+if GL_COND_OBJ_ACCEPT
+libgnu_la_SOURCES += accept.c
+endif
 
-EXTRA_DIST += accept.c w32sock.h
-
-EXTRA_libgnu_la_SOURCES += accept.c
+EXTRA_DIST += w32sock.h
 
 ## end   gnulib module accept
 
@@ -221,6 +224,16 @@ libgnu_la_SOURCES += accept4.c
 
 ## end   gnulib module accept4
 
+## begin gnulib module access
+
+if gl_GNULIB_ENABLED_access
+if GL_COND_OBJ_ACCESS
+libgnu_la_SOURCES += access.c
+endif
+
+endif
+## end   gnulib module access
+
 ## begin gnulib module alignof
 
 
@@ -249,11 +262,10 @@ BUILT_SOURCES += $(ALLOCA_H)
 # doesn't have one that works with the given compiler.
 if GL_GENERATE_ALLOCA_H
 alloca.h: alloca.in.h $(top_builddir)/config.status
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
-	  sed -e 's|@''HAVE_ALLOCA_H''@|$(HAVE_ALLOCA_H)|g' < $(srcdir)/alloca.in.h; \
-	} > $@-t && \
-	mv -f $@-t $@
+	$(gl_V_at)$(SED_HEADER_STDOUT) \
+	  -e 's|@''HAVE_ALLOCA_H''@|$(HAVE_ALLOCA_H)|g' \
+	  $(srcdir)/alloca.in.h > $@-t
+	$(AM_V_at)mv $@-t $@
 else
 alloca.h: $(top_builddir)/config.status
 	rm -f $@
@@ -278,10 +290,9 @@ BUILT_SOURCES += arpa/inet.h
 # We need the following in order to create <arpa/inet.h> when the system
 # doesn't have one.
 arpa/inet.h: arpa_inet.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H) $(ARG_NONNULL_H)
-	$(AM_V_at)$(MKDIR_P) arpa
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
-	  sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+	$(AM_V_GEN)$(MKDIR_P) '%reldir%/arpa'
+	$(AM_V_at)$(SED_HEADER_STDOUT) \
+	      -e 's|@''GUARD_PREFIX''@|GL|g' \
 	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
 	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
 	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
@@ -298,9 +309,8 @@ arpa/inet.h: arpa_inet.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON
 	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
 	      -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
 	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
-	      < $(srcdir)/arpa_inet.in.h; \
-	} > $@-t && \
-	mv $@-t $@
+	      $(srcdir)/arpa_inet.in.h > $@-t
+	$(AM_V_at)mv $@-t $@
 MOSTLYCLEANFILES += arpa/inet.h arpa/inet.h-t
 MOSTLYCLEANDIRS += arpa
 
@@ -340,22 +350,22 @@ libgnu_la_SOURCES += binary-io.h binary-io.c
 
 ## begin gnulib module bind
 
+if GL_COND_OBJ_BIND
+libgnu_la_SOURCES += bind.c
+endif
 
-EXTRA_DIST += bind.c w32sock.h
-
-EXTRA_libgnu_la_SOURCES += bind.c
+EXTRA_DIST += w32sock.h
 
 ## end   gnulib module bind
 
 ## begin gnulib module btowc
 
 if gl_GNULIB_ENABLED_btowc
-
+if GL_COND_OBJ_BTOWC
+libgnu_la_SOURCES += btowc.c
 endif
-EXTRA_DIST += btowc.c
-
-EXTRA_libgnu_la_SOURCES += btowc.c
 
+endif
 ## end   gnulib module btowc
 
 ## begin gnulib module byteswap
@@ -366,11 +376,8 @@ BUILT_SOURCES += $(BYTESWAP_H)
 # doesn't have one.
 if GL_GENERATE_BYTESWAP_H
 byteswap.h: byteswap.in.h $(top_builddir)/config.status
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
-	  cat $(srcdir)/byteswap.in.h; \
-	} > $@-t && \
-	mv -f $@-t $@
+	$(gl_V_at)$(SED_HEADER_TO_AT_t) $(srcdir)/byteswap.in.h
+	$(AM_V_at)mv $@-t $@
 else
 byteswap.h: $(top_builddir)/config.status
 	rm -f $@
@@ -402,19 +409,17 @@ EXTRA_DIST += c-strcaseeq.h
 
 ## begin gnulib module canonicalize-lgpl
 
-
-EXTRA_DIST += canonicalize-lgpl.c
-
-EXTRA_libgnu_la_SOURCES += canonicalize-lgpl.c
+if GL_COND_OBJ_CANONICALIZE_LGPL
+libgnu_la_SOURCES += canonicalize-lgpl.c
+endif
 
 ## end   gnulib module canonicalize-lgpl
 
 ## begin gnulib module ceil
 
-
-EXTRA_DIST += ceil.c
-
-EXTRA_libgnu_la_SOURCES += ceil.c
+if GL_COND_OBJ_CEIL
+libgnu_la_SOURCES += ceil.c
+endif
 
 ## end   gnulib module ceil
 
@@ -430,28 +435,37 @@ EXTRA_DIST += cloexec.h
 
 ## begin gnulib module close
 
+if GL_COND_OBJ_CLOSE
+libgnu_la_SOURCES += close.c
+endif
 
-EXTRA_DIST += close.c
+## end   gnulib module close
 
-EXTRA_libgnu_la_SOURCES += close.c
+## begin gnulib module concat-filename
 
-## end   gnulib module close
+if gl_GNULIB_ENABLED_6da965dc4d3aa4f87d68116dce96f1a5
+libgnu_la_SOURCES += concat-filename.c
 
-## begin gnulib module connect
+endif
+EXTRA_DIST += concat-filename.h
 
+## end   gnulib module concat-filename
 
-EXTRA_DIST += connect.c w32sock.h
+## begin gnulib module connect
 
-EXTRA_libgnu_la_SOURCES += connect.c
+if GL_COND_OBJ_CONNECT
+libgnu_la_SOURCES += connect.c
+endif
+
+EXTRA_DIST += w32sock.h
 
 ## end   gnulib module connect
 
 ## begin gnulib module copysign
 
-
-EXTRA_DIST += copysign.c
-
-EXTRA_libgnu_la_SOURCES += copysign.c
+if GL_COND_OBJ_COPYSIGN
+libgnu_la_SOURCES += copysign.c
+endif
 
 ## end   gnulib module copysign
 
@@ -462,9 +476,8 @@ BUILT_SOURCES += dirent.h
 # We need the following in order to create <dirent.h> when the system
 # doesn't have one that works with the given compiler.
 dirent.h: dirent.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
-	  sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+	$(gl_V_at)$(SED_HEADER_STDOUT) \
+	      -e 's|@''GUARD_PREFIX''@|GL|g' \
 	      -e 's|@''HAVE_DIRENT_H''@|$(HAVE_DIRENT_H)|g' \
 	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
 	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
@@ -494,9 +507,8 @@ dirent.h: dirent.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
 	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
 	      -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
 	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
-	      < $(srcdir)/dirent.in.h; \
-	} > $@-t && \
-	mv $@-t $@
+	      $(srcdir)/dirent.in.h > $@-t
+	$(AM_V_at)mv $@-t $@
 MOSTLYCLEANFILES += dirent.h dirent.h-t
 
 EXTRA_DIST += dirent.in.h
@@ -505,10 +517,9 @@ EXTRA_DIST += dirent.in.h
 
 ## begin gnulib module dirfd
 
-
-EXTRA_DIST += dirfd.c
-
-EXTRA_libgnu_la_SOURCES += dirfd.c
+if GL_COND_OBJ_DIRFD
+libgnu_la_SOURCES += dirfd.c
+endif
 
 ## end   gnulib module dirfd
 
@@ -523,20 +534,18 @@ EXTRA_DIST += dirname.h
 ## begin gnulib module dup2
 
 if gl_GNULIB_ENABLED_dup2
-
+if GL_COND_OBJ_DUP2
+libgnu_la_SOURCES += dup2.c
 endif
-EXTRA_DIST += dup2.c
-
-EXTRA_libgnu_la_SOURCES += dup2.c
 
+endif
 ## end   gnulib module dup2
 
 ## begin gnulib module duplocale
 
-
-EXTRA_DIST += duplocale.c
-
-EXTRA_libgnu_la_SOURCES += duplocale.c
+if GL_COND_OBJ_DUPLOCALE
+libgnu_la_SOURCES += duplocale.c
+endif
 
 ## end   gnulib module duplocale
 
@@ -546,27 +555,24 @@ if gl_GNULIB_ENABLED_dynarray
 BUILT_SOURCES += malloc/dynarray.gl.h malloc/dynarray-skeleton.gl.h
 
 malloc/dynarray.gl.h: malloc/dynarray.h
-	$(AM_V_at)$(MKDIR_P) malloc
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
-	  sed -e '/libc_hidden_proto/d' < $(srcdir)/malloc/dynarray.h; \
-	} > $@-t && \
-	mv $@-t $@
+	$(AM_V_GEN)$(MKDIR_P) '%reldir%/malloc'
+	$(AM_V_at)$(SED_HEADER_STDOUT) \
+	  -e '/libc_hidden_proto/d' \
+	  $(srcdir)/malloc/dynarray.h > $@-t
+	$(AM_V_at)mv $@-t $@
 MOSTLYCLEANFILES += malloc/dynarray.gl.h malloc/dynarray.gl.h-t
 
 malloc/dynarray-skeleton.gl.h: malloc/dynarray-skeleton.c
-	$(AM_V_at)$(MKDIR_P) malloc
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
-	  sed -e 's|<malloc/dynarray\.h>|<malloc/dynarray.gl.h>|g' \
+	$(AM_V_GEN)$(MKDIR_P) '%reldir%/malloc'
+	$(AM_V_at)$(SED_HEADER_STDOUT) \
+	      -e 's|<malloc/dynarray\.h>|<malloc/dynarray.gl.h>|g' \
 	      -e 's|__attribute_maybe_unused__|_GL_ATTRIBUTE_MAYBE_UNUSED|g' \
 	      -e 's|__attribute_nonnull__|_GL_ATTRIBUTE_NONNULL|g' \
 	      -e 's|__attribute_warn_unused_result__|_GL_ATTRIBUTE_NODISCARD|g' \
 	      -e 's|__glibc_likely|_GL_LIKELY|g' \
 	      -e 's|__glibc_unlikely|_GL_UNLIKELY|g' \
-	      < $(srcdir)/malloc/dynarray-skeleton.c; \
-	} > $@-t && \
-	mv $@-t $@
+	      $(srcdir)/malloc/dynarray-skeleton.c > $@-t
+	$(AM_V_at)mv $@-t $@
 MOSTLYCLEANFILES += malloc/dynarray-skeleton.gl.h malloc/dynarray-skeleton.gl.h-t
 
 libgnu_la_SOURCES += malloc/dynarray_at_failure.c                 malloc/dynarray_emplace_enlarge.c                 malloc/dynarray_finalize.c                 malloc/dynarray_resize.c                 malloc/dynarray_resize_clear.c
@@ -595,9 +601,8 @@ BUILT_SOURCES += $(ERRNO_H)
 # doesn't have one that is POSIX compliant.
 if GL_GENERATE_ERRNO_H
 errno.h: errno.in.h $(top_builddir)/config.status
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
-	  sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+	$(gl_V_at)$(SED_HEADER_STDOUT) \
+	      -e 's|@''GUARD_PREFIX''@|GL|g' \
 	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
 	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
 	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
@@ -608,9 +613,8 @@ errno.h: errno.in.h $(top_builddir)/config.status
 	      -e 's|@''ENOLINK_VALUE''@|$(ENOLINK_VALUE)|g' \
 	      -e 's|@''EOVERFLOW_HIDDEN''@|$(EOVERFLOW_HIDDEN)|g' \
 	      -e 's|@''EOVERFLOW_VALUE''@|$(EOVERFLOW_VALUE)|g' \
-	      < $(srcdir)/errno.in.h; \
-	} > $@-t && \
-	mv $@-t $@
+	      $(srcdir)/errno.in.h > $@-t
+	$(AM_V_at)mv $@-t $@
 else
 errno.h: $(top_builddir)/config.status
 	rm -f $@
@@ -624,12 +628,11 @@ EXTRA_DIST += errno.in.h
 ## begin gnulib module fcntl
 
 if gl_GNULIB_ENABLED_fcntl
-
+if GL_COND_OBJ_FCNTL
+libgnu_la_SOURCES += fcntl.c
 endif
-EXTRA_DIST += fcntl.c
-
-EXTRA_libgnu_la_SOURCES += fcntl.c
 
+endif
 ## end   gnulib module fcntl
 
 ## begin gnulib module fcntl-h
@@ -639,9 +642,8 @@ BUILT_SOURCES += fcntl.h
 # We need the following in order to create <fcntl.h> when the system
 # doesn't have one that works with the given compiler.
 fcntl.h: fcntl.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
-	  sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+	$(gl_V_at)$(SED_HEADER_STDOUT) \
+	      -e 's|@''GUARD_PREFIX''@|GL|g' \
 	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
 	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
 	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
@@ -662,9 +664,8 @@ fcntl.h: fcntl.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H)
 	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
 	      -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
 	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
-	      < $(srcdir)/fcntl.in.h; \
-	} > $@-t && \
-	mv $@-t $@
+	      $(srcdir)/fcntl.in.h > $@-t
+	$(AM_V_at)mv $@-t $@
 MOSTLYCLEANFILES += fcntl.h fcntl.h-t
 
 EXTRA_DIST += fcntl.in.h
@@ -688,6 +689,14 @@ EXTRA_DIST += filename.h
 
 ## end   gnulib module filename
 
+## begin gnulib module findprog-in
+
+if gl_GNULIB_ENABLED_7be38c8cf2027003f573b80556d26ff2
+libgnu_la_SOURCES += findprog.h findprog-in.c
+
+endif
+## end   gnulib module findprog-in
+
 ## begin gnulib module flexmember
 
 
@@ -703,53 +712,53 @@ BUILT_SOURCES += $(FLOAT_H)
 # doesn't have one that works with the given compiler.
 if GL_GENERATE_FLOAT_H
 float.h: float.in.h $(top_builddir)/config.status
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
-	  sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+	$(gl_V_at)$(SED_HEADER_STDOUT) \
+	      -e 's|@''GUARD_PREFIX''@|GL|g' \
 	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
 	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
 	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
 	      -e 's|@''NEXT_FLOAT_H''@|$(NEXT_FLOAT_H)|g' \
 	      -e 's|@''REPLACE_ITOLD''@|$(REPLACE_ITOLD)|g' \
-	      < $(srcdir)/float.in.h; \
-	} > $@-t && \
-	mv $@-t $@
+	      $(srcdir)/float.in.h > $@-t
+	$(AM_V_at)mv $@-t $@
 else
 float.h: $(top_builddir)/config.status
 	rm -f $@
 endif
 MOSTLYCLEANFILES += float.h float.h-t
 
-EXTRA_DIST += float.c float.in.h itold.c
+if GL_COND_OBJ_FLOAT
+libgnu_la_SOURCES += float.c
+endif
+if GL_COND_OBJ_ITOLD
+libgnu_la_SOURCES += itold.c
+endif
 
-EXTRA_libgnu_la_SOURCES += float.c itold.c
+EXTRA_DIST += float.in.h
 
 ## end   gnulib module float
 
 ## begin gnulib module flock
 
-
-EXTRA_DIST += flock.c
-
-EXTRA_libgnu_la_SOURCES += flock.c
+if GL_COND_OBJ_FLOCK
+libgnu_la_SOURCES += flock.c
+endif
 
 ## end   gnulib module flock
 
 ## begin gnulib module floor
 
-
-EXTRA_DIST += floor.c
-
-EXTRA_libgnu_la_SOURCES += floor.c
+if GL_COND_OBJ_FLOOR
+libgnu_la_SOURCES += floor.c
+endif
 
 ## end   gnulib module floor
 
 ## begin gnulib module free-posix
 
-
-EXTRA_DIST += free.c
-
-EXTRA_libgnu_la_SOURCES += free.c
+if GL_COND_OBJ_FREE
+libgnu_la_SOURCES += free.c
+endif
 
 ## end   gnulib module free-posix
 
@@ -764,19 +773,21 @@ EXTRA_libgnu_la_SOURCES += frexp.c
 
 ## begin gnulib module fstat
 
+if GL_COND_OBJ_FSTAT
+libgnu_la_SOURCES += fstat.c
+endif
 
-EXTRA_DIST += fstat.c stat-w32.c stat-w32.h
+EXTRA_DIST += stat-w32.c stat-w32.h
 
-EXTRA_libgnu_la_SOURCES += fstat.c stat-w32.c
+EXTRA_libgnu_la_SOURCES += stat-w32.c
 
 ## end   gnulib module fstat
 
 ## begin gnulib module fsync
 
-
-EXTRA_DIST += fsync.c
-
-EXTRA_libgnu_la_SOURCES += fsync.c
+if GL_COND_OBJ_FSYNC
+libgnu_la_SOURCES += fsync.c
+endif
 
 ## end   gnulib module fsync
 
@@ -796,6 +807,25 @@ libgnu_la_SOURCES += full-write.h full-write.c
 
 ## end   gnulib module full-write
 
+## begin gnulib module gen-header
+
+# In 'sed', replace the pattern space with a "DO NOT EDIT" comment.
+SED_HEADER_NOEDIT = s,.*,/* DO NOT EDIT! GENERATED AUTOMATICALLY! */,
+
+# '$(SED_HEADER_STDOUT) -e "..."' runs 'sed' but first outputs "DO NOT EDIT".
+SED_HEADER_STDOUT = sed -e 1h -e '1$(SED_HEADER_NOEDIT)' -e 1G
+
+# '$(SED_HEADER_TO_AT_t) FILE' copies FILE to $@-t, prepending a leading
+# "DO_NOT_EDIT".  Although this could be done more simply via:
+#	SED_HEADER_TO_AT_t = $(SED_HEADER_STDOUT) > $@-t
+# the -n and 'w' avoid a fork+exec, at least when GNU Make is used.
+SED_HEADER_TO_AT_t = $(SED_HEADER_STDOUT) -n -e 'w $@-t'
+
+# Use $(gl_V_at) instead of $(AM_V_GEN) or $(AM_V_at) on a line that
+gl_V_at = $(AM_V_GEN)
+
+## end   gnulib module gen-header
+
 ## begin gnulib module gendocs
 
 
@@ -805,68 +835,70 @@ EXTRA_DIST += $(top_srcdir)/build-aux/gendocs.sh
 
 ## begin gnulib module getaddrinfo
 
-
-EXTRA_DIST += gai_strerror.c getaddrinfo.c
-
-EXTRA_libgnu_la_SOURCES += gai_strerror.c getaddrinfo.c
+if GL_COND_OBJ_GETADDRINFO
+libgnu_la_SOURCES += getaddrinfo.c
+endif
+if GL_COND_OBJ_GAI_STRERROR
+libgnu_la_SOURCES += gai_strerror.c
+endif
 
 ## end   gnulib module getaddrinfo
 
 ## begin gnulib module getdtablesize
 
 if gl_GNULIB_ENABLED_getdtablesize
-
+if GL_COND_OBJ_GETDTABLESIZE
+libgnu_la_SOURCES += getdtablesize.c
 endif
-EXTRA_DIST += getdtablesize.c
-
-EXTRA_libgnu_la_SOURCES += getdtablesize.c
 
+endif
 ## end   gnulib module getdtablesize
 
 ## begin gnulib module getlogin
 
-
-EXTRA_DIST += getlogin.c
-
-EXTRA_libgnu_la_SOURCES += getlogin.c
+if GL_COND_OBJ_GETLOGIN
+libgnu_la_SOURCES += getlogin.c
+endif
 
 ## end   gnulib module getlogin
 
 ## begin gnulib module getpeername
 
+if GL_COND_OBJ_GETPEERNAME
+libgnu_la_SOURCES += getpeername.c
+endif
 
-EXTRA_DIST += getpeername.c w32sock.h
-
-EXTRA_libgnu_la_SOURCES += getpeername.c
+EXTRA_DIST += w32sock.h
 
 ## end   gnulib module getpeername
 
 ## begin gnulib module getrandom
 
 if gl_GNULIB_ENABLED_getrandom
-
+if GL_COND_OBJ_GETRANDOM
+libgnu_la_SOURCES += getrandom.c
 endif
-EXTRA_DIST += getrandom.c
-
-EXTRA_libgnu_la_SOURCES += getrandom.c
 
+endif
 ## end   gnulib module getrandom
 
 ## begin gnulib module getsockname
 
+if GL_COND_OBJ_GETSOCKNAME
+libgnu_la_SOURCES += getsockname.c
+endif
 
-EXTRA_DIST += getsockname.c w32sock.h
-
-EXTRA_libgnu_la_SOURCES += getsockname.c
+EXTRA_DIST += w32sock.h
 
 ## end   gnulib module getsockname
 
 ## begin gnulib module getsockopt
 
+if GL_COND_OBJ_GETSOCKOPT
+libgnu_la_SOURCES += getsockopt.c
+endif
 
-EXTRA_DIST += getsockopt.c w32sock.h
-
-EXTRA_libgnu_la_SOURCES += getsockopt.c
+EXTRA_DIST += w32sock.h
 
 ## end   gnulib module getsockopt
 
@@ -949,9 +981,8 @@ BUILT_SOURCES += $(ICONV_H)
 # doesn't have one that works with the given compiler.
 if GL_GENERATE_ICONV_H
 iconv.h: iconv.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
-	  sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+	$(gl_V_at)$(SED_HEADER_STDOUT) \
+	      -e 's|@''GUARD_PREFIX''@|GL|g' \
 	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
 	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
 	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
@@ -964,9 +995,8 @@ iconv.h: iconv.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H)
 	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
 	      -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
 	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
-	      < $(srcdir)/iconv.in.h; \
-	} > $@-t && \
-	mv $@-t $@
+	      $(srcdir)/iconv.in.h > $@-t
+	$(AM_V_at)mv $@-t $@
 else
 iconv.h: $(top_builddir)/config.status
 	rm -f $@
@@ -979,6 +1009,13 @@ EXTRA_DIST += iconv.in.h
 
 ## begin gnulib module iconv_open
 
+if GL_COND_OBJ_ICONV_OPEN
+libgnu_la_SOURCES += iconv_open.c
+endif
+if GL_COND_OBJ_ICONV
+libgnu_la_SOURCES += iconv.c iconv_close.c
+endif
+
 $(srcdir)/iconv_open-aix.h: $(srcdir)/iconv_open-aix.gperf
 	$(V_GPERF)$(GPERF) -m 10 $(srcdir)/iconv_open-aix.gperf > $(srcdir)/iconv_open-aix.h-t && \
 	mv $(srcdir)/iconv_open-aix.h-t $(srcdir)/iconv_open-aix.h
@@ -1002,9 +1039,7 @@ MOSTLYCLEANFILES     += iconv_open-aix.h-t iconv_open-hpux.h-t iconv_open-irix.h
 MAINTAINERCLEANFILES += iconv_open-aix.h iconv_open-hpux.h iconv_open-irix.h iconv_open-osf.h iconv_open-solaris.h iconv_open-zos.h
 EXTRA_DIST           += iconv_open-aix.h iconv_open-hpux.h iconv_open-irix.h iconv_open-osf.h iconv_open-solaris.h iconv_open-zos.h
 
-EXTRA_DIST += iconv.c iconv_close.c iconv_open-aix.gperf iconv_open-hpux.gperf iconv_open-irix.gperf iconv_open-osf.gperf iconv_open-solaris.gperf iconv_open-zos.gperf iconv_open.c
-
-EXTRA_libgnu_la_SOURCES += iconv.c iconv_close.c iconv_open.c
+EXTRA_DIST += iconv_open-aix.gperf iconv_open-hpux.gperf iconv_open-irix.gperf iconv_open-osf.gperf iconv_open-solaris.gperf iconv_open-zos.gperf
 
 ## end   gnulib module iconv_open
 
@@ -1016,26 +1051,24 @@ libgnu_la_SOURCES += idx.h
 
 ## begin gnulib module inet_ntop
 
-
-EXTRA_DIST += inet_ntop.c
-
-EXTRA_libgnu_la_SOURCES += inet_ntop.c
+if GL_COND_OBJ_INET_NTOP
+libgnu_la_SOURCES += inet_ntop.c
+endif
 
 ## end   gnulib module inet_ntop
 
 ## begin gnulib module inet_pton
 
-
-EXTRA_DIST += inet_pton.c
-
-EXTRA_libgnu_la_SOURCES += inet_pton.c
+if GL_COND_OBJ_INET_PTON
+libgnu_la_SOURCES += inet_pton.c
+endif
 
 ## end   gnulib module inet_pton
 
 ## begin gnulib module intprops
 
 
-EXTRA_DIST += intprops.h
+EXTRA_DIST += intprops-internal.h intprops.h
 
 ## end   gnulib module intprops
 
@@ -1046,9 +1079,8 @@ BUILT_SOURCES += inttypes.h
 # We need the following in order to create <inttypes.h> when the system
 # doesn't have one that works with the given compiler.
 inttypes.h: inttypes.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H) $(ARG_NONNULL_H)
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
-	  sed -e 's/@''HAVE_INTTYPES_H''@/$(HAVE_INTTYPES_H)/g' \
+	$(gl_V_at)$(SED_HEADER_STDOUT) \
+	      -e 's/@''HAVE_INTTYPES_H''@/$(HAVE_INTTYPES_H)/g' \
 	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
 	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
 	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
@@ -1073,9 +1105,8 @@ inttypes.h: inttypes.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_U
 	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
 	      -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
 	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
-	      < $(srcdir)/inttypes.in.h; \
-	} > $@-t && \
-	mv $@-t $@
+	      $(srcdir)/inttypes.in.h > $@-t
+	$(AM_V_at)mv $@-t $@
 MOSTLYCLEANFILES += inttypes.h inttypes.h-t
 
 EXTRA_DIST += inttypes.in.h
@@ -1084,19 +1115,17 @@ EXTRA_DIST += inttypes.in.h
 
 ## begin gnulib module isfinite
 
-
-EXTRA_DIST += isfinite.c
-
-EXTRA_libgnu_la_SOURCES += isfinite.c
+if GL_COND_OBJ_ISFINITE
+libgnu_la_SOURCES += isfinite.c
+endif
 
 ## end   gnulib module isfinite
 
 ## begin gnulib module isinf
 
-
-EXTRA_DIST += isinf.c
-
-EXTRA_libgnu_la_SOURCES += isinf.c
+if GL_COND_OBJ_ISINF
+libgnu_la_SOURCES += isinf.c
+endif
 
 ## end   gnulib module isinf
 
@@ -1167,9 +1196,8 @@ BUILT_SOURCES += langinfo.h
 # We need the following in order to create an empty placeholder for
 # <langinfo.h> when the system doesn't have one.
 langinfo.h: langinfo.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H)
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
-	  sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+	$(gl_V_at)$(SED_HEADER_STDOUT) \
+	      -e 's|@''GUARD_PREFIX''@|GL|g' \
 	      -e 's|@''HAVE_LANGINFO_H''@|$(HAVE_LANGINFO_H)|g' \
 	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
 	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
@@ -1185,9 +1213,8 @@ langinfo.h: langinfo.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_U
 	      -e 's|@''REPLACE_NL_LANGINFO''@|$(REPLACE_NL_LANGINFO)|g' \
 	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
 	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
-	      < $(srcdir)/langinfo.in.h; \
-	} > $@-t && \
-	mv $@-t $@
+	      $(srcdir)/langinfo.in.h > $@-t
+	$(AM_V_at)mv $@-t $@
 MOSTLYCLEANFILES += langinfo.h langinfo.h-t
 
 EXTRA_DIST += langinfo.in.h
@@ -1206,9 +1233,7 @@ AM_CFLAGS += $(CFLAG_VISIBILITY)
 
 ## begin gnulib module libc-config
 
-if gl_GNULIB_ENABLED_21ee726a3540c09237a8e70c0baf7467
 
-endif
 EXTRA_DIST += cdefs.h libc-config.h
 
 ## end   gnulib module libc-config
@@ -1228,16 +1253,14 @@ BUILT_SOURCES += $(LIMITS_H)
 # doesn't have one that is compatible with GNU.
 if GL_GENERATE_LIMITS_H
 limits.h: limits.in.h $(top_builddir)/config.status
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
-	  sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+	$(gl_V_at)$(SED_HEADER_STDOUT) \
+	      -e 's|@''GUARD_PREFIX''@|GL|g' \
 	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
 	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
 	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
 	      -e 's|@''NEXT_LIMITS_H''@|$(NEXT_LIMITS_H)|g' \
-	      < $(srcdir)/limits.in.h; \
-	} > $@-t && \
-	mv $@-t $@
+	      $(srcdir)/limits.in.h > $@-t
+	$(AM_V_at)mv $@-t $@
 else
 limits.h: $(top_builddir)/config.status
 	rm -f $@
@@ -1250,19 +1273,19 @@ EXTRA_DIST += limits.in.h
 
 ## begin gnulib module link
 
-
-EXTRA_DIST += link.c
-
-EXTRA_libgnu_la_SOURCES += link.c
+if GL_COND_OBJ_LINK
+libgnu_la_SOURCES += link.c
+endif
 
 ## end   gnulib module link
 
 ## begin gnulib module listen
 
+if GL_COND_OBJ_LISTEN
+libgnu_la_SOURCES += listen.c
+endif
 
-EXTRA_DIST += listen.c w32sock.h
-
-EXTRA_libgnu_la_SOURCES += listen.c
+EXTRA_DIST += w32sock.h
 
 ## end   gnulib module listen
 
@@ -1281,9 +1304,8 @@ BUILT_SOURCES += locale.h
 # We need the following in order to create <locale.h> when the system
 # doesn't have one that provides all definitions.
 locale.h: locale.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
-	  sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+	$(gl_V_at)$(SED_HEADER_STDOUT) \
+	      -e 's|@''GUARD_PREFIX''@|GL|g' \
 	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
 	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
 	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
@@ -1307,9 +1329,8 @@ locale.h: locale.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
 	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
 	      -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
 	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
-	      < $(srcdir)/locale.in.h; \
-	} > $@-t && \
-	mv $@-t $@
+	      $(srcdir)/locale.in.h > $@-t
+	$(AM_V_at)mv $@-t $@
 MOSTLYCLEANFILES += locale.h locale.h-t
 
 EXTRA_DIST += locale.in.h
@@ -1319,40 +1340,36 @@ EXTRA_DIST += locale.in.h
 ## begin gnulib module localeconv
 
 if gl_GNULIB_ENABLED_localeconv
-
+if GL_COND_OBJ_LOCALECONV
+libgnu_la_SOURCES += localeconv.c
 endif
-EXTRA_DIST += localeconv.c
-
-EXTRA_libgnu_la_SOURCES += localeconv.c
 
+endif
 ## end   gnulib module localeconv
 
 ## begin gnulib module log
 
 if gl_GNULIB_ENABLED_log
-
+if GL_COND_OBJ_LOG
+libgnu_la_SOURCES += log.c
 endif
-EXTRA_DIST += log.c
-
-EXTRA_libgnu_la_SOURCES += log.c
 
+endif
 ## end   gnulib module log
 
 ## begin gnulib module log1p
 
-
-EXTRA_DIST += log1p.c
-
-EXTRA_libgnu_la_SOURCES += log1p.c
+if GL_COND_OBJ_LOG1P
+libgnu_la_SOURCES += log1p.c
+endif
 
 ## end   gnulib module log1p
 
 ## begin gnulib module lstat
 
-
-EXTRA_DIST += lstat.c
-
-EXTRA_libgnu_la_SOURCES += lstat.c
+if GL_COND_OBJ_LSTAT
+libgnu_la_SOURCES += lstat.c
+endif
 
 ## end   gnulib module lstat
 
@@ -1396,9 +1413,8 @@ libgnu_la_SOURCES += math.c
 # We need the following in order to create <math.h> when the system
 # doesn't have one that works with the given compiler.
 math.h: math.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
-	  sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+	$(gl_V_at)$(SED_HEADER_STDOUT) \
+	      -e 's|@''GUARD_PREFIX''@|GL|g' \
 	      -e 's|@''INCLUDE_NEXT_AS_FIRST_DIRECTIVE''@|$(INCLUDE_NEXT_AS_FIRST_DIRECTIVE)|g' \
 	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
 	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
@@ -1685,9 +1701,9 @@ math.h: math.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(
 	      -e 's|@''REPLACE_TRUNCL''@|$(REPLACE_TRUNCL)|g' \
 	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
 	      -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
-	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \
-	} > $@-t && \
-	mv $@-t $@
+	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
+	      > $@-t
+	$(AM_V_at)mv $@-t $@
 MOSTLYCLEANFILES += math.h math.h-t
 
 EXTRA_DIST += math.in.h
@@ -1697,56 +1713,59 @@ EXTRA_DIST += math.in.h
 ## begin gnulib module mbrtowc
 
 if gl_GNULIB_ENABLED_mbrtowc
+if GL_COND_OBJ_MBRTOWC
+libgnu_la_SOURCES += mbrtowc.c
+endif
 
 endif
-EXTRA_DIST += lc-charset-dispatch.c lc-charset-dispatch.h mbrtowc-impl-utf8.h mbrtowc-impl.h mbrtowc.c mbtowc-lock.c mbtowc-lock.h windows-initguard.h
+EXTRA_DIST += lc-charset-dispatch.c lc-charset-dispatch.h mbrtowc-impl-utf8.h mbrtowc-impl.h mbtowc-lock.c mbtowc-lock.h windows-initguard.h
 
-EXTRA_libgnu_la_SOURCES += lc-charset-dispatch.c mbrtowc.c mbtowc-lock.c
+EXTRA_libgnu_la_SOURCES += lc-charset-dispatch.c mbtowc-lock.c
 
 ## end   gnulib module mbrtowc
 
 ## begin gnulib module mbsinit
 
 if gl_GNULIB_ENABLED_mbsinit
-
+if GL_COND_OBJ_MBSINIT
+libgnu_la_SOURCES += mbsinit.c
 endif
-EXTRA_DIST += mbsinit.c
-
-EXTRA_libgnu_la_SOURCES += mbsinit.c
 
+endif
 ## end   gnulib module mbsinit
 
 ## begin gnulib module mbtowc
 
 if gl_GNULIB_ENABLED_mbtowc
-
+if GL_COND_OBJ_MBTOWC
+libgnu_la_SOURCES += mbtowc.c
 endif
-EXTRA_DIST += mbtowc-impl.h mbtowc.c
 
-EXTRA_libgnu_la_SOURCES += mbtowc.c
+endif
+EXTRA_DIST += mbtowc-impl.h
 
 ## end   gnulib module mbtowc
 
 ## begin gnulib module memchr
 
 if gl_GNULIB_ENABLED_memchr
-
+if GL_COND_OBJ_MEMCHR
+libgnu_la_SOURCES += memchr.c
 endif
-EXTRA_DIST += memchr.c memchr.valgrind
 
-EXTRA_libgnu_la_SOURCES += memchr.c
+endif
+EXTRA_DIST += memchr.valgrind
 
 ## end   gnulib module memchr
 
 ## begin gnulib module mempcpy
 
 if gl_GNULIB_ENABLED_mempcpy
-
+if GL_COND_OBJ_MEMPCPY
+libgnu_la_SOURCES += mempcpy.c
 endif
-EXTRA_DIST += mempcpy.c
-
-EXTRA_libgnu_la_SOURCES += mempcpy.c
 
+endif
 ## end   gnulib module mempcpy
 
 ## begin gnulib module minmax
@@ -1757,19 +1776,17 @@ libgnu_la_SOURCES += minmax.h
 
 ## begin gnulib module mkdir
 
-
-EXTRA_DIST += mkdir.c
-
-EXTRA_libgnu_la_SOURCES += mkdir.c
+if GL_COND_OBJ_MKDIR
+libgnu_la_SOURCES += mkdir.c
+endif
 
 ## end   gnulib module mkdir
 
 ## begin gnulib module mkostemp
 
-
-EXTRA_DIST += mkostemp.c
-
-EXTRA_libgnu_la_SOURCES += mkostemp.c
+if GL_COND_OBJ_MKOSTEMP
+libgnu_la_SOURCES += mkostemp.c
+endif
 
 ## end   gnulib module mkostemp
 
@@ -1797,19 +1814,21 @@ EXTRA_libgnu_la_SOURCES += mktime.c
 
 ## begin gnulib module msvc-inval
 
+if GL_COND_OBJ_MSVC_INVAL
+libgnu_la_SOURCES += msvc-inval.c
+endif
 
-EXTRA_DIST += msvc-inval.c msvc-inval.h
-
-EXTRA_libgnu_la_SOURCES += msvc-inval.c
+EXTRA_DIST += msvc-inval.h
 
 ## end   gnulib module msvc-inval
 
 ## begin gnulib module msvc-nothrow
 
+if GL_COND_OBJ_MSVC_NOTHROW
+libgnu_la_SOURCES += msvc-nothrow.c
+endif
 
-EXTRA_DIST += msvc-nothrow.c msvc-nothrow.h
-
-EXTRA_libgnu_la_SOURCES += msvc-nothrow.c
+EXTRA_DIST += msvc-nothrow.h
 
 ## end   gnulib module msvc-nothrow
 
@@ -1820,9 +1839,8 @@ BUILT_SOURCES += netdb.h
 # We need the following in order to create <netdb.h> when the system
 # doesn't have one that works with the given compiler.
 netdb.h: netdb.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
-	  sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+	$(gl_V_at)$(SED_HEADER_STDOUT) \
+	      -e 's|@''GUARD_PREFIX''@|GL|g' \
 	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
 	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
 	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
@@ -1839,9 +1857,8 @@ netdb.h: netdb.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H)
 	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
 	      -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
 	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
-	      < $(srcdir)/netdb.in.h; \
-	} > $@-t && \
-	mv $@-t $@
+	      $(srcdir)/netdb.in.h > $@-t
+	$(AM_V_at)mv $@-t $@
 MOSTLYCLEANFILES += netdb.h netdb.h-t
 
 EXTRA_DIST += netdb.in.h
@@ -1850,24 +1867,23 @@ EXTRA_DIST += netdb.in.h
 
 ## begin gnulib module netinet_in
 
+if gl_GNULIB_ENABLED_netinet_in
 BUILT_SOURCES += $(NETINET_IN_H)
 
 # We need the following in order to create <netinet/in.h> when the system
 # doesn't have one.
 if GL_GENERATE_NETINET_IN_H
 netinet/in.h: netinet_in.in.h $(top_builddir)/config.status
-	$(AM_V_at)$(MKDIR_P) netinet
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
-	  sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+	$(AM_V_GEN)$(MKDIR_P) '%reldir%/netinet'
+	$(AM_V_at)$(SED_HEADER_STDOUT) \
+	      -e 's|@''GUARD_PREFIX''@|GL|g' \
 	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
 	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
 	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
 	      -e 's|@''NEXT_NETINET_IN_H''@|$(NEXT_NETINET_IN_H)|g' \
 	      -e 's|@''HAVE_NETINET_IN_H''@|$(HAVE_NETINET_IN_H)|g' \
-	      < $(srcdir)/netinet_in.in.h; \
-	} > $@-t && \
-	mv $@-t $@
+	      $(srcdir)/netinet_in.in.h > $@-t
+	$(AM_V_at)mv $@-t $@
 else
 netinet/in.h: $(top_builddir)/config.status
 	rm -f $@
@@ -1875,16 +1891,21 @@ endif
 MOSTLYCLEANFILES += netinet/in.h netinet/in.h-t
 MOSTLYCLEANDIRS += netinet
 
+endif
 EXTRA_DIST += netinet_in.in.h
 
 ## end   gnulib module netinet_in
 
 ## begin gnulib module nl_langinfo
 
+if GL_COND_OBJ_NL_LANGINFO
+libgnu_la_SOURCES += nl_langinfo.c
+endif
+if GL_COND_OBJ_NL_LANGINFO_LOCK
+libgnu_la_SOURCES += nl_langinfo-lock.c
+endif
 
-EXTRA_DIST += nl_langinfo-lock.c nl_langinfo.c windows-initguard.h
-
-EXTRA_libgnu_la_SOURCES += nl_langinfo-lock.c nl_langinfo.c
+EXTRA_DIST += windows-initguard.h
 
 ## end   gnulib module nl_langinfo
 
@@ -1906,10 +1927,9 @@ EXTRA_DIST += strftime.h
 
 ## begin gnulib module open
 
-
-EXTRA_DIST += open.c
-
-EXTRA_libgnu_la_SOURCES += open.c
+if GL_COND_OBJ_OPEN
+libgnu_la_SOURCES += open.c
+endif
 
 ## end   gnulib module open
 
@@ -1924,10 +1944,9 @@ EXTRA_DIST += pathmax.h
 
 ## begin gnulib module pipe-posix
 
-
-EXTRA_DIST += pipe.c
-
-EXTRA_libgnu_la_SOURCES += pipe.c
+if GL_COND_OBJ_PIPE
+libgnu_la_SOURCES += pipe.c
+endif
 
 ## end   gnulib module pipe-posix
 
@@ -1939,10 +1958,9 @@ libgnu_la_SOURCES += pipe2.c
 
 ## begin gnulib module poll
 
-
-EXTRA_DIST += poll.c
-
-EXTRA_libgnu_la_SOURCES += poll.c
+if GL_COND_OBJ_POLL
+libgnu_la_SOURCES += poll.c
+endif
 
 ## end   gnulib module poll
 
@@ -1953,9 +1971,8 @@ BUILT_SOURCES += poll.h
 # We need the following in order to create <poll.h> when the system
 # doesn't have one.
 poll.h: poll.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H)
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
-	  sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+	$(gl_V_at)$(SED_HEADER_STDOUT) \
+	      -e 's|@''GUARD_PREFIX''@|GL|g' \
 	      -e 's|@''HAVE_POLL_H''@|$(HAVE_POLL_H)|g' \
 	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
 	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
@@ -1967,61 +1984,77 @@ poll.h: poll.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H)
 	      -e 's|@''REPLACE_POLL''@|$(REPLACE_POLL)|g' \
 	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
 	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
-	      < $(srcdir)/poll.in.h; \
-	} > $@-t && \
-	mv -f $@-t $@
+	      $(srcdir)/poll.in.h > $@-t
+	$(AM_V_at)mv $@-t $@
 MOSTLYCLEANFILES += poll.h poll.h-t
 
 EXTRA_DIST += poll.in.h
 
 ## end   gnulib module poll-h
 
-## begin gnulib module putenv
+## begin gnulib module posix_spawn-internal
+
+if gl_GNULIB_ENABLED_332607f759618fb73dfc3076748afea7
+if GL_COND_OBJ_SPAWNI
+libgnu_la_SOURCES += spawni.c
+endif
+
+endif
+EXTRA_DIST += spawn_int.h
+
+## end   gnulib module posix_spawn-internal
+
+## begin gnulib module posix_spawnp
+
+if GL_COND_OBJ_SPAWNP
+libgnu_la_SOURCES += spawnp.c
+endif
 
+## end   gnulib module posix_spawnp
 
-EXTRA_DIST += putenv.c
+## begin gnulib module putenv
 
-EXTRA_libgnu_la_SOURCES += putenv.c
+if GL_COND_OBJ_PUTENV
+libgnu_la_SOURCES += putenv.c
+endif
 
 ## end   gnulib module putenv
 
 ## begin gnulib module raise
 
 if gl_GNULIB_ENABLED_raise
-
+if GL_COND_OBJ_RAISE
+libgnu_la_SOURCES += raise.c
 endif
-EXTRA_DIST += raise.c
-
-EXTRA_libgnu_la_SOURCES += raise.c
 
+endif
 ## end   gnulib module raise
 
 ## begin gnulib module rawmemchr
 
 if gl_GNULIB_ENABLED_rawmemchr
-
+if GL_COND_OBJ_RAWMEMCHR
+libgnu_la_SOURCES += rawmemchr.c
 endif
-EXTRA_DIST += rawmemchr.c rawmemchr.valgrind
 
-EXTRA_libgnu_la_SOURCES += rawmemchr.c
+endif
+EXTRA_DIST += rawmemchr.valgrind
 
 ## end   gnulib module rawmemchr
 
 ## begin gnulib module read
 
-
-EXTRA_DIST += read.c
-
-EXTRA_libgnu_la_SOURCES += read.c
+if GL_COND_OBJ_READ
+libgnu_la_SOURCES += read.c
+endif
 
 ## end   gnulib module read
 
 ## begin gnulib module readlink
 
-
-EXTRA_DIST += readlink.c
-
-EXTRA_libgnu_la_SOURCES += readlink.c
+if GL_COND_OBJ_READLINK
+libgnu_la_SOURCES += readlink.c
+endif
 
 ## end   gnulib module readlink
 
@@ -2038,58 +2071,60 @@ EXTRA_libgnu_la_SOURCES += realloc.c
 
 ## begin gnulib module recv
 
+if GL_COND_OBJ_RECV
+libgnu_la_SOURCES += recv.c
+endif
 
-EXTRA_DIST += recv.c w32sock.h
-
-EXTRA_libgnu_la_SOURCES += recv.c
+EXTRA_DIST += w32sock.h
 
 ## end   gnulib module recv
 
 ## begin gnulib module recvfrom
 
+if GL_COND_OBJ_RECVFROM
+libgnu_la_SOURCES += recvfrom.c
+endif
 
-EXTRA_DIST += recvfrom.c w32sock.h
-
-EXTRA_libgnu_la_SOURCES += recvfrom.c
+EXTRA_DIST += w32sock.h
 
 ## end   gnulib module recvfrom
 
 ## begin gnulib module regex
 
+if GL_COND_OBJ_REGEX
+libgnu_la_SOURCES += regex.c
+endif
 
-EXTRA_DIST += regcomp.c regex.c regex.h regex_internal.c regex_internal.h regexec.c
+EXTRA_DIST += regcomp.c regex.h regex_internal.c regex_internal.h regexec.c
 
-EXTRA_libgnu_la_SOURCES += regcomp.c regex.c regex_internal.c regexec.c
+EXTRA_libgnu_la_SOURCES += regcomp.c regex_internal.c regexec.c
 
 ## end   gnulib module regex
 
 ## begin gnulib module rename
 
-
-EXTRA_DIST += rename.c
-
-EXTRA_libgnu_la_SOURCES += rename.c
+if GL_COND_OBJ_RENAME
+libgnu_la_SOURCES += rename.c
+endif
 
 ## end   gnulib module rename
 
 ## begin gnulib module rmdir
 
-
-EXTRA_DIST += rmdir.c
-
-EXTRA_libgnu_la_SOURCES += rmdir.c
+if GL_COND_OBJ_RMDIR
+libgnu_la_SOURCES += rmdir.c
+endif
 
 ## end   gnulib module rmdir
 
 ## begin gnulib module round
 
 if gl_GNULIB_ENABLED_round
-
+if GL_COND_OBJ_ROUND
+libgnu_la_SOURCES += round.c
 endif
-EXTRA_DIST += round.c
-
-EXTRA_libgnu_la_SOURCES += round.c
 
+endif
 ## end   gnulib module round
 
 ## begin gnulib module safe-read
@@ -2119,22 +2154,49 @@ EXTRA_DIST += same-inode.h
 
 ## end   gnulib module same-inode
 
+## begin gnulib module sched
+
+BUILT_SOURCES += sched.h
+
+# We need the following in order to create a replacement for <sched.h> when
+# the system doesn't have one.
+sched.h: sched.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H)
+	$(gl_V_at)$(SED_HEADER_STDOUT) \
+	      -e 's|@''GUARD_PREFIX''@|GL|g' \
+	      -e 's|@''HAVE_SCHED_H''@|$(HAVE_SCHED_H)|g' \
+	      -e 's|@''HAVE_SYS_CDEFS_H''@|$(HAVE_SYS_CDEFS_H)|g' \
+	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
+	      -e 's|@''NEXT_SCHED_H''@|$(NEXT_SCHED_H)|g' \
+	      -e 's|@''HAVE_STRUCT_SCHED_PARAM''@|$(HAVE_STRUCT_SCHED_PARAM)|g' \
+	      -e 's/@''GNULIB_SCHED_YIELD''@/$(GL_GNULIB_SCHED_YIELD)/g' \
+	      -e 's|@''HAVE_SCHED_YIELD''@|$(HAVE_SCHED_YIELD)|g' \
+	      -e 's|@''REPLACE_SCHED_YIELD''@|$(REPLACE_SCHED_YIELD)|g' \
+	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
+	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
+	      $(srcdir)/sched.in.h > $@-t
+	$(AM_V_at)mv $@-t $@
+MOSTLYCLEANFILES += sched.h sched.h-t
+
+EXTRA_DIST += sched.in.h
+
+## end   gnulib module sched
+
 ## begin gnulib module scratch_buffer
 
 if gl_GNULIB_ENABLED_scratch_buffer
 BUILT_SOURCES += malloc/scratch_buffer.gl.h
 
 malloc/scratch_buffer.gl.h: malloc/scratch_buffer.h
-	$(AM_V_at)$(MKDIR_P) malloc
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
-	  sed -e 's|__always_inline|inline _GL_ATTRIBUTE_ALWAYS_INLINE|g' \
+	$(AM_V_GEN)$(MKDIR_P) '%reldir%/malloc'
+	$(AM_V_at)$(SED_HEADER_STDOUT) \
+	      -e 's|__always_inline|inline _GL_ATTRIBUTE_ALWAYS_INLINE|g' \
 	      -e 's|__glibc_likely|_GL_LIKELY|g' \
 	      -e 's|__glibc_unlikely|_GL_UNLIKELY|g' \
 	      -e '/libc_hidden_proto/d' \
-	      < $(srcdir)/malloc/scratch_buffer.h; \
-	} > $@-t && \
-	mv $@-t $@
+	      $(srcdir)/malloc/scratch_buffer.h > $@-t
+	$(AM_V_at)mv $@-t $@
 MOSTLYCLEANFILES += malloc/scratch_buffer.gl.h malloc/scratch_buffer.gl.h-t
 
 libgnu_la_SOURCES += malloc/scratch_buffer_dupfree.c                 malloc/scratch_buffer_grow.c                 malloc/scratch_buffer_grow_preserve.c                 malloc/scratch_buffer_set_array_size.c
@@ -2146,37 +2208,37 @@ EXTRA_DIST += malloc/scratch_buffer.h scratch_buffer.h
 
 ## begin gnulib module select
 
-
-EXTRA_DIST += select.c
-
-EXTRA_libgnu_la_SOURCES += select.c
+if GL_COND_OBJ_SELECT
+libgnu_la_SOURCES += select.c
+endif
 
 ## end   gnulib module select
 
 ## begin gnulib module send
 
+if GL_COND_OBJ_SEND
+libgnu_la_SOURCES += send.c
+endif
 
-EXTRA_DIST += send.c w32sock.h
-
-EXTRA_libgnu_la_SOURCES += send.c
+EXTRA_DIST += w32sock.h
 
 ## end   gnulib module send
 
 ## begin gnulib module sendto
 
+if GL_COND_OBJ_SENDTO
+libgnu_la_SOURCES += sendto.c
+endif
 
-EXTRA_DIST += sendto.c w32sock.h
-
-EXTRA_libgnu_la_SOURCES += sendto.c
+EXTRA_DIST += w32sock.h
 
 ## end   gnulib module sendto
 
 ## begin gnulib module setenv
 
-
-EXTRA_DIST += setenv.c
-
-EXTRA_libgnu_la_SOURCES += setenv.c
+if GL_COND_OBJ_SETENV
+libgnu_la_SOURCES += setenv.c
+endif
 
 ## end   gnulib module setenv
 
@@ -2184,29 +2246,32 @@ EXTRA_libgnu_la_SOURCES += setenv.c
 
 if gl_GNULIB_ENABLED_e7e881d32ca02f1c997b13c737c64bbd
 libgnu_la_SOURCES += setlocale_null.c
-
+if GL_COND_OBJ_SETLOCALE_LOCK
+libgnu_la_SOURCES += setlocale-lock.c
 endif
-EXTRA_DIST += setlocale-lock.c setlocale_null.h windows-initguard.h
 
-EXTRA_libgnu_la_SOURCES += setlocale-lock.c
+endif
+EXTRA_DIST += setlocale_null.h windows-initguard.h
 
 ## end   gnulib module setlocale-null
 
 ## begin gnulib module setsockopt
 
+if GL_COND_OBJ_SETSOCKOPT
+libgnu_la_SOURCES += setsockopt.c
+endif
 
-EXTRA_DIST += setsockopt.c w32sock.h
-
-EXTRA_libgnu_la_SOURCES += setsockopt.c
+EXTRA_DIST += w32sock.h
 
 ## end   gnulib module setsockopt
 
 ## begin gnulib module shutdown
 
+if GL_COND_OBJ_SHUTDOWN
+libgnu_la_SOURCES += shutdown.c
+endif
 
-EXTRA_DIST += shutdown.c w32sock.h
-
-EXTRA_libgnu_la_SOURCES += shutdown.c
+EXTRA_DIST += w32sock.h
 
 ## end   gnulib module shutdown
 
@@ -2217,9 +2282,8 @@ BUILT_SOURCES += signal.h
 # We need the following in order to create <signal.h> when the system
 # doesn't have a complete one.
 signal.h: signal.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
-	  sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+	$(gl_V_at)$(SED_HEADER_STDOUT) \
+	      -e 's|@''GUARD_PREFIX''@|GL|g' \
 	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
 	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
 	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
@@ -2243,9 +2307,8 @@ signal.h: signal.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
 	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
 	      -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
 	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
-	      < $(srcdir)/signal.in.h; \
-	} > $@-t && \
-	mv $@-t $@
+	      $(srcdir)/signal.in.h > $@-t
+	$(AM_V_at)mv $@-t $@
 MOSTLYCLEANFILES += signal.h signal.h-t
 
 EXTRA_DIST += signal.in.h
@@ -2255,11 +2318,12 @@ EXTRA_DIST += signal.in.h
 ## begin gnulib module signbit
 
 if gl_GNULIB_ENABLED_signbit
-
+if GL_COND_OBJ_SIGNBIT3
+libgnu_la_SOURCES += signbitf.c signbitd.c signbitl.c
 endif
-EXTRA_DIST += float+.h signbitd.c signbitf.c signbitl.c
 
-EXTRA_libgnu_la_SOURCES += signbitd.c signbitf.c signbitl.c
+endif
+EXTRA_DIST += float+.h
 
 ## end   gnulib module signbit
 
@@ -2332,10 +2396,11 @@ EXTRA_libgnu_la_SOURCES += snprintf.c
 
 ## begin gnulib module socket
 
+if GL_COND_OBJ_SOCKET
+libgnu_la_SOURCES += socket.c
+endif
 
-EXTRA_DIST += socket.c w32sock.h
-
-EXTRA_libgnu_la_SOURCES += socket.c
+EXTRA_DIST += w32sock.h
 
 ## end   gnulib module socket
 
@@ -2349,14 +2414,76 @@ EXTRA_DIST += w32sock.h
 
 ## end   gnulib module sockets
 
+## begin gnulib module spawn
+
+BUILT_SOURCES += spawn.h
+
+# We need the following in order to create a replacement for <spawn.h> when
+# the system doesn't have one.
+spawn.h: spawn.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
+	$(gl_V_at)$(SED_HEADER_STDOUT) \
+	      -e 's|@''GUARD_PREFIX''@|GL|g' \
+	      -e 's|@''HAVE_SPAWN_H''@|$(HAVE_SPAWN_H)|g' \
+	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
+	      -e 's|@''NEXT_SPAWN_H''@|$(NEXT_SPAWN_H)|g' \
+	      -e 's/@''GNULIB_POSIX_SPAWN''@/$(GL_GNULIB_POSIX_SPAWN)/g' \
+	      -e 's/@''GNULIB_POSIX_SPAWNP''@/$(GL_GNULIB_POSIX_SPAWNP)/g' \
+	      -e 's/@''GNULIB_POSIX_SPAWN_FILE_ACTIONS_INIT''@/$(GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_INIT)/g' \
+	      -e 's/@''GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR''@/$(GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR)/g' \
+	      -e 's/@''GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE''@/$(GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE)/g' \
+	      -e 's/@''GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2''@/$(GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2)/g' \
+	      -e 's/@''GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR''@/$(GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR)/g' \
+	      -e 's/@''GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN''@/$(GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN)/g' \
+	      -e 's/@''GNULIB_POSIX_SPAWN_FILE_ACTIONS_DESTROY''@/$(GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_DESTROY)/g' \
+	      -e 's/@''GNULIB_POSIX_SPAWNATTR_INIT''@/$(GL_GNULIB_POSIX_SPAWNATTR_INIT)/g' \
+	      -e 's/@''GNULIB_POSIX_SPAWNATTR_GETFLAGS''@/$(GL_GNULIB_POSIX_SPAWNATTR_GETFLAGS)/g' \
+	      -e 's/@''GNULIB_POSIX_SPAWNATTR_SETFLAGS''@/$(GL_GNULIB_POSIX_SPAWNATTR_SETFLAGS)/g' \
+	      -e 's/@''GNULIB_POSIX_SPAWNATTR_GETPGROUP''@/$(GL_GNULIB_POSIX_SPAWNATTR_GETPGROUP)/g' \
+	      -e 's/@''GNULIB_POSIX_SPAWNATTR_SETPGROUP''@/$(GL_GNULIB_POSIX_SPAWNATTR_SETPGROUP)/g' \
+	      -e 's/@''GNULIB_POSIX_SPAWNATTR_GETSCHEDPARAM''@/$(GL_GNULIB_POSIX_SPAWNATTR_GETSCHEDPARAM)/g' \
+	      -e 's/@''GNULIB_POSIX_SPAWNATTR_SETSCHEDPARAM''@/$(GL_GNULIB_POSIX_SPAWNATTR_SETSCHEDPARAM)/g' \
+	      -e 's/@''GNULIB_POSIX_SPAWNATTR_GETSCHEDPOLICY''@/$(GL_GNULIB_POSIX_SPAWNATTR_GETSCHEDPOLICY)/g' \
+	      -e 's/@''GNULIB_POSIX_SPAWNATTR_SETSCHEDPOLICY''@/$(GL_GNULIB_POSIX_SPAWNATTR_SETSCHEDPOLICY)/g' \
+	      -e 's/@''GNULIB_POSIX_SPAWNATTR_GETSIGDEFAULT''@/$(GL_GNULIB_POSIX_SPAWNATTR_GETSIGDEFAULT)/g' \
+	      -e 's/@''GNULIB_POSIX_SPAWNATTR_SETSIGDEFAULT''@/$(GL_GNULIB_POSIX_SPAWNATTR_SETSIGDEFAULT)/g' \
+	      -e 's/@''GNULIB_POSIX_SPAWNATTR_GETSIGMASK''@/$(GL_GNULIB_POSIX_SPAWNATTR_GETSIGMASK)/g' \
+	      -e 's/@''GNULIB_POSIX_SPAWNATTR_SETSIGMASK''@/$(GL_GNULIB_POSIX_SPAWNATTR_SETSIGMASK)/g' \
+	      -e 's/@''GNULIB_POSIX_SPAWNATTR_DESTROY''@/$(GL_GNULIB_POSIX_SPAWNATTR_DESTROY)/g' \
+	      -e 's|@''HAVE_POSIX_SPAWN''@|$(HAVE_POSIX_SPAWN)|g' \
+	      -e 's|@''HAVE_POSIX_SPAWNATTR_T''@|$(HAVE_POSIX_SPAWNATTR_T)|g' \
+	      -e 's|@''HAVE_POSIX_SPAWN_FILE_ACTIONS_T''@|$(HAVE_POSIX_SPAWN_FILE_ACTIONS_T)|g' \
+	      -e 's|@''HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR''@|$(HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR)|g' \
+	      -e 's|@''HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR''@|$(HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR)|g' \
+	      -e 's|@''REPLACE_POSIX_SPAWN''@|$(REPLACE_POSIX_SPAWN)|g' \
+	      -e 's|@''REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR''@|$(REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR)|g' \
+	      -e 's|@''REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE''@|$(REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE)|g' \
+	      -e 's|@''REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2''@|$(REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2)|g' \
+	      -e 's|@''REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR''@|$(REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR)|g' \
+	      -e 's|@''REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN''@|$(REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN)|g' \
+	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
+	      -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
+	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
+	      $(srcdir)/spawn.in.h > $@-t
+	$(AM_V_at)mv $@-t $@
+MOSTLYCLEANFILES += spawn.h spawn.h-t
+
+EXTRA_DIST += spawn.in.h
+
+## end   gnulib module spawn
+
 ## begin gnulib module stat
 
 if gl_GNULIB_ENABLED_stat
+if GL_COND_OBJ_STAT
+libgnu_la_SOURCES += stat.c
+endif
 
 endif
-EXTRA_DIST += stat-w32.c stat-w32.h stat.c
+EXTRA_DIST += stat-w32.c stat-w32.h
 
-EXTRA_libgnu_la_SOURCES += stat-w32.c stat.c
+EXTRA_libgnu_la_SOURCES += stat-w32.c
 
 ## end   gnulib module stat
 
@@ -2376,11 +2503,8 @@ BUILT_SOURCES += $(STDALIGN_H)
 # doesn't have one that works.
 if GL_GENERATE_STDALIGN_H
 stdalign.h: stdalign.in.h $(top_builddir)/config.status
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
-	  cat $(srcdir)/stdalign.in.h; \
-	} > $@-t && \
-	mv $@-t $@
+	$(gl_V_at)$(SED_HEADER_TO_AT_t) $(srcdir)/stdalign.in.h
+	$(AM_V_at)mv $@-t $@
 else
 stdalign.h: $(top_builddir)/config.status
 	rm -f $@
@@ -2399,11 +2523,10 @@ BUILT_SOURCES += $(STDBOOL_H)
 # doesn't have one that works.
 if GL_GENERATE_STDBOOL_H
 stdbool.h: stdbool.in.h $(top_builddir)/config.status
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
-	  sed -e 's/@''HAVE__BOOL''@/$(HAVE__BOOL)/g' < $(srcdir)/stdbool.in.h; \
-	} > $@-t && \
-	mv $@-t $@
+	$(gl_V_at)$(SED_HEADER_STDOUT) \
+	  -e 's/@''HAVE__BOOL''@/$(HAVE__BOOL)/g' \
+	  $(srcdir)/stdbool.in.h > $@-t
+	$(AM_V_at)mv $@-t $@
 else
 stdbool.h: $(top_builddir)/config.status
 	rm -f $@
@@ -2414,6 +2537,27 @@ EXTRA_DIST += stdbool.in.h
 
 ## end   gnulib module stdbool
 
+## begin gnulib module stdckdint
+
+BUILT_SOURCES += $(STDCKDINT_H)
+
+# We need the following in order to create <stdckdint.h> when the system
+# doesn't have one that works with the given compiler.
+if GL_GENERATE_STDCKDINT_H
+stdckdint.h: stdckdint.in.h $(top_builddir)/config.status
+	$(gl_V_at)$(SED_HEADER_STDOUT) \
+	  $(srcdir)/stdckdint.in.h > $@-t
+	$(AM_V_at)mv $@-t $@
+else
+stdckdint.h: $(top_builddir)/config.status
+	rm -f $@
+endif
+MOSTLYCLEANFILES += stdckdint.h stdckdint.h-t
+
+EXTRA_DIST += intprops-internal.h stdckdint.in.h
+
+## end   gnulib module stdckdint
+
 ## begin gnulib module stddef
 
 BUILT_SOURCES += $(STDDEF_H)
@@ -2422,9 +2566,8 @@ BUILT_SOURCES += $(STDDEF_H)
 # doesn't have one that works with the given compiler.
 if GL_GENERATE_STDDEF_H
 stddef.h: stddef.in.h $(top_builddir)/config.status
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
-	  sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+	$(gl_V_at)$(SED_HEADER_STDOUT) \
+	      -e 's|@''GUARD_PREFIX''@|GL|g' \
 	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
 	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
 	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
@@ -2432,9 +2575,8 @@ stddef.h: stddef.in.h $(top_builddir)/config.status
 	      -e 's|@''HAVE_MAX_ALIGN_T''@|$(HAVE_MAX_ALIGN_T)|g' \
 	      -e 's|@''HAVE_WCHAR_T''@|$(HAVE_WCHAR_T)|g' \
 	      -e 's|@''REPLACE_NULL''@|$(REPLACE_NULL)|g' \
-	      < $(srcdir)/stddef.in.h; \
-	} > $@-t && \
-	mv $@-t $@
+	      $(srcdir)/stddef.in.h > $@-t
+	$(AM_V_at)mv $@-t $@
 else
 stddef.h: $(top_builddir)/config.status
 	rm -f $@
@@ -2453,9 +2595,8 @@ BUILT_SOURCES += $(STDINT_H)
 # doesn't have one that works with the given compiler.
 if GL_GENERATE_STDINT_H
 stdint.h: stdint.in.h $(top_builddir)/config.status
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
-	  sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+	$(gl_V_at)$(SED_HEADER_STDOUT) \
+	      -e 's|@''GUARD_PREFIX''@|GL|g' \
 	      -e 's/@''HAVE_STDINT_H''@/$(HAVE_STDINT_H)/g' \
 	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
 	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
@@ -2482,9 +2623,8 @@ stdint.h: stdint.in.h $(top_builddir)/config.status
 	      -e 's/@''HAVE_SIGNED_WINT_T''@/$(HAVE_SIGNED_WINT_T)/g' \
 	      -e 's/@''WINT_T_SUFFIX''@/$(WINT_T_SUFFIX)/g' \
 	      -e 's/@''GNULIBHEADERS_OVERRIDE_WINT_T''@/$(GNULIBHEADERS_OVERRIDE_WINT_T)/g' \
-	      < $(srcdir)/stdint.in.h; \
-	} > $@-t && \
-	mv $@-t $@
+	      $(srcdir)/stdint.in.h > $@-t
+	$(AM_V_at)mv $@-t $@
 else
 stdint.h: $(top_builddir)/config.status
 	rm -f $@
@@ -2502,9 +2642,8 @@ BUILT_SOURCES += stdio.h
 # We need the following in order to create <stdio.h> when the system
 # doesn't have one that works with the given compiler.
 stdio.h: stdio.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
-	  sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+	$(gl_V_at)$(SED_HEADER_STDOUT) \
+	      -e 's|@''GUARD_PREFIX''@|GL|g' \
 	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
 	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
 	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
@@ -2516,6 +2655,7 @@ stdio.h: stdio.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H)
 	      -e 's/@''GNULIB_FGETC''@/$(GL_GNULIB_FGETC)/g' \
 	      -e 's/@''GNULIB_FGETS''@/$(GL_GNULIB_FGETS)/g' \
 	      -e 's/@''GNULIB_FOPEN''@/$(GL_GNULIB_FOPEN)/g' \
+	      -e 's/@''GNULIB_FOPEN_GNU''@/$(GL_GNULIB_FOPEN_GNU)/g' \
 	      -e 's/@''GNULIB_FPRINTF''@/$(GL_GNULIB_FPRINTF)/g' \
 	      -e 's/@''GNULIB_FPRINTF_POSIX''@/$(GL_GNULIB_FPRINTF_POSIX)/g' \
 	      -e 's/@''GNULIB_FPURGE''@/$(GL_GNULIB_FPURGE)/g' \
@@ -2591,6 +2731,7 @@ stdio.h: stdio.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H)
 	      -e 's|@''REPLACE_FDOPEN''@|$(REPLACE_FDOPEN)|g' \
 	      -e 's|@''REPLACE_FFLUSH''@|$(REPLACE_FFLUSH)|g' \
 	      -e 's|@''REPLACE_FOPEN''@|$(REPLACE_FOPEN)|g' \
+	      -e 's|@''REPLACE_FOPEN_FOR_FOPEN_GNU''@|$(REPLACE_FOPEN_FOR_FOPEN_GNU)|g' \
 	      -e 's|@''REPLACE_FPRINTF''@|$(REPLACE_FPRINTF)|g' \
 	      -e 's|@''REPLACE_FPURGE''@|$(REPLACE_FPURGE)|g' \
 	      -e 's|@''REPLACE_FREOPEN''@|$(REPLACE_FREOPEN)|g' \
@@ -2621,11 +2762,18 @@ stdio.h: stdio.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H)
 	      -e 's|@''ASM_SYMBOL_PREFIX''@|$(ASM_SYMBOL_PREFIX)|g' \
 	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
 	      -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
-	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \
-	} > $@-t && \
-	mv $@-t $@
+	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
+	      > $@-t
+	$(AM_V_at)mv $@-t $@
 MOSTLYCLEANFILES += stdio.h stdio.h-t
 
+if GL_COND_OBJ_STDIO_READ
+libgnu_la_SOURCES += stdio-read.c
+endif
+if GL_COND_OBJ_STDIO_WRITE
+libgnu_la_SOURCES += stdio-write.c
+endif
+
 EXTRA_DIST += stdio.in.h
 
 ## end   gnulib module stdio
@@ -2638,9 +2786,8 @@ BUILT_SOURCES += stdlib.h
 # doesn't have one that works with the given compiler.
 stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \
   $(_NORETURN_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
-	  sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+	$(gl_V_at)$(SED_HEADER_STDOUT) \
+	      -e 's|@''GUARD_PREFIX''@|GL|g' \
 	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
 	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
 	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
@@ -2648,12 +2795,14 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \
 	      -e 's/@''GNULIB__EXIT''@/$(GL_GNULIB__EXIT)/g' \
 	      -e 's/@''GNULIB_ALIGNED_ALLOC''@/$(GL_GNULIB_ALIGNED_ALLOC)/g' \
 	      -e 's/@''GNULIB_ATOLL''@/$(GL_GNULIB_ATOLL)/g' \
+	      -e 's/@''GNULIB_CALLOC_GNU''@/$(GL_GNULIB_CALLOC_GNU)/g' \
 	      -e 's/@''GNULIB_CALLOC_POSIX''@/$(GL_GNULIB_CALLOC_POSIX)/g' \
 	      -e 's/@''GNULIB_CANONICALIZE_FILE_NAME''@/$(GL_GNULIB_CANONICALIZE_FILE_NAME)/g' \
 	      -e 's/@''GNULIB_FREE_POSIX''@/$(GL_GNULIB_FREE_POSIX)/g' \
 	      -e 's/@''GNULIB_GETLOADAVG''@/$(GL_GNULIB_GETLOADAVG)/g' \
 	      -e 's/@''GNULIB_GETSUBOPT''@/$(GL_GNULIB_GETSUBOPT)/g' \
 	      -e 's/@''GNULIB_GRANTPT''@/$(GL_GNULIB_GRANTPT)/g' \
+	      -e 's/@''GNULIB_MALLOC_GNU''@/$(GL_GNULIB_MALLOC_GNU)/g' \
 	      -e 's/@''GNULIB_MALLOC_POSIX''@/$(GL_GNULIB_MALLOC_POSIX)/g' \
 	      -e 's/@''GNULIB_MBTOWC''@/$(GL_GNULIB_MBTOWC)/g' \
 	      -e 's/@''GNULIB_MKDTEMP''@/$(GL_GNULIB_MKDTEMP)/g' \
@@ -2669,6 +2818,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \
 	      -e 's/@''GNULIB_QSORT_R''@/$(GL_GNULIB_QSORT_R)/g' \
 	      -e 's/@''GNULIB_RANDOM''@/$(GL_GNULIB_RANDOM)/g' \
 	      -e 's/@''GNULIB_RANDOM_R''@/$(GL_GNULIB_RANDOM_R)/g' \
+	      -e 's/@''GNULIB_REALLOC_GNU''@/$(GL_GNULIB_REALLOC_GNU)/g' \
 	      -e 's/@''GNULIB_REALLOC_POSIX''@/$(GL_GNULIB_REALLOC_POSIX)/g' \
 	      -e 's/@''GNULIB_REALLOCARRAY''@/$(GL_GNULIB_REALLOCARRAY)/g' \
 	      -e 's/@''GNULIB_REALPATH''@/$(GL_GNULIB_REALPATH)/g' \
@@ -2735,11 +2885,13 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \
 	      -e 's|@''HAVE_UNLOCKPT''@|$(HAVE_UNLOCKPT)|g' \
 	      -e 's|@''HAVE_DECL_UNSETENV''@|$(HAVE_DECL_UNSETENV)|g' \
 	      -e 's|@''REPLACE_ALIGNED_ALLOC''@|$(REPLACE_ALIGNED_ALLOC)|g' \
-	      -e 's|@''REPLACE_CALLOC''@|$(REPLACE_CALLOC)|g' \
+	      -e 's|@''REPLACE_CALLOC_FOR_CALLOC_GNU''@|$(REPLACE_CALLOC_FOR_CALLOC_GNU)|g' \
+	      -e 's|@''REPLACE_CALLOC_FOR_CALLOC_POSIX''@|$(REPLACE_CALLOC_FOR_CALLOC_POSIX)|g' \
 	      -e 's|@''REPLACE_CANONICALIZE_FILE_NAME''@|$(REPLACE_CANONICALIZE_FILE_NAME)|g' \
 	      -e 's|@''REPLACE_FREE''@|$(REPLACE_FREE)|g' \
 	      -e 's|@''REPLACE_INITSTATE''@|$(REPLACE_INITSTATE)|g' \
-	      -e 's|@''REPLACE_MALLOC''@|$(REPLACE_MALLOC)|g' \
+	      -e 's|@''REPLACE_MALLOC_FOR_MALLOC_GNU''@|$(REPLACE_MALLOC_FOR_MALLOC_GNU)|g' \
+	      -e 's|@''REPLACE_MALLOC_FOR_MALLOC_POSIX''@|$(REPLACE_MALLOC_FOR_MALLOC_POSIX)|g' \
 	      -e 's|@''REPLACE_MBTOWC''@|$(REPLACE_MBTOWC)|g' \
 	      -e 's|@''REPLACE_MKSTEMP''@|$(REPLACE_MKSTEMP)|g' \
 	      -e 's|@''REPLACE_POSIX_MEMALIGN''@|$(REPLACE_POSIX_MEMALIGN)|g' \
@@ -2749,7 +2901,8 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \
 	      -e 's|@''REPLACE_QSORT_R''@|$(REPLACE_QSORT_R)|g' \
 	      -e 's|@''REPLACE_RANDOM''@|$(REPLACE_RANDOM)|g' \
 	      -e 's|@''REPLACE_RANDOM_R''@|$(REPLACE_RANDOM_R)|g' \
-	      -e 's|@''REPLACE_REALLOC''@|$(REPLACE_REALLOC)|g' \
+	      -e 's|@''REPLACE_REALLOC_FOR_REALLOC_GNU''@|$(REPLACE_REALLOC_FOR_REALLOC_GNU)|g' \
+	      -e 's|@''REPLACE_REALLOC_FOR_REALLOC_POSIX''@|$(REPLACE_REALLOC_FOR_REALLOC_POSIX)|g' \
 	      -e 's|@''REPLACE_REALLOCARRAY''@|$(REPLACE_REALLOCARRAY)|g' \
 	      -e 's|@''REPLACE_REALPATH''@|$(REPLACE_REALPATH)|g' \
 	      -e 's|@''REPLACE_SETENV''@|$(REPLACE_SETENV)|g' \
@@ -2765,24 +2918,45 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \
 	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
 	      -e '/definition of _Noreturn/r $(_NORETURN_H)' \
 	      -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
-	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \
-	} > $@-t && \
-	mv $@-t $@
+	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
+	      > $@-t
+	$(AM_V_at)mv $@-t $@
 MOSTLYCLEANFILES += stdlib.h stdlib.h-t
 
 EXTRA_DIST += stdlib.in.h
 
 ## end   gnulib module stdlib
 
-## begin gnulib module strdup-posix
+## begin gnulib module stpcpy
 
-if gl_GNULIB_ENABLED_f9850631dca91859e9cddac9359921c0
+if gl_GNULIB_ENABLED_stpcpy
+if GL_COND_OBJ_STPCPY
+libgnu_la_SOURCES += stpcpy.c
+endif
 
 endif
-EXTRA_DIST += strdup.c
+## end   gnulib module stpcpy
 
-EXTRA_libgnu_la_SOURCES += strdup.c
+## begin gnulib module strchrnul
 
+if gl_GNULIB_ENABLED_strchrnul
+if GL_COND_OBJ_STRCHRNUL
+libgnu_la_SOURCES += strchrnul.c
+endif
+
+endif
+EXTRA_DIST += strchrnul.valgrind
+
+## end   gnulib module strchrnul
+
+## begin gnulib module strdup-posix
+
+if gl_GNULIB_ENABLED_f9850631dca91859e9cddac9359921c0
+if GL_COND_OBJ_STRDUP
+libgnu_la_SOURCES += strdup.c
+endif
+
+endif
 ## end   gnulib module strdup-posix
 
 ## begin gnulib module streq
@@ -2812,9 +2986,8 @@ BUILT_SOURCES += string.h
 # We need the following in order to create <string.h> when the system
 # doesn't have one that works with the given compiler.
 string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
-	  sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+	$(gl_V_at)$(SED_HEADER_STDOUT) \
+	      -e 's|@''GUARD_PREFIX''@|GL|g' \
 	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
 	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
 	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
@@ -2862,6 +3035,7 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
 	      -e 's/@''GNULIB_STRVERSCMP''@/$(GL_GNULIB_STRVERSCMP)/g' \
 	      -e 's/@''GNULIB_MDA_MEMCCPY''@/$(GL_GNULIB_MDA_MEMCCPY)/g' \
 	      -e 's/@''GNULIB_MDA_STRDUP''@/$(GL_GNULIB_MDA_STRDUP)/g' \
+	      -e 's/@''GNULIB_FREE_POSIX''@/$(GL_GNULIB_FREE_POSIX)/g' \
 	      < $(srcdir)/string.in.h | \
 	  sed -e 's|@''HAVE_EXPLICIT_BZERO''@|$(HAVE_EXPLICIT_BZERO)|g' \
 	      -e 's|@''HAVE_FFSL''@|$(HAVE_FFSL)|g' \
@@ -2890,6 +3064,7 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
 	      -e 's|@''REPLACE_FFSLL''@|$(REPLACE_FFSLL)|g' \
 	      -e 's|@''REPLACE_MEMCHR''@|$(REPLACE_MEMCHR)|g' \
 	      -e 's|@''REPLACE_MEMMEM''@|$(REPLACE_MEMMEM)|g' \
+	      -e 's|@''REPLACE_FREE''@|$(REPLACE_FREE)|g' \
 	      -e 's|@''REPLACE_STPNCPY''@|$(REPLACE_STPNCPY)|g' \
 	      -e 's|@''REPLACE_STRCHRNUL''@|$(REPLACE_STRCHRNUL)|g' \
 	      -e 's|@''REPLACE_STRDUP''@|$(REPLACE_STRDUP)|g' \
@@ -2906,10 +3081,9 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
 	      -e 's|@''UNDEFINE_STRTOK_R''@|$(UNDEFINE_STRTOK_R)|g' \
 	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
 	      -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
-	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \
-	      < $(srcdir)/string.in.h; \
-	} > $@-t && \
-	mv $@-t $@
+	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
+	      > $@-t
+	$(AM_V_at)mv $@-t $@
 MOSTLYCLEANFILES += string.h string.h-t
 
 EXTRA_DIST += string.in.h
@@ -2923,10 +3097,9 @@ BUILT_SOURCES += sys/file.h
 # We need the following in order to create <sys/file.h> when the system
 # has one that is incomplete.
 sys/file.h: sys_file.in.h $(top_builddir)/config.status $(WARN_ON_USE_H)
-	$(AM_V_at)$(MKDIR_P) sys
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
-	  sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+	$(AM_V_GEN)$(MKDIR_P) '%reldir%/sys'
+	$(AM_V_at)$(SED_HEADER_STDOUT) \
+	      -e 's|@''GUARD_PREFIX''@|GL|g' \
 	      -e 's/@''HAVE_SYS_FILE_H''@/$(HAVE_SYS_FILE_H)/g' \
 	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
 	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
@@ -2935,9 +3108,8 @@ sys/file.h: sys_file.in.h $(top_builddir)/config.status $(WARN_ON_USE_H)
 	      -e 's/@''HAVE_FLOCK''@/$(HAVE_FLOCK)/g' \
 	      -e 's/@''GNULIB_FLOCK''@/$(GL_GNULIB_FLOCK)/g' \
 	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
-	      < $(srcdir)/sys_file.in.h; \
-	} > $@-t && \
-	mv $@-t $@
+	      $(srcdir)/sys_file.in.h > $@-t
+	$(AM_V_at)mv $@-t $@
 MOSTLYCLEANFILES += sys/file.h sys/file.h-t
 MOSTLYCLEANDIRS += sys
 
@@ -2953,10 +3125,9 @@ BUILT_SOURCES += sys/random.h
 # We need the following in order to create <sys/random.h> when the system
 # doesn't have one.
 sys/random.h: sys_random.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
-	$(AM_V_at)$(MKDIR_P) sys
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
-	  sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+	$(AM_V_GEN)$(MKDIR_P) '%reldir%/sys'
+	$(AM_V_at)$(SED_HEADER_STDOUT) \
+	      -e 's|@''GUARD_PREFIX''@|GL|g' \
 	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
 	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
 	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
@@ -2968,9 +3139,8 @@ sys/random.h: sys_random.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_N
 	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
 	      -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
 	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
-	      < $(srcdir)/sys_random.in.h; \
-	} > $@-t && \
-	mv -f $@-t $@
+	      $(srcdir)/sys_random.in.h > $@-t
+	$(AM_V_at)mv $@-t $@
 MOSTLYCLEANFILES += sys/random.h sys/random.h-t
 MOSTLYCLEANDIRS += sys
 
@@ -2986,10 +3156,9 @@ BUILT_SOURCES += sys/select.h
 # We need the following in order to create <sys/select.h> when the system
 # doesn't have one that works with the given compiler.
 sys/select.h: sys_select.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H)
-	$(AM_V_at)$(MKDIR_P) sys
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
-	  sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+	$(AM_V_GEN)$(MKDIR_P) '%reldir%/sys'
+	$(AM_V_at)$(SED_HEADER_STDOUT) \
+	      -e 's|@''GUARD_PREFIX''@|GL|g' \
 	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
 	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
 	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
@@ -3003,9 +3172,8 @@ sys/select.h: sys_select.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_
 	      -e 's|@''REPLACE_SELECT''@|$(REPLACE_SELECT)|g' \
 	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
 	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
-	      < $(srcdir)/sys_select.in.h; \
-	} > $@-t && \
-	mv $@-t $@
+	      $(srcdir)/sys_select.in.h > $@-t
+	$(AM_V_at)mv $@-t $@
 MOSTLYCLEANFILES += sys/select.h sys/select.h-t
 MOSTLYCLEANDIRS += sys
 
@@ -3021,10 +3189,9 @@ libgnu_la_SOURCES += sys_socket.c
 # We need the following in order to create <sys/socket.h> when the system
 # doesn't have one that works with the given compiler.
 sys/socket.h: sys_socket.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H) $(ARG_NONNULL_H)
-	$(AM_V_at)$(MKDIR_P) sys
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
-	  sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+	$(AM_V_GEN)$(MKDIR_P) '%reldir%/sys'
+	$(AM_V_at)$(SED_HEADER_STDOUT) \
+	      -e 's|@''GUARD_PREFIX''@|GL|g' \
 	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
 	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
 	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
@@ -3055,9 +3222,8 @@ sys/socket.h: sys_socket.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_
 	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
 	      -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
 	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
-	      < $(srcdir)/sys_socket.in.h; \
-	} > $@-t && \
-	mv -f $@-t $@
+	      $(srcdir)/sys_socket.in.h > $@-t
+	$(AM_V_at)mv $@-t $@
 MOSTLYCLEANFILES += sys/socket.h sys/socket.h-t
 MOSTLYCLEANDIRS += sys
 
@@ -3072,16 +3238,16 @@ BUILT_SOURCES += sys/stat.h
 # We need the following in order to create <sys/stat.h> when the system
 # has one that is incomplete.
 sys/stat.h: sys_stat.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
-	$(AM_V_at)$(MKDIR_P) sys
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
-	  sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+	$(AM_V_GEN)$(MKDIR_P) '%reldir%/sys'
+	$(AM_V_at)$(SED_HEADER_STDOUT) \
+	      -e 's|@''GUARD_PREFIX''@|GL|g' \
 	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
 	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
 	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
 	      -e 's|@''NEXT_SYS_STAT_H''@|$(NEXT_SYS_STAT_H)|g' \
 	      -e 's|@''WINDOWS_64_BIT_ST_SIZE''@|$(WINDOWS_64_BIT_ST_SIZE)|g' \
 	      -e 's|@''WINDOWS_STAT_TIMESPEC''@|$(WINDOWS_STAT_TIMESPEC)|g' \
+	      -e 's/@''GNULIB_CHMOD''@/$(GL_GNULIB_CHMOD)/g' \
 	      -e 's/@''GNULIB_FCHMODAT''@/$(GL_GNULIB_FCHMODAT)/g' \
 	      -e 's/@''GNULIB_FSTAT''@/$(GL_GNULIB_FSTAT)/g' \
 	      -e 's/@''GNULIB_FSTATAT''@/$(GL_GNULIB_FSTATAT)/g' \
@@ -3113,6 +3279,7 @@ sys/stat.h: sys_stat.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNU
 	      -e 's|@''HAVE_MKNOD''@|$(HAVE_MKNOD)|g' \
 	      -e 's|@''HAVE_MKNODAT''@|$(HAVE_MKNODAT)|g' \
 	      -e 's|@''HAVE_UTIMENSAT''@|$(HAVE_UTIMENSAT)|g' \
+	      -e 's|@''REPLACE_CHMOD''@|$(REPLACE_CHMOD)|g' \
 	      -e 's|@''REPLACE_FCHMODAT''@|$(REPLACE_FCHMODAT)|g' \
 	      -e 's|@''REPLACE_FSTAT''@|$(REPLACE_FSTAT)|g' \
 	      -e 's|@''REPLACE_FSTATAT''@|$(REPLACE_FSTATAT)|g' \
@@ -3128,9 +3295,8 @@ sys/stat.h: sys_stat.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNU
 	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
 	      -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
 	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
-	      < $(srcdir)/sys_stat.in.h; \
-	} > $@-t && \
-	mv $@-t $@
+	      $(srcdir)/sys_stat.in.h > $@-t
+	$(AM_V_at)mv $@-t $@
 MOSTLYCLEANFILES += sys/stat.h sys/stat.h-t
 MOSTLYCLEANDIRS += sys
 
@@ -3145,10 +3311,9 @@ BUILT_SOURCES += sys/time.h
 # We need the following in order to create <sys/time.h> when the system
 # doesn't have one that works with the given compiler.
 sys/time.h: sys_time.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
-	$(AM_V_at)$(MKDIR_P) sys
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
-	  sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+	$(AM_V_GEN)$(MKDIR_P) '%reldir%/sys'
+	$(AM_V_at)$(SED_HEADER_STDOUT) \
+	      -e 's|@''GUARD_PREFIX''@|GL|g' \
 	      -e 's/@''HAVE_SYS_TIME_H''@/$(HAVE_SYS_TIME_H)/g' \
 	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
 	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
@@ -3163,9 +3328,8 @@ sys/time.h: sys_time.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNU
 	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
 	      -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
 	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
-	      < $(srcdir)/sys_time.in.h; \
-	} > $@-t && \
-	mv $@-t $@
+	      $(srcdir)/sys_time.in.h > $@-t
+	$(AM_V_at)mv $@-t $@
 MOSTLYCLEANFILES += sys/time.h sys/time.h-t
 
 EXTRA_DIST += sys_time.in.h
@@ -3179,10 +3343,9 @@ BUILT_SOURCES += sys/times.h
 # We need the following in order to create <sys/times.h> when the system
 # doesn't have one that works with the given compiler.
 sys/times.h: sys_times.in.h $(top_builddir)/config.status $(WARN_ON_USE_H) $(ARG_NONNULL_H)
-	$(AM_V_at)$(MKDIR_P) sys
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
-	  sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+	$(AM_V_GEN)$(MKDIR_P) '%reldir%/sys'
+	$(AM_V_at)$(SED_HEADER_STDOUT) \
+	      -e 's|@''GUARD_PREFIX''@|GL|g' \
 	      -e 's/@''HAVE_SYS_TIMES_H''@/$(HAVE_SYS_TIMES_H)/g' \
 	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
 	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
@@ -3193,9 +3356,8 @@ sys/times.h: sys_times.in.h $(top_builddir)/config.status $(WARN_ON_USE_H) $(ARG
 	      -e 's|@''HAVE_TIMES''@|$(HAVE_TIMES)|g' \
 	      -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
 	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
-	      < $(srcdir)/sys_times.in.h; \
-	} > $@-t && \
-	mv $@-t $@
+	      $(srcdir)/sys_times.in.h > $@-t
+	$(AM_V_at)mv $@-t $@
 MOSTLYCLEANFILES += sys/times.h sys/times.h-t
 MOSTLYCLEANDIRS += sys
 
@@ -3210,19 +3372,17 @@ BUILT_SOURCES += sys/types.h
 # We need the following in order to create <sys/types.h> when the system
 # doesn't have one that works with the given compiler.
 sys/types.h: sys_types.in.h $(top_builddir)/config.status
-	$(AM_V_at)$(MKDIR_P) sys
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
-	  sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+	$(AM_V_GEN)$(MKDIR_P) '%reldir%/sys'
+	$(AM_V_at)$(SED_HEADER_STDOUT) \
+	      -e 's|@''GUARD_PREFIX''@|GL|g' \
 	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
 	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
 	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
 	      -e 's|@''NEXT_SYS_TYPES_H''@|$(NEXT_SYS_TYPES_H)|g' \
 	      -e 's|@''WINDOWS_64_BIT_OFF_T''@|$(WINDOWS_64_BIT_OFF_T)|g' \
 	      -e 's|@''WINDOWS_STAT_INODES''@|$(WINDOWS_STAT_INODES)|g' \
-	      < $(srcdir)/sys_types.in.h; \
-	} > $@-t && \
-	mv $@-t $@
+	      $(srcdir)/sys_types.in.h > $@-t
+	$(AM_V_at)mv $@-t $@
 MOSTLYCLEANFILES += sys/types.h sys/types.h-t
 
 EXTRA_DIST += sys_types.in.h
@@ -3236,18 +3396,16 @@ BUILT_SOURCES += sys/uio.h
 # We need the following in order to create <sys/uio.h> when the system
 # doesn't have one that works with the given compiler.
 sys/uio.h: sys_uio.in.h $(top_builddir)/config.status
-	$(AM_V_at)$(MKDIR_P) sys
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
-	  sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+	$(AM_V_GEN)$(MKDIR_P) '%reldir%/sys'
+	$(AM_V_at)$(SED_HEADER_STDOUT) \
+	      -e 's|@''GUARD_PREFIX''@|GL|g' \
 	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
 	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
 	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
 	      -e 's|@''NEXT_SYS_UIO_H''@|$(NEXT_SYS_UIO_H)|g' \
 	      -e 's|@''HAVE_SYS_UIO_H''@|$(HAVE_SYS_UIO_H)|g' \
-	      < $(srcdir)/sys_uio.in.h; \
-	} > $@-t && \
-	mv -f $@-t $@
+	      $(srcdir)/sys_uio.in.h > $@-t
+	$(AM_V_at)mv $@-t $@
 MOSTLYCLEANFILES += sys/uio.h sys/uio.h-t
 MOSTLYCLEANDIRS += sys
 
@@ -3272,9 +3430,8 @@ BUILT_SOURCES += time.h
 # We need the following in order to create <time.h> when the system
 # doesn't have one that works with the given compiler.
 time.h: time.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
-	  sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+	$(gl_V_at)$(SED_HEADER_STDOUT) \
+	      -e 's|@''GUARD_PREFIX''@|GL|g' \
 	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
 	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
 	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
@@ -3287,6 +3444,7 @@ time.h: time.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(
 	      -e 's/@''GNULIB_STRPTIME''@/$(GL_GNULIB_STRPTIME)/g' \
 	      -e 's/@''GNULIB_TIMEGM''@/$(GL_GNULIB_TIMEGM)/g' \
 	      -e 's/@''GNULIB_TIMESPEC_GET''@/$(GL_GNULIB_TIMESPEC_GET)/g' \
+	      -e 's/@''GNULIB_TIMESPEC_GETRES''@/$(GL_GNULIB_TIMESPEC_GETRES)/g' \
 	      -e 's/@''GNULIB_TIME_R''@/$(GL_GNULIB_TIME_R)/g' \
 	      -e 's/@''GNULIB_TIME_RZ''@/$(GL_GNULIB_TIME_RZ)/g' \
 	      -e 's/@''GNULIB_TZSET''@/$(GL_GNULIB_TZSET)/g' \
@@ -3296,6 +3454,7 @@ time.h: time.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(
 	      -e 's|@''HAVE_STRPTIME''@|$(HAVE_STRPTIME)|g' \
 	      -e 's|@''HAVE_TIMEGM''@|$(HAVE_TIMEGM)|g' \
 	      -e 's|@''HAVE_TIMESPEC_GET''@|$(HAVE_TIMESPEC_GET)|g' \
+	      -e 's|@''HAVE_TIMESPEC_GETRES''@|$(HAVE_TIMESPEC_GETRES)|g' \
 	      -e 's|@''HAVE_TIMEZONE_T''@|$(HAVE_TIMEZONE_T)|g' \
 	      -e 's|@''REPLACE_CTIME''@|$(REPLACE_CTIME)|g' \
 	      -e 's|@''REPLACE_GMTIME''@|$(REPLACE_GMTIME)|g' \
@@ -3314,9 +3473,8 @@ time.h: time.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(
 	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
 	      -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
 	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
-	      < $(srcdir)/time.in.h; \
-	} > $@-t && \
-	mv $@-t $@
+	      $(srcdir)/time.in.h > $@-t
+	$(AM_V_at)mv $@-t $@
 MOSTLYCLEANFILES += time.h time.h-t
 
 EXTRA_DIST += time.in.h
@@ -3326,61 +3484,59 @@ EXTRA_DIST += time.in.h
 ## begin gnulib module time_r
 
 if gl_GNULIB_ENABLED_time_r
-
+if GL_COND_OBJ_TIME_R
+libgnu_la_SOURCES += time_r.c
 endif
-EXTRA_DIST += time_r.c
-
-EXTRA_libgnu_la_SOURCES += time_r.c
 
+endif
 ## end   gnulib module time_r
 
 ## begin gnulib module time_rz
 
+if GL_COND_OBJ_TIME_RZ
+libgnu_la_SOURCES += time_rz.c
+endif
 
-EXTRA_DIST += time-internal.h time_rz.c
-
-EXTRA_libgnu_la_SOURCES += time_rz.c
+EXTRA_DIST += time-internal.h
 
 ## end   gnulib module time_rz
 
 ## begin gnulib module timegm
 
 if gl_GNULIB_ENABLED_timegm
-
+if GL_COND_OBJ_TIMEGM
+libgnu_la_SOURCES += timegm.c
 endif
-EXTRA_DIST += mktime-internal.h timegm.c
 
-EXTRA_libgnu_la_SOURCES += timegm.c
+endif
+EXTRA_DIST += mktime-internal.h
 
 ## end   gnulib module timegm
 
 ## begin gnulib module times
 
-
-EXTRA_DIST += times.c
-
-EXTRA_libgnu_la_SOURCES += times.c
+if GL_COND_OBJ_TIMES
+libgnu_la_SOURCES += times.c
+endif
 
 ## end   gnulib module times
 
 ## begin gnulib module trunc
 
-
-EXTRA_DIST += trunc.c
-
-EXTRA_libgnu_la_SOURCES += trunc.c
+if GL_COND_OBJ_TRUNC
+libgnu_la_SOURCES += trunc.c
+endif
 
 ## end   gnulib module trunc
 
 ## begin gnulib module tzset
 
 if gl_GNULIB_ENABLED_tzset
-
+if GL_COND_OBJ_TZSET
+libgnu_la_SOURCES += tzset.c
 endif
-EXTRA_DIST += tzset.c
-
-EXTRA_libgnu_la_SOURCES += tzset.c
 
+endif
 ## end   gnulib module tzset
 
 ## begin gnulib module unistd
@@ -3391,9 +3547,8 @@ libgnu_la_SOURCES += unistd.c
 # We need the following in order to create an empty placeholder for
 # <unistd.h> when the system doesn't have one.
 unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
-	  sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+	$(gl_V_at)$(SED_HEADER_STDOUT) \
+	      -e 's|@''GUARD_PREFIX''@|GL|g' \
 	      -e 's|@''HAVE_UNISTD_H''@|$(HAVE_UNISTD_H)|g' \
 	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
 	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
@@ -3434,6 +3589,7 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
 	      -e 's/@''GNULIB_GETOPT_POSIX''@/$(GL_GNULIB_GETOPT_POSIX)/g' \
 	      -e 's/@''GNULIB_GETPAGESIZE''@/$(GL_GNULIB_GETPAGESIZE)/g' \
 	      -e 's/@''GNULIB_GETPASS''@/$(GL_GNULIB_GETPASS)/g' \
+	      -e 's/@''GNULIB_GETPASS_GNU''@/$(GL_GNULIB_GETPASS_GNU)/g' \
 	      -e 's/@''GNULIB_GETUSERSHELL''@/$(GL_GNULIB_GETUSERSHELL)/g' \
 	      -e 's/@''GNULIB_GROUP_MEMBER''@/$(GL_GNULIB_GROUP_MEMBER)/g' \
 	      -e 's/@''GNULIB_ISATTY''@/$(GL_GNULIB_ISATTY)/g' \
@@ -3535,6 +3691,7 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
 	  sed -e 's|@''REPLACE_ACCESS''@|$(REPLACE_ACCESS)|g' \
 	      -e 's|@''REPLACE_CHOWN''@|$(REPLACE_CHOWN)|g' \
 	      -e 's|@''REPLACE_CLOSE''@|$(REPLACE_CLOSE)|g' \
+	      -e 's|@''REPLACE_COPY_FILE_RANGE''@|$(REPLACE_COPY_FILE_RANGE)|g' \
 	      -e 's|@''REPLACE_DUP''@|$(REPLACE_DUP)|g' \
 	      -e 's|@''REPLACE_DUP2''@|$(REPLACE_DUP2)|g' \
 	      -e 's|@''REPLACE_EXECL''@|$(REPLACE_EXECL)|g' \
@@ -3554,6 +3711,7 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
 	      -e 's|@''REPLACE_GETGROUPS''@|$(REPLACE_GETGROUPS)|g' \
 	      -e 's|@''REPLACE_GETPAGESIZE''@|$(REPLACE_GETPAGESIZE)|g' \
 	      -e 's|@''REPLACE_GETPASS''@|$(REPLACE_GETPASS)|g' \
+	      -e 's|@''REPLACE_GETPASS_FOR_GETPASS_GNU''@|$(REPLACE_GETPASS_FOR_GETPASS_GNU)|g' \
 	      -e 's|@''REPLACE_ISATTY''@|$(REPLACE_ISATTY)|g' \
 	      -e 's|@''REPLACE_LCHOWN''@|$(REPLACE_LCHOWN)|g' \
 	      -e 's|@''REPLACE_LINK''@|$(REPLACE_LINK)|g' \
@@ -3579,9 +3737,9 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
 	      -e 's|@''UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS''@|$(UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS)|g' \
 	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
 	      -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
-	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \
-	} > $@-t && \
-	mv $@-t $@
+	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
+	      > $@-t
+	$(AM_V_at)mv $@-t $@
 MOSTLYCLEANFILES += unistd.h unistd.h-t
 
 EXTRA_DIST += unistd.in.h
@@ -3591,12 +3749,11 @@ EXTRA_DIST += unistd.in.h
 ## begin gnulib module unsetenv
 
 if gl_GNULIB_ENABLED_unsetenv
-
+if GL_COND_OBJ_UNSETENV
+libgnu_la_SOURCES += unsetenv.c
 endif
-EXTRA_DIST += unsetenv.c
-
-EXTRA_libgnu_la_SOURCES += unsetenv.c
 
+endif
 ## end   gnulib module unsetenv
 
 ## begin gnulib module useless-if-before-free
@@ -3647,9 +3804,8 @@ BUILT_SOURCES += wchar.h
 # We need the following in order to create <wchar.h> when the system
 # version does not work standalone.
 wchar.h: wchar.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
-	  sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+	$(gl_V_at)$(SED_HEADER_STDOUT) \
+	      -e 's|@''GUARD_PREFIX''@|GL|g' \
 	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
 	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
 	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
@@ -3700,6 +3856,7 @@ wchar.h: wchar.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H)
 	      -e 's/@''GNULIB_WCSWIDTH''@/$(GL_GNULIB_WCSWIDTH)/g' \
 	      -e 's/@''GNULIB_WCSFTIME''@/$(GL_GNULIB_WCSFTIME)/g' \
 	      -e 's/@''GNULIB_MDA_WCSDUP''@/$(GL_GNULIB_MDA_WCSDUP)/g' \
+	      -e 's/@''GNULIB_FREE_POSIX''@/$(GL_GNULIB_FREE_POSIX)/g' \
 	      < $(srcdir)/wchar.in.h | \
 	  sed -e 's|@''HAVE_WINT_T''@|$(HAVE_WINT_T)|g' \
 	      -e 's|@''HAVE_BTOWC''@|$(HAVE_BTOWC)|g' \
@@ -3748,6 +3905,7 @@ wchar.h: wchar.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H)
 	  sed -e 's|@''REPLACE_MBSTATE_T''@|$(REPLACE_MBSTATE_T)|g' \
 	      -e 's|@''REPLACE_BTOWC''@|$(REPLACE_BTOWC)|g' \
 	      -e 's|@''REPLACE_WCTOB''@|$(REPLACE_WCTOB)|g' \
+	      -e 's|@''REPLACE_FREE''@|$(REPLACE_FREE)|g' \
 	      -e 's|@''REPLACE_MBSINIT''@|$(REPLACE_MBSINIT)|g' \
 	      -e 's|@''REPLACE_MBRTOWC''@|$(REPLACE_MBRTOWC)|g' \
 	      -e 's|@''REPLACE_MBRLEN''@|$(REPLACE_MBRLEN)|g' \
@@ -3762,9 +3920,9 @@ wchar.h: wchar.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H)
 	      -e 's|@''REPLACE_WCSTOK''@|$(REPLACE_WCSTOK)|g' \
 	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
 	      -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
-	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \
-	} > $@-t && \
-	mv $@-t $@
+	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
+	      > $@-t
+	$(AM_V_at)mv $@-t $@
 MOSTLYCLEANFILES += wchar.h wchar.h-t
 
 EXTRA_DIST += wchar.in.h
@@ -3774,12 +3932,11 @@ EXTRA_DIST += wchar.in.h
 ## begin gnulib module wcrtomb
 
 if gl_GNULIB_ENABLED_wcrtomb
-
+if GL_COND_OBJ_WCRTOMB
+libgnu_la_SOURCES += wcrtomb.c
 endif
-EXTRA_DIST += wcrtomb.c
-
-EXTRA_libgnu_la_SOURCES += wcrtomb.c
 
+endif
 ## end   gnulib module wcrtomb
 
 ## begin gnulib module wctype-h
@@ -3791,9 +3948,8 @@ libgnu_la_SOURCES += wctype-h.c
 # We need the following in order to create <wctype.h> when the system
 # doesn't have one that works with the given compiler.
 wctype.h: wctype.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H)
-	$(AM_V_GEN)rm -f $@-t $@ && \
-	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
-	  sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+	$(gl_V_at)$(SED_HEADER_STDOUT) \
+	      -e 's|@''GUARD_PREFIX''@|GL|g' \
 	      -e 's/@''HAVE_WCTYPE_H''@/$(HAVE_WCTYPE_H)/g' \
 	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
 	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
@@ -3820,9 +3976,8 @@ wctype.h: wctype.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H
 	      -e 's/@''REPLACE_TOWLOWER''@/$(REPLACE_TOWLOWER)/g' \
 	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
 	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
-	      < $(srcdir)/wctype.in.h; \
-	} > $@-t && \
-	mv $@-t $@
+	      $(srcdir)/wctype.in.h > $@-t
+	$(AM_V_at)mv $@-t $@
 MOSTLYCLEANFILES += wctype.h wctype.h-t
 
 endif
@@ -3830,12 +3985,23 @@ EXTRA_DIST += wctype.in.h
 
 ## end   gnulib module wctype-h
 
-## begin gnulib module write
+## begin gnulib module windows-spawn
 
+if gl_GNULIB_ENABLED_fd43d02c899a251eacc999baf40b238e
+if GL_COND_OBJ_WINDOWS_SPAWN
+libgnu_la_SOURCES += windows-spawn.c
+endif
 
-EXTRA_DIST += write.c
+endif
+EXTRA_DIST += windows-spawn.h
 
-EXTRA_libgnu_la_SOURCES += write.c
+## end   gnulib module windows-spawn
+
+## begin gnulib module write
+
+if GL_COND_OBJ_WRITE
+libgnu_la_SOURCES += write.c
+endif
 
 ## end   gnulib module write
 
@@ -3862,3 +4028,7 @@ mostlyclean-local: mostlyclean-generic
 	  fi; \
 	done; \
 	:
+distclean-local: distclean-gnulib-libobjs
+distclean-gnulib-libobjs:
+	-rm -f @gl_LIBOBJDEPS@
+maintainer-clean-local: distclean-gnulib-libobjs
diff --git a/lib/_Noreturn.h b/lib/_Noreturn.h
index 6fed3c797..e914627a8 100644
--- a/lib/_Noreturn.h
+++ b/lib/_Noreturn.h
@@ -1,5 +1,5 @@
 /* A C macro for declaring that a function does not return.
-   Copyright (C) 2011-2021 Free Software Foundation, Inc.
+   Copyright (C) 2011-2022 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify it
    under the terms of the GNU Lesser General Public License as published
diff --git a/lib/accept.c b/lib/accept.c
index 71457dbf6..5c4d1f352 100644
--- a/lib/accept.c
+++ b/lib/accept.c
@@ -1,6 +1,6 @@
 /* accept.c --- wrappers for Windows accept function
 
-   Copyright (C) 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2008-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/accept4.c b/lib/accept4.c
index 4c2b80e50..61ab6c77c 100644
--- a/lib/accept4.c
+++ b/lib/accept4.c
@@ -1,9 +1,9 @@
 /* Accept a connection on a socket, with specific opening flags.
-   Copyright (C) 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2009-2022 Free Software Foundation, Inc.
 
    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 3 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/access.c b/lib/access.c
new file mode 100644
index 000000000..e39c158ec
--- /dev/null
+++ b/lib/access.c
@@ -0,0 +1,31 @@
+/* Test the access rights of a file.
+   Copyright (C) 2019-2022 Free Software Foundation, Inc.
+
+   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 2.1 of the
+   License, or (at your option) any later version.
+
+   This file 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include <unistd.h>
+
+#include <fcntl.h>
+#include <io.h>
+
+int
+access (const char *file, int mode)
+{
+  if ((mode & X_OK) != 0)
+    mode = (mode & ~X_OK) | R_OK;
+  return _access (file, mode);
+}
diff --git a/lib/alignof.h b/lib/alignof.h
index e6e7a51b2..3f4a54257 100644
--- a/lib/alignof.h
+++ b/lib/alignof.h
@@ -1,5 +1,5 @@
 /* Determine alignment of types.
-   Copyright (C) 2003-2004, 2006, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2003-2004, 2006, 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/alloca.c b/lib/alloca.c
index 48802832a..5eb16a9ff 100644
--- a/lib/alloca.c
+++ b/lib/alloca.c
@@ -30,17 +30,6 @@
 #include <string.h>
 #include <stdlib.h>
 
-#ifdef emacs
-# include "lisp.h"
-# include "blockinput.h"
-# ifdef EMACS_FREE
-#  undef free
-#  define free EMACS_FREE
-# endif
-#else
-# define memory_full() abort ()
-#endif
-
 /* If compiling with GCC or clang, this file is not needed.  */
 #if !(defined __GNUC__ || defined __clang__)
 
@@ -48,22 +37,6 @@
    there must be some other way alloca is supposed to work.  */
 # ifndef alloca
 
-#  ifdef emacs
-#   ifdef static
-/* actually, only want this if static is defined as ""
-   -- this is for usg, in which emacs must undefine static
-   in order to make unexec workable
-   */
-#    ifndef STACK_DIRECTION
-you
-lose
--- must know STACK_DIRECTION at compile-time
-/* Using #error here is not wise since this file should work for
-   old and obscure compilers.  */
-#    endif /* STACK_DIRECTION undefined */
-#   endif /* static */
-#  endif /* emacs */
-
 /* Define STACK_DIRECTION if you know the direction of stack
    growth for your system; otherwise it will be automatically
    deduced at run-time.
@@ -145,10 +118,6 @@ alloca (size_t size)
   {
     register header *hp;        /* Traverses linked list.  */
 
-#  ifdef emacs
-    BLOCK_INPUT;
-#  endif
-
     for (hp = last_alloca_header; hp != NULL;)
       if ((STACK_DIR > 0 && hp->h.deep > depth)
           || (STACK_DIR < 0 && hp->h.deep < depth))
@@ -163,10 +132,6 @@ alloca (size_t size)
         break;                  /* Rest are not deeper.  */
 
     last_alloca_header = hp;    /* -> last valid storage.  */
-
-#  ifdef emacs
-    UNBLOCK_INPUT;
-#  endif
   }
 
   if (size == 0)
diff --git a/lib/alloca.in.h b/lib/alloca.in.h
index 65c2d4d93..e2b146138 100644
--- a/lib/alloca.in.h
+++ b/lib/alloca.in.h
@@ -1,6 +1,6 @@
 /* Memory allocation on the stack.
 
-   Copyright (C) 1995, 1999, 2001-2004, 2006-2021 Free Software Foundation,
+   Copyright (C) 1995, 1999, 2001-2004, 2006-2022 Free Software Foundation,
    Inc.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/arg-nonnull.h b/lib/arg-nonnull.h
index b4de241e9..e4513efe9 100644
--- a/lib/arg-nonnull.h
+++ b/lib/arg-nonnull.h
@@ -1,5 +1,5 @@
 /* A C macro for declaring that specific arguments must not be NULL.
-   Copyright (C) 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2009-2022 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify it
    under the terms of the GNU Lesser General Public License as published
diff --git a/lib/arpa_inet.in.h b/lib/arpa_inet.in.h
index 9968067aa..f5d7db2df 100644
--- a/lib/arpa_inet.in.h
+++ b/lib/arpa_inet.in.h
@@ -1,6 +1,6 @@
 /* A GNU-like <arpa/inet.h>.
 
-   Copyright (C) 2005-2006, 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2005-2006, 2008-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/asnprintf.c b/lib/asnprintf.c
index c5367b281..0c5c76ea5 100644
--- a/lib/asnprintf.c
+++ b/lib/asnprintf.c
@@ -1,5 +1,5 @@
 /* Formatted output to strings.
-   Copyright (C) 1999, 2002, 2006, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2002, 2006, 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/assure.h b/lib/assure.h
index 49aa82fec..20e806aa4 100644
--- a/lib/assure.h
+++ b/lib/assure.h
@@ -1,6 +1,6 @@
 /* Run-time assert-like macros.
 
-   Copyright (C) 2014-2021 Free Software Foundation, Inc.
+   Copyright (C) 2014-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/attribute.h b/lib/attribute.h
index 80a23f550..378d4f0a8 100644
--- a/lib/attribute.h
+++ b/lib/attribute.h
@@ -1,6 +1,6 @@
 /* ATTRIBUTE_* macros for using attributes in GCC and similar compilers
 
-   Copyright 2020-2021 Free Software Foundation, Inc.
+   Copyright 2020-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
@@ -76,6 +76,14 @@
 /* Applies to: function, pointer to function, function types.  */
 #define ATTRIBUTE_ALLOC_SIZE(args) _GL_ATTRIBUTE_ALLOC_SIZE (args)
 
+/* ATTRIBUTE_DEALLOC (F, I) declares that the function returns pointers
+   that can be freed by passing them as the Ith argument to the
+   function F.
+   ATTRIBUTE_DEALLOC_FREE declares that the function returns pointers that
+   can be freed via 'free'; it can be used only after declaring 'free'.  */
+/* Applies to: functions.  Cannot be used on inline functions.  */
+#define ATTRIBUTE_DEALLOC(f, i) _GL_ATTRIBUTE_DEALLOC(f, i)
+#define ATTRIBUTE_DEALLOC_FREE _GL_ATTRIBUTE_DEALLOC_FREE
 
 /* Attributes for variadic functions.  */
 
diff --git a/lib/basename-lgpl.c b/lib/basename-lgpl.c
index 5dbd15708..eb07e2541 100644
--- a/lib/basename-lgpl.c
+++ b/lib/basename-lgpl.c
@@ -1,6 +1,6 @@
 /* basename.c -- return the last element in a file name
 
-   Copyright (C) 1990, 1998-2001, 2003-2006, 2009-2021 Free Software
+   Copyright (C) 1990, 1998-2001, 2003-2006, 2009-2022 Free Software
    Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/basename-lgpl.h b/lib/basename-lgpl.h
index d520c0930..5569f2193 100644
--- a/lib/basename-lgpl.h
+++ b/lib/basename-lgpl.h
@@ -1,6 +1,6 @@
 /* Extract the last component (base name) of a file name.
 
-   Copyright (C) 1998, 2001, 2003-2006, 2009-2021 Free Software Foundation,
+   Copyright (C) 1998, 2001, 2003-2006, 2009-2022 Free Software Foundation,
    Inc.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/binary-io.c b/lib/binary-io.c
index adc0ae2b0..ea407fd74 100644
--- a/lib/binary-io.c
+++ b/lib/binary-io.c
@@ -1,5 +1,5 @@
 /* Binary mode I/O.
-   Copyright 2017-2021 Free Software Foundation, Inc.
+   Copyright 2017-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/binary-io.h b/lib/binary-io.h
index 0fa8d546f..5b7661e23 100644
--- a/lib/binary-io.h
+++ b/lib/binary-io.h
@@ -1,5 +1,5 @@
 /* Binary mode I/O.
-   Copyright (C) 2001, 2003, 2005, 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2003, 2005, 2008-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
@@ -47,7 +47,7 @@ _GL_INLINE_HEADER_BEGIN
   /* Use a function rather than a macro, to avoid gcc warnings
      "warning: statement with no effect".  */
 BINARY_IO_INLINE int
-__gl_setmode (int fd _GL_UNUSED, int mode _GL_UNUSED)
+__gl_setmode (_GL_UNUSED int fd, _GL_UNUSED int mode)
 {
   return O_BINARY;
 }
diff --git a/lib/bind.c b/lib/bind.c
index 0e4725446..199e0ba99 100644
--- a/lib/bind.c
+++ b/lib/bind.c
@@ -1,6 +1,6 @@
 /* bind.c --- wrappers for Windows bind function
 
-   Copyright (C) 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2008-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/btowc.c b/lib/btowc.c
index b8239afae..4af58bb02 100644
--- a/lib/btowc.c
+++ b/lib/btowc.c
@@ -1,5 +1,5 @@
 /* Convert unibyte character to wide character.
-   Copyright (C) 2008, 2010-2021 Free Software Foundation, Inc.
+   Copyright (C) 2008, 2010-2022 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2008.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/byteswap.in.h b/lib/byteswap.in.h
index 113f87802..f4746d399 100644
--- a/lib/byteswap.in.h
+++ b/lib/byteswap.in.h
@@ -1,5 +1,5 @@
 /* byteswap.h - Byte swapping
-   Copyright (C) 2005, 2007, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2005, 2007, 2009-2022 Free Software Foundation, Inc.
    Written by Oskar Liljeblad <oskar@osk.mine.nu>, 2005.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/c++defs.h b/lib/c++defs.h
index a47b61a00..ad181558f 100644
--- a/lib/c++defs.h
+++ b/lib/c++defs.h
@@ -1,5 +1,5 @@
 /* C++ compatible function declaration macros.
-   Copyright (C) 2010-2021 Free Software Foundation, Inc.
+   Copyright (C) 2010-2022 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify it
    under the terms of the GNU Lesser General Public License as published
diff --git a/lib/c-ctype.c b/lib/c-ctype.c
index 300f97c29..a247514cd 100644
--- a/lib/c-ctype.c
+++ b/lib/c-ctype.c
@@ -1,6 +1,6 @@
 /* Character handling in C locale.
 
-   Copyright (C) 2003-2021 Free Software Foundation, Inc.
+   Copyright (C) 2003-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/c-ctype.h b/lib/c-ctype.h
index 3a652ac1f..1a4f60389 100644
--- a/lib/c-ctype.h
+++ b/lib/c-ctype.h
@@ -5,7 +5,7 @@
    <ctype.h> functions' behaviour depends on the current locale set via
    setlocale.
 
-   Copyright (C) 2000-2003, 2006, 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2000-2003, 2006, 2008-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/c-strcase.h b/lib/c-strcase.h
index 82f99bb06..3e874b5ea 100644
--- a/lib/c-strcase.h
+++ b/lib/c-strcase.h
@@ -1,5 +1,5 @@
 /* Case-insensitive string comparison functions in C locale.
-   Copyright (C) 1995-1996, 2001, 2003, 2005, 2009-2021 Free Software
+   Copyright (C) 1995-1996, 2001, 2003, 2005, 2009-2022 Free Software
    Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/c-strcasecmp.c b/lib/c-strcasecmp.c
index 3c2245508..87b993cb2 100644
--- a/lib/c-strcasecmp.c
+++ b/lib/c-strcasecmp.c
@@ -1,5 +1,5 @@
 /* c-strcasecmp.c -- case insensitive string comparator in C locale
-   Copyright (C) 1998-1999, 2005-2006, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 1998-1999, 2005-2006, 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/c-strcaseeq.h b/lib/c-strcaseeq.h
index 66b9cf3c1..1c4607cc9 100644
--- a/lib/c-strcaseeq.h
+++ b/lib/c-strcaseeq.h
@@ -1,5 +1,5 @@
 /* Optimized case-insensitive string comparison in C locale.
-   Copyright (C) 2001-2002, 2007, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2001-2002, 2007, 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/c-strncasecmp.c b/lib/c-strncasecmp.c
index f3ca786cb..5a5d30b6e 100644
--- a/lib/c-strncasecmp.c
+++ b/lib/c-strncasecmp.c
@@ -1,5 +1,5 @@
 /* c-strncasecmp.c -- case insensitive string comparator in C locale
-   Copyright (C) 1998-1999, 2005-2006, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 1998-1999, 2005-2006, 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/canonicalize-lgpl.c b/lib/canonicalize-lgpl.c
index 92e963972..a7fa7feb6 100644
--- a/lib/canonicalize-lgpl.c
+++ b/lib/canonicalize-lgpl.c
@@ -1,5 +1,5 @@
 /* Return the canonical absolute name of a given file.
-   Copyright (C) 1996-2021 Free Software Foundation, Inc.
+   Copyright (C) 1996-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
diff --git a/lib/cdefs.h b/lib/cdefs.h
index 4dac9d264..7b8ed5b34 100644
--- a/lib/cdefs.h
+++ b/lib/cdefs.h
@@ -1,4 +1,5 @@
-/* Copyright (C) 1992-2021 Free Software Foundation, Inc.
+/* Copyright (C) 1992-2022 Free Software Foundation, Inc.
+   Copyright The GNU Toolchain Authors.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -40,7 +41,9 @@
    Similarly for __has_builtin, etc.  */
 #if (defined __has_attribute \
      && (!defined __clang_minor__ \
-         || 3 < __clang_major__ + (5 <= __clang_minor__)))
+         || (defined __apple_build_version__ \
+             ? 6000000 <= __apple_build_version__ \
+             : 3 < __clang_major__ + (5 <= __clang_minor__))))
 # define __glibc_has_attribute(attr) __has_attribute (attr)
 #else
 # define __glibc_has_attribute(attr) 0
@@ -142,7 +145,8 @@
 #define __bos0(ptr) __builtin_object_size (ptr, 0)
 
 /* Use __builtin_dynamic_object_size at _FORTIFY_SOURCE=3 when available.  */
-#if __USE_FORTIFY_LEVEL == 3 && __glibc_clang_prereq (9, 0)
+#if __USE_FORTIFY_LEVEL == 3 && (__glibc_clang_prereq (9, 0)		      \
+				 || __GNUC_PREREQ (12, 0))
 # define __glibc_objsize0(__o) __builtin_dynamic_object_size (__o, 0)
 # define __glibc_objsize(__o) __builtin_dynamic_object_size (__o, 1)
 #else
@@ -150,6 +154,53 @@
 # define __glibc_objsize(__o) __bos (__o)
 #endif
 
+/* Compile time conditions to choose between the regular, _chk and _chk_warn
+   variants.  These conditions should get evaluated to constant and optimized
+   away.  */
+
+#define __glibc_safe_len_cond(__l, __s, __osz) ((__l) <= (__osz) / (__s))
+#define __glibc_unsigned_or_positive(__l) \
+  ((__typeof (__l)) 0 < (__typeof (__l)) -1				      \
+   || (__builtin_constant_p (__l) && (__l) > 0))
+
+/* Length is known to be safe at compile time if the __L * __S <= __OBJSZ
+   condition can be folded to a constant and if it is true, or unknown (-1) */
+#define __glibc_safe_or_unknown_len(__l, __s, __osz) \
+  ((__osz) == (__SIZE_TYPE__) -1					      \
+   || (__glibc_unsigned_or_positive (__l)				      \
+       && __builtin_constant_p (__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), \
+						       (__s), (__osz)))	      \
+       && __glibc_safe_len_cond ((__SIZE_TYPE__) (__l), (__s), (__osz))))
+
+/* Conversely, we know at compile time that the length is unsafe if the
+   __L * __S <= __OBJSZ condition can be folded to a constant and if it is
+   false.  */
+#define __glibc_unsafe_len(__l, __s, __osz) \
+  (__glibc_unsigned_or_positive (__l)					      \
+   && __builtin_constant_p (__glibc_safe_len_cond ((__SIZE_TYPE__) (__l),     \
+						   __s, __osz))		      \
+   && !__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), __s, __osz))
+
+/* Fortify function f.  __f_alias, __f_chk and __f_chk_warn must be
+   declared.  */
+
+#define __glibc_fortify(f, __l, __s, __osz, ...) \
+  (__glibc_safe_or_unknown_len (__l, __s, __osz)			      \
+   ? __ ## f ## _alias (__VA_ARGS__)					      \
+   : (__glibc_unsafe_len (__l, __s, __osz)				      \
+      ? __ ## f ## _chk_warn (__VA_ARGS__, __osz)			      \
+      : __ ## f ## _chk (__VA_ARGS__, __osz)))			      \
+
+/* Fortify function f, where object size argument passed to f is the number of
+   elements and not total size.  */
+
+#define __glibc_fortify_n(f, __l, __s, __osz, ...) \
+  (__glibc_safe_or_unknown_len (__l, __s, __osz)			      \
+   ? __ ## f ## _alias (__VA_ARGS__)					      \
+   : (__glibc_unsafe_len (__l, __s, __osz)				      \
+      ? __ ## f ## _chk_warn (__VA_ARGS__, (__osz) / (__s))		      \
+      : __ ## f ## _chk (__VA_ARGS__, (__osz) / (__s))))		      \
+
 #if __GNUC_PREREQ (4,3)
 # define __warnattr(msg) __attribute__((__warning__ (msg)))
 # define __errordecl(name, msg) \
@@ -243,6 +294,15 @@
 # define __attribute_alloc_size__(params) /* Ignore.  */
 #endif
 
+/* Tell the compiler which argument to an allocation function
+   indicates the alignment of the allocation.  */
+#if __GNUC_PREREQ (4, 9) || __glibc_has_attribute (__alloc_align__)
+# define __attribute_alloc_align__(param) \
+  __attribute__ ((__alloc_align__ param))
+#else
+# define __attribute_alloc_align__(param) /* Ignore.  */
+#endif
+
 /* At some point during the gcc 2.96 development the `pure' attribute
    for functions was introduced.  We don't want to use it unconditionally
    (although this would be possible) since it generates warnings.  */
@@ -605,12 +665,22 @@ _Static_assert (0, "IEEE 128-bits long double requires redirection on this platf
    size-index is not provided:
      access (access-mode, <ref-index> [, <size-index>])  */
 #  define __attr_access(x) __attribute__ ((__access__ x))
+/* For _FORTIFY_SOURCE == 3 we use __builtin_dynamic_object_size, which may
+   use the access attribute to get object sizes from function definition
+   arguments, so we can't use them on functions we fortify.  Drop the object
+   size hints for such functions.  */
+#  if __USE_FORTIFY_LEVEL == 3
+#    define __fortified_attr_access(a, o, s) __attribute__ ((__access__ (a, o)))
+#  else
+#    define __fortified_attr_access(a, o, s) __attr_access ((a, o, s))
+#  endif
 #  if __GNUC_PREREQ (11, 0)
 #    define __attr_access_none(argno) __attribute__ ((__access__ (__none__, argno)))
 #  else
 #    define __attr_access_none(argno)
 #  endif
 #else
+#  define __fortified_attr_access(a, o, s)
 #  define __attr_access(x)
 #  define __attr_access_none(argno)
 #endif
diff --git a/lib/ceil.c b/lib/ceil.c
index fce05d986..4ab192a54 100644
--- a/lib/ceil.c
+++ b/lib/ceil.c
@@ -1,9 +1,9 @@
 /* Round towards positive infinity.
-   Copyright (C) 2007, 2010-2021 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2010-2022 Free Software Foundation, Inc.
 
    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 3 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/cloexec.c b/lib/cloexec.c
index 7defa9344..812be01a0 100644
--- a/lib/cloexec.c
+++ b/lib/cloexec.c
@@ -1,6 +1,6 @@
 /* cloexec.c - set or clear the close-on-exec descriptor flag
 
-   Copyright (C) 1991, 2004-2006, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 1991, 2004-2006, 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/cloexec.h b/lib/cloexec.h
index 97a3659ef..7a22d7753 100644
--- a/lib/cloexec.h
+++ b/lib/cloexec.h
@@ -1,6 +1,6 @@
 /* cloexec.c - set or clear the close-on-exec descriptor flag
 
-   Copyright (C) 2004, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/close.c b/lib/close.c
index 5b9ab6c9f..44990ba71 100644
--- a/lib/close.c
+++ b/lib/close.c
@@ -1,5 +1,5 @@
 /* close replacement.
-   Copyright (C) 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2008-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/concat-filename.c b/lib/concat-filename.c
new file mode 100644
index 000000000..f05484904
--- /dev/null
+++ b/lib/concat-filename.c
@@ -0,0 +1,73 @@
+/* Construct a full filename from a directory and a relative filename.
+   Copyright (C) 2001-2004, 2006-2022 Free Software Foundation, Inc.
+
+   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 2.1 of the
+   License, or (at your option) any later version.
+
+   This file 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+/* Written by Bruno Haible <haible@clisp.cons.org>.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include "concat-filename.h"
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "filename.h"
+
+/* Concatenate a directory filename, a relative filename and an optional
+   suffix.  The directory may end with the directory separator.  The second
+   argument may not start with the directory separator (it is relative).
+   Return a freshly allocated filename.  Return NULL and set errno
+   upon memory allocation failure.  */
+char *
+concatenated_filename (const char *directory, const char *filename,
+                       const char *suffix)
+{
+  char *result;
+  char *p;
+
+  if (strcmp (directory, ".") == 0)
+    {
+      /* No need to prepend the directory.  */
+      result = (char *) malloc (strlen (filename)
+                                + (suffix != NULL ? strlen (suffix) : 0)
+                                + 1);
+      if (result == NULL)
+        return NULL; /* errno is set here */
+      p = result;
+    }
+  else
+    {
+      size_t directory_len = strlen (directory);
+      int need_slash =
+        (directory_len > FILE_SYSTEM_PREFIX_LEN (directory)
+         && !ISSLASH (directory[directory_len - 1]));
+      result = (char *) malloc (directory_len + need_slash
+                                + strlen (filename)
+                                + (suffix != NULL ? strlen (suffix) : 0)
+                                + 1);
+      if (result == NULL)
+        return NULL; /* errno is set here */
+      memcpy (result, directory, directory_len);
+      p = result + directory_len;
+      if (need_slash)
+        *p++ = '/';
+    }
+  p = stpcpy (p, filename);
+  if (suffix != NULL)
+    stpcpy (p, suffix);
+  return result;
+}
diff --git a/lib/concat-filename.h b/lib/concat-filename.h
new file mode 100644
index 000000000..0348b0d93
--- /dev/null
+++ b/lib/concat-filename.h
@@ -0,0 +1,46 @@
+/* Construct a full filename from a directory and a relative filename.
+   Copyright (C) 2001-2004, 2007-2022 Free Software Foundation, Inc.
+
+   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 2.1 of the
+   License, or (at your option) any later version.
+
+   This file 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+#ifndef _CONCAT_FILENAME_H
+#define _CONCAT_FILENAME_H
+
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Concatenate a directory filename, a relative filename and an optional
+   suffix.  Return a freshly allocated filename.  Return NULL and set errno
+   upon memory allocation failure.  */
+extern char *concatenated_filename (const char *directory,
+                                    const char *filename, const char *suffix)
+  _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE;
+
+/* Concatenate a directory filename, a relative filename and an optional
+   suffix.  Return a freshly allocated filename.  */
+extern char *xconcatenated_filename (const char *directory,
+                                     const char *filename, const char *suffix)
+  _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE
+  _GL_ATTRIBUTE_RETURNS_NONNULL;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CONCAT_FILENAME_H */
diff --git a/lib/connect.c b/lib/connect.c
index b2b2e9334..d1600634e 100644
--- a/lib/connect.c
+++ b/lib/connect.c
@@ -1,6 +1,6 @@
 /* connect.c --- wrappers for Windows connect function
 
-   Copyright (C) 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2008-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/copysign.c b/lib/copysign.c
index fee131be1..613346574 100644
--- a/lib/copysign.c
+++ b/lib/copysign.c
@@ -1,9 +1,9 @@
 /* Copy sign into another 'double' number.
-   Copyright (C) 2011-2021 Free Software Foundation, Inc.
+   Copyright (C) 2011-2022 Free Software Foundation, Inc.
 
    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 3 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/dirent.in.h b/lib/dirent.in.h
index 5775edf09..f28288d1a 100644
--- a/lib/dirent.in.h
+++ b/lib/dirent.in.h
@@ -1,5 +1,5 @@
 /* A GNU-like <dirent.h>.
-   Copyright (C) 2006-2021 Free Software Foundation, Inc.
+   Copyright (C) 2006-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
@@ -55,6 +55,28 @@ typedef struct gl_directory DIR;
 # endif
 #endif
 
+/* _GL_ATTRIBUTE_DEALLOC (F, I) declares that the function returns pointers
+   that can be freed by passing them as the Ith argument to the
+   function F.  */
+#ifndef _GL_ATTRIBUTE_DEALLOC
+# if __GNUC__ >= 11
+#  define _GL_ATTRIBUTE_DEALLOC(f, i) __attribute__ ((__malloc__ (f, i)))
+# else
+#  define _GL_ATTRIBUTE_DEALLOC(f, i)
+# endif
+#endif
+
+/* _GL_ATTRIBUTE_MALLOC declares that the function returns a pointer to freshly
+   allocated memory.  */
+/* Applies to: functions.  */
+#ifndef _GL_ATTRIBUTE_MALLOC
+# if __GNUC__ >= 3 || defined __clang__
+#  define _GL_ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
+# else
+#  define _GL_ATTRIBUTE_MALLOC
+# endif
+#endif
+
 /* The __attribute__ feature is available in gcc versions 2.5 and later.
    The attribute __pure__ was added in gcc 2.96.  */
 #ifndef _GL_ATTRIBUTE_PURE
diff --git a/lib/dirfd.c b/lib/dirfd.c
index 640cb4ff1..4104683fb 100644
--- a/lib/dirfd.c
+++ b/lib/dirfd.c
@@ -1,6 +1,6 @@
 /* dirfd.c -- return the file descriptor associated with an open DIR*
 
-   Copyright (C) 2001, 2006, 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2006, 2008-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/dirname-lgpl.c b/lib/dirname-lgpl.c
index 95f9c9919..d54f6a910 100644
--- a/lib/dirname-lgpl.c
+++ b/lib/dirname-lgpl.c
@@ -1,6 +1,6 @@
 /* dirname.c -- return all but the last element in a file name
 
-   Copyright (C) 1990, 1998, 2000-2001, 2003-2006, 2009-2021 Free Software
+   Copyright (C) 1990, 1998, 2000-2001, 2003-2006, 2009-2022 Free Software
    Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/dirname.h b/lib/dirname.h
index 25abc7b7e..e18a97ea1 100644
--- a/lib/dirname.h
+++ b/lib/dirname.h
@@ -1,6 +1,6 @@
 /* Take file names apart into directory and base names.
 
-   Copyright (C) 1998, 2001, 2003-2006, 2009-2021 Free Software Foundation,
+   Copyright (C) 1998, 2001, 2003-2006, 2009-2022 Free Software Foundation,
    Inc.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/dup2.c b/lib/dup2.c
index 53e555213..1c766ab38 100644
--- a/lib/dup2.c
+++ b/lib/dup2.c
@@ -1,6 +1,6 @@
 /* Duplicate an open file descriptor to a specified file descriptor.
 
-   Copyright (C) 1999, 2004-2007, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2004-2007, 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/duplocale.c b/lib/duplocale.c
index bc8740d4f..0ecd989cd 100644
--- a/lib/duplocale.c
+++ b/lib/duplocale.c
@@ -1,9 +1,9 @@
 /* Duplicate a locale object.
-   Copyright (C) 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2009-2022 Free Software Foundation, Inc.
 
    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 3 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/dynarray.h b/lib/dynarray.h
index ec64273b3..ca6439d3a 100644
--- a/lib/dynarray.h
+++ b/lib/dynarray.h
@@ -1,5 +1,5 @@
 /* Type-safe arrays which grow dynamically.
-   Copyright 2021 Free Software Foundation, Inc.
+   Copyright 2021-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/eloop-threshold.h b/lib/eloop-threshold.h
index fcd30ab1e..8b3145711 100644
--- a/lib/eloop-threshold.h
+++ b/lib/eloop-threshold.h
@@ -1,5 +1,5 @@
 /* Threshold at which to diagnose ELOOP.  Generic version.
-   Copyright (C) 2012-2021 Free Software Foundation, Inc.
+   Copyright (C) 2012-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
diff --git a/lib/errno.in.h b/lib/errno.in.h
index 3cad9e2d6..3ec184569 100644
--- a/lib/errno.in.h
+++ b/lib/errno.in.h
@@ -1,6 +1,6 @@
 /* A POSIX-like <errno.h>.
 
-   Copyright (C) 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2008-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/fcntl.c b/lib/fcntl.c
index c744eb91e..f9753c403 100644
--- a/lib/fcntl.c
+++ b/lib/fcntl.c
@@ -1,6 +1,6 @@
 /* Provide file descriptor control.
 
-   Copyright (C) 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/fcntl.in.h b/lib/fcntl.in.h
index 26dedc304..9270ced89 100644
--- a/lib/fcntl.in.h
+++ b/lib/fcntl.in.h
@@ -1,6 +1,6 @@
 /* Like <fcntl.h>, but with non-working flags defined to 0.
 
-   Copyright (C) 2006-2021 Free Software Foundation, Inc.
+   Copyright (C) 2006-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
@@ -435,6 +435,10 @@ _GL_WARN_ON_USE (openat, "openat is not portable - "
 # define AT_EACCESS 4
 #endif
 
+/* Ignore this flag if not supported.  */
+#ifndef AT_NO_AUTOMOUNT
+# define AT_NO_AUTOMOUNT 0
+#endif
 
 #endif /* _@GUARD_PREFIX@_FCNTL_H */
 #endif /* _@GUARD_PREFIX@_FCNTL_H */
diff --git a/lib/fd-hook.c b/lib/fd-hook.c
index 75b1626de..64a7a80c0 100644
--- a/lib/fd-hook.c
+++ b/lib/fd-hook.c
@@ -1,5 +1,5 @@
 /* Hook for making file descriptor functions close(), ioctl() extensible.
-   Copyright (C) 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2009-2022 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2009.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/fd-hook.h b/lib/fd-hook.h
index 98e2a5263..d6c4964d1 100644
--- a/lib/fd-hook.h
+++ b/lib/fd-hook.h
@@ -1,5 +1,5 @@
 /* Hook for making file descriptor functions close(), ioctl() extensible.
-   Copyright (C) 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/filename.h b/lib/filename.h
index dafe3dfdd..ab77ca2df 100644
--- a/lib/filename.h
+++ b/lib/filename.h
@@ -1,5 +1,5 @@
 /* Basic filename support macros.
-   Copyright (C) 2001-2004, 2007-2021 Free Software Foundation, Inc.
+   Copyright (C) 2001-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
diff --git a/lib/findprog-in.c b/lib/findprog-in.c
new file mode 100644
index 000000000..72a05dbf5
--- /dev/null
+++ b/lib/findprog-in.c
@@ -0,0 +1,399 @@
+/* Locating a program in a given path.
+   Copyright (C) 2001-2004, 2006-2022 Free Software Foundation, Inc.
+   Written by Bruno Haible <haible@clisp.cons.org>, 2001, 2019.
+
+   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 2.1 of the
+   License, or (at your option) any later version.
+
+   This file 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+
+#include <config.h>
+
+/* Specification.  */
+#include "findprog.h"
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+#include "filename.h"
+#include "concat-filename.h"
+
+#if (defined _WIN32 && !defined __CYGWIN__) || defined __EMX__ || defined __DJGPP__
+  /* Native Windows, OS/2, DOS */
+# define NATIVE_SLASH '\\'
+#else
+  /* Unix */
+# define NATIVE_SLASH '/'
+#endif
+
+/* Separator in PATH like lists of pathnames.  */
+#if (defined _WIN32 && !defined __CYGWIN__) || defined __EMX__ || defined __DJGPP__
+  /* Native Windows, OS/2, DOS */
+# define PATH_SEPARATOR ';'
+#else
+  /* Unix */
+# define PATH_SEPARATOR ':'
+#endif
+
+/* The list of suffixes that the execlp/execvp function tries when searching
+   for the program.  */
+static const char * const suffixes[] =
+  {
+    #if defined _WIN32 && !defined __CYGWIN__ /* Native Windows */
+    "", ".com", ".exe", ".bat", ".cmd"
+    /* Note: Files without any suffix are not considered executable.  */
+    /* Note: The cmd.exe program does a different lookup: It searches according
+       to the PATHEXT environment variable.
+       See <https://stackoverflow.com/questions/7839150/>.
+       Also, it executes files ending in .bat and .cmd directly without letting
+       the kernel interpret the program file.  */
+    #elif defined __CYGWIN__
+    "", ".exe", ".com"
+    #elif defined __EMX__
+    "", ".exe"
+    #elif defined __DJGPP__
+    "", ".com", ".exe", ".bat"
+    #else /* Unix */
+    ""
+    #endif
+  };
+
+const char *
+find_in_given_path (const char *progname, const char *path,
+                    const char *directory, bool optimize_for_exec)
+{
+  {
+    bool has_slash = false;
+    {
+      const char *p;
+
+      for (p = progname; *p != '\0'; p++)
+        if (ISSLASH (*p))
+          {
+            has_slash = true;
+            break;
+          }
+    }
+    if (has_slash)
+      {
+        /* If progname contains a slash, it is either absolute or relative to
+           the current directory.  PATH is not used.  */
+        if (optimize_for_exec)
+          /* The execl/execv/execlp/execvp functions will try the various
+             suffixes anyway and fail if no executable is found.  */
+          return progname;
+        else
+          {
+            /* Try the various suffixes and see whether one of the files
+               with such a suffix is actually executable.  */
+            int failure_errno;
+            size_t i;
+
+            const char *directory_as_prefix =
+              (directory != NULL && IS_RELATIVE_FILE_NAME (progname)
+               ? directory
+               : "");
+
+            #if defined _WIN32 && !defined __CYGWIN__ /* Native Windows */
+            const char *progbasename;
+
+            {
+              const char *p;
+
+              progbasename = progname;
+              for (p = progname; *p != '\0'; p++)
+                if (ISSLASH (*p))
+                  progbasename = p + 1;
+            }
+
+            bool progbasename_has_dot = (strchr (progbasename, '.') != NULL);
+            #endif
+
+            /* Try all platform-dependent suffixes.  */
+            failure_errno = ENOENT;
+            for (i = 0; i < sizeof (suffixes) / sizeof (suffixes[0]); i++)
+              {
+                const char *suffix = suffixes[i];
+
+                #if defined _WIN32 && !defined __CYGWIN__ /* Native Windows */
+                /* File names without a '.' are not considered executable, and
+                   for file names with a '.' no additional suffix is tried.  */
+                if ((*suffix != '\0') != progbasename_has_dot)
+                #endif
+                  {
+                    /* Concatenate directory_as_prefix, progname, suffix.  */
+                    char *progpathname =
+                      concatenated_filename (directory_as_prefix, progname,
+                                             suffix);
+
+                    if (progpathname == NULL)
+                      return NULL; /* errno is set here */
+
+                    /* On systems which have the eaccess() system call, let's
+                       use it.  On other systems, let's hope that this program
+                       is not installed setuid or setgid, so that it is ok to
+                       call access() despite its design flaw.  */
+                    if (eaccess (progpathname, X_OK) == 0)
+                      {
+                        /* Check that the progpathname does not point to a
+                           directory.  */
+                        struct stat statbuf;
+
+                        if (stat (progpathname, &statbuf) >= 0)
+                          {
+                            if (! S_ISDIR (statbuf.st_mode))
+                              {
+                                /* Found!  */
+                                if (strcmp (progpathname, progname) == 0)
+                                  {
+                                    free (progpathname);
+                                    return progname;
+                                  }
+                                else
+                                  return progpathname;
+                              }
+
+                            errno = EACCES;
+                          }
+                      }
+
+                    if (errno != ENOENT)
+                      failure_errno = errno;
+
+                    free (progpathname);
+                  }
+              }
+            #if defined _WIN32 && !defined __CYGWIN__ /* Native Windows */
+            if (failure_errno == ENOENT && !progbasename_has_dot)
+              {
+                /* In the loop above, we skipped suffix = "".  Do this loop
+                   round now, merely to provide a better errno than ENOENT.  */
+
+                char *progpathname =
+                  concatenated_filename (directory_as_prefix, progname, "");
+
+                if (progpathname == NULL)
+                  return NULL; /* errno is set here */
+
+                if (eaccess (progpathname, X_OK) == 0)
+                  {
+                    struct stat statbuf;
+
+                    if (stat (progpathname, &statbuf) >= 0)
+                      {
+                        if (! S_ISDIR (statbuf.st_mode))
+                          errno = ENOEXEC;
+                        else
+                          errno = EACCES;
+                      }
+                  }
+
+                failure_errno = errno;
+
+                free (progpathname);
+              }
+            #endif
+
+            errno = failure_errno;
+            return NULL;
+          }
+      }
+  }
+
+  if (path == NULL)
+    /* If PATH is not set, the default search path is implementation dependent.
+       In practice, it is treated like an empty PATH.  */
+    path = "";
+
+  {
+    /* Make a copy, to prepare for destructive modifications.  */
+    char *path_copy = strdup (path);
+    if (path_copy == NULL)
+      return NULL; /* errno is set here */
+
+    int failure_errno;
+    char *path_rest;
+    char *cp;
+
+    #if defined _WIN32 && !defined __CYGWIN__ /* Native Windows */
+    bool progname_has_dot = (strchr (progname, '.') != NULL);
+    #endif
+
+    failure_errno = ENOENT;
+    for (path_rest = path_copy; ; path_rest = cp + 1)
+      {
+        const char *dir;
+        bool last;
+        char *dir_as_prefix_to_free;
+        const char *dir_as_prefix;
+        size_t i;
+
+        /* Extract next directory in PATH.  */
+        dir = path_rest;
+        for (cp = path_rest; *cp != '\0' && *cp != PATH_SEPARATOR; cp++)
+          ;
+        last = (*cp == '\0');
+        *cp = '\0';
+
+        /* Empty PATH components designate the current directory.  */
+        if (dir == cp)
+          dir = ".";
+
+        /* Concatenate directory and dir.  */
+        if (directory != NULL && IS_RELATIVE_FILE_NAME (dir))
+          {
+            dir_as_prefix_to_free =
+              concatenated_filename (directory, dir, NULL);
+            if (dir_as_prefix_to_free == NULL)
+              {
+                /* errno is set here.  */
+                failure_errno = errno;
+                goto failed;
+              }
+            dir_as_prefix = dir_as_prefix_to_free;
+          }
+        else
+          {
+            dir_as_prefix_to_free = NULL;
+            dir_as_prefix = dir;
+          }
+
+        /* Try all platform-dependent suffixes.  */
+        for (i = 0; i < sizeof (suffixes) / sizeof (suffixes[0]); i++)
+          {
+            const char *suffix = suffixes[i];
+
+            #if defined _WIN32 && !defined __CYGWIN__ /* Native Windows */
+            /* File names without a '.' are not considered executable, and
+               for file names with a '.' no additional suffix is tried.  */
+            if ((*suffix != '\0') != progname_has_dot)
+            #endif
+              {
+                /* Concatenate dir_as_prefix, progname, and suffix.  */
+                char *progpathname =
+                  concatenated_filename (dir_as_prefix, progname, suffix);
+
+                if (progpathname == NULL)
+                  {
+                    /* errno is set here.  */
+                    failure_errno = errno;
+                    free (dir_as_prefix_to_free);
+                    goto failed;
+                  }
+
+                /* On systems which have the eaccess() system call, let's
+                   use it.  On other systems, let's hope that this program
+                   is not installed setuid or setgid, so that it is ok to
+                   call access() despite its design flaw.  */
+                if (eaccess (progpathname, X_OK) == 0)
+                  {
+                    /* Check that the progpathname does not point to a
+                       directory.  */
+                    struct stat statbuf;
+
+                    if (stat (progpathname, &statbuf) >= 0)
+                      {
+                        if (! S_ISDIR (statbuf.st_mode))
+                          {
+                            /* Found!  */
+                            if (strcmp (progpathname, progname) == 0)
+                              {
+                                free (progpathname);
+
+                                /* Add the "./" prefix for real, that
+                                   concatenated_filename() optimized away.
+                                   This avoids a second PATH search when the
+                                   caller uses execl/execv/execlp/execvp.  */
+                                progpathname =
+                                  (char *) malloc (2 + strlen (progname) + 1);
+                                if (progpathname == NULL)
+                                  {
+                                    /* errno is set here.  */
+                                    failure_errno = errno;
+                                    free (dir_as_prefix_to_free);
+                                    goto failed;
+                                  }
+                                progpathname[0] = '.';
+                                progpathname[1] = NATIVE_SLASH;
+                                memcpy (progpathname + 2, progname,
+                                        strlen (progname) + 1);
+                              }
+
+                            free (dir_as_prefix_to_free);
+                            free (path_copy);
+                            return progpathname;
+                          }
+
+                        errno = EACCES;
+                      }
+                  }
+
+                if (errno != ENOENT)
+                  failure_errno = errno;
+
+                free (progpathname);
+              }
+          }
+        #if defined _WIN32 && !defined __CYGWIN__ /* Native Windows */
+        if (failure_errno == ENOENT && !progname_has_dot)
+          {
+            /* In the loop above, we skipped suffix = "".  Do this loop
+               round now, merely to provide a better errno than ENOENT.  */
+
+            char *progpathname =
+              concatenated_filename (dir_as_prefix, progname, "");
+
+            if (progpathname == NULL)
+              {
+                /* errno is set here.  */
+                failure_errno = errno;
+                free (dir_as_prefix_to_free);
+                goto failed;
+              }
+
+            if (eaccess (progpathname, X_OK) == 0)
+              {
+                struct stat statbuf;
+
+                if (stat (progpathname, &statbuf) >= 0)
+                  {
+                    if (! S_ISDIR (statbuf.st_mode))
+                      errno = ENOEXEC;
+                    else
+                      errno = EACCES;
+                  }
+              }
+
+            failure_errno = errno;
+
+            free (progpathname);
+          }
+        #endif
+
+        free (dir_as_prefix_to_free);
+
+        if (last)
+          break;
+      }
+
+   failed:
+    /* Not found in PATH.  */
+    free (path_copy);
+
+    errno = failure_errno;
+    return NULL;
+  }
+}
diff --git a/lib/findprog.h b/lib/findprog.h
new file mode 100644
index 000000000..e47acc5e4
--- /dev/null
+++ b/lib/findprog.h
@@ -0,0 +1,77 @@
+/* Locating a program in PATH.
+   Copyright (C) 2001-2003, 2009-2022 Free Software Foundation, Inc.
+   Written by Bruno Haible <haible@clisp.cons.org>, 2001.
+
+   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 2.1 of the
+   License, or (at your option) any later version.
+
+   This file 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+#ifndef _FINDPROG_H
+#define _FINDPROG_H
+
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Looks up a program in the PATH.
+   Attempts to determine the pathname that would be called by execlp/execvp
+   of PROGNAME.  If successful, it returns a pathname containing a slash
+   (either absolute or relative to the current directory).  Otherwise, it
+   returns PROGNAME unmodified.
+   Because of the latter case, callers should use execlp/execvp, not
+   execl/execv on the returned pathname.
+   The returned string is freshly malloc()ed if it is != PROGNAME.  */
+extern const char *find_in_path (const char *progname);
+
+/* Looks up a program in the given PATH-like string.
+
+   The PATH argument consists of a list of directories, separated by ':' or
+   (on native Windows) by ';'.  An empty PATH element designates the current
+   directory.  A null PATH is equivalent to an empty PATH, that is, to the
+   singleton list that contains only the current directory.
+
+   If DIRECTORY is not NULL, all relative filenames (i.e. PROGNAME when it
+   contains a slash, and the PATH elements) are considered relative to
+   DIRECTORY instead of relative to the current directory of this process.
+
+   Determines the pathname that would be called by execlp/execvp of PROGNAME.
+   - If successful, it returns a pathname containing a slash (either absolute
+     or relative to the current directory).  The returned string can be used
+     with either execl/execv or execlp/execvp.  It is freshly malloc()ed if it
+     is != PROGNAME.
+   - Otherwise, it sets errno and returns NULL.
+     Specific errno values include:
+       - ENOENT: means that the program's file was not found.
+       - EACCES: means that the program's file cannot be accessed (due to some
+         issue with one of the ancestor directories) or lacks the execute
+         permissions.
+       - ENOMEM: means out of memory.
+   If OPTIMIZE_FOR_EXEC is true, the function saves some work, under the
+   assumption that the resulting pathname will not be accessed directly,
+   only through execl/execv or execlp/execvp.
+
+   Here, a "slash" means:
+     - On POSIX systems excluding Cygwin: a '/',
+     - On Windows, OS/2, DOS platforms: a '/' or '\'. */
+extern const char *find_in_given_path (const char *progname, const char *path,
+                                       const char *directory,
+                                       bool optimize_for_exec);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _FINDPROG_H */
diff --git a/lib/flexmember.h b/lib/flexmember.h
index 1b19a2bfd..1545639f7 100644
--- a/lib/flexmember.h
+++ b/lib/flexmember.h
@@ -1,6 +1,6 @@
 /* Sizes of structs with flexible array members.
 
-   Copyright 2016-2021 Free Software Foundation, Inc.
+   Copyright 2016-2022 Free Software Foundation, Inc.
 
    This file is part of the GNU C Library.
 
diff --git a/lib/float+.h b/lib/float+.h
index ad891f65d..9ab45208d 100644
--- a/lib/float+.h
+++ b/lib/float+.h
@@ -1,5 +1,5 @@
 /* Supplemental information about the floating-point formats.
-   Copyright (C) 2007, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2009-2022 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2007.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/float.c b/lib/float.c
index dd1e84ad1..de8506450 100644
--- a/lib/float.c
+++ b/lib/float.c
@@ -1,5 +1,5 @@
 /* Auxiliary definitions for <float.h>.
-   Copyright (C) 2011-2021 Free Software Foundation, Inc.
+   Copyright (C) 2011-2022 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2011.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/float.in.h b/lib/float.in.h
index f52aba36e..a4183765d 100644
--- a/lib/float.in.h
+++ b/lib/float.in.h
@@ -1,6 +1,6 @@
 /* A correct <float.h>.
 
-   Copyright (C) 2007-2021 Free Software Foundation, Inc.
+   Copyright (C) 2007-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/flock.c b/lib/flock.c
index 95c354eb0..28773d5c3 100644
--- a/lib/flock.c
+++ b/lib/flock.c
@@ -6,7 +6,7 @@
 
    Written by Richard W.M. Jones <rjones.at.redhat.com>
 
-   Copyright (C) 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2008-2022 Free Software Foundation, Inc.
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
diff --git a/lib/floor.c b/lib/floor.c
index 15303004f..3e4f8d058 100644
--- a/lib/floor.c
+++ b/lib/floor.c
@@ -1,9 +1,9 @@
 /* Round towards negative infinity.
-   Copyright (C) 2007, 2010-2021 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2010-2022 Free Software Foundation, Inc.
 
    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 3 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/free.c b/lib/free.c
index 780f03dd1..86ebe6c63 100644
--- a/lib/free.c
+++ b/lib/free.c
@@ -1,6 +1,6 @@
 /* Make free() preserve errno.
 
-   Copyright (C) 2003, 2006, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2006, 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/frexp.c b/lib/frexp.c
index ab5f34315..2c15733e2 100644
--- a/lib/frexp.c
+++ b/lib/frexp.c
@@ -1,5 +1,5 @@
 /* Split a double into fraction and mantissa.
-   Copyright (C) 2007-2021 Free Software Foundation, Inc.
+   Copyright (C) 2007-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/fstat.c b/lib/fstat.c
index 512c688c4..3928c8602 100644
--- a/lib/fstat.c
+++ b/lib/fstat.c
@@ -1,5 +1,5 @@
 /* fstat() replacement.
-   Copyright (C) 2011-2021 Free Software Foundation, Inc.
+   Copyright (C) 2011-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/fsync.c b/lib/fsync.c
index 99a932d77..9b561ab96 100644
--- a/lib/fsync.c
+++ b/lib/fsync.c
@@ -7,7 +7,7 @@
 
    Written by Richard W.M. Jones <rjones.at.redhat.com>
 
-   Copyright (C) 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2008-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/full-read.c b/lib/full-read.c
index 53be6596a..7b5308771 100644
--- a/lib/full-read.c
+++ b/lib/full-read.c
@@ -1,5 +1,5 @@
 /* An interface to read that retries after partial reads and interrupts.
-   Copyright (C) 2002-2003, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2002-2003, 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/full-read.h b/lib/full-read.h
index b36f2e169..b30c68ad5 100644
--- a/lib/full-read.h
+++ b/lib/full-read.h
@@ -1,6 +1,6 @@
 /* An interface to read() that reads all it is asked to read.
 
-   Copyright (C) 2002, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/full-write.c b/lib/full-write.c
index 614ca0b4f..2d593727c 100644
--- a/lib/full-write.c
+++ b/lib/full-write.c
@@ -1,6 +1,6 @@
 /* An interface to read and write that retries (if necessary) until complete.
 
-   Copyright (C) 1993-1994, 1997-2006, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 1993-1994, 1997-2006, 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/full-write.h b/lib/full-write.h
index c316224b4..7e006d1f4 100644
--- a/lib/full-write.h
+++ b/lib/full-write.h
@@ -1,6 +1,6 @@
 /* An interface to write() that writes all it is asked to write.
 
-   Copyright (C) 2002-2003, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2002-2003, 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/gai_strerror.c b/lib/gai_strerror.c
index 4874ef5e3..c7eedb2f3 100644
--- a/lib/gai_strerror.c
+++ b/lib/gai_strerror.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 2001-2002, 2004-2006, 2008-2021 Free Software
+/* Copyright (C) 1997, 2001-2002, 2004-2006, 2008-2022 Free Software
    Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Philip Blundell <pjb27@cam.ac.uk>, 1997.
diff --git a/lib/getaddrinfo.c b/lib/getaddrinfo.c
index 0c42d1b7b..392289858 100644
--- a/lib/getaddrinfo.c
+++ b/lib/getaddrinfo.c
@@ -1,5 +1,5 @@
 /* Get address information (partial implementation).
-   Copyright (C) 1997, 2001-2002, 2004-2021 Free Software Foundation, Inc.
+   Copyright (C) 1997, 2001-2002, 2004-2022 Free Software Foundation, Inc.
    Contributed by Simon Josefsson <simon@josefsson.org>.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/getdtablesize.c b/lib/getdtablesize.c
index 5006c2d5c..793e0f889 100644
--- a/lib/getdtablesize.c
+++ b/lib/getdtablesize.c
@@ -1,5 +1,5 @@
 /* getdtablesize() function: Return maximum possible file descriptor value + 1.
-   Copyright (C) 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2008-2022 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2008.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/getlogin.c b/lib/getlogin.c
index 7b78c67ce..97b6ed659 100644
--- a/lib/getlogin.c
+++ b/lib/getlogin.c
@@ -1,6 +1,6 @@
 /* Provide a working getlogin for systems which lack it.
 
-   Copyright (C) 2010-2021 Free Software Foundation, Inc.
+   Copyright (C) 2010-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/getpeername.c b/lib/getpeername.c
index 468bb3d7c..ac4926f38 100644
--- a/lib/getpeername.c
+++ b/lib/getpeername.c
@@ -1,6 +1,6 @@
 /* getpeername.c --- wrappers for Windows getpeername function
 
-   Copyright (C) 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2008-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/getrandom.c b/lib/getrandom.c
index a186c4d3b..e14687309 100644
--- a/lib/getrandom.c
+++ b/lib/getrandom.c
@@ -1,6 +1,6 @@
 /* Obtain a series of random bytes.
 
-   Copyright 2020-2021 Free Software Foundation, Inc.
+   Copyright 2020-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/getsockname.c b/lib/getsockname.c
index d1f17b3ed..3ab3a7545 100644
--- a/lib/getsockname.c
+++ b/lib/getsockname.c
@@ -1,6 +1,6 @@
 /* getsockname.c --- wrappers for Windows getsockname function
 
-   Copyright (C) 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2008-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/getsockopt.c b/lib/getsockopt.c
index b92d034bb..9c87afadb 100644
--- a/lib/getsockopt.c
+++ b/lib/getsockopt.c
@@ -1,6 +1,6 @@
 /* getsockopt.c --- wrappers for Windows getsockopt function
 
-   Copyright (C) 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2008-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/gettext.h b/lib/gettext.h
index f1c7a2407..b3577a043 100644
--- a/lib/gettext.h
+++ b/lib/gettext.h
@@ -1,5 +1,5 @@
 /* Convenience header for conditional use of GNU <libintl.h>.
-   Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009-2021 Free Software
+   Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009-2022 Free Software
    Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
@@ -138,7 +138,7 @@
 #define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \
   npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category)
 
-#ifdef __GNUC__
+#if defined __GNUC__ || defined __clang__
 __inline
 #else
 #ifdef __cplusplus
@@ -157,7 +157,7 @@ pgettext_aux (const char *domain,
     return translation;
 }
 
-#ifdef __GNUC__
+#if defined __GNUC__ || defined __clang__
 __inline
 #else
 #ifdef __cplusplus
@@ -191,9 +191,8 @@ npgettext_aux (const char *domain,
    or may have security implications due to non-deterministic stack usage.  */
 
 #if (!defined GNULIB_NO_VLA \
-     && (((__GNUC__ >= 3 || __GNUG__ >= 2) && !defined __STRICT_ANSI__) \
-     /*  || (__STDC_VERSION__ == 199901L && !defined __HP_cc)
-         || (__STDC_VERSION__ >= 201112L && !defined __STDC_NO_VLA__) */ ))
+     && defined __STDC_VERSION__ && 199901L <= __STDC_VERSION__ \
+     && !defined __STDC_NO_VLA__)
 # define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 1
 #else
 # define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 0
@@ -208,7 +207,7 @@ npgettext_aux (const char *domain,
 #define dpgettext_expr(Domainname, Msgctxt, Msgid) \
   dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES)
 
-#ifdef __GNUC__
+#if defined __GNUC__ || defined __clang__
 __inline
 #else
 #ifdef __cplusplus
@@ -255,7 +254,7 @@ dcpgettext_expr (const char *domain,
 #define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
   dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
 
-#ifdef __GNUC__
+#if defined __GNUC__ || defined __clang__
 __inline
 #else
 #ifdef __cplusplus
diff --git a/lib/hard-locale.c b/lib/hard-locale.c
index 8b6802d10..f7fbc470b 100644
--- a/lib/hard-locale.c
+++ b/lib/hard-locale.c
@@ -1,6 +1,6 @@
 /* hard-locale.c -- Determine whether a locale is hard.
 
-   Copyright (C) 1997-1999, 2002-2004, 2006-2007, 2009-2021 Free Software
+   Copyright (C) 1997-1999, 2002-2004, 2006-2007, 2009-2022 Free Software
    Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/hard-locale.h b/lib/hard-locale.h
index eba66018c..6066f4ed4 100644
--- a/lib/hard-locale.h
+++ b/lib/hard-locale.h
@@ -1,6 +1,6 @@
 /* Determine whether a locale is hard.
 
-   Copyright (C) 1999, 2003-2004, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2003-2004, 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/iconv.c b/lib/iconv.c
index bf5149349..efab53d88 100644
--- a/lib/iconv.c
+++ b/lib/iconv.c
@@ -1,5 +1,5 @@
 /* Character set conversion.
-   Copyright (C) 1999-2001, 2007, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 1999-2001, 2007, 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/iconv.in.h b/lib/iconv.in.h
index 3a2f94e75..4c5a31c3b 100644
--- a/lib/iconv.in.h
+++ b/lib/iconv.in.h
@@ -1,6 +1,6 @@
 /* A GNU-like <iconv.h>.
 
-   Copyright (C) 2007-2021 Free Software Foundation, Inc.
+   Copyright (C) 2007-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/iconv_close.c b/lib/iconv_close.c
index 7429b925b..2d7fb17ef 100644
--- a/lib/iconv_close.c
+++ b/lib/iconv_close.c
@@ -1,5 +1,5 @@
 /* Character set conversion.
-   Copyright (C) 2007, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/iconv_open-aix.gperf b/lib/iconv_open-aix.gperf
index d07375914..024da2158 100644
--- a/lib/iconv_open-aix.gperf
+++ b/lib/iconv_open-aix.gperf
@@ -1,5 +1,5 @@
 /* Character set conversion.
-   Copyright (C) 2007, 2020-2021 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2020-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/iconv_open-hpux.gperf b/lib/iconv_open-hpux.gperf
index f4664d615..12057505d 100644
--- a/lib/iconv_open-hpux.gperf
+++ b/lib/iconv_open-hpux.gperf
@@ -1,5 +1,5 @@
 /* Character set conversion.
-   Copyright (C) 2007, 2020-2021 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2020-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/iconv_open-irix.gperf b/lib/iconv_open-irix.gperf
index 9885d9278..92a2689df 100644
--- a/lib/iconv_open-irix.gperf
+++ b/lib/iconv_open-irix.gperf
@@ -1,5 +1,5 @@
 /* Character set conversion.
-   Copyright (C) 2007, 2020-2021 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2020-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/iconv_open-osf.gperf b/lib/iconv_open-osf.gperf
index d818d79dc..746f56302 100644
--- a/lib/iconv_open-osf.gperf
+++ b/lib/iconv_open-osf.gperf
@@ -1,5 +1,5 @@
 /* Character set conversion.
-   Copyright (C) 2007, 2020-2021 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2020-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/iconv_open-solaris.gperf b/lib/iconv_open-solaris.gperf
index 648dd3afb..fbd6f9d74 100644
--- a/lib/iconv_open-solaris.gperf
+++ b/lib/iconv_open-solaris.gperf
@@ -1,5 +1,5 @@
 /* Character set conversion.
-   Copyright (C) 2007, 2009, 2020-2021 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2009, 2020-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/iconv_open-zos.gperf b/lib/iconv_open-zos.gperf
index 1c3552e0f..6912485e1 100644
--- a/lib/iconv_open-zos.gperf
+++ b/lib/iconv_open-zos.gperf
@@ -1,5 +1,5 @@
 /* Character set conversion.
-   Copyright (C) 2019-2021 Free Software Foundation, Inc.
+   Copyright (C) 2019-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/iconv_open-zos.h b/lib/iconv_open-zos.h
new file mode 100644
index 000000000..5f847251f
--- /dev/null
+++ b/lib/iconv_open-zos.h
@@ -0,0 +1,329 @@
+/* ANSI-C code produced by gperf version 3.1 */
+/* Command-line: gperf -m 10 ./iconv_open-zos.gperf  */
+/* Computed positions: -k'4,$' */
+
+#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
+      && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
+      && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
+      && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
+      && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
+      && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
+      && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
+      && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
+      && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
+      && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
+      && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
+      && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
+      && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
+      && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
+      && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
+      && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
+      && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
+      && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
+      && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
+      && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
+      && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
+      && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
+      && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
+/* The character set is not based on ISO-646.  */
+#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gperf@gnu.org>."
+#endif
+
+#line 17 "./iconv_open-zos.gperf"
+struct mapping { int standard_name; const char vendor_name[10 + 1]; };
+
+#define TOTAL_KEYWORDS 49
+#define MIN_WORD_LENGTH 3
+#define MAX_WORD_LENGTH 11
+#define MIN_HASH_VALUE 3
+#define MAX_HASH_VALUE 64
+/* maximum key range = 62, duplicates = 0 */
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+static unsigned int
+mapping_hash (register const char *str, register size_t len)
+{
+  static const unsigned char asso_values[] =
+    {
+      65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+      65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+      65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+      65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+      65, 65, 65, 65, 65, 65, 65, 65, 16, 38,
+      14,  1, 32, 22, 29,  3,  0,  7, 40,  2,
+       5, 18, 23, 65, 65, 65, 65, 65, 65, 65,
+      65, 65, 65,  0, 65,  0, 65, 65, 65,  0,
+      43, 65,  1, 65, 65,  8, 65, 65, 65, 65,
+      65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+      65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+      65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+      65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+      65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+      65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+      65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+      65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+      65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+      65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+      65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+      65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+      65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+      65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+      65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+      65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+      65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+      65, 65
+    };
+  register unsigned int hval = len;
+
+  switch (hval)
+    {
+      default:
+        hval += asso_values[(unsigned char)str[3]+6];
+      /*FALLTHROUGH*/
+      case 3:
+        break;
+    }
+  return hval + asso_values[(unsigned char)str[len - 1]];
+}
+
+struct stringpool_t
+  {
+    char stringpool_str3[sizeof("GBK")];
+    char stringpool_str5[sizeof("ASCII")];
+    char stringpool_str7[sizeof("CP1253")];
+    char stringpool_str8[sizeof("EUC-KR")];
+    char stringpool_str9[sizeof("CP1257")];
+    char stringpool_str10[sizeof("CP857")];
+    char stringpool_str11[sizeof("ISO-8859-8")];
+    char stringpool_str12[sizeof("ISO-8859-3")];
+    char stringpool_str13[sizeof("ISO-8859-13")];
+    char stringpool_str14[sizeof("ISO-8859-7")];
+    char stringpool_str15[sizeof("CP437")];
+    char stringpool_str16[sizeof("CP1129")];
+    char stringpool_str17[sizeof("CP869")];
+    char stringpool_str18[sizeof("ISO-8859-9")];
+    char stringpool_str19[sizeof("CP922")];
+    char stringpool_str20[sizeof("CP1252")];
+    char stringpool_str21[sizeof("CP852")];
+    char stringpool_str22[sizeof("CP1250")];
+    char stringpool_str23[sizeof("CP850")];
+    char stringpool_str24[sizeof("CP862")];
+    char stringpool_str25[sizeof("ISO-8859-2")];
+    char stringpool_str26[sizeof("CP932")];
+    char stringpool_str27[sizeof("GB2312")];
+    char stringpool_str28[sizeof("CP1255")];
+    char stringpool_str29[sizeof("CP855")];
+    char stringpool_str30[sizeof("KOI8-R")];
+    char stringpool_str31[sizeof("CP1125")];
+    char stringpool_str32[sizeof("CP865")];
+    char stringpool_str33[sizeof("ISO-8859-5")];
+    char stringpool_str34[sizeof("ISO-8859-15")];
+    char stringpool_str35[sizeof("CP1256")];
+    char stringpool_str36[sizeof("CP856")];
+    char stringpool_str37[sizeof("KOI8-U")];
+    char stringpool_str38[sizeof("CP1254")];
+    char stringpool_str39[sizeof("CP866")];
+    char stringpool_str40[sizeof("ISO-8859-6")];
+    char stringpool_str41[sizeof("CP1124")];
+    char stringpool_str42[sizeof("CP864")];
+    char stringpool_str43[sizeof("ISO-8859-4")];
+    char stringpool_str44[sizeof("CP1251")];
+    char stringpool_str45[sizeof("CP775")];
+    char stringpool_str46[sizeof("CP943")];
+    char stringpool_str47[sizeof("CP1131")];
+    char stringpool_str48[sizeof("CP861")];
+    char stringpool_str49[sizeof("ISO-8859-1")];
+    char stringpool_str50[sizeof("EUC-JP")];
+    char stringpool_str52[sizeof("CP949")];
+    char stringpool_str55[sizeof("CP874")];
+    char stringpool_str64[sizeof("CP1046")];
+  };
+static const struct stringpool_t stringpool_contents =
+  {
+    "GBK",
+    "ASCII",
+    "CP1253",
+    "EUC-KR",
+    "CP1257",
+    "CP857",
+    "ISO-8859-8",
+    "ISO-8859-3",
+    "ISO-8859-13",
+    "ISO-8859-7",
+    "CP437",
+    "CP1129",
+    "CP869",
+    "ISO-8859-9",
+    "CP922",
+    "CP1252",
+    "CP852",
+    "CP1250",
+    "CP850",
+    "CP862",
+    "ISO-8859-2",
+    "CP932",
+    "GB2312",
+    "CP1255",
+    "CP855",
+    "KOI8-R",
+    "CP1125",
+    "CP865",
+    "ISO-8859-5",
+    "ISO-8859-15",
+    "CP1256",
+    "CP856",
+    "KOI8-U",
+    "CP1254",
+    "CP866",
+    "ISO-8859-6",
+    "CP1124",
+    "CP864",
+    "ISO-8859-4",
+    "CP1251",
+    "CP775",
+    "CP943",
+    "CP1131",
+    "CP861",
+    "ISO-8859-1",
+    "EUC-JP",
+    "CP949",
+    "CP874",
+    "CP1046"
+  };
+#define stringpool ((const char *) &stringpool_contents)
+
+static const struct mapping mappings[] =
+  {
+    {-1}, {-1}, {-1},
+#line 76 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str3, "IBM-1386"},
+    {-1},
+#line 28 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str5, "00367"},
+    {-1},
+#line 68 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str7, "IBM-5349"},
+#line 75 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str8, "IBM-eucKR"},
+#line 72 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str9, "09449"},
+#line 48 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str10, "00857"},
+#line 36 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str11, "05012"},
+#line 31 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str12, "00913"},
+#line 38 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str13, "ISO8859-13"},
+#line 35 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str14, "ISO8859-7"},
+#line 42 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str15, "IBM-437"},
+#line 63 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str16, "01129"},
+#line 54 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str17, "IBM-869"},
+#line 37 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str18, "ISO8859-9"},
+#line 56 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str19, "IBM-922"},
+#line 67 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str20, "IBM-5348"},
+#line 45 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str21, "IBM-852"},
+#line 65 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str22, "IBM-5346"},
+#line 44 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str23, "09042"},
+#line 50 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str24, "IBM-862"},
+#line 30 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str25, "ISO8859-2"},
+#line 57 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str26, "IBM-943"},
+#line 73 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str27, "IBM-eucCN"},
+#line 70 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str28, "09447"},
+#line 46 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str29, "13143"},
+#line 40 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str30, "00878"},
+#line 62 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str31, "IBM-1125"},
+#line 52 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str32, "00865"},
+#line 33 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str33, "ISO8859-5"},
+#line 39 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str34, "ISO8859-15"},
+#line 71 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str35, "09448"},
+#line 47 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str36, "IBM-856"},
+#line 41 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str37, "01168"},
+#line 69 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str38, "IBM-5350"},
+#line 53 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str39, "04962"},
+#line 34 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str40, "ISO8859-6"},
+#line 61 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str41, "IBM-1124"},
+#line 51 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str42, "IBM-864"},
+#line 32 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str43, "ISO8859-4"},
+#line 66 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str44, "IBM-5347"},
+#line 43 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str45, "00775"},
+#line 58 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str46, "IBM-943"},
+#line 64 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str47, "01131"},
+#line 49 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str48, "IBM-861"},
+#line 29 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str49, "ISO8859-1"},
+#line 74 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str50, "01350"},
+    {-1},
+#line 59 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str52, "IBM-1363"},
+    {-1}, {-1},
+#line 55 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str55, "TIS-620"},
+    {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+#line 60 "./iconv_open-zos.gperf"
+    {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str64, "IBM-1046"}
+  };
+
+const struct mapping *
+mapping_lookup (register const char *str, register size_t len)
+{
+  if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
+    {
+      register unsigned int key = mapping_hash (str, len);
+
+      if (key <= MAX_HASH_VALUE)
+        {
+          register int o = mappings[key].standard_name;
+          if (o >= 0)
+            {
+              register const char *s = o + stringpool;
+
+              if (*str == *s && !strcmp (str + 1, s + 1))
+                return &mappings[key];
+            }
+        }
+    }
+  return 0;
+}
diff --git a/lib/iconv_open.c b/lib/iconv_open.c
index e573556e9..02c240ee9 100644
--- a/lib/iconv_open.c
+++ b/lib/iconv_open.c
@@ -1,5 +1,5 @@
 /* Character set conversion.
-   Copyright (C) 2007, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/iconveh.h b/lib/iconveh.h
index cbf692ebe..058f68ca2 100644
--- a/lib/iconveh.h
+++ b/lib/iconveh.h
@@ -1,5 +1,5 @@
 /* Character set conversion handler type.
-   Copyright (C) 2001-2007, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2001-2007, 2009-2022 Free Software Foundation, Inc.
    Written by Bruno Haible.
 
    This file is free software: you can redistribute it and/or modify
@@ -29,7 +29,10 @@ enum iconv_ilseq_handler
 {
   iconveh_error,                /* return and set errno = EILSEQ */
   iconveh_question_mark,        /* use one '?' per unconvertible character */
-  iconveh_escape_sequence       /* use escape sequence \uxxxx or \Uxxxxxxxx */
+  iconveh_escape_sequence,      /* use escape sequence \uxxxx or \Uxxxxxxxx */
+  iconveh_replacement_character /* use one U+FFFD per unconvertible character
+                                   if that fits in the target encoding,
+                                   otherwise one '?' */
 };
 
 
diff --git a/lib/idx.h b/lib/idx.h
index 483587eab..c3669ddac 100644
--- a/lib/idx.h
+++ b/lib/idx.h
@@ -1,5 +1,5 @@
 /* A type for indices and sizes.
-   Copyright (C) 2020-2021 Free Software Foundation, Inc.
+   Copyright (C) 2020-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -56,6 +56,26 @@
      * Because 'size_t' is an unsigned type, and a signed type is better.
        See above.
 
+   Why not use 'ssize_t'?
+
+     * 'ptrdiff_t' is more portable; it is standardized by ISO C
+       whereas 'ssize_t' is standardized only by POSIX.
+
+     * 'ssize_t' is not required to be as wide as 'size_t', and some
+       now-obsolete POSIX platforms had 'size_t' wider than 'ssize_t'.
+
+     * Conversely, some now-obsolete platforms had 'ptrdiff_t' wider
+       than 'size_t', which can be a win and conforms to POSIX.
+
+   Won't this cause a problem with objects larger than PTRDIFF_MAX?
+
+     * Typical modern or large platforms do not allocate such objects,
+       so this is not much of a problem in practice; for example, you
+       can safely write 'idx_t len = strlen (s);'.  To port to older
+       small platforms where allocations larger than PTRDIFF_MAX could
+       in theory be a problem, you can use Gnulib's ialloc module, or
+       functions like ximalloc in Gnulib's xalloc module.
+
    Why not use 'ptrdiff_t' directly?
 
      * Maintainability: When reading and modifying code, it helps to know that
diff --git a/lib/inet_ntop.c b/lib/inet_ntop.c
index 409e88c76..2d401d22b 100644
--- a/lib/inet_ntop.c
+++ b/lib/inet_ntop.c
@@ -1,6 +1,6 @@
 /* inet_ntop.c -- convert IPv4 and IPv6 addresses from binary to text form
 
-   Copyright (C) 2005-2006, 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2005-2006, 2008-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/inet_pton.c b/lib/inet_pton.c
index 14e8b0acd..a239b7d1e 100644
--- a/lib/inet_pton.c
+++ b/lib/inet_pton.c
@@ -1,6 +1,6 @@
 /* inet_pton.c -- convert IPv4 and IPv6 addresses from text to binary form
 
-   Copyright (C) 2006, 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2006, 2008-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/intprops-internal.h b/lib/intprops-internal.h
new file mode 100644
index 000000000..f6455f785
--- /dev/null
+++ b/lib/intprops-internal.h
@@ -0,0 +1,392 @@
+/* intprops-internal.h -- properties of integer types not visible to users
+
+   Copyright (C) 2001-2022 Free Software Foundation, Inc.
+
+   This program 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 2.1 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+#ifndef _GL_INTPROPS_INTERNAL_H
+#define _GL_INTPROPS_INTERNAL_H
+
+#include <limits.h>
+
+/* Return a value with the common real type of E and V and the value of V.
+   Do not evaluate E.  */
+#define _GL_INT_CONVERT(e, v) ((1 ? 0 : (e)) + (v))
+
+/* Act like _GL_INT_CONVERT (E, -V) but work around a bug in IRIX 6.5 cc; see
+   <https://lists.gnu.org/r/bug-gnulib/2011-05/msg00406.html>.  */
+#define _GL_INT_NEGATE_CONVERT(e, v) ((1 ? 0 : (e)) - (v))
+
+/* The extra casts in the following macros work around compiler bugs,
+   e.g., in Cray C 5.0.3.0.  */
+
+/* True if the real type T is signed.  */
+#define _GL_TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
+
+/* Return 1 if the real expression E, after promotion, has a
+   signed or floating type.  Do not evaluate E.  */
+#define _GL_EXPR_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0)
+
+
+/* Minimum and maximum values for integer types and expressions.  */
+
+/* The width in bits of the integer type or expression T.
+   Do not evaluate T.  T must not be a bit-field expression.
+   Padding bits are not supported; this is checked at compile-time below.  */
+#define _GL_TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT)
+
+/* The maximum and minimum values for the type of the expression E,
+   after integer promotion.  E is not evaluated.  */
+#define _GL_INT_MINIMUM(e)                                              \
+  (_GL_EXPR_SIGNED (e)                                                  \
+   ? ~ _GL_SIGNED_INT_MAXIMUM (e)                                       \
+   : _GL_INT_CONVERT (e, 0))
+#define _GL_INT_MAXIMUM(e)                                              \
+  (_GL_EXPR_SIGNED (e)                                                  \
+   ? _GL_SIGNED_INT_MAXIMUM (e)                                         \
+   : _GL_INT_NEGATE_CONVERT (e, 1))
+#define _GL_SIGNED_INT_MAXIMUM(e)                                       \
+  (((_GL_INT_CONVERT (e, 1) << (_GL_TYPE_WIDTH (+ (e)) - 2)) - 1) * 2 + 1)
+
+/* Work around OpenVMS incompatibility with C99.  */
+#if !defined LLONG_MAX && defined __INT64_MAX
+# define LLONG_MAX __INT64_MAX
+# define LLONG_MIN __INT64_MIN
+#endif
+
+/* This include file assumes that signed types are two's complement without
+   padding bits; the above macros have undefined behavior otherwise.
+   If this is a problem for you, please let us know how to fix it for your host.
+   This assumption is tested by the intprops-tests module.  */
+
+/* Does the __typeof__ keyword work?  This could be done by
+   'configure', but for now it's easier to do it by hand.  */
+#if (2 <= __GNUC__ \
+     || (4 <= __clang_major__) \
+     || (1210 <= __IBMC__ && defined __IBM__TYPEOF__) \
+     || (0x5110 <= __SUNPRO_C && !__STDC__))
+# define _GL_HAVE___TYPEOF__ 1
+#else
+# define _GL_HAVE___TYPEOF__ 0
+#endif
+
+/* Return 1 if the integer type or expression T might be signed.  Return 0
+   if it is definitely unsigned.  T must not be a bit-field expression.
+   This macro does not evaluate its argument, and expands to an
+   integer constant expression.  */
+#if _GL_HAVE___TYPEOF__
+# define _GL_SIGNED_TYPE_OR_EXPR(t) _GL_TYPE_SIGNED (__typeof__ (t))
+#else
+# define _GL_SIGNED_TYPE_OR_EXPR(t) 1
+#endif
+
+/* Return 1 if - A would overflow in [MIN,MAX] arithmetic.
+   A should not have side effects, and A's type should be an
+   integer with minimum value MIN and maximum MAX.  */
+#define _GL_INT_NEGATE_RANGE_OVERFLOW(a, min, max) \
+  ((min) < 0 ? (a) < - (max) : 0 < (a))
+
+/* True if __builtin_add_overflow (A, B, P) and __builtin_sub_overflow
+   (A, B, P) work when P is non-null.  */
+#ifdef __EDG__
+/* EDG-based compilers like nvc 22.1 cannot add 64-bit signed to unsigned
+   <https://bugs.gnu.org/53256>.  */
+# define _GL_HAS_BUILTIN_ADD_OVERFLOW 0
+#elif defined __has_builtin
+# define _GL_HAS_BUILTIN_ADD_OVERFLOW __has_builtin (__builtin_add_overflow)
+/* __builtin_{add,sub}_overflow exists but is not reliable in GCC 5.x and 6.x,
+   see <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98269>.  */
+#elif 7 <= __GNUC__
+# define _GL_HAS_BUILTIN_ADD_OVERFLOW 1
+#else
+# define _GL_HAS_BUILTIN_ADD_OVERFLOW 0
+#endif
+
+/* True if __builtin_mul_overflow (A, B, P) works when P is non-null.  */
+#if defined __clang_major__ && __clang_major__ < 14
+/* Work around Clang bug <https://bugs.llvm.org/show_bug.cgi?id=16404>.  */
+# define _GL_HAS_BUILTIN_MUL_OVERFLOW 0
+#else
+# define _GL_HAS_BUILTIN_MUL_OVERFLOW _GL_HAS_BUILTIN_ADD_OVERFLOW
+#endif
+
+/* True if __builtin_add_overflow_p (A, B, C) works, and similarly for
+   __builtin_sub_overflow_p and __builtin_mul_overflow_p.  */
+#ifdef __EDG__
+/* In EDG-based compilers like ICC 2021.3 and earlier,
+   __builtin_add_overflow_p etc. are not treated as integral constant
+   expressions even when all arguments are.  */
+# define _GL_HAS_BUILTIN_OVERFLOW_P 0
+#elif defined __has_builtin
+# define _GL_HAS_BUILTIN_OVERFLOW_P __has_builtin (__builtin_mul_overflow_p)
+#else
+# define _GL_HAS_BUILTIN_OVERFLOW_P (7 <= __GNUC__)
+#endif
+
+#if (!defined _GL_STDCKDINT_H && 202311 <= __STDC_VERSION__ \
+     && ! (_GL_HAS_BUILTIN_ADD_OVERFLOW && _GL_HAS_BUILTIN_MUL_OVERFLOW))
+# include <stdckdint.h>
+#endif
+
+/* Store the low-order bits of A + B, A - B, A * B, respectively, into *R.
+   Return 1 if the result overflows.  Arguments should not have side
+   effects and A, B and *R can be of any integer type other than char,
+   bool, a bit-precise integer type, or an enumeration type.  */
+#if _GL_HAS_BUILTIN_ADD_OVERFLOW
+# define _GL_INT_ADD_WRAPV(a, b, r) __builtin_add_overflow (a, b, r)
+# define _GL_INT_SUBTRACT_WRAPV(a, b, r) __builtin_sub_overflow (a, b, r)
+#elif defined ckd_add && defined ckd_sub && !defined _GL_STDCKDINT_H
+# define _GL_INT_ADD_WRAPV(a, b, r) ckd_add (r, + (a), + (b))
+# define _GL_INT_SUBTRACT_WRAPV(a, b, r) ckd_sub (r, + (a), + (b))
+#else
+# define _GL_INT_ADD_WRAPV(a, b, r) \
+   _GL_INT_OP_WRAPV (a, b, r, +, _GL_INT_ADD_RANGE_OVERFLOW)
+# define _GL_INT_SUBTRACT_WRAPV(a, b, r) \
+   _GL_INT_OP_WRAPV (a, b, r, -, _GL_INT_SUBTRACT_RANGE_OVERFLOW)
+#endif
+#if _GL_HAS_BUILTIN_MUL_OVERFLOW
+# if ((9 < __GNUC__ + (3 <= __GNUC_MINOR__) \
+       || (__GNUC__ == 8 && 4 <= __GNUC_MINOR__)) \
+      && !defined __EDG__)
+#  define _GL_INT_MULTIPLY_WRAPV(a, b, r) __builtin_mul_overflow (a, b, r)
+# else
+   /* Work around GCC bug 91450.  */
+#  define _GL_INT_MULTIPLY_WRAPV(a, b, r) \
+    ((!_GL_SIGNED_TYPE_OR_EXPR (*(r)) && _GL_EXPR_SIGNED (a) && _GL_EXPR_SIGNED (b) \
+      && _GL_INT_MULTIPLY_RANGE_OVERFLOW (a, b, 0, (__typeof__ (*(r))) -1)) \
+     ? ((void) __builtin_mul_overflow (a, b, r), 1) \
+     : __builtin_mul_overflow (a, b, r))
+# endif
+#elif defined ckd_mul && !defined _GL_STDCKDINT_H
+# define _GL_INT_MULTIPLY_WRAPV(a, b, r) ckd_mul (r, + (a), + (b))
+#else
+# define _GL_INT_MULTIPLY_WRAPV(a, b, r) \
+   _GL_INT_OP_WRAPV (a, b, r, *, _GL_INT_MULTIPLY_RANGE_OVERFLOW)
+#endif
+
+/* Nonzero if this compiler has GCC bug 68193 or Clang bug 25390.  See:
+   https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68193
+   https://llvm.org/bugs/show_bug.cgi?id=25390
+   For now, assume all versions of GCC-like compilers generate bogus
+   warnings for _Generic.  This matters only for compilers that
+   lack relevant builtins.  */
+#if __GNUC__ || defined __clang__
+# define _GL__GENERIC_BOGUS 1
+#else
+# define _GL__GENERIC_BOGUS 0
+#endif
+
+/* Store the low-order bits of A <op> B into *R, where OP specifies
+   the operation and OVERFLOW the overflow predicate.  Return 1 if the
+   result overflows.  Arguments should not have side effects,
+   and A, B and *R can be of any integer type other than char, bool, a
+   bit-precise integer type, or an enumeration type.  */
+#if 201112 <= __STDC_VERSION__ && !_GL__GENERIC_BOGUS
+# define _GL_INT_OP_WRAPV(a, b, r, op, overflow) \
+   (_Generic \
+    (*(r), \
+     signed char: \
+       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
+                        signed char, SCHAR_MIN, SCHAR_MAX), \
+     unsigned char: \
+       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
+                        unsigned char, 0, UCHAR_MAX), \
+     short int: \
+       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
+                        short int, SHRT_MIN, SHRT_MAX), \
+     unsigned short int: \
+       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
+                        unsigned short int, 0, USHRT_MAX), \
+     int: \
+       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
+                        int, INT_MIN, INT_MAX), \
+     unsigned int: \
+       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
+                        unsigned int, 0, UINT_MAX), \
+     long int: \
+       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \
+                        long int, LONG_MIN, LONG_MAX), \
+     unsigned long int: \
+       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \
+                        unsigned long int, 0, ULONG_MAX), \
+     long long int: \
+       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long long int, \
+                        long long int, LLONG_MIN, LLONG_MAX), \
+     unsigned long long int: \
+       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long long int, \
+                        unsigned long long int, 0, ULLONG_MAX)))
+#else
+/* Store the low-order bits of A <op> B into *R, where OP specifies
+   the operation and OVERFLOW the overflow predicate.  If *R is
+   signed, its type is ST with bounds SMIN..SMAX; otherwise its type
+   is UT with bounds U..UMAX.  ST and UT are narrower than int.
+   Return 1 if the result overflows.  Arguments should not have side
+   effects, and A, B and *R can be of any integer type other than
+   char, bool, a bit-precise integer type, or an enumeration type.  */
+# if _GL_HAVE___TYPEOF__
+#  define _GL_INT_OP_WRAPV_SMALLISH(a,b,r,op,overflow,st,smin,smax,ut,umax) \
+    (_GL_TYPE_SIGNED (__typeof__ (*(r))) \
+     ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, st, smin, smax) \
+     : _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, ut, 0, umax))
+# else
+#  define _GL_INT_OP_WRAPV_SMALLISH(a,b,r,op,overflow,st,smin,smax,ut,umax) \
+    (overflow (a, b, smin, smax) \
+     ? (overflow (a, b, 0, umax) \
+        ? (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a,b,op,unsigned,st), 1) \
+        : (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a,b,op,unsigned,st)) < 0) \
+     : (overflow (a, b, 0, umax) \
+        ? (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a,b,op,unsigned,st)) >= 0 \
+        : (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a,b,op,unsigned,st), 0)))
+# endif
+
+# define _GL_INT_OP_WRAPV(a, b, r, op, overflow) \
+   (sizeof *(r) == sizeof (signed char) \
+    ? _GL_INT_OP_WRAPV_SMALLISH (a, b, r, op, overflow, \
+                                 signed char, SCHAR_MIN, SCHAR_MAX, \
+                                 unsigned char, UCHAR_MAX) \
+    : sizeof *(r) == sizeof (short int) \
+    ? _GL_INT_OP_WRAPV_SMALLISH (a, b, r, op, overflow, \
+                                 short int, SHRT_MIN, SHRT_MAX, \
+                                 unsigned short int, USHRT_MAX) \
+    : sizeof *(r) == sizeof (int) \
+    ? (_GL_EXPR_SIGNED (*(r)) \
+       ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
+                          int, INT_MIN, INT_MAX) \
+       : _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
+                          unsigned int, 0, UINT_MAX)) \
+    : _GL_INT_OP_WRAPV_LONGISH(a, b, r, op, overflow))
+# ifdef LLONG_MAX
+#  define _GL_INT_OP_WRAPV_LONGISH(a, b, r, op, overflow) \
+    (sizeof *(r) == sizeof (long int) \
+     ? (_GL_EXPR_SIGNED (*(r)) \
+        ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \
+                           long int, LONG_MIN, LONG_MAX) \
+        : _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \
+                           unsigned long int, 0, ULONG_MAX)) \
+     : (_GL_EXPR_SIGNED (*(r)) \
+        ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long long int, \
+                           long long int, LLONG_MIN, LLONG_MAX) \
+        : _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long long int, \
+                           unsigned long long int, 0, ULLONG_MAX)))
+# else
+#  define _GL_INT_OP_WRAPV_LONGISH(a, b, r, op, overflow) \
+    (_GL_EXPR_SIGNED (*(r)) \
+     ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \
+                        long int, LONG_MIN, LONG_MAX) \
+     : _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \
+                        unsigned long int, 0, ULONG_MAX))
+# endif
+#endif
+
+/* Store the low-order bits of A <op> B into *R, where the operation
+   is given by OP.  Use the unsigned type UT for calculation to avoid
+   overflow problems.  *R's type is T, with extrema TMIN and TMAX.
+   T can be any signed integer type other than char, bool, a
+   bit-precise integer type, or an enumeration type.
+   Return 1 if the result overflows.  */
+#define _GL_INT_OP_CALC(a, b, r, op, overflow, ut, t, tmin, tmax) \
+  (overflow (a, b, tmin, tmax) \
+   ? (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t), 1) \
+   : (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t), 0))
+
+/* Return 1 if the integer expressions A - B and -A would overflow,
+   respectively.  Arguments should not have side effects,
+   and can be any signed integer type other than char, bool, a
+   bit-precise integer type, or an enumeration type.
+   These macros are tuned for their last input argument being a constant.  */
+
+#if _GL_HAS_BUILTIN_OVERFLOW_P
+# define _GL_INT_NEGATE_OVERFLOW(a) \
+   __builtin_sub_overflow_p (0, a, (__typeof__ (- (a))) 0)
+#else
+# define _GL_INT_NEGATE_OVERFLOW(a) \
+   _GL_INT_NEGATE_RANGE_OVERFLOW (a, _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a))
+#endif
+
+/* Return the low-order bits of A <op> B, where the operation is given
+   by OP.  Use the unsigned type UT for calculation to avoid undefined
+   behavior on signed integer overflow, and convert the result to type T.
+   UT is at least as wide as T and is no narrower than unsigned int,
+   T is two's complement, and there is no padding or trap representations.
+   Assume that converting UT to T yields the low-order bits, as is
+   done in all known two's-complement C compilers.  E.g., see:
+   https://gcc.gnu.org/onlinedocs/gcc/Integers-implementation.html
+
+   According to the C standard, converting UT to T yields an
+   implementation-defined result or signal for values outside T's
+   range.  However, code that works around this theoretical problem
+   runs afoul of a compiler bug in Oracle Studio 12.3 x86.  See:
+   https://lists.gnu.org/r/bug-gnulib/2017-04/msg00049.html
+   As the compiler bug is real, don't try to work around the
+   theoretical problem.  */
+
+#define _GL_INT_OP_WRAPV_VIA_UNSIGNED(a, b, op, ut, t) \
+  ((t) ((ut) (a) op (ut) (b)))
+
+/* Return true if the numeric values A + B, A - B, A * B fall outside
+   the range TMIN..TMAX.  Arguments should not have side effects
+   and can be any integer type other than char, bool,
+   a bit-precise integer type, or an enumeration type.
+   TMIN should be signed and nonpositive.
+   TMAX should be positive, and should be signed unless TMIN is zero.  */
+#define _GL_INT_ADD_RANGE_OVERFLOW(a, b, tmin, tmax) \
+  ((b) < 0 \
+   ? (((tmin) \
+       ? ((_GL_EXPR_SIGNED (_GL_INT_CONVERT (a, (tmin) - (b))) || (b) < (tmin)) \
+          && (a) < (tmin) - (b)) \
+       : (a) <= -1 - (b)) \
+      || ((_GL_EXPR_SIGNED (a) ? 0 <= (a) : (tmax) < (a)) && (tmax) < (a) + (b))) \
+   : (a) < 0 \
+   ? (((tmin) \
+       ? ((_GL_EXPR_SIGNED (_GL_INT_CONVERT (b, (tmin) - (a))) || (a) < (tmin)) \
+          && (b) < (tmin) - (a)) \
+       : (b) <= -1 - (a)) \
+      || ((_GL_EXPR_SIGNED (_GL_INT_CONVERT (a, b)) || (tmax) < (b)) \
+          && (tmax) < (a) + (b))) \
+   : (tmax) < (b) || (tmax) - (b) < (a))
+#define _GL_INT_SUBTRACT_RANGE_OVERFLOW(a, b, tmin, tmax) \
+  (((a) < 0) == ((b) < 0) \
+   ? ((a) < (b) \
+      ? !(tmin) || -1 - (tmin) < (b) - (a) - 1 \
+      : (tmax) < (a) - (b)) \
+   : (a) < 0 \
+   ? ((!_GL_EXPR_SIGNED (_GL_INT_CONVERT ((a) - (tmin), b)) && (a) - (tmin) < 0) \
+      || (a) - (tmin) < (b)) \
+   : ((! (_GL_EXPR_SIGNED (_GL_INT_CONVERT (tmax, b)) \
+          && _GL_EXPR_SIGNED (_GL_INT_CONVERT ((tmax) + (b), a))) \
+       && (tmax) <= -1 - (b)) \
+      || (tmax) + (b) < (a)))
+#define _GL_INT_MULTIPLY_RANGE_OVERFLOW(a, b, tmin, tmax) \
+  ((b) < 0 \
+   ? ((a) < 0 \
+      ? (_GL_EXPR_SIGNED (_GL_INT_CONVERT (tmax, b)) \
+         ? (a) < (tmax) / (b) \
+         : ((_GL_INT_NEGATE_OVERFLOW (b) \
+             ? _GL_INT_CONVERT (b, tmax) >> (_GL_TYPE_WIDTH (+ (b)) - 1) \
+             : (tmax) / -(b)) \
+            <= -1 - (a))) \
+      : _GL_INT_NEGATE_OVERFLOW (_GL_INT_CONVERT (b, tmin)) && (b) == -1 \
+      ? (_GL_EXPR_SIGNED (a) \
+         ? 0 < (a) + (tmin) \
+         : 0 < (a) && -1 - (tmin) < (a) - 1) \
+      : (tmin) / (b) < (a)) \
+   : (b) == 0 \
+   ? 0 \
+   : ((a) < 0 \
+      ? (_GL_INT_NEGATE_OVERFLOW (_GL_INT_CONVERT (a, tmin)) && (a) == -1 \
+         ? (_GL_EXPR_SIGNED (b) ? 0 < (b) + (tmin) : -1 - (tmin) < (b) - 1) \
+         : (tmin) / (a) < (b)) \
+      : (tmax) / (b) < (a)))
+
+#endif /* _GL_INTPROPS_INTERNAL_H */
diff --git a/lib/intprops.h b/lib/intprops.h
index 9d10028a5..f182ddc1f 100644
--- a/lib/intprops.h
+++ b/lib/intprops.h
@@ -1,6 +1,6 @@
 /* intprops.h -- properties of integer types
 
-   Copyright (C) 2001-2021 Free Software Foundation, Inc.
+   Copyright (C) 2001-2022 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify it
    under the terms of the GNU Lesser General Public License as published
@@ -15,20 +15,10 @@
    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
 
-/* Written by Paul Eggert.  */
-
 #ifndef _GL_INTPROPS_H
 #define _GL_INTPROPS_H
 
-#include <limits.h>
-
-/* Return a value with the common real type of E and V and the value of V.
-   Do not evaluate E.  */
-#define _GL_INT_CONVERT(e, v) ((1 ? 0 : (e)) + (v))
-
-/* Act like _GL_INT_CONVERT (E, -V) but work around a bug in IRIX 6.5 cc; see
-   <https://lists.gnu.org/r/bug-gnulib/2011-05/msg00406.html>.  */
-#define _GL_INT_NEGATE_CONVERT(e, v) ((1 ? 0 : (e)) - (v))
+#include "intprops-internal.h"
 
 /* The extra casts in the following macros work around compiler bugs,
    e.g., in Cray C 5.0.3.0.  */
@@ -38,11 +28,11 @@
 #define TYPE_IS_INTEGER(t) ((t) 1.5 == 1)
 
 /* True if the real type T is signed.  */
-#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
+#define TYPE_SIGNED(t) _GL_TYPE_SIGNED (t)
 
 /* Return 1 if the real expression E, after promotion, has a
    signed or floating type.  Do not evaluate E.  */
-#define EXPR_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0)
+#define EXPR_SIGNED(e) _GL_EXPR_SIGNED (e)
 
 
 /* Minimum and maximum values for integer types and expressions.  */
@@ -50,7 +40,7 @@
 /* The width in bits of the integer type or expression T.
    Do not evaluate T.  T must not be a bit-field expression.
    Padding bits are not supported; this is checked at compile-time below.  */
-#define TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT)
+#define TYPE_WIDTH(t) _GL_TYPE_WIDTH (t)
 
 /* The maximum and minimum values for the integer type T.  */
 #define TYPE_MINIMUM(t) ((t) ~ TYPE_MAXIMUM (t))
@@ -59,51 +49,6 @@
         ? (t) -1                                                        \
         : ((((t) 1 << (TYPE_WIDTH (t) - 2)) - 1) * 2 + 1)))
 
-/* The maximum and minimum values for the type of the expression E,
-   after integer promotion.  E is not evaluated.  */
-#define _GL_INT_MINIMUM(e)                                              \
-  (EXPR_SIGNED (e)                                                      \
-   ? ~ _GL_SIGNED_INT_MAXIMUM (e)                                       \
-   : _GL_INT_CONVERT (e, 0))
-#define _GL_INT_MAXIMUM(e)                                              \
-  (EXPR_SIGNED (e)                                                      \
-   ? _GL_SIGNED_INT_MAXIMUM (e)                                         \
-   : _GL_INT_NEGATE_CONVERT (e, 1))
-#define _GL_SIGNED_INT_MAXIMUM(e)                                       \
-  (((_GL_INT_CONVERT (e, 1) << (TYPE_WIDTH (+ (e)) - 2)) - 1) * 2 + 1)
-
-/* Work around OpenVMS incompatibility with C99.  */
-#if !defined LLONG_MAX && defined __INT64_MAX
-# define LLONG_MAX __INT64_MAX
-# define LLONG_MIN __INT64_MIN
-#endif
-
-/* This include file assumes that signed types are two's complement without
-   padding bits; the above macros have undefined behavior otherwise.
-   If this is a problem for you, please let us know how to fix it for your host.
-   This assumption is tested by the intprops-tests module.  */
-
-/* Does the __typeof__ keyword work?  This could be done by
-   'configure', but for now it's easier to do it by hand.  */
-#if (2 <= __GNUC__ \
-     || (4 <= __clang_major__) \
-     || (1210 <= __IBMC__ && defined __IBM__TYPEOF__) \
-     || (0x5110 <= __SUNPRO_C && !__STDC__))
-# define _GL_HAVE___TYPEOF__ 1
-#else
-# define _GL_HAVE___TYPEOF__ 0
-#endif
-
-/* Return 1 if the integer type or expression T might be signed.  Return 0
-   if it is definitely unsigned.  T must not be a bit-field expression.
-   This macro does not evaluate its argument, and expands to an
-   integer constant expression.  */
-#if _GL_HAVE___TYPEOF__
-# define _GL_SIGNED_TYPE_OR_EXPR(t) TYPE_SIGNED (__typeof__ (t))
-#else
-# define _GL_SIGNED_TYPE_OR_EXPR(t) 1
-#endif
-
 /* Bound on length of the string representing an unsigned integer
    value representable in B bits.  log10 (2.0) < 146/485.  The
    smallest value of B where this bound is not tight is 2621.  */
@@ -130,12 +75,11 @@
 /* Range overflow checks.
 
    The INT_<op>_RANGE_OVERFLOW macros return 1 if the corresponding C
-   operators might not yield numerically correct answers due to
-   arithmetic overflow.  They do not rely on undefined or
-   implementation-defined behavior.  Their implementations are simple
-   and straightforward, but they are harder to use and may be less
-   efficient than the INT_<op>_WRAPV, INT_<op>_OK, and
-   INT_<op>_OVERFLOW macros described below.
+   operators overflow arithmetically when given the same arguments.
+   These macros do not rely on undefined or implementation-defined behavior.
+   Although their implementations are simple and straightforward,
+   they are harder to use and may be less efficient than the
+   INT_<op>_WRAPV, INT_<op>_OK, and INT_<op>_OVERFLOW macros described below.
 
    Example usage:
 
@@ -182,9 +126,7 @@
 /* Return 1 if - A would overflow in [MIN,MAX] arithmetic.
    See above for restrictions.  */
 #define INT_NEGATE_RANGE_OVERFLOW(a, min, max)          \
-  ((min) < 0                                            \
-   ? (a) < - (max)                                      \
-   : 0 < (a))
+  _GL_INT_NEGATE_RANGE_OVERFLOW (a, min, max)
 
 /* Return 1 if A * B would overflow in [MIN,MAX] arithmetic.
    See above for restrictions.  Avoid && and || as they tickle
@@ -228,40 +170,6 @@
    ? (a) < (min) >> (b)                                 \
    : (max) >> (b) < (a))
 
-/* True if __builtin_add_overflow (A, B, P) and __builtin_sub_overflow
-   (A, B, P) work when P is non-null.  */
-/* __builtin_{add,sub}_overflow exists but is not reliable in GCC 5.x and 6.x,
-   see <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98269>.  */
-#if 7 <= __GNUC__ && !defined __ICC
-# define _GL_HAS_BUILTIN_ADD_OVERFLOW 1
-#elif defined __has_builtin
-# define _GL_HAS_BUILTIN_ADD_OVERFLOW __has_builtin (__builtin_add_overflow)
-#else
-# define _GL_HAS_BUILTIN_ADD_OVERFLOW 0
-#endif
-
-/* True if __builtin_mul_overflow (A, B, P) works when P is non-null.  */
-#ifdef __clang__
-/* Work around Clang bug <https://bugs.llvm.org/show_bug.cgi?id=16404>.  */
-# define _GL_HAS_BUILTIN_MUL_OVERFLOW 0
-#else
-# define _GL_HAS_BUILTIN_MUL_OVERFLOW _GL_HAS_BUILTIN_ADD_OVERFLOW
-#endif
-
-/* True if __builtin_add_overflow_p (A, B, C) works, and similarly for
-   __builtin_sub_overflow_p and __builtin_mul_overflow_p.  */
-#if defined __clang__ || defined __ICC
-/* Clang 11 lacks __builtin_mul_overflow_p, and even if it did it
-   would presumably run afoul of Clang bug 16404.  ICC 2021.1's
-   __builtin_add_overflow_p etc. are not treated as integral constant
-   expressions even when all arguments are.  */
-# define _GL_HAS_BUILTIN_OVERFLOW_P 0
-#elif defined __has_builtin
-# define _GL_HAS_BUILTIN_OVERFLOW_P __has_builtin (__builtin_mul_overflow_p)
-#else
-# define _GL_HAS_BUILTIN_OVERFLOW_P (7 <= __GNUC__)
-#endif
-
 /* The _GL*_OVERFLOW macros have the same restrictions as the
    *_RANGE_OVERFLOW macros, except that they do not assume that operands
    (e.g., A and B) have the same type as MIN and MAX.  Instead, they assume
@@ -348,13 +256,18 @@
    Because the WRAPV macros convert the result, they report overflow
    in different circumstances than the OVERFLOW macros do.  For
    example, in the typical case with 16-bit 'short' and 32-bit 'int',
-   if A, B and R are all of type 'short' then INT_ADD_OVERFLOW (A, B)
+   if A, B and *R are all of type 'short' then INT_ADD_OVERFLOW (A, B)
    returns false because the addition cannot overflow after A and B
-   are converted to 'int', whereas INT_ADD_WRAPV (A, B, &R) returns
+   are converted to 'int', whereas INT_ADD_WRAPV (A, B, R) returns
    true or false depending on whether the sum fits into 'short'.
 
    These macros are tuned for their last input argument being a constant.
 
+   A, B, and *R should be integers; they need not be the same type,
+   and they need not be all signed or all unsigned.
+   However, none of the integer types should be bit-precise,
+   and *R's type should not be char, bool, or an enumeration type.
+
    Return 1 if the integer expressions A * B, A - B, -A, A * B, A / B,
    A % B, and A << B would overflow, respectively.  */
 
@@ -362,12 +275,7 @@
   _GL_BINARY_OP_OVERFLOW (a, b, _GL_ADD_OVERFLOW)
 #define INT_SUBTRACT_OVERFLOW(a, b) \
   _GL_BINARY_OP_OVERFLOW (a, b, _GL_SUBTRACT_OVERFLOW)
-#if _GL_HAS_BUILTIN_OVERFLOW_P
-# define INT_NEGATE_OVERFLOW(a) INT_SUBTRACT_OVERFLOW (0, a)
-#else
-# define INT_NEGATE_OVERFLOW(a) \
-   INT_NEGATE_RANGE_OVERFLOW (a, _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a))
-#endif
+#define INT_NEGATE_OVERFLOW(a) _GL_INT_NEGATE_OVERFLOW (a)
 #define INT_MULTIPLY_OVERFLOW(a, b) \
   _GL_BINARY_OP_OVERFLOW (a, b, _GL_MULTIPLY_OVERFLOW)
 #define INT_DIVIDE_OVERFLOW(a, b) \
@@ -389,224 +297,9 @@
 
 /* Store the low-order bits of A + B, A - B, A * B, respectively, into *R.
    Return 1 if the result overflows.  See above for restrictions.  */
-#if _GL_HAS_BUILTIN_ADD_OVERFLOW
-# define INT_ADD_WRAPV(a, b, r) __builtin_add_overflow (a, b, r)
-# define INT_SUBTRACT_WRAPV(a, b, r) __builtin_sub_overflow (a, b, r)
-#else
-# define INT_ADD_WRAPV(a, b, r) \
-   _GL_INT_OP_WRAPV (a, b, r, +, _GL_INT_ADD_RANGE_OVERFLOW)
-# define INT_SUBTRACT_WRAPV(a, b, r) \
-   _GL_INT_OP_WRAPV (a, b, r, -, _GL_INT_SUBTRACT_RANGE_OVERFLOW)
-#endif
-#if _GL_HAS_BUILTIN_MUL_OVERFLOW
-# if ((9 < __GNUC__ + (3 <= __GNUC_MINOR__) \
-       || (__GNUC__ == 8 && 4 <= __GNUC_MINOR__)) \
-      && !defined __ICC)
-#  define INT_MULTIPLY_WRAPV(a, b, r) __builtin_mul_overflow (a, b, r)
-# else
-   /* Work around GCC bug 91450.  */
-#  define INT_MULTIPLY_WRAPV(a, b, r) \
-    ((!_GL_SIGNED_TYPE_OR_EXPR (*(r)) && EXPR_SIGNED (a) && EXPR_SIGNED (b) \
-      && _GL_INT_MULTIPLY_RANGE_OVERFLOW (a, b, 0, (__typeof__ (*(r))) -1)) \
-     ? ((void) __builtin_mul_overflow (a, b, r), 1) \
-     : __builtin_mul_overflow (a, b, r))
-# endif
-#else
-# define INT_MULTIPLY_WRAPV(a, b, r) \
-   _GL_INT_OP_WRAPV (a, b, r, *, _GL_INT_MULTIPLY_RANGE_OVERFLOW)
-#endif
-
-/* Nonzero if this compiler has GCC bug 68193 or Clang bug 25390.  See:
-   https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68193
-   https://llvm.org/bugs/show_bug.cgi?id=25390
-   For now, assume all versions of GCC-like compilers generate bogus
-   warnings for _Generic.  This matters only for compilers that
-   lack relevant builtins.  */
-#if __GNUC__ || defined __clang__
-# define _GL__GENERIC_BOGUS 1
-#else
-# define _GL__GENERIC_BOGUS 0
-#endif
-
-/* Store the low-order bits of A <op> B into *R, where OP specifies
-   the operation and OVERFLOW the overflow predicate.  Return 1 if the
-   result overflows.  See above for restrictions.  */
-#if 201112 <= __STDC_VERSION__ && !_GL__GENERIC_BOGUS
-# define _GL_INT_OP_WRAPV(a, b, r, op, overflow) \
-   (_Generic \
-    (*(r), \
-     signed char: \
-       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
-                        signed char, SCHAR_MIN, SCHAR_MAX), \
-     unsigned char: \
-       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
-                        unsigned char, 0, UCHAR_MAX), \
-     short int: \
-       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
-                        short int, SHRT_MIN, SHRT_MAX), \
-     unsigned short int: \
-       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
-                        unsigned short int, 0, USHRT_MAX), \
-     int: \
-       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
-                        int, INT_MIN, INT_MAX), \
-     unsigned int: \
-       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
-                        unsigned int, 0, UINT_MAX), \
-     long int: \
-       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \
-                        long int, LONG_MIN, LONG_MAX), \
-     unsigned long int: \
-       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \
-                        unsigned long int, 0, ULONG_MAX), \
-     long long int: \
-       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long long int, \
-                        long long int, LLONG_MIN, LLONG_MAX), \
-     unsigned long long int: \
-       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long long int, \
-                        unsigned long long int, 0, ULLONG_MAX)))
-#else
-/* Store the low-order bits of A <op> B into *R, where OP specifies
-   the operation and OVERFLOW the overflow predicate.  If *R is
-   signed, its type is ST with bounds SMIN..SMAX; otherwise its type
-   is UT with bounds U..UMAX.  ST and UT are narrower than int.
-   Return 1 if the result overflows.  See above for restrictions.  */
-# if _GL_HAVE___TYPEOF__
-#  define _GL_INT_OP_WRAPV_SMALLISH(a,b,r,op,overflow,st,smin,smax,ut,umax) \
-    (TYPE_SIGNED (__typeof__ (*(r))) \
-     ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, st, smin, smax) \
-     : _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, ut, 0, umax))
-# else
-#  define _GL_INT_OP_WRAPV_SMALLISH(a,b,r,op,overflow,st,smin,smax,ut,umax) \
-    (overflow (a, b, smin, smax) \
-     ? (overflow (a, b, 0, umax) \
-        ? (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a,b,op,unsigned,st), 1) \
-        : (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a,b,op,unsigned,st)) < 0) \
-     : (overflow (a, b, 0, umax) \
-        ? (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a,b,op,unsigned,st)) >= 0 \
-        : (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a,b,op,unsigned,st), 0)))
-# endif
-
-# define _GL_INT_OP_WRAPV(a, b, r, op, overflow) \
-   (sizeof *(r) == sizeof (signed char) \
-    ? _GL_INT_OP_WRAPV_SMALLISH (a, b, r, op, overflow, \
-                                 signed char, SCHAR_MIN, SCHAR_MAX, \
-                                 unsigned char, UCHAR_MAX) \
-    : sizeof *(r) == sizeof (short int) \
-    ? _GL_INT_OP_WRAPV_SMALLISH (a, b, r, op, overflow, \
-                                 short int, SHRT_MIN, SHRT_MAX, \
-                                 unsigned short int, USHRT_MAX) \
-    : sizeof *(r) == sizeof (int) \
-    ? (EXPR_SIGNED (*(r)) \
-       ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
-                          int, INT_MIN, INT_MAX) \
-       : _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
-                          unsigned int, 0, UINT_MAX)) \
-    : _GL_INT_OP_WRAPV_LONGISH(a, b, r, op, overflow))
-# ifdef LLONG_MAX
-#  define _GL_INT_OP_WRAPV_LONGISH(a, b, r, op, overflow) \
-    (sizeof *(r) == sizeof (long int) \
-     ? (EXPR_SIGNED (*(r)) \
-        ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \
-                           long int, LONG_MIN, LONG_MAX) \
-        : _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \
-                           unsigned long int, 0, ULONG_MAX)) \
-     : (EXPR_SIGNED (*(r)) \
-        ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long long int, \
-                           long long int, LLONG_MIN, LLONG_MAX) \
-        : _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long long int, \
-                           unsigned long long int, 0, ULLONG_MAX)))
-# else
-#  define _GL_INT_OP_WRAPV_LONGISH(a, b, r, op, overflow) \
-    (EXPR_SIGNED (*(r)) \
-     ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \
-                        long int, LONG_MIN, LONG_MAX) \
-     : _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \
-                        unsigned long int, 0, ULONG_MAX))
-# endif
-#endif
-
-/* Store the low-order bits of A <op> B into *R, where the operation
-   is given by OP.  Use the unsigned type UT for calculation to avoid
-   overflow problems.  *R's type is T, with extrema TMIN and TMAX.
-   T must be a signed integer type.  Return 1 if the result overflows.  */
-#define _GL_INT_OP_CALC(a, b, r, op, overflow, ut, t, tmin, tmax) \
-  (overflow (a, b, tmin, tmax) \
-   ? (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t), 1) \
-   : (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t), 0))
-
-/* Return the low-order bits of A <op> B, where the operation is given
-   by OP.  Use the unsigned type UT for calculation to avoid undefined
-   behavior on signed integer overflow, and convert the result to type T.
-   UT is at least as wide as T and is no narrower than unsigned int,
-   T is two's complement, and there is no padding or trap representations.
-   Assume that converting UT to T yields the low-order bits, as is
-   done in all known two's-complement C compilers.  E.g., see:
-   https://gcc.gnu.org/onlinedocs/gcc/Integers-implementation.html
-
-   According to the C standard, converting UT to T yields an
-   implementation-defined result or signal for values outside T's
-   range.  However, code that works around this theoretical problem
-   runs afoul of a compiler bug in Oracle Studio 12.3 x86.  See:
-   https://lists.gnu.org/r/bug-gnulib/2017-04/msg00049.html
-   As the compiler bug is real, don't try to work around the
-   theoretical problem.  */
-
-#define _GL_INT_OP_WRAPV_VIA_UNSIGNED(a, b, op, ut, t) \
-  ((t) ((ut) (a) op (ut) (b)))
-
-/* Return true if the numeric values A + B, A - B, A * B fall outside
-   the range TMIN..TMAX.  Arguments should be integer expressions
-   without side effects.  TMIN should be signed and nonpositive.
-   TMAX should be positive, and should be signed unless TMIN is zero.  */
-#define _GL_INT_ADD_RANGE_OVERFLOW(a, b, tmin, tmax) \
-  ((b) < 0 \
-   ? (((tmin) \
-       ? ((EXPR_SIGNED (_GL_INT_CONVERT (a, (tmin) - (b))) || (b) < (tmin)) \
-          && (a) < (tmin) - (b)) \
-       : (a) <= -1 - (b)) \
-      || ((EXPR_SIGNED (a) ? 0 <= (a) : (tmax) < (a)) && (tmax) < (a) + (b))) \
-   : (a) < 0 \
-   ? (((tmin) \
-       ? ((EXPR_SIGNED (_GL_INT_CONVERT (b, (tmin) - (a))) || (a) < (tmin)) \
-          && (b) < (tmin) - (a)) \
-       : (b) <= -1 - (a)) \
-      || ((EXPR_SIGNED (_GL_INT_CONVERT (a, b)) || (tmax) < (b)) \
-          && (tmax) < (a) + (b))) \
-   : (tmax) < (b) || (tmax) - (b) < (a))
-#define _GL_INT_SUBTRACT_RANGE_OVERFLOW(a, b, tmin, tmax) \
-  (((a) < 0) == ((b) < 0) \
-   ? ((a) < (b) \
-      ? !(tmin) || -1 - (tmin) < (b) - (a) - 1 \
-      : (tmax) < (a) - (b)) \
-   : (a) < 0 \
-   ? ((!EXPR_SIGNED (_GL_INT_CONVERT ((a) - (tmin), b)) && (a) - (tmin) < 0) \
-      || (a) - (tmin) < (b)) \
-   : ((! (EXPR_SIGNED (_GL_INT_CONVERT (tmax, b)) \
-          && EXPR_SIGNED (_GL_INT_CONVERT ((tmax) + (b), a))) \
-       && (tmax) <= -1 - (b)) \
-      || (tmax) + (b) < (a)))
-#define _GL_INT_MULTIPLY_RANGE_OVERFLOW(a, b, tmin, tmax) \
-  ((b) < 0 \
-   ? ((a) < 0 \
-      ? (EXPR_SIGNED (_GL_INT_CONVERT (tmax, b)) \
-         ? (a) < (tmax) / (b) \
-         : ((INT_NEGATE_OVERFLOW (b) \
-             ? _GL_INT_CONVERT (b, tmax) >> (TYPE_WIDTH (+ (b)) - 1) \
-             : (tmax) / -(b)) \
-            <= -1 - (a))) \
-      : INT_NEGATE_OVERFLOW (_GL_INT_CONVERT (b, tmin)) && (b) == -1 \
-      ? (EXPR_SIGNED (a) \
-         ? 0 < (a) + (tmin) \
-         : 0 < (a) && -1 - (tmin) < (a) - 1) \
-      : (tmin) / (b) < (a)) \
-   : (b) == 0 \
-   ? 0 \
-   : ((a) < 0 \
-      ? (INT_NEGATE_OVERFLOW (_GL_INT_CONVERT (a, tmin)) && (a) == -1 \
-         ? (EXPR_SIGNED (b) ? 0 < (b) + (tmin) : -1 - (tmin) < (b) - 1) \
-         : (tmin) / (a) < (b)) \
-      : (tmax) / (b) < (a)))
+#define INT_ADD_WRAPV(a, b, r) _GL_INT_ADD_WRAPV (a, b, r)
+#define INT_SUBTRACT_WRAPV(a, b, r) _GL_INT_SUBTRACT_WRAPV (a, b, r)
+#define INT_MULTIPLY_WRAPV(a, b, r) _GL_INT_MULTIPLY_WRAPV (a, b, r)
 
 /* The following macros compute A + B, A - B, and A * B, respectively.
    If no overflow occurs, they set *R to the result and return 1;
@@ -622,6 +315,8 @@
 
    A, B, and *R should be integers; they need not be the same type,
    and they need not be all signed or all unsigned.
+   However, none of the integer types should be bit-precise,
+   and *R's type should not be char, bool, or an enumeration type.
 
    These macros work correctly on all known practical hosts, and do not rely
    on undefined behavior due to signed arithmetic overflow.
@@ -633,8 +328,8 @@
 
    These macros are tuned for B being a constant.  */
 
-#define INT_ADD_OK(a, b, r) ! INT_ADD_WRAPV (a, b, r)
-#define INT_SUBTRACT_OK(a, b, r) ! INT_SUBTRACT_WRAPV (a, b, r)
-#define INT_MULTIPLY_OK(a, b, r) ! INT_MULTIPLY_WRAPV (a, b, r)
+#define INT_ADD_OK(a, b, r) (! INT_ADD_WRAPV (a, b, r))
+#define INT_SUBTRACT_OK(a, b, r) (! INT_SUBTRACT_WRAPV (a, b, r))
+#define INT_MULTIPLY_OK(a, b, r) (! INT_MULTIPLY_WRAPV (a, b, r))
 
 #endif /* _GL_INTPROPS_H */
diff --git a/lib/inttypes.h b/lib/inttypes.h
new file mode 100644
index 000000000..445a59959
--- /dev/null
+++ b/lib/inttypes.h
@@ -0,0 +1,1509 @@
+/* DO NOT EDIT! GENERATED AUTOMATICALLY! */
+/* Copyright (C) 2006-2022 Free Software Foundation, Inc.
+   Written by Paul Eggert, Bruno Haible, Derek Price.
+   This file is part of gnulib.
+
+   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 2.1 of the
+   License, or (at your option) any later version.
+
+   This file 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+/*
+ * ISO C 99 <inttypes.h> for platforms that lack it.
+ * <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/inttypes.h.html>
+ */
+
+#if __GNUC__ >= 3
+#pragma GCC system_header
+#endif
+
+
+/* Include the original <inttypes.h> if it exists, and if this file
+   has not been included yet or if this file includes gnulib stdint.h
+   which in turn includes this file.
+   The include_next requires a split double-inclusion guard.  */
+#if ! defined INTTYPES_H || defined _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H
+# if 1
+
+   /* Some pre-C++11 <stdint.h> implementations need this.  */
+#  if defined __cplusplus && ! defined __STDC_FORMAT_MACROS
+#   define __STDC_FORMAT_MACROS 1
+#  endif
+
+#  include_next <inttypes.h>
+
+#  define _GL_FINISHED_INCLUDING_SYSTEM_INTTYPES_H
+# endif
+#endif
+
+#if ! defined INTTYPES_H && ! defined _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H
+#define INTTYPES_H
+
+/* Include <stdint.h> or the gnulib replacement.
+   But avoid namespace pollution on glibc systems.  */
+#ifndef __GLIBC__
+# include <stdint.h>
+#endif
+/* Get CHAR_BIT, INT_MAX, LONG_MAX, etc.  */
+#include <limits.h>
+/* On mingw, __USE_MINGW_ANSI_STDIO only works if <stdio.h> is also included */
+#if defined _WIN32 && ! defined __CYGWIN__
+# include <stdio.h>
+#endif
+
+#if !(INT_MAX == 0x7fffffff && INT_MIN + INT_MAX == -1)
+# error "This file assumes that 'int' is 32-bit two's complement. Please report your platform and compiler to <bug-gnulib@gnu.org>."
+#endif
+
+/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */
+/* C++ compatible function declaration macros.
+   Copyright (C) 2010-2022 Free Software Foundation, Inc.
+
+   This program 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 2 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+#ifndef _GL_CXXDEFS_H
+#define _GL_CXXDEFS_H
+
+/* Begin/end the GNULIB_NAMESPACE namespace.  */
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+# define _GL_BEGIN_NAMESPACE namespace GNULIB_NAMESPACE {
+# define _GL_END_NAMESPACE }
+#else
+# define _GL_BEGIN_NAMESPACE
+# define _GL_END_NAMESPACE
+#endif
+
+/* The three most frequent use cases of these macros are:
+
+   * For providing a substitute for a function that is missing on some
+     platforms, but is declared and works fine on the platforms on which
+     it exists:
+
+       #if @GNULIB_FOO@
+       # if !@HAVE_FOO@
+       _GL_FUNCDECL_SYS (foo, ...);
+       # endif
+       _GL_CXXALIAS_SYS (foo, ...);
+       _GL_CXXALIASWARN (foo);
+       #elif defined GNULIB_POSIXCHECK
+       ...
+       #endif
+
+   * For providing a replacement for a function that exists on all platforms,
+     but is broken/insufficient and needs to be replaced on some platforms:
+
+       #if @GNULIB_FOO@
+       # if @REPLACE_FOO@
+       #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+       #   undef foo
+       #   define foo rpl_foo
+       #  endif
+       _GL_FUNCDECL_RPL (foo, ...);
+       _GL_CXXALIAS_RPL (foo, ...);
+       # else
+       _GL_CXXALIAS_SYS (foo, ...);
+       # endif
+       _GL_CXXALIASWARN (foo);
+       #elif defined GNULIB_POSIXCHECK
+       ...
+       #endif
+
+   * For providing a replacement for a function that exists on some platforms
+     but is broken/insufficient and needs to be replaced on some of them and
+     is additionally either missing or undeclared on some other platforms:
+
+       #if @GNULIB_FOO@
+       # if @REPLACE_FOO@
+       #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+       #   undef foo
+       #   define foo rpl_foo
+       #  endif
+       _GL_FUNCDECL_RPL (foo, ...);
+       _GL_CXXALIAS_RPL (foo, ...);
+       # else
+       #  if !@HAVE_FOO@   or   if !@HAVE_DECL_FOO@
+       _GL_FUNCDECL_SYS (foo, ...);
+       #  endif
+       _GL_CXXALIAS_SYS (foo, ...);
+       # endif
+       _GL_CXXALIASWARN (foo);
+       #elif defined GNULIB_POSIXCHECK
+       ...
+       #endif
+*/
+
+/* _GL_EXTERN_C declaration;
+   performs the declaration with C linkage.  */
+#if defined __cplusplus
+# define _GL_EXTERN_C extern "C"
+#else
+# define _GL_EXTERN_C extern
+#endif
+
+/* _GL_FUNCDECL_RPL (func, rettype, parameters_and_attributes);
+   declares a replacement function, named rpl_func, with the given prototype,
+   consisting of return type, parameters, and attributes.
+   Example:
+     _GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...)
+                                  _GL_ARG_NONNULL ((1)));
+ */
+#define _GL_FUNCDECL_RPL(func,rettype,parameters_and_attributes) \
+  _GL_FUNCDECL_RPL_1 (rpl_##func, rettype, parameters_and_attributes)
+#define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters_and_attributes) \
+  _GL_EXTERN_C rettype rpl_func parameters_and_attributes
+
+/* _GL_FUNCDECL_SYS (func, rettype, parameters_and_attributes);
+   declares the system function, named func, with the given prototype,
+   consisting of return type, parameters, and attributes.
+   Example:
+     _GL_FUNCDECL_SYS (open, int, (const char *filename, int flags, ...)
+                                  _GL_ARG_NONNULL ((1)));
+ */
+#define _GL_FUNCDECL_SYS(func,rettype,parameters_and_attributes) \
+  _GL_EXTERN_C rettype func parameters_and_attributes
+
+/* _GL_CXXALIAS_RPL (func, rettype, parameters);
+   declares a C++ alias called GNULIB_NAMESPACE::func
+   that redirects to rpl_func, if GNULIB_NAMESPACE is defined.
+   Example:
+     _GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...));
+
+   Wrapping rpl_func in an object with an inline conversion operator
+   avoids a reference to rpl_func unless GNULIB_NAMESPACE::func is
+   actually used in the program.  */
+#define _GL_CXXALIAS_RPL(func,rettype,parameters) \
+  _GL_CXXALIAS_RPL_1 (func, rpl_##func, rettype, parameters)
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \
+    namespace GNULIB_NAMESPACE                                \
+    {                                                         \
+      static const struct _gl_ ## func ## _wrapper            \
+      {                                                       \
+        typedef rettype (*type) parameters;                   \
+                                                              \
+        inline operator type () const                         \
+        {                                                     \
+          return ::rpl_func;                                  \
+        }                                                     \
+      } func = {};                                            \
+    }                                                         \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#else
+# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#endif
+
+/* _GL_CXXALIAS_MDA (func, rettype, parameters);
+   is to be used when func is a Microsoft deprecated alias, on native Windows.
+   It declares a C++ alias called GNULIB_NAMESPACE::func
+   that redirects to _func, if GNULIB_NAMESPACE is defined.
+   Example:
+     _GL_CXXALIAS_MDA (open, int, (const char *filename, int flags, ...));
+ */
+#define _GL_CXXALIAS_MDA(func,rettype,parameters) \
+  _GL_CXXALIAS_RPL_1 (func, _##func, rettype, parameters)
+
+/* _GL_CXXALIAS_RPL_CAST_1 (func, rpl_func, rettype, parameters);
+   is like  _GL_CXXALIAS_RPL_1 (func, rpl_func, rettype, parameters);
+   except that the C function rpl_func may have a slightly different
+   declaration.  A cast is used to silence the "invalid conversion" error
+   that would otherwise occur.  */
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \
+    namespace GNULIB_NAMESPACE                                     \
+    {                                                              \
+      static const struct _gl_ ## func ## _wrapper                 \
+      {                                                            \
+        typedef rettype (*type) parameters;                        \
+                                                                   \
+        inline operator type () const                              \
+        {                                                          \
+          return reinterpret_cast<type>(::rpl_func);               \
+        }                                                          \
+      } func = {};                                                 \
+    }                                                              \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#else
+# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#endif
+
+/* _GL_CXXALIAS_MDA_CAST (func, rettype, parameters);
+   is like  _GL_CXXALIAS_MDA (func, rettype, parameters);
+   except that the C function func may have a slightly different declaration.
+   A cast is used to silence the "invalid conversion" error that would
+   otherwise occur.  */
+#define _GL_CXXALIAS_MDA_CAST(func,rettype,parameters) \
+  _GL_CXXALIAS_RPL_CAST_1 (func, _##func, rettype, parameters)
+
+/* _GL_CXXALIAS_SYS (func, rettype, parameters);
+   declares a C++ alias called GNULIB_NAMESPACE::func
+   that redirects to the system provided function func, if GNULIB_NAMESPACE
+   is defined.
+   Example:
+     _GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...));
+
+   Wrapping func in an object with an inline conversion operator
+   avoids a reference to func unless GNULIB_NAMESPACE::func is
+   actually used in the program.  */
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+# define _GL_CXXALIAS_SYS(func,rettype,parameters)            \
+    namespace GNULIB_NAMESPACE                                \
+    {                                                         \
+      static const struct _gl_ ## func ## _wrapper            \
+      {                                                       \
+        typedef rettype (*type) parameters;                   \
+                                                              \
+        inline operator type () const                         \
+        {                                                     \
+          return ::func;                                      \
+        }                                                     \
+      } func = {};                                            \
+    }                                                         \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#else
+# define _GL_CXXALIAS_SYS(func,rettype,parameters) \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#endif
+
+/* _GL_CXXALIAS_SYS_CAST (func, rettype, parameters);
+   is like  _GL_CXXALIAS_SYS (func, rettype, parameters);
+   except that the C function func may have a slightly different declaration.
+   A cast is used to silence the "invalid conversion" error that would
+   otherwise occur.  */
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \
+    namespace GNULIB_NAMESPACE                          \
+    {                                                   \
+      static const struct _gl_ ## func ## _wrapper      \
+      {                                                 \
+        typedef rettype (*type) parameters;             \
+                                                        \
+        inline operator type () const                   \
+        {                                               \
+          return reinterpret_cast<type>(::func);        \
+        }                                               \
+      } func = {};                                      \
+    }                                                   \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#else
+# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#endif
+
+/* _GL_CXXALIAS_SYS_CAST2 (func, rettype, parameters, rettype2, parameters2);
+   is like  _GL_CXXALIAS_SYS (func, rettype, parameters);
+   except that the C function is picked among a set of overloaded functions,
+   namely the one with rettype2 and parameters2.  Two consecutive casts
+   are used to silence the "cannot find a match" and "invalid conversion"
+   errors that would otherwise occur.  */
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+  /* The outer cast must be a reinterpret_cast.
+     The inner cast: When the function is defined as a set of overloaded
+     functions, it works as a static_cast<>, choosing the designated variant.
+     When the function is defined as a single variant, it works as a
+     reinterpret_cast<>. The parenthesized cast syntax works both ways.  */
+# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \
+    namespace GNULIB_NAMESPACE                                                \
+    {                                                                         \
+      static const struct _gl_ ## func ## _wrapper                            \
+      {                                                                       \
+        typedef rettype (*type) parameters;                                   \
+                                                                              \
+        inline operator type () const                                         \
+        {                                                                     \
+          return reinterpret_cast<type>((rettype2 (*) parameters2)(::func));  \
+        }                                                                     \
+      } func = {};                                                            \
+    }                                                                         \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#else
+# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#endif
+
+/* _GL_CXXALIASWARN (func);
+   causes a warning to be emitted when ::func is used but not when
+   GNULIB_NAMESPACE::func is used.  func must be defined without overloaded
+   variants.  */
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+# define _GL_CXXALIASWARN(func) \
+   _GL_CXXALIASWARN_1 (func, GNULIB_NAMESPACE)
+# define _GL_CXXALIASWARN_1(func,namespace) \
+   _GL_CXXALIASWARN_2 (func, namespace)
+/* To work around GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,
+   we enable the warning only when not optimizing.  */
+# if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__)
+#  define _GL_CXXALIASWARN_2(func,namespace) \
+    _GL_WARN_ON_USE (func, \
+                     "The symbol ::" #func " refers to the system function. " \
+                     "Use " #namespace "::" #func " instead.")
+# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
+#  define _GL_CXXALIASWARN_2(func,namespace) \
+     extern __typeof__ (func) func
+# else
+#  define _GL_CXXALIASWARN_2(func,namespace) \
+     _GL_EXTERN_C int _gl_cxxalias_dummy
+# endif
+#else
+# define _GL_CXXALIASWARN(func) \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#endif
+
+/* _GL_CXXALIASWARN1 (func, rettype, parameters_and_attributes);
+   causes a warning to be emitted when the given overloaded variant of ::func
+   is used but not when GNULIB_NAMESPACE::func is used.  */
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \
+   _GL_CXXALIASWARN1_1 (func, rettype, parameters_and_attributes, \
+                        GNULIB_NAMESPACE)
+# define _GL_CXXALIASWARN1_1(func,rettype,parameters_and_attributes,namespace) \
+   _GL_CXXALIASWARN1_2 (func, rettype, parameters_and_attributes, namespace)
+/* To work around GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,
+   we enable the warning only when not optimizing.  */
+# if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__)
+#  define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
+    _GL_WARN_ON_USE_CXX (func, rettype, rettype, parameters_and_attributes, \
+                         "The symbol ::" #func " refers to the system function. " \
+                         "Use " #namespace "::" #func " instead.")
+# else
+#  define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
+     _GL_EXTERN_C int _gl_cxxalias_dummy
+# endif
+#else
+# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#endif
+
+#endif /* _GL_CXXDEFS_H */
+
+/* The definition of _GL_ARG_NONNULL is copied here.  */
+/* A C macro for declaring that specific arguments must not be NULL.
+   Copyright (C) 2009-2022 Free Software Foundation, Inc.
+
+   This program 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 2 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+/* _GL_ARG_NONNULL((n,...,m)) tells the compiler and static analyzer tools
+   that the values passed as arguments n, ..., m must be non-NULL pointers.
+   n = 1 stands for the first argument, n = 2 for the second argument etc.  */
+#ifndef _GL_ARG_NONNULL
+# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || defined __clang__
+#  define _GL_ARG_NONNULL(params) __attribute__ ((__nonnull__ params))
+# else
+#  define _GL_ARG_NONNULL(params)
+# endif
+#endif
+
+/* The definition of _GL_WARN_ON_USE is copied here.  */
+/* A C macro for emitting warnings if a function is used.
+   Copyright (C) 2010-2022 Free Software Foundation, Inc.
+
+   This program 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 2 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+/* _GL_WARN_ON_USE (function, "literal string") issues a declaration
+   for FUNCTION which will then trigger a compiler warning containing
+   the text of "literal string" anywhere that function is called, if
+   supported by the compiler.  If the compiler does not support this
+   feature, the macro expands to an unused extern declaration.
+
+   _GL_WARN_ON_USE_ATTRIBUTE ("literal string") expands to the
+   attribute used in _GL_WARN_ON_USE.  If the compiler does not support
+   this feature, it expands to empty.
+
+   These macros are useful for marking a function as a potential
+   portability trap, with the intent that "literal string" include
+   instructions on the replacement function that should be used
+   instead.
+   _GL_WARN_ON_USE is for functions with 'extern' linkage.
+   _GL_WARN_ON_USE_ATTRIBUTE is for functions with 'static' or 'inline'
+   linkage.
+
+   However, one of the reasons that a function is a portability trap is
+   if it has the wrong signature.  Declaring FUNCTION with a different
+   signature in C is a compilation error, so this macro must use the
+   same type as any existing declaration so that programs that avoid
+   the problematic FUNCTION do not fail to compile merely because they
+   included a header that poisoned the function.  But this implies that
+   _GL_WARN_ON_USE is only safe to use if FUNCTION is known to already
+   have a declaration.  Use of this macro implies that there must not
+   be any other macro hiding the declaration of FUNCTION; but
+   undefining FUNCTION first is part of the poisoning process anyway
+   (although for symbols that are provided only via a macro, the result
+   is a compilation error rather than a warning containing
+   "literal string").  Also note that in C++, it is only safe to use if
+   FUNCTION has no overloads.
+
+   For an example, it is possible to poison 'getline' by:
+   - adding a call to gl_WARN_ON_USE_PREPARE([[#include <stdio.h>]],
+     [getline]) in configure.ac, which potentially defines
+     HAVE_RAW_DECL_GETLINE
+   - adding this code to a header that wraps the system <stdio.h>:
+     #undef getline
+     #if HAVE_RAW_DECL_GETLINE
+     _GL_WARN_ON_USE (getline, "getline is required by POSIX 2008, but"
+       "not universally present; use the gnulib module getline");
+     #endif
+
+   It is not possible to directly poison global variables.  But it is
+   possible to write a wrapper accessor function, and poison that
+   (less common usage, like &environ, will cause a compilation error
+   rather than issue the nice warning, but the end result of informing
+   the developer about their portability problem is still achieved):
+     #if HAVE_RAW_DECL_ENVIRON
+     static char ***
+     rpl_environ (void) { return &environ; }
+     _GL_WARN_ON_USE (rpl_environ, "environ is not always properly declared");
+     # undef environ
+     # define environ (*rpl_environ ())
+     #endif
+   or better (avoiding contradictory use of 'static' and 'extern'):
+     #if HAVE_RAW_DECL_ENVIRON
+     static char ***
+     _GL_WARN_ON_USE_ATTRIBUTE ("environ is not always properly declared")
+     rpl_environ (void) { return &environ; }
+     # undef environ
+     # define environ (*rpl_environ ())
+     #endif
+   */
+#ifndef _GL_WARN_ON_USE
+
+# if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)
+/* A compiler attribute is available in gcc versions 4.3.0 and later.  */
+#  define _GL_WARN_ON_USE(function, message) \
+_GL_WARN_EXTERN_C __typeof__ (function) function __attribute__ ((__warning__ (message)))
+#  define _GL_WARN_ON_USE_ATTRIBUTE(message) \
+  __attribute__ ((__warning__ (message)))
+# elif __clang_major__ >= 4
+/* Another compiler attribute is available in clang.  */
+#  define _GL_WARN_ON_USE(function, message) \
+_GL_WARN_EXTERN_C __typeof__ (function) function \
+  __attribute__ ((__diagnose_if__ (1, message, "warning")))
+#  define _GL_WARN_ON_USE_ATTRIBUTE(message) \
+  __attribute__ ((__diagnose_if__ (1, message, "warning")))
+# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
+/* Verify the existence of the function.  */
+#  define _GL_WARN_ON_USE(function, message) \
+_GL_WARN_EXTERN_C __typeof__ (function) function
+#  define _GL_WARN_ON_USE_ATTRIBUTE(message)
+# else /* Unsupported.  */
+#  define _GL_WARN_ON_USE(function, message) \
+_GL_WARN_EXTERN_C int _gl_warn_on_use
+#  define _GL_WARN_ON_USE_ATTRIBUTE(message)
+# endif
+#endif
+
+/* _GL_WARN_ON_USE_CXX (function, rettype_gcc, rettype_clang, parameters_and_attributes, "message")
+   is like _GL_WARN_ON_USE (function, "message"), except that in C++ mode the
+   function is declared with the given prototype, consisting of return type,
+   parameters, and attributes.
+   This variant is useful for overloaded functions in C++. _GL_WARN_ON_USE does
+   not work in this case.  */
+#ifndef _GL_WARN_ON_USE_CXX
+# if !defined __cplusplus
+#  define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \
+     _GL_WARN_ON_USE (function, msg)
+# else
+#  if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)
+/* A compiler attribute is available in gcc versions 4.3.0 and later.  */
+#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \
+extern rettype_gcc function parameters_and_attributes \
+  __attribute__ ((__warning__ (msg)))
+#  elif __clang_major__ >= 4
+/* Another compiler attribute is available in clang.  */
+#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \
+extern rettype_clang function parameters_and_attributes \
+  __attribute__ ((__diagnose_if__ (1, msg, "warning")))
+#  elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
+/* Verify the existence of the function.  */
+#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \
+extern rettype_gcc function parameters_and_attributes
+#  else /* Unsupported.  */
+#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \
+_GL_WARN_EXTERN_C int _gl_warn_on_use
+#  endif
+# endif
+#endif
+
+/* _GL_WARN_EXTERN_C declaration;
+   performs the declaration with C linkage.  */
+#ifndef _GL_WARN_EXTERN_C
+# if defined __cplusplus
+#  define _GL_WARN_EXTERN_C extern "C"
+# else
+#  define _GL_WARN_EXTERN_C extern
+# endif
+#endif
+
+/* 7.8.1 Macros for format specifiers */
+
+#if defined _TNS_R_TARGET
+   /* Tandem NonStop R series and compatible platforms released before
+      July 2005 support %Ld but not %lld.  */
+# define _LONG_LONG_FORMAT_PREFIX "L"
+#else
+# define _LONG_LONG_FORMAT_PREFIX "ll"
+#endif
+
+#if !defined PRId8
+# ifdef INT8_MAX
+#  define PRId8 "d"
+# endif
+#endif
+#if !defined PRIi8
+# ifdef INT8_MAX
+#  define PRIi8 "i"
+# endif
+#endif
+#if !defined PRIo8
+# ifdef UINT8_MAX
+#  define PRIo8 "o"
+# endif
+#endif
+#if !defined PRIu8
+# ifdef UINT8_MAX
+#  define PRIu8 "u"
+# endif
+#endif
+#if !defined PRIx8
+# ifdef UINT8_MAX
+#  define PRIx8 "x"
+# endif
+#endif
+#if !defined PRIX8
+# ifdef UINT8_MAX
+#  define PRIX8 "X"
+# endif
+#endif
+#if !defined PRId16
+# ifdef INT16_MAX
+#  define PRId16 "d"
+# endif
+#endif
+#if !defined PRIi16
+# ifdef INT16_MAX
+#  define PRIi16 "i"
+# endif
+#endif
+#if !defined PRIo16
+# ifdef UINT16_MAX
+#  define PRIo16 "o"
+# endif
+#endif
+#if !defined PRIu16
+# ifdef UINT16_MAX
+#  define PRIu16 "u"
+# endif
+#endif
+#if !defined PRIx16
+# ifdef UINT16_MAX
+#  define PRIx16 "x"
+# endif
+#endif
+#if !defined PRIX16
+# ifdef UINT16_MAX
+#  define PRIX16 "X"
+# endif
+#endif
+#if !defined PRId32
+# ifdef INT32_MAX
+#  define PRId32 "d"
+# endif
+#endif
+#if !defined PRIi32
+# ifdef INT32_MAX
+#  define PRIi32 "i"
+# endif
+#endif
+#if !defined PRIo32
+# ifdef UINT32_MAX
+#  define PRIo32 "o"
+# endif
+#endif
+#if !defined PRIu32
+# ifdef UINT32_MAX
+#  define PRIu32 "u"
+# endif
+#endif
+#if !defined PRIx32
+# ifdef UINT32_MAX
+#  define PRIx32 "x"
+# endif
+#endif
+#if !defined PRIX32
+# ifdef UINT32_MAX
+#  define PRIX32 "X"
+# endif
+#endif
+#ifdef INT64_MAX
+# if (0 ? defined _LP64 : defined _LP64)
+#  define _PRI64_PREFIX "l"
+# elif defined _MSC_VER || defined __MINGW32__
+#  define _PRI64_PREFIX "I64"
+# elif LONG_MAX >> 30 == 1
+#  define _PRI64_PREFIX _LONG_LONG_FORMAT_PREFIX
+# endif
+# if !defined PRId64
+#  define PRId64 _PRI64_PREFIX "d"
+# endif
+# if !defined PRIi64
+#  define PRIi64 _PRI64_PREFIX "i"
+# endif
+#endif
+#ifdef UINT64_MAX
+# if (0 ? defined _LP64 : defined _LP64)
+#  define _PRIu64_PREFIX "l"
+# elif defined _MSC_VER || defined __MINGW32__
+#  define _PRIu64_PREFIX "I64"
+# elif ULONG_MAX >> 31 == 1
+#  define _PRIu64_PREFIX _LONG_LONG_FORMAT_PREFIX
+# endif
+# if !defined PRIo64
+#  define PRIo64 _PRIu64_PREFIX "o"
+# endif
+# if !defined PRIu64
+#  define PRIu64 _PRIu64_PREFIX "u"
+# endif
+# if !defined PRIx64
+#  define PRIx64 _PRIu64_PREFIX "x"
+# endif
+# if !defined PRIX64
+#  define PRIX64 _PRIu64_PREFIX "X"
+# endif
+#endif
+
+#if !defined PRIdLEAST8
+# define PRIdLEAST8 "d"
+#endif
+#if !defined PRIiLEAST8
+# define PRIiLEAST8 "i"
+#endif
+#if !defined PRIoLEAST8
+# define PRIoLEAST8 "o"
+#endif
+#if !defined PRIuLEAST8
+# define PRIuLEAST8 "u"
+#endif
+#if !defined PRIxLEAST8
+# define PRIxLEAST8 "x"
+#endif
+#if !defined PRIXLEAST8
+# define PRIXLEAST8 "X"
+#endif
+#if !defined PRIdLEAST16
+# define PRIdLEAST16 "d"
+#endif
+#if !defined PRIiLEAST16
+# define PRIiLEAST16 "i"
+#endif
+#if !defined PRIoLEAST16
+# define PRIoLEAST16 "o"
+#endif
+#if !defined PRIuLEAST16
+# define PRIuLEAST16 "u"
+#endif
+#if !defined PRIxLEAST16
+# define PRIxLEAST16 "x"
+#endif
+#if !defined PRIXLEAST16
+# define PRIXLEAST16 "X"
+#endif
+#if !defined PRIdLEAST32
+# define PRIdLEAST32 "d"
+#endif
+#if !defined PRIiLEAST32
+# define PRIiLEAST32 "i"
+#endif
+#if !defined PRIoLEAST32
+# define PRIoLEAST32 "o"
+#endif
+#if !defined PRIuLEAST32
+# define PRIuLEAST32 "u"
+#endif
+#if !defined PRIxLEAST32
+# define PRIxLEAST32 "x"
+#endif
+#if !defined PRIXLEAST32
+# define PRIXLEAST32 "X"
+#endif
+#ifdef INT64_MAX
+# if !defined PRIdLEAST64
+#  define PRIdLEAST64 PRId64
+# endif
+# if !defined PRIiLEAST64
+#  define PRIiLEAST64 PRIi64
+# endif
+#endif
+#ifdef UINT64_MAX
+# if !defined PRIoLEAST64
+#  define PRIoLEAST64 PRIo64
+# endif
+# if !defined PRIuLEAST64
+#  define PRIuLEAST64 PRIu64
+# endif
+# if !defined PRIxLEAST64
+#  define PRIxLEAST64 PRIx64
+# endif
+# if !defined PRIXLEAST64
+#  define PRIXLEAST64 PRIX64
+# endif
+#endif
+
+#if !defined PRIdFAST8
+# if INT_FAST8_MAX > INT32_MAX
+#  define PRIdFAST8 PRId64
+# else
+#  define PRIdFAST8 "d"
+# endif
+#endif
+#if !defined PRIiFAST8
+# if INT_FAST8_MAX > INT32_MAX
+#  define PRIiFAST8 PRIi64
+# else
+#  define PRIiFAST8 "i"
+# endif
+#endif
+#if !defined PRIoFAST8
+# if UINT_FAST8_MAX > UINT32_MAX
+#  define PRIoFAST8 PRIo64
+# else
+#  define PRIoFAST8 "o"
+# endif
+#endif
+#if !defined PRIuFAST8
+# if UINT_FAST8_MAX > UINT32_MAX
+#  define PRIuFAST8 PRIu64
+# else
+#  define PRIuFAST8 "u"
+# endif
+#endif
+#if !defined PRIxFAST8
+# if UINT_FAST8_MAX > UINT32_MAX
+#  define PRIxFAST8 PRIx64
+# else
+#  define PRIxFAST8 "x"
+# endif
+#endif
+#if !defined PRIXFAST8
+# if UINT_FAST8_MAX > UINT32_MAX
+#  define PRIXFAST8 PRIX64
+# else
+#  define PRIXFAST8 "X"
+# endif
+#endif
+#if !defined PRIdFAST16
+# if INT_FAST16_MAX > INT32_MAX
+#  define PRIdFAST16 PRId64
+# else
+#  define PRIdFAST16 "d"
+# endif
+#endif
+#if !defined PRIiFAST16
+# if INT_FAST16_MAX > INT32_MAX
+#  define PRIiFAST16 PRIi64
+# else
+#  define PRIiFAST16 "i"
+# endif
+#endif
+#if !defined PRIoFAST16
+# if UINT_FAST16_MAX > UINT32_MAX
+#  define PRIoFAST16 PRIo64
+# else
+#  define PRIoFAST16 "o"
+# endif
+#endif
+#if !defined PRIuFAST16
+# if UINT_FAST16_MAX > UINT32_MAX
+#  define PRIuFAST16 PRIu64
+# else
+#  define PRIuFAST16 "u"
+# endif
+#endif
+#if !defined PRIxFAST16
+# if UINT_FAST16_MAX > UINT32_MAX
+#  define PRIxFAST16 PRIx64
+# else
+#  define PRIxFAST16 "x"
+# endif
+#endif
+#if !defined PRIXFAST16
+# if UINT_FAST16_MAX > UINT32_MAX
+#  define PRIXFAST16 PRIX64
+# else
+#  define PRIXFAST16 "X"
+# endif
+#endif
+#if !defined PRIdFAST32
+# if INT_FAST32_MAX > INT32_MAX
+#  define PRIdFAST32 PRId64
+# else
+#  define PRIdFAST32 "d"
+# endif
+#endif
+#if !defined PRIiFAST32
+# if INT_FAST32_MAX > INT32_MAX
+#  define PRIiFAST32 PRIi64
+# else
+#  define PRIiFAST32 "i"
+# endif
+#endif
+#if !defined PRIoFAST32
+# if UINT_FAST32_MAX > UINT32_MAX
+#  define PRIoFAST32 PRIo64
+# else
+#  define PRIoFAST32 "o"
+# endif
+#endif
+#if !defined PRIuFAST32
+# if UINT_FAST32_MAX > UINT32_MAX
+#  define PRIuFAST32 PRIu64
+# else
+#  define PRIuFAST32 "u"
+# endif
+#endif
+#if !defined PRIxFAST32
+# if UINT_FAST32_MAX > UINT32_MAX
+#  define PRIxFAST32 PRIx64
+# else
+#  define PRIxFAST32 "x"
+# endif
+#endif
+#if !defined PRIXFAST32
+# if UINT_FAST32_MAX > UINT32_MAX
+#  define PRIXFAST32 PRIX64
+# else
+#  define PRIXFAST32 "X"
+# endif
+#endif
+#ifdef INT64_MAX
+# if !defined PRIdFAST64
+#  define PRIdFAST64 PRId64
+# endif
+# if !defined PRIiFAST64
+#  define PRIiFAST64 PRIi64
+# endif
+#endif
+#ifdef UINT64_MAX
+# if !defined PRIoFAST64
+#  define PRIoFAST64 PRIo64
+# endif
+# if !defined PRIuFAST64
+#  define PRIuFAST64 PRIu64
+# endif
+# if !defined PRIxFAST64
+#  define PRIxFAST64 PRIx64
+# endif
+# if !defined PRIXFAST64
+#  define PRIXFAST64 PRIX64
+# endif
+#endif
+
+#if !defined PRIdMAX
+# if 1
+#  define PRIdMAX PRId64
+# else
+#  define PRIdMAX "ld"
+# endif
+#endif
+#if !defined PRIiMAX
+# if 1
+#  define PRIiMAX PRIi64
+# else
+#  define PRIiMAX "li"
+# endif
+#endif
+#if !defined PRIoMAX
+# if 1
+#  define PRIoMAX PRIo64
+# else
+#  define PRIoMAX "lo"
+# endif
+#endif
+#if !defined PRIuMAX
+# if 1
+#  define PRIuMAX PRIu64
+# else
+#  define PRIuMAX "lu"
+# endif
+#endif
+#if !defined PRIxMAX
+# if 1
+#  define PRIxMAX PRIx64
+# else
+#  define PRIxMAX "lx"
+# endif
+#endif
+#if !defined PRIXMAX
+# if 1
+#  define PRIXMAX PRIX64
+# else
+#  define PRIXMAX "lX"
+# endif
+#endif
+
+#if !defined PRIdPTR
+# ifdef INTPTR_MAX
+#  define PRIdPTR __PRIPTR_PREFIX "d"
+# endif
+#endif
+#if !defined PRIiPTR
+# ifdef INTPTR_MAX
+#  define PRIiPTR __PRIPTR_PREFIX "i"
+# endif
+#endif
+#if !defined PRIoPTR
+# ifdef UINTPTR_MAX
+#  define PRIoPTR __PRIPTR_PREFIX "o"
+# endif
+#endif
+#if !defined PRIuPTR
+# ifdef UINTPTR_MAX
+#  define PRIuPTR __PRIPTR_PREFIX "u"
+# endif
+#endif
+#if !defined PRIxPTR
+# ifdef UINTPTR_MAX
+#  define PRIxPTR __PRIPTR_PREFIX "x"
+# endif
+#endif
+#if !defined PRIXPTR
+# ifdef UINTPTR_MAX
+#  define PRIXPTR __PRIPTR_PREFIX "X"
+# endif
+#endif
+
+#if !defined SCNd8
+# ifdef INT8_MAX
+#  define SCNd8 "hhd"
+# endif
+#endif
+#if !defined SCNi8
+# ifdef INT8_MAX
+#  define SCNi8 "hhi"
+# endif
+#endif
+#if !defined SCNo8
+# ifdef UINT8_MAX
+#  define SCNo8 "hho"
+# endif
+#endif
+#if !defined SCNu8
+# ifdef UINT8_MAX
+#  define SCNu8 "hhu"
+# endif
+#endif
+#if !defined SCNx8
+# ifdef UINT8_MAX
+#  define SCNx8 "hhx"
+# endif
+#endif
+#if !defined SCNd16
+# ifdef INT16_MAX
+#  define SCNd16 "hd"
+# endif
+#endif
+#if !defined SCNi16
+# ifdef INT16_MAX
+#  define SCNi16 "hi"
+# endif
+#endif
+#if !defined SCNo16
+# ifdef UINT16_MAX
+#  define SCNo16 "ho"
+# endif
+#endif
+#if !defined SCNu16
+# ifdef UINT16_MAX
+#  define SCNu16 "hu"
+# endif
+#endif
+#if !defined SCNx16
+# ifdef UINT16_MAX
+#  define SCNx16 "hx"
+# endif
+#endif
+#if !defined SCNd32
+# ifdef INT32_MAX
+#  define SCNd32 "d"
+# endif
+#endif
+#if !defined SCNi32
+# ifdef INT32_MAX
+#  define SCNi32 "i"
+# endif
+#endif
+#if !defined SCNo32
+# ifdef UINT32_MAX
+#  define SCNo32 "o"
+# endif
+#endif
+#if !defined SCNu32
+# ifdef UINT32_MAX
+#  define SCNu32 "u"
+# endif
+#endif
+#if !defined SCNx32
+# ifdef UINT32_MAX
+#  define SCNx32 "x"
+# endif
+#endif
+#ifdef INT64_MAX
+# if (0 ? defined _LP64 : defined _LP64)
+#  define _SCN64_PREFIX "l"
+# elif defined _MSC_VER || defined __MINGW32__
+#  define _SCN64_PREFIX "I64"
+# elif LONG_MAX >> 30 == 1
+#  define _SCN64_PREFIX _LONG_LONG_FORMAT_PREFIX
+# endif
+# if !defined SCNd64
+#  define SCNd64 _SCN64_PREFIX "d"
+# endif
+# if !defined SCNi64
+#  define SCNi64 _SCN64_PREFIX "i"
+# endif
+#endif
+#ifdef UINT64_MAX
+# if (0 ? defined _LP64 : defined _LP64)
+#  define _SCNu64_PREFIX "l"
+# elif defined _MSC_VER || defined __MINGW32__
+#  define _SCNu64_PREFIX "I64"
+# elif ULONG_MAX >> 31 == 1
+#  define _SCNu64_PREFIX _LONG_LONG_FORMAT_PREFIX
+# endif
+# if !defined SCNo64
+#  define SCNo64 _SCNu64_PREFIX "o"
+# endif
+# if !defined SCNu64
+#  define SCNu64 _SCNu64_PREFIX "u"
+# endif
+# if !defined SCNx64
+#  define SCNx64 _SCNu64_PREFIX "x"
+# endif
+#endif
+
+#if !defined SCNdLEAST8
+# define SCNdLEAST8 "hhd"
+#endif
+#if !defined SCNiLEAST8
+# define SCNiLEAST8 "hhi"
+#endif
+#if !defined SCNoLEAST8
+# define SCNoLEAST8 "hho"
+#endif
+#if !defined SCNuLEAST8
+# define SCNuLEAST8 "hhu"
+#endif
+#if !defined SCNxLEAST8
+# define SCNxLEAST8 "hhx"
+#endif
+#if !defined SCNdLEAST16
+# define SCNdLEAST16 "hd"
+#endif
+#if !defined SCNiLEAST16
+# define SCNiLEAST16 "hi"
+#endif
+#if !defined SCNoLEAST16
+# define SCNoLEAST16 "ho"
+#endif
+#if !defined SCNuLEAST16
+# define SCNuLEAST16 "hu"
+#endif
+#if !defined SCNxLEAST16
+# define SCNxLEAST16 "hx"
+#endif
+#if !defined SCNdLEAST32
+# define SCNdLEAST32 "d"
+#endif
+#if !defined SCNiLEAST32
+# define SCNiLEAST32 "i"
+#endif
+#if !defined SCNoLEAST32
+# define SCNoLEAST32 "o"
+#endif
+#if !defined SCNuLEAST32
+# define SCNuLEAST32 "u"
+#endif
+#if !defined SCNxLEAST32
+# define SCNxLEAST32 "x"
+#endif
+#ifdef INT64_MAX
+# if !defined SCNdLEAST64
+#  define SCNdLEAST64 SCNd64
+# endif
+# if !defined SCNiLEAST64
+#  define SCNiLEAST64 SCNi64
+# endif
+#endif
+#ifdef UINT64_MAX
+# if !defined SCNoLEAST64
+#  define SCNoLEAST64 SCNo64
+# endif
+# if !defined SCNuLEAST64
+#  define SCNuLEAST64 SCNu64
+# endif
+# if !defined SCNxLEAST64
+#  define SCNxLEAST64 SCNx64
+# endif
+#endif
+
+#if !defined SCNdFAST8
+# if INT_FAST8_MAX > INT32_MAX
+#  define SCNdFAST8 SCNd64
+# elif INT_FAST8_MAX == 0x7fff
+#  define SCNdFAST8 "hd"
+# elif INT_FAST8_MAX == 0x7f
+#  define SCNdFAST8 "hhd"
+# else
+#  define SCNdFAST8 "d"
+# endif
+#endif
+#if !defined SCNiFAST8
+# if INT_FAST8_MAX > INT32_MAX
+#  define SCNiFAST8 SCNi64
+# elif INT_FAST8_MAX == 0x7fff
+#  define SCNiFAST8 "hi"
+# elif INT_FAST8_MAX == 0x7f
+#  define SCNiFAST8 "hhi"
+# else
+#  define SCNiFAST8 "i"
+# endif
+#endif
+#if !defined SCNoFAST8
+# if UINT_FAST8_MAX > UINT32_MAX
+#  define SCNoFAST8 SCNo64
+# elif UINT_FAST8_MAX == 0xffff
+#  define SCNoFAST8 "ho"
+# elif UINT_FAST8_MAX == 0xff
+#  define SCNoFAST8 "hho"
+# else
+#  define SCNoFAST8 "o"
+# endif
+#endif
+#if !defined SCNuFAST8
+# if UINT_FAST8_MAX > UINT32_MAX
+#  define SCNuFAST8 SCNu64
+# elif UINT_FAST8_MAX == 0xffff
+#  define SCNuFAST8 "hu"
+# elif UINT_FAST8_MAX == 0xff
+#  define SCNuFAST8 "hhu"
+# else
+#  define SCNuFAST8 "u"
+# endif
+#endif
+#if !defined SCNxFAST8
+# if UINT_FAST8_MAX > UINT32_MAX
+#  define SCNxFAST8 SCNx64
+# elif UINT_FAST8_MAX == 0xffff
+#  define SCNxFAST8 "hx"
+# elif UINT_FAST8_MAX == 0xff
+#  define SCNxFAST8 "hhx"
+# else
+#  define SCNxFAST8 "x"
+# endif
+#endif
+#if !defined SCNdFAST16
+# if INT_FAST16_MAX > INT32_MAX
+#  define SCNdFAST16 SCNd64
+# elif INT_FAST16_MAX == 0x7fff
+#  define SCNdFAST16 "hd"
+# else
+#  define SCNdFAST16 "d"
+# endif
+#endif
+#if !defined SCNiFAST16
+# if INT_FAST16_MAX > INT32_MAX
+#  define SCNiFAST16 SCNi64
+# elif INT_FAST16_MAX == 0x7fff
+#  define SCNiFAST16 "hi"
+# else
+#  define SCNiFAST16 "i"
+# endif
+#endif
+#if !defined SCNoFAST16
+# if UINT_FAST16_MAX > UINT32_MAX
+#  define SCNoFAST16 SCNo64
+# elif UINT_FAST16_MAX == 0xffff
+#  define SCNoFAST16 "ho"
+# else
+#  define SCNoFAST16 "o"
+# endif
+#endif
+#if !defined SCNuFAST16
+# if UINT_FAST16_MAX > UINT32_MAX
+#  define SCNuFAST16 SCNu64
+# elif UINT_FAST16_MAX == 0xffff
+#  define SCNuFAST16 "hu"
+# else
+#  define SCNuFAST16 "u"
+# endif
+#endif
+#if !defined SCNxFAST16
+# if UINT_FAST16_MAX > UINT32_MAX
+#  define SCNxFAST16 SCNx64
+# elif UINT_FAST16_MAX == 0xffff
+#  define SCNxFAST16 "hx"
+# else
+#  define SCNxFAST16 "x"
+# endif
+#endif
+#if !defined SCNdFAST32
+# if INT_FAST32_MAX > INT32_MAX
+#  define SCNdFAST32 SCNd64
+# else
+#  define SCNdFAST32 "d"
+# endif
+#endif
+#if !defined SCNiFAST32
+# if INT_FAST32_MAX > INT32_MAX
+#  define SCNiFAST32 SCNi64
+# else
+#  define SCNiFAST32 "i"
+# endif
+#endif
+#if !defined SCNoFAST32
+# if UINT_FAST32_MAX > UINT32_MAX
+#  define SCNoFAST32 SCNo64
+# else
+#  define SCNoFAST32 "o"
+# endif
+#endif
+#if !defined SCNuFAST32
+# if UINT_FAST32_MAX > UINT32_MAX
+#  define SCNuFAST32 SCNu64
+# else
+#  define SCNuFAST32 "u"
+# endif
+#endif
+#if !defined SCNxFAST32
+# if UINT_FAST32_MAX > UINT32_MAX
+#  define SCNxFAST32 SCNx64
+# else
+#  define SCNxFAST32 "x"
+# endif
+#endif
+#ifdef INT64_MAX
+# if !defined SCNdFAST64
+#  define SCNdFAST64 SCNd64
+# endif
+# if !defined SCNiFAST64
+#  define SCNiFAST64 SCNi64
+# endif
+#endif
+#ifdef UINT64_MAX
+# if !defined SCNoFAST64
+#  define SCNoFAST64 SCNo64
+# endif
+# if !defined SCNuFAST64
+#  define SCNuFAST64 SCNu64
+# endif
+# if !defined SCNxFAST64
+#  define SCNxFAST64 SCNx64
+# endif
+#endif
+
+#if !defined SCNdMAX
+# if 1
+#  define SCNdMAX SCNd64
+# else
+#  define SCNdMAX "ld"
+# endif
+#endif
+#if !defined SCNiMAX
+# if 1
+#  define SCNiMAX SCNi64
+# else
+#  define SCNiMAX "li"
+# endif
+#endif
+#if !defined SCNoMAX
+# if 1
+#  define SCNoMAX SCNo64
+# else
+#  define SCNoMAX "lo"
+# endif
+#endif
+#if !defined SCNuMAX
+# if 1
+#  define SCNuMAX SCNu64
+# else
+#  define SCNuMAX "lu"
+# endif
+#endif
+#if !defined SCNxMAX
+# if 1
+#  define SCNxMAX SCNx64
+# else
+#  define SCNxMAX "lx"
+# endif
+#endif
+
+#if !defined SCNdPTR
+# ifdef INTPTR_MAX
+#  define SCNdPTR __PRIPTR_PREFIX "d"
+# endif
+#endif
+#if !defined SCNiPTR
+# ifdef INTPTR_MAX
+#  define SCNiPTR __PRIPTR_PREFIX "i"
+# endif
+#endif
+#if !defined SCNoPTR
+# ifdef UINTPTR_MAX
+#  define SCNoPTR __PRIPTR_PREFIX "o"
+# endif
+#endif
+#if !defined SCNuPTR
+# ifdef UINTPTR_MAX
+#  define SCNuPTR __PRIPTR_PREFIX "u"
+# endif
+#endif
+#if !defined SCNxPTR
+# ifdef UINTPTR_MAX
+#  define SCNxPTR __PRIPTR_PREFIX "x"
+# endif
+#endif
+
+/* 7.8.2 Functions for greatest-width integer types */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if 0
+# if !1
+extern intmax_t imaxabs (intmax_t);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef imaxabs
+# if HAVE_RAW_DECL_IMAXABS
+_GL_WARN_ON_USE (imaxabs, "imaxabs is unportable - "
+                 "use gnulib module imaxabs for portability");
+# endif
+#endif
+
+#if 0
+# if !1
+#  if !GNULIB_defined_imaxdiv_t
+typedef struct { intmax_t quot; intmax_t rem; } imaxdiv_t;
+#   define GNULIB_defined_imaxdiv_t 1
+#  endif
+# endif
+# if !1
+extern imaxdiv_t imaxdiv (intmax_t, intmax_t);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef imaxdiv
+# if HAVE_RAW_DECL_IMAXDIV
+_GL_WARN_ON_USE (imaxdiv, "imaxdiv is unportable - "
+                 "use gnulib module imaxdiv for portability");
+# endif
+#endif
+
+#if 0
+# if 0
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef strtoimax
+#   define strtoimax rpl_strtoimax
+#  endif
+_GL_FUNCDECL_RPL (strtoimax, intmax_t,
+                  (const char *restrict, char **restrict, int)
+                  _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (strtoimax, intmax_t,
+                  (const char *restrict, char **restrict, int));
+# else
+#  if !1
+#   undef strtoimax
+_GL_FUNCDECL_SYS (strtoimax, intmax_t,
+                  (const char *restrict, char **restrict, int)
+                  _GL_ARG_NONNULL ((1)));
+#  endif
+_GL_CXXALIAS_SYS (strtoimax, intmax_t,
+                  (const char *restrict, char **restrict, int));
+# endif
+_GL_CXXALIASWARN (strtoimax);
+#elif defined GNULIB_POSIXCHECK
+# undef strtoimax
+# if HAVE_RAW_DECL_STRTOIMAX
+_GL_WARN_ON_USE (strtoimax, "strtoimax is unportable - "
+                 "use gnulib module strtoimax for portability");
+# endif
+#endif
+
+#if 0
+# if 0
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef strtoumax
+#   define strtoumax rpl_strtoumax
+#  endif
+_GL_FUNCDECL_RPL (strtoumax, uintmax_t,
+                  (const char *restrict, char **restrict, int)
+                  _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (strtoumax, uintmax_t,
+                  (const char *restrict, char **restrict, int));
+# else
+#  if !1
+#   undef strtoumax
+_GL_FUNCDECL_SYS (strtoumax, uintmax_t,
+                  (const char *restrict, char **restrict, int)
+                  _GL_ARG_NONNULL ((1)));
+#  endif
+_GL_CXXALIAS_SYS (strtoumax, uintmax_t,
+                  (const char *restrict, char **restrict, int));
+# endif
+_GL_CXXALIASWARN (strtoumax);
+#elif defined GNULIB_POSIXCHECK
+# undef strtoumax
+# if HAVE_RAW_DECL_STRTOUMAX
+_GL_WARN_ON_USE (strtoumax, "strtoumax is unportable - "
+                 "use gnulib module strtoumax for portability");
+# endif
+#endif
+
+/* Don't bother defining or declaring wcstoimax and wcstoumax, since
+   wide-character functions like this are hardly ever useful.  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !defined INTTYPES_H && !defined _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H */
diff --git a/lib/inttypes.in.h b/lib/inttypes.in.h
index 41cb4220c..853eca087 100644
--- a/lib/inttypes.in.h
+++ b/lib/inttypes.in.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006-2021 Free Software Foundation, Inc.
+/* Copyright (C) 2006-2022 Free Software Foundation, Inc.
    Written by Paul Eggert, Bruno Haible, Derek Price.
    This file is part of gnulib.
 
diff --git a/lib/isfinite.c b/lib/isfinite.c
index f1373b90e..c3a0da57c 100644
--- a/lib/isfinite.c
+++ b/lib/isfinite.c
@@ -1,9 +1,9 @@
 /* Test for finite value (zero, subnormal, or normal, and not infinite or NaN).
-   Copyright (C) 2007-2021 Free Software Foundation, Inc.
+   Copyright (C) 2007-2022 Free Software Foundation, Inc.
 
    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 3 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/isinf.c b/lib/isinf.c
index 62becf22d..c3a505304 100644
--- a/lib/isinf.c
+++ b/lib/isinf.c
@@ -1,9 +1,9 @@
 /* Test for positive or negative infinity.
-   Copyright (C) 2007-2021 Free Software Foundation, Inc.
+   Copyright (C) 2007-2022 Free Software Foundation, Inc.
 
    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 3 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/isnan.c b/lib/isnan.c
index ed3452f90..bd119f691 100644
--- a/lib/isnan.c
+++ b/lib/isnan.c
@@ -1,5 +1,5 @@
 /* Test for NaN that does not need libm.
-   Copyright (C) 2007-2021 Free Software Foundation, Inc.
+   Copyright (C) 2007-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/isnand-nolibm.h b/lib/isnand-nolibm.h
index df64f4e17..aad139159 100644
--- a/lib/isnand-nolibm.h
+++ b/lib/isnand-nolibm.h
@@ -1,5 +1,5 @@
 /* Test for NaN that does not need libm.
-   Copyright (C) 2007-2021 Free Software Foundation, Inc.
+   Copyright (C) 2007-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/isnand.c b/lib/isnand.c
index 7c5df9072..26501b5d6 100644
--- a/lib/isnand.c
+++ b/lib/isnand.c
@@ -1,5 +1,5 @@
 /* Test for NaN that does not need libm.
-   Copyright (C) 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2008-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/isnanf-nolibm.h b/lib/isnanf-nolibm.h
index bd858117b..4ce81d6cd 100644
--- a/lib/isnanf-nolibm.h
+++ b/lib/isnanf-nolibm.h
@@ -1,5 +1,5 @@
 /* Test for NaN that does not need libm.
-   Copyright (C) 2007-2021 Free Software Foundation, Inc.
+   Copyright (C) 2007-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/isnanf.c b/lib/isnanf.c
index 3b60340a2..e8b721acf 100644
--- a/lib/isnanf.c
+++ b/lib/isnanf.c
@@ -1,5 +1,5 @@
 /* Test for NaN that does not need libm.
-   Copyright (C) 2007, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/isnanl-nolibm.h b/lib/isnanl-nolibm.h
index 41fe15699..a4374e70d 100644
--- a/lib/isnanl-nolibm.h
+++ b/lib/isnanl-nolibm.h
@@ -1,5 +1,5 @@
 /* Test for NaN that does not need libm.
-   Copyright (C) 2007-2021 Free Software Foundation, Inc.
+   Copyright (C) 2007-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/isnanl.c b/lib/isnanl.c
index e8dedf0f4..2f71d6c3e 100644
--- a/lib/isnanl.c
+++ b/lib/isnanl.c
@@ -1,5 +1,5 @@
 /* Test for NaN that does not need libm.
-   Copyright (C) 2007, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/itold.c b/lib/itold.c
index 798486636..fe4a38423 100644
--- a/lib/itold.c
+++ b/lib/itold.c
@@ -1,5 +1,5 @@
 /* Replacement for 'int' to 'long double' conversion routine.
-   Copyright (C) 2011-2021 Free Software Foundation, Inc.
+   Copyright (C) 2011-2022 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2011.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/langinfo.in.h b/lib/langinfo.in.h
index 4873899d8..98aea6a84 100644
--- a/lib/langinfo.in.h
+++ b/lib/langinfo.in.h
@@ -1,5 +1,5 @@
 /* Substitute for and wrapper around <langinfo.h>.
-   Copyright (C) 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/lc-charset-dispatch.c b/lib/lc-charset-dispatch.c
index 88a0bd325..66d78fd3e 100644
--- a/lib/lc-charset-dispatch.c
+++ b/lib/lc-charset-dispatch.c
@@ -1,5 +1,5 @@
 /* Dispatching based on the current locale's character encoding.
-   Copyright (C) 2018-2021 Free Software Foundation, Inc.
+   Copyright (C) 2018-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/lc-charset-dispatch.h b/lib/lc-charset-dispatch.h
index 59b485de4..3867c3232 100644
--- a/lib/lc-charset-dispatch.h
+++ b/lib/lc-charset-dispatch.h
@@ -1,5 +1,5 @@
 /* Dispatching based on the current locale's character encoding.
-   Copyright (C) 2018-2021 Free Software Foundation, Inc.
+   Copyright (C) 2018-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/libc-config.h b/lib/libc-config.h
index 886c11f37..a56665b1c 100644
--- a/lib/libc-config.h
+++ b/lib/libc-config.h
@@ -1,6 +1,6 @@
 /* System definitions for code taken from the GNU C Library
 
-   Copyright 2017-2021 Free Software Foundation, Inc.
+   Copyright 2017-2022 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -121,6 +121,7 @@
 # undef __attr_dealloc
 # undef __attr_dealloc_free
 # undef __attribute__
+# undef __attribute_alloc_align__
 # undef __attribute_alloc_size__
 # undef __attribute_artificial__
 # undef __attribute_const__
@@ -129,6 +130,7 @@
 # undef __attribute_format_arg__
 # undef __attribute_format_strfmon__
 # undef __attribute_malloc__
+# undef __attribute_maybe_unused__
 # undef __attribute_noinline__
 # undef __attribute_nonstring__
 # undef __attribute_pure__
@@ -142,16 +144,24 @@
 # undef __extern_always_inline
 # undef __extern_inline
 # undef __flexarr
+# undef __fortified_attr_access
 # undef __fortify_function
 # undef __glibc_c99_flexarr_available
+# undef __glibc_fortify
+# undef __glibc_fortify_n
 # undef __glibc_has_attribute
 # undef __glibc_has_builtin
 # undef __glibc_has_extension
+# undef __glibc_likely
 # undef __glibc_macro_warning
 # undef __glibc_macro_warning1
 # undef __glibc_objsize
 # undef __glibc_objsize0
+# undef __glibc_safe_len_cond
+# undef __glibc_safe_or_unknown_len
 # undef __glibc_unlikely
+# undef __glibc_unsafe_len
+# undef __glibc_unsigned_or_positive
 # undef __inline
 # undef __ptr_t
 # undef __restrict
@@ -159,6 +169,7 @@
 # undef __va_arg_pack
 # undef __va_arg_pack_len
 # undef __warnattr
+# undef __wur
 
 /* Include our copy of glibc <sys/cdefs.h>.  */
 # include <cdefs.h>
diff --git a/lib/libunistring.valgrind b/lib/libunistring.valgrind
index 9eee19afa..630ded08b 100644
--- a/lib/libunistring.valgrind
+++ b/lib/libunistring.valgrind
@@ -1,12 +1,12 @@
 # Suppress valgrind messages in an installed libunistring.
 
-# Copyright (C) 2010-2021 Free Software Foundation, Inc.
+# Copyright (C) 2010-2022 Free Software Foundation, Inc.
 #
 # This file is free software.
 # It is dual-licensed under "the GNU LGPLv3+ or the GNU GPLv2+".
 # You can redistribute it and/or modify it under either
 #   - the terms of the GNU Lesser General Public License as published
-#     by the Free Software Foundation; either version 3, or (at your
+#     by the Free Software Foundation, either version 3, or (at your
 #     option) any later version, or
 #   - the terms of the GNU General Public License as published by the
 #     Free Software Foundation; either version 2, or (at your option)
diff --git a/lib/limits.in.h b/lib/limits.in.h
index 2ecafebb0..b77bf75c5 100644
--- a/lib/limits.in.h
+++ b/lib/limits.in.h
@@ -1,6 +1,6 @@
 /* A GNU-like <limits.h>.
 
-   Copyright 2016-2021 Free Software Foundation, Inc.
+   Copyright 2016-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/link.c b/lib/link.c
index bd4bef9f8..2023d75bc 100644
--- a/lib/link.c
+++ b/lib/link.c
@@ -1,6 +1,6 @@
 /* Emulate link on platforms that lack it, namely native Windows platforms.
 
-   Copyright (C) 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/listen.c b/lib/listen.c
index a145f82c5..e67bdc9e9 100644
--- a/lib/listen.c
+++ b/lib/listen.c
@@ -1,6 +1,6 @@
 /* listen.c --- wrappers for Windows listen function
 
-   Copyright (C) 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2008-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/localcharset.c b/lib/localcharset.c
index 9c22050dc..383e50f70 100644
--- a/lib/localcharset.c
+++ b/lib/localcharset.c
@@ -1,6 +1,6 @@
 /* Determine a canonical name for the current locale's character encoding.
 
-   Copyright (C) 2000-2006, 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2000-2006, 2008-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/localcharset.h b/lib/localcharset.h
index 27c3ab60e..14b4c7ef4 100644
--- a/lib/localcharset.h
+++ b/lib/localcharset.h
@@ -1,5 +1,5 @@
 /* Determine a canonical name for the current locale's character encoding.
-   Copyright (C) 2000-2003, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2000-2003, 2009-2022 Free Software Foundation, Inc.
    This file is part of the GNU CHARSET Library.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/locale.in.h b/lib/locale.in.h
index 106307069..4aef74d48 100644
--- a/lib/locale.in.h
+++ b/lib/locale.in.h
@@ -1,5 +1,5 @@
 /* A POSIX <locale.h>.
-   Copyright (C) 2007-2021 Free Software Foundation, Inc.
+   Copyright (C) 2007-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/localeconv.c b/lib/localeconv.c
index 25e95a112..ef261205d 100644
--- a/lib/localeconv.c
+++ b/lib/localeconv.c
@@ -1,5 +1,5 @@
 /* Query locale dependent information for formatting numbers.
-   Copyright (C) 2012-2021 Free Software Foundation, Inc.
+   Copyright (C) 2012-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/log.c b/lib/log.c
index 3f142e88d..84ff5e9f7 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -1,9 +1,9 @@
 /* Logarithm.
-   Copyright (C) 2012-2021 Free Software Foundation, Inc.
+   Copyright (C) 2012-2022 Free Software Foundation, Inc.
 
    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 3 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/log1p.c b/lib/log1p.c
index c45c6ff34..31070a37b 100644
--- a/lib/log1p.c
+++ b/lib/log1p.c
@@ -1,9 +1,9 @@
 /* Natural logarithm of 1 plus argument.
-   Copyright (C) 2012-2021 Free Software Foundation, Inc.
+   Copyright (C) 2012-2022 Free Software Foundation, Inc.
 
    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 3 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/lstat.c b/lib/lstat.c
index 7de0bf102..472bfbceb 100644
--- a/lib/lstat.c
+++ b/lib/lstat.c
@@ -1,6 +1,6 @@
 /* Work around a bug of lstat on some systems
 
-   Copyright (C) 1997-2006, 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 1997-2006, 2008-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/malloc.c b/lib/malloc.c
index 0d8b3596c..f334dd6e9 100644
--- a/lib/malloc.c
+++ b/lib/malloc.c
@@ -1,6 +1,6 @@
 /* malloc() function that is glibc compatible.
 
-   Copyright (C) 1997-1998, 2006-2007, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 1997-1998, 2006-2007, 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/malloc/.dirstamp b/lib/malloc/.dirstamp
new file mode 100644
index 000000000..e69de29bb
diff --git a/lib/malloc/dynarray-skeleton.c b/lib/malloc/dynarray-skeleton.c
index 48210e325..bad548a49 100644
--- a/lib/malloc/dynarray-skeleton.c
+++ b/lib/malloc/dynarray-skeleton.c
@@ -1,5 +1,5 @@
 /* Type-safe arrays which grow dynamically.
-   Copyright (C) 2017-2021 Free Software Foundation, Inc.
+   Copyright (C) 2017-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
diff --git a/lib/malloc/dynarray-skeleton.gl.h b/lib/malloc/dynarray-skeleton.gl.h
new file mode 100644
index 000000000..b48c6a920
--- /dev/null
+++ b/lib/malloc/dynarray-skeleton.gl.h
@@ -0,0 +1,529 @@
+/* DO NOT EDIT! GENERATED AUTOMATICALLY! */
+/* Type-safe arrays which grow dynamically.
+   Copyright (C) 2017-2021 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library 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 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+/* Pre-processor macros which act as parameters:
+
+   DYNARRAY_STRUCT
+      The struct tag of dynamic array to be defined.
+   DYNARRAY_ELEMENT
+      The type name of the element type.  Elements are copied
+      as if by memcpy, and can change address as the dynamic
+      array grows.
+   DYNARRAY_PREFIX
+      The prefix of the functions which are defined.
+
+   The following parameters are optional:
+
+   DYNARRAY_ELEMENT_FREE
+      DYNARRAY_ELEMENT_FREE (E) is evaluated to deallocate the
+      contents of elements. E is of type  DYNARRAY_ELEMENT *.
+   DYNARRAY_ELEMENT_INIT
+      DYNARRAY_ELEMENT_INIT (E) is evaluated to initialize a new
+      element.  E is of type  DYNARRAY_ELEMENT *.
+      If DYNARRAY_ELEMENT_FREE but not DYNARRAY_ELEMENT_INIT is
+      defined, new elements are automatically zero-initialized.
+      Otherwise, new elements have undefined contents.
+   DYNARRAY_INITIAL_SIZE
+      The size of the statically allocated array (default:
+      at least 2, more elements if they fit into 128 bytes).
+      Must be a preprocessor constant.  If DYNARRAY_INITIAL_SIZE is 0,
+      there is no statically allocated array at, and all non-empty
+      arrays are heap-allocated.
+   DYNARRAY_FINAL_TYPE
+      The name of the type which holds the final array.  If not
+      defined, is PREFIX##finalize not provided.  DYNARRAY_FINAL_TYPE
+      must be a struct type, with members of type DYNARRAY_ELEMENT and
+      size_t at the start (in this order).
+
+   These macros are undefined after this header file has been
+   included.
+
+   The following types are provided (their members are private to the
+   dynarray implementation):
+
+     struct DYNARRAY_STRUCT
+
+   The following functions are provided:
+
+     void DYNARRAY_PREFIX##init (struct DYNARRAY_STRUCT *);
+     void DYNARRAY_PREFIX##free (struct DYNARRAY_STRUCT *);
+     bool DYNARRAY_PREFIX##has_failed (const struct DYNARRAY_STRUCT *);
+     void DYNARRAY_PREFIX##mark_failed (struct DYNARRAY_STRUCT *);
+     size_t DYNARRAY_PREFIX##size (const struct DYNARRAY_STRUCT *);
+     DYNARRAY_ELEMENT *DYNARRAY_PREFIX##begin (const struct DYNARRAY_STRUCT *);
+     DYNARRAY_ELEMENT *DYNARRAY_PREFIX##end (const struct DYNARRAY_STRUCT *);
+     DYNARRAY_ELEMENT *DYNARRAY_PREFIX##at (struct DYNARRAY_STRUCT *, size_t);
+     void DYNARRAY_PREFIX##add (struct DYNARRAY_STRUCT *, DYNARRAY_ELEMENT);
+     DYNARRAY_ELEMENT *DYNARRAY_PREFIX##emplace (struct DYNARRAY_STRUCT *);
+     bool DYNARRAY_PREFIX##resize (struct DYNARRAY_STRUCT *, size_t);
+     void DYNARRAY_PREFIX##remove_last (struct DYNARRAY_STRUCT *);
+     void DYNARRAY_PREFIX##clear (struct DYNARRAY_STRUCT *);
+
+   The following functions are provided are provided if the
+   prerequisites are met:
+
+     bool DYNARRAY_PREFIX##finalize (struct DYNARRAY_STRUCT *,
+                                     DYNARRAY_FINAL_TYPE *);
+       (if DYNARRAY_FINAL_TYPE is defined)
+     DYNARRAY_ELEMENT *DYNARRAY_PREFIX##finalize (struct DYNARRAY_STRUCT *,
+                                                  size_t *);
+       (if DYNARRAY_FINAL_TYPE is not defined)
+*/
+
+#include <malloc/dynarray.gl.h>
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef DYNARRAY_STRUCT
+# error "DYNARRAY_STRUCT must be defined"
+#endif
+
+#ifndef DYNARRAY_ELEMENT
+# error "DYNARRAY_ELEMENT must be defined"
+#endif
+
+#ifndef DYNARRAY_PREFIX
+# error "DYNARRAY_PREFIX must be defined"
+#endif
+
+#ifdef DYNARRAY_INITIAL_SIZE
+# if DYNARRAY_INITIAL_SIZE < 0
+#  error "DYNARRAY_INITIAL_SIZE must be non-negative"
+# endif
+# if DYNARRAY_INITIAL_SIZE > 0
+#  define DYNARRAY_HAVE_SCRATCH 1
+# else
+#  define DYNARRAY_HAVE_SCRATCH 0
+# endif
+#else
+/* Provide a reasonable default which limits the size of
+   DYNARRAY_STRUCT.  */
+# define DYNARRAY_INITIAL_SIZE \
+  (sizeof (DYNARRAY_ELEMENT) > 64 ? 2 : 128 / sizeof (DYNARRAY_ELEMENT))
+# define DYNARRAY_HAVE_SCRATCH 1
+#endif
+
+/* Public type definitions.  */
+
+/* All fields of this struct are private to the implementation.  */
+struct DYNARRAY_STRUCT
+{
+  union
+  {
+    struct dynarray_header dynarray_abstract;
+    struct
+    {
+      /* These fields must match struct dynarray_header.  */
+      size_t used;
+      size_t allocated;
+      DYNARRAY_ELEMENT *array;
+    } dynarray_header;
+  } u;
+
+#if DYNARRAY_HAVE_SCRATCH
+  /* Initial inline allocation.  */
+  DYNARRAY_ELEMENT scratch[DYNARRAY_INITIAL_SIZE];
+#endif
+};
+
+/* Internal use only: Helper macros.  */
+
+/* Ensure macro-expansion of DYNARRAY_PREFIX.  */
+#define DYNARRAY_CONCAT0(prefix, name) prefix##name
+#define DYNARRAY_CONCAT1(prefix, name) DYNARRAY_CONCAT0(prefix, name)
+#define DYNARRAY_NAME(name) DYNARRAY_CONCAT1(DYNARRAY_PREFIX, name)
+
+/* Use DYNARRAY_FREE instead of DYNARRAY_NAME (free),
+   so that Gnulib does not change 'free' to 'rpl_free'.  */
+#define DYNARRAY_FREE DYNARRAY_CONCAT1 (DYNARRAY_NAME (f), ree)
+
+/* Address of the scratch buffer if any.  */
+#if DYNARRAY_HAVE_SCRATCH
+# define DYNARRAY_SCRATCH(list) (list)->scratch
+#else
+# define DYNARRAY_SCRATCH(list) NULL
+#endif
+
+/* Internal use only: Helper functions.  */
+
+/* Internal function.  Call DYNARRAY_ELEMENT_FREE with the array
+   elements.  Name mangling needed due to the DYNARRAY_ELEMENT_FREE
+   macro expansion.  */
+static inline void
+DYNARRAY_NAME (free__elements__) (DYNARRAY_ELEMENT *__dynarray_array,
+                                  size_t __dynarray_used)
+{
+#ifdef DYNARRAY_ELEMENT_FREE
+  for (size_t __dynarray_i = 0; __dynarray_i < __dynarray_used; ++__dynarray_i)
+    DYNARRAY_ELEMENT_FREE (&__dynarray_array[__dynarray_i]);
+#endif /* DYNARRAY_ELEMENT_FREE */
+}
+
+/* Internal function.  Free the non-scratch array allocation.  */
+static inline void
+DYNARRAY_NAME (free__array__) (struct DYNARRAY_STRUCT *list)
+{
+#if DYNARRAY_HAVE_SCRATCH
+  if (list->u.dynarray_header.array != list->scratch)
+    free (list->u.dynarray_header.array);
+#else
+  free (list->u.dynarray_header.array);
+#endif
+}
+
+/* Public functions.  */
+
+/* Initialize a dynamic array object.  This must be called before any
+   use of the object.  */
+_GL_ATTRIBUTE_NONNULL ((1))
+static void
+DYNARRAY_NAME (init) (struct DYNARRAY_STRUCT *list)
+{
+  list->u.dynarray_header.used = 0;
+  list->u.dynarray_header.allocated = DYNARRAY_INITIAL_SIZE;
+  list->u.dynarray_header.array = DYNARRAY_SCRATCH (list);
+}
+
+/* Deallocate the dynamic array and its elements.  */
+_GL_ATTRIBUTE_MAYBE_UNUSED _GL_ATTRIBUTE_NONNULL ((1))
+static void
+DYNARRAY_FREE (struct DYNARRAY_STRUCT *list)
+{
+  DYNARRAY_NAME (free__elements__)
+    (list->u.dynarray_header.array, list->u.dynarray_header.used);
+  DYNARRAY_NAME (free__array__) (list);
+  DYNARRAY_NAME (init) (list);
+}
+
+/* Return true if the dynamic array is in an error state.  */
+_GL_ATTRIBUTE_NONNULL ((1))
+static inline bool
+DYNARRAY_NAME (has_failed) (const struct DYNARRAY_STRUCT *list)
+{
+  return list->u.dynarray_header.allocated == __dynarray_error_marker ();
+}
+
+/* Mark the dynamic array as failed.  All elements are deallocated as
+   a side effect.  */
+_GL_ATTRIBUTE_NONNULL ((1))
+static void
+DYNARRAY_NAME (mark_failed) (struct DYNARRAY_STRUCT *list)
+{
+  DYNARRAY_NAME (free__elements__)
+    (list->u.dynarray_header.array, list->u.dynarray_header.used);
+  DYNARRAY_NAME (free__array__) (list);
+  list->u.dynarray_header.array = DYNARRAY_SCRATCH (list);
+  list->u.dynarray_header.used = 0;
+  list->u.dynarray_header.allocated = __dynarray_error_marker ();
+}
+
+/* Return the number of elements which have been added to the dynamic
+   array.  */
+_GL_ATTRIBUTE_NONNULL ((1))
+static inline size_t
+DYNARRAY_NAME (size) (const struct DYNARRAY_STRUCT *list)
+{
+  return list->u.dynarray_header.used;
+}
+
+/* Return a pointer to the array element at INDEX.  Terminate the
+   process if INDEX is out of bounds.  */
+_GL_ATTRIBUTE_NONNULL ((1))
+static inline DYNARRAY_ELEMENT *
+DYNARRAY_NAME (at) (struct DYNARRAY_STRUCT *list, size_t index)
+{
+  if (_GL_UNLIKELY (index >= DYNARRAY_NAME (size) (list)))
+    __libc_dynarray_at_failure (DYNARRAY_NAME (size) (list), index);
+  return list->u.dynarray_header.array + index;
+}
+
+/* Return a pointer to the first array element, if any.  For a
+   zero-length array, the pointer can be NULL even though the dynamic
+   array has not entered the failure state.  */
+_GL_ATTRIBUTE_NONNULL ((1))
+static inline DYNARRAY_ELEMENT *
+DYNARRAY_NAME (begin) (struct DYNARRAY_STRUCT *list)
+{
+  return list->u.dynarray_header.array;
+}
+
+/* Return a pointer one element past the last array element.  For a
+   zero-length array, the pointer can be NULL even though the dynamic
+   array has not entered the failure state.  */
+_GL_ATTRIBUTE_NONNULL ((1))
+static inline DYNARRAY_ELEMENT *
+DYNARRAY_NAME (end) (struct DYNARRAY_STRUCT *list)
+{
+  return list->u.dynarray_header.array + list->u.dynarray_header.used;
+}
+
+/* Internal function.  Slow path for the add function below.  */
+static void
+DYNARRAY_NAME (add__) (struct DYNARRAY_STRUCT *list, DYNARRAY_ELEMENT item)
+{
+  if (_GL_UNLIKELY
+      (!__libc_dynarray_emplace_enlarge (&list->u.dynarray_abstract,
+                                         DYNARRAY_SCRATCH (list),
+                                         sizeof (DYNARRAY_ELEMENT))))
+    {
+      DYNARRAY_NAME (mark_failed) (list);
+      return;
+    }
+
+  /* Copy the new element and increase the array length.  */
+  list->u.dynarray_header.array[list->u.dynarray_header.used++] = item;
+}
+
+/* Add ITEM at the end of the array, enlarging it by one element.
+   Mark *LIST as failed if the dynamic array allocation size cannot be
+   increased.  */
+_GL_ATTRIBUTE_NONNULL ((1))
+static inline void
+DYNARRAY_NAME (add) (struct DYNARRAY_STRUCT *list, DYNARRAY_ELEMENT item)
+{
+  /* Do nothing in case of previous error.  */
+  if (DYNARRAY_NAME (has_failed) (list))
+    return;
+
+  /* Enlarge the array if necessary.  */
+  if (_GL_UNLIKELY (list->u.dynarray_header.used
+                        == list->u.dynarray_header.allocated))
+    {
+      DYNARRAY_NAME (add__) (list, item);
+      return;
+    }
+
+  /* Copy the new element and increase the array length.  */
+  list->u.dynarray_header.array[list->u.dynarray_header.used++] = item;
+}
+
+/* Internal function.  Building block for the emplace functions below.
+   Assumes space for one more element in *LIST.  */
+static inline DYNARRAY_ELEMENT *
+DYNARRAY_NAME (emplace__tail__) (struct DYNARRAY_STRUCT *list)
+{
+  DYNARRAY_ELEMENT *result
+    = &list->u.dynarray_header.array[list->u.dynarray_header.used];
+  ++list->u.dynarray_header.used;
+#if defined (DYNARRAY_ELEMENT_INIT)
+  DYNARRAY_ELEMENT_INIT (result);
+#elif defined (DYNARRAY_ELEMENT_FREE)
+  memset (result, 0, sizeof (*result));
+#endif
+  return result;
+}
+
+/* Internal function.  Slow path for the emplace function below.  */
+static DYNARRAY_ELEMENT *
+DYNARRAY_NAME (emplace__) (struct DYNARRAY_STRUCT *list)
+{
+  if (_GL_UNLIKELY
+      (!__libc_dynarray_emplace_enlarge (&list->u.dynarray_abstract,
+                                         DYNARRAY_SCRATCH (list),
+                                         sizeof (DYNARRAY_ELEMENT))))
+    {
+      DYNARRAY_NAME (mark_failed) (list);
+      return NULL;
+    }
+  return DYNARRAY_NAME (emplace__tail__) (list);
+}
+
+/* Allocate a place for a new element in *LIST and return a pointer to
+   it.  The pointer can be NULL if the dynamic array cannot be
+   enlarged due to a memory allocation failure.  */
+_GL_ATTRIBUTE_MAYBE_UNUSED _GL_ATTRIBUTE_NODISCARD
+_GL_ATTRIBUTE_NONNULL ((1))
+static
+/* Avoid inlining with the larger initialization code.  */
+#if !(defined (DYNARRAY_ELEMENT_INIT) || defined (DYNARRAY_ELEMENT_FREE))
+inline
+#endif
+DYNARRAY_ELEMENT *
+DYNARRAY_NAME (emplace) (struct DYNARRAY_STRUCT *list)
+{
+  /* Do nothing in case of previous error.  */
+  if (DYNARRAY_NAME (has_failed) (list))
+    return NULL;
+
+  /* Enlarge the array if necessary.  */
+  if (_GL_UNLIKELY (list->u.dynarray_header.used
+                        == list->u.dynarray_header.allocated))
+    return (DYNARRAY_NAME (emplace__) (list));
+  return DYNARRAY_NAME (emplace__tail__) (list);
+}
+
+/* Change the size of *LIST to SIZE.  If SIZE is larger than the
+   existing size, new elements are added (which can be initialized).
+   Otherwise, the list is truncated, and elements are freed.  Return
+   false on memory allocation failure (and mark *LIST as failed).  */
+_GL_ATTRIBUTE_MAYBE_UNUSED _GL_ATTRIBUTE_NONNULL ((1))
+static bool
+DYNARRAY_NAME (resize) (struct DYNARRAY_STRUCT *list, size_t size)
+{
+  if (size > list->u.dynarray_header.used)
+    {
+      bool ok;
+#if defined (DYNARRAY_ELEMENT_INIT)
+      /* The new elements have to be initialized.  */
+      size_t old_size = list->u.dynarray_header.used;
+      ok = __libc_dynarray_resize (&list->u.dynarray_abstract,
+                                   size, DYNARRAY_SCRATCH (list),
+                                   sizeof (DYNARRAY_ELEMENT));
+      if (ok)
+        for (size_t i = old_size; i < size; ++i)
+          {
+            DYNARRAY_ELEMENT_INIT (&list->u.dynarray_header.array[i]);
+          }
+#elif defined (DYNARRAY_ELEMENT_FREE)
+      /* Zero initialization is needed so that the elements can be
+         safely freed.  */
+      ok = __libc_dynarray_resize_clear
+        (&list->u.dynarray_abstract, size,
+         DYNARRAY_SCRATCH (list), sizeof (DYNARRAY_ELEMENT));
+#else
+      ok =  __libc_dynarray_resize (&list->u.dynarray_abstract,
+                                    size, DYNARRAY_SCRATCH (list),
+                                    sizeof (DYNARRAY_ELEMENT));
+#endif
+      if (_GL_UNLIKELY (!ok))
+        DYNARRAY_NAME (mark_failed) (list);
+      return ok;
+    }
+  else
+    {
+      /* The list has shrunk in size.  Free the removed elements.  */
+      DYNARRAY_NAME (free__elements__)
+        (list->u.dynarray_header.array + size,
+         list->u.dynarray_header.used - size);
+      list->u.dynarray_header.used = size;
+      return true;
+    }
+}
+
+/* Remove the last element of LIST if it is present.  */
+_GL_ATTRIBUTE_MAYBE_UNUSED _GL_ATTRIBUTE_NONNULL ((1))
+static void
+DYNARRAY_NAME (remove_last) (struct DYNARRAY_STRUCT *list)
+{
+  /* used > 0 implies that the array is the non-failed state.  */
+  if (list->u.dynarray_header.used > 0)
+    {
+      size_t new_length = list->u.dynarray_header.used - 1;
+#ifdef DYNARRAY_ELEMENT_FREE
+      DYNARRAY_ELEMENT_FREE (&list->u.dynarray_header.array[new_length]);
+#endif
+      list->u.dynarray_header.used = new_length;
+    }
+}
+
+/* Remove all elements from the list.  The elements are freed, but the
+   list itself is not.  */
+_GL_ATTRIBUTE_MAYBE_UNUSED _GL_ATTRIBUTE_NONNULL ((1))
+static void
+DYNARRAY_NAME (clear) (struct DYNARRAY_STRUCT *list)
+{
+  /* free__elements__ does nothing if the list is in the failed
+     state.  */
+  DYNARRAY_NAME (free__elements__)
+    (list->u.dynarray_header.array, list->u.dynarray_header.used);
+  list->u.dynarray_header.used = 0;
+}
+
+#ifdef DYNARRAY_FINAL_TYPE
+/* Transfer the dynamic array to a permanent location at *RESULT.
+   Returns true on success on false on allocation failure.  In either
+   case, *LIST is re-initialized and can be reused.  A NULL pointer is
+   stored in *RESULT if LIST refers to an empty list.  On success, the
+   pointer in *RESULT is heap-allocated and must be deallocated using
+   free.  */
+_GL_ATTRIBUTE_MAYBE_UNUSED _GL_ATTRIBUTE_NODISCARD
+_GL_ATTRIBUTE_NONNULL ((1, 2))
+static bool
+DYNARRAY_NAME (finalize) (struct DYNARRAY_STRUCT *list,
+                          DYNARRAY_FINAL_TYPE *result)
+{
+  struct dynarray_finalize_result res;
+  if (__libc_dynarray_finalize (&list->u.dynarray_abstract,
+                                DYNARRAY_SCRATCH (list),
+                                sizeof (DYNARRAY_ELEMENT), &res))
+    {
+      /* On success, the result owns all the data.  */
+      DYNARRAY_NAME (init) (list);
+      *result = (DYNARRAY_FINAL_TYPE) { res.array, res.length };
+      return true;
+    }
+  else
+    {
+      /* On error, we need to free all data.  */
+      DYNARRAY_FREE (list);
+      errno = ENOMEM;
+      return false;
+    }
+}
+#else /* !DYNARRAY_FINAL_TYPE */
+/* Transfer the dynamic array to a heap-allocated array and return a
+   pointer to it.  The pointer is NULL if memory allocation fails, or
+   if the array is empty, so this function should be used only for
+   arrays which are known not be empty (usually because they always
+   have a sentinel at the end).  If LENGTHP is not NULL, the array
+   length is written to *LENGTHP.  *LIST is re-initialized and can be
+   reused.  */
+_GL_ATTRIBUTE_MAYBE_UNUSED _GL_ATTRIBUTE_NODISCARD
+_GL_ATTRIBUTE_NONNULL ((1))
+static DYNARRAY_ELEMENT *
+DYNARRAY_NAME (finalize) (struct DYNARRAY_STRUCT *list, size_t *lengthp)
+{
+  struct dynarray_finalize_result res;
+  if (__libc_dynarray_finalize (&list->u.dynarray_abstract,
+                                DYNARRAY_SCRATCH (list),
+                                sizeof (DYNARRAY_ELEMENT), &res))
+    {
+      /* On success, the result owns all the data.  */
+      DYNARRAY_NAME (init) (list);
+      if (lengthp != NULL)
+        *lengthp = res.length;
+      return res.array;
+    }
+  else
+    {
+      /* On error, we need to free all data.  */
+      DYNARRAY_FREE (list);
+      errno = ENOMEM;
+      return NULL;
+    }
+}
+#endif /* !DYNARRAY_FINAL_TYPE */
+
+/* Undo macro definitions.  */
+
+#undef DYNARRAY_CONCAT0
+#undef DYNARRAY_CONCAT1
+#undef DYNARRAY_NAME
+#undef DYNARRAY_SCRATCH
+#undef DYNARRAY_HAVE_SCRATCH
+
+#undef DYNARRAY_STRUCT
+#undef DYNARRAY_ELEMENT
+#undef DYNARRAY_PREFIX
+#undef DYNARRAY_ELEMENT_FREE
+#undef DYNARRAY_ELEMENT_INIT
+#undef DYNARRAY_INITIAL_SIZE
+#undef DYNARRAY_FINAL_TYPE
diff --git a/lib/malloc/dynarray.gl.h b/lib/malloc/dynarray.gl.h
new file mode 100644
index 000000000..8227362bb
--- /dev/null
+++ b/lib/malloc/dynarray.gl.h
@@ -0,0 +1,174 @@
+/* DO NOT EDIT! GENERATED AUTOMATICALLY! */
+/* Type-safe arrays which grow dynamically.  Shared definitions.
+   Copyright (C) 2017-2021 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library 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 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+/* To use the dynarray facility, you need to include
+   <malloc/dynarray-skeleton.c> and define the parameter macros
+   documented in that file.
+
+   A minimal example which provides a growing list of integers can be
+   defined like this:
+
+     struct int_array
+     {
+       // Pointer to result array followed by its length,
+       // as required by DYNARRAY_FINAL_TYPE.
+       int *array;
+       size_t length;
+     };
+
+     #define DYNARRAY_STRUCT dynarray_int
+     #define DYNARRAY_ELEMENT int
+     #define DYNARRAY_PREFIX dynarray_int_
+     #define DYNARRAY_FINAL_TYPE struct int_array
+     #include <malloc/dynarray-skeleton.c>
+
+   To create a three-element array with elements 1, 2, 3, use this
+   code:
+
+     struct dynarray_int dyn;
+     dynarray_int_init (&dyn);
+     for (int i = 1; i <= 3; ++i)
+       {
+         int *place = dynarray_int_emplace (&dyn);
+         assert (place != NULL);
+         *place = i;
+       }
+     struct int_array result;
+     bool ok = dynarray_int_finalize (&dyn, &result);
+     assert (ok);
+     assert (result.length == 3);
+     assert (result.array[0] == 1);
+     assert (result.array[1] == 2);
+     assert (result.array[2] == 3);
+     free (result.array);
+
+   If the elements contain resources which must be freed, define
+   DYNARRAY_ELEMENT_FREE appropriately, like this:
+
+     struct str_array
+     {
+       char **array;
+       size_t length;
+     };
+
+     #define DYNARRAY_STRUCT dynarray_str
+     #define DYNARRAY_ELEMENT char *
+     #define DYNARRAY_ELEMENT_FREE(ptr) free (*ptr)
+     #define DYNARRAY_PREFIX dynarray_str_
+     #define DYNARRAY_FINAL_TYPE struct str_array
+     #include <malloc/dynarray-skeleton.c>
+
+   Compared to scratch buffers, dynamic arrays have the following
+   features:
+
+   - They have an element type, and are not just an untyped buffer of
+     bytes.
+
+   - When growing, previously stored elements are preserved.  (It is
+     expected that scratch_buffer_grow_preserve and
+     scratch_buffer_set_array_size eventually go away because all
+     current users are moved to dynamic arrays.)
+
+   - Scratch buffers have a more aggressive growth policy because
+     growing them typically means a retry of an operation (across an
+     NSS service module boundary), which is expensive.
+
+   - For the same reason, scratch buffers have a much larger initial
+     stack allocation.  */
+
+#ifndef _DYNARRAY_H
+#define _DYNARRAY_H
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <string.h>
+
+struct dynarray_header
+{
+  size_t used;
+  size_t allocated;
+  void *array;
+};
+
+/* Marker used in the allocated member to indicate that an error was
+   encountered.  */
+static inline size_t
+__dynarray_error_marker (void)
+{
+  return -1;
+}
+
+/* Internal function.  See the has_failed function in
+   dynarray-skeleton.c.  */
+static inline bool
+__dynarray_error (struct dynarray_header *list)
+{
+  return list->allocated == __dynarray_error_marker ();
+}
+
+/* Internal function.  Enlarge the dynamically allocated area of the
+   array to make room for one more element.  SCRATCH is a pointer to
+   the scratch area (which is not heap-allocated and must not be
+   freed).  ELEMENT_SIZE is the size, in bytes, of one element.
+   Return false on failure, true on success.  */
+bool __libc_dynarray_emplace_enlarge (struct dynarray_header *,
+                                      void *scratch, size_t element_size);
+
+/* Internal function.  Enlarge the dynamically allocated area of the
+   array to make room for at least SIZE elements (which must be larger
+   than the existing used part of the dynamic array).  SCRATCH is a
+   pointer to the scratch area (which is not heap-allocated and must
+   not be freed).  ELEMENT_SIZE is the size, in bytes, of one element.
+   Return false on failure, true on success.  */
+bool __libc_dynarray_resize (struct dynarray_header *, size_t size,
+                             void *scratch, size_t element_size);
+
+/* Internal function.  Like __libc_dynarray_resize, but clear the new
+   part of the dynamic array.  */
+bool __libc_dynarray_resize_clear (struct dynarray_header *, size_t size,
+                                   void *scratch, size_t element_size);
+
+/* Internal type.  */
+struct dynarray_finalize_result
+{
+  void *array;
+  size_t length;
+};
+
+/* Internal function.  Copy the dynamically-allocated area to an
+   explicitly-sized heap allocation.  SCRATCH is a pointer to the
+   embedded scratch space.  ELEMENT_SIZE is the size, in bytes, of the
+   element type.  On success, true is returned, and pointer and length
+   are written to *RESULT.  On failure, false is returned.  The caller
+   has to take care of some of the memory management; this function is
+   expected to be called from dynarray-skeleton.c.  */
+bool __libc_dynarray_finalize (struct dynarray_header *list, void *scratch,
+                               size_t element_size,
+                               struct dynarray_finalize_result *result);
+
+
+/* Internal function.  Terminate the process after an index error.
+   SIZE is the number of elements of the dynamic array.  INDEX is the
+   lookup index which triggered the failure.  */
+_Noreturn void __libc_dynarray_at_failure (size_t size, size_t index);
+
+#ifndef _ISOMAC
+#endif
+
+#endif /* _DYNARRAY_H */
diff --git a/lib/malloc/dynarray.h b/lib/malloc/dynarray.h
index 638c33f98..f16fd950d 100644
--- a/lib/malloc/dynarray.h
+++ b/lib/malloc/dynarray.h
@@ -1,5 +1,5 @@
 /* Type-safe arrays which grow dynamically.  Shared definitions.
-   Copyright (C) 2017-2021 Free Software Foundation, Inc.
+   Copyright (C) 2017-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
diff --git a/lib/malloc/dynarray_at_failure.c b/lib/malloc/dynarray_at_failure.c
index 8dd685078..062ab7062 100644
--- a/lib/malloc/dynarray_at_failure.c
+++ b/lib/malloc/dynarray_at_failure.c
@@ -1,5 +1,5 @@
 /* Report an dynamic array index out of bounds condition.
-   Copyright (C) 2017-2021 Free Software Foundation, Inc.
+   Copyright (C) 2017-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
diff --git a/lib/malloc/dynarray_emplace_enlarge.c b/lib/malloc/dynarray_emplace_enlarge.c
index 0f8baf94a..0cff2e705 100644
--- a/lib/malloc/dynarray_emplace_enlarge.c
+++ b/lib/malloc/dynarray_emplace_enlarge.c
@@ -1,5 +1,5 @@
 /* Increase the size of a dynamic array in preparation of an emplace operation.
-   Copyright (C) 2017-2021 Free Software Foundation, Inc.
+   Copyright (C) 2017-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
diff --git a/lib/malloc/dynarray_finalize.c b/lib/malloc/dynarray_finalize.c
index c33da4138..3f360c3aa 100644
--- a/lib/malloc/dynarray_finalize.c
+++ b/lib/malloc/dynarray_finalize.c
@@ -1,5 +1,5 @@
 /* Copy the dynamically-allocated area to an explicitly-sized heap allocation.
-   Copyright (C) 2017-2021 Free Software Foundation, Inc.
+   Copyright (C) 2017-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
diff --git a/lib/malloc/dynarray_resize.c b/lib/malloc/dynarray_resize.c
index 5a57166a8..8d1922e5c 100644
--- a/lib/malloc/dynarray_resize.c
+++ b/lib/malloc/dynarray_resize.c
@@ -1,5 +1,5 @@
 /* Increase the size of a dynamic array.
-   Copyright (C) 2017-2021 Free Software Foundation, Inc.
+   Copyright (C) 2017-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
diff --git a/lib/malloc/dynarray_resize_clear.c b/lib/malloc/dynarray_resize_clear.c
index 9c43b00c3..8cf1b0d02 100644
--- a/lib/malloc/dynarray_resize_clear.c
+++ b/lib/malloc/dynarray_resize_clear.c
@@ -1,5 +1,5 @@
 /* Increase the size of a dynamic array and clear the new part.
-   Copyright (C) 2017-2021 Free Software Foundation, Inc.
+   Copyright (C) 2017-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
diff --git a/lib/malloc/scratch_buffer.h b/lib/malloc/scratch_buffer.h
index 36d0bef4b..e4c5c8a85 100644
--- a/lib/malloc/scratch_buffer.h
+++ b/lib/malloc/scratch_buffer.h
@@ -1,5 +1,5 @@
 /* Variable-sized buffer with on-stack default allocation.
-   Copyright (C) 2015-2021 Free Software Foundation, Inc.
+   Copyright (C) 2015-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
diff --git a/lib/malloc/scratch_buffer_dupfree.c b/lib/malloc/scratch_buffer_dupfree.c
index 07363b9bc..eb3b95c1b 100644
--- a/lib/malloc/scratch_buffer_dupfree.c
+++ b/lib/malloc/scratch_buffer_dupfree.c
@@ -1,5 +1,5 @@
 /* Variable-sized buffer with on-stack default allocation.
-   Copyright (C) 2020-2021 Free Software Foundation, Inc.
+   Copyright (C) 2020-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
diff --git a/lib/malloc/scratch_buffer_grow.c b/lib/malloc/scratch_buffer_grow.c
index 22c8c7781..9a5e4dbb1 100644
--- a/lib/malloc/scratch_buffer_grow.c
+++ b/lib/malloc/scratch_buffer_grow.c
@@ -1,5 +1,5 @@
 /* Variable-sized buffer with on-stack default allocation.
-   Copyright (C) 2015-2021 Free Software Foundation, Inc.
+   Copyright (C) 2015-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
diff --git a/lib/malloc/scratch_buffer_grow_preserve.c b/lib/malloc/scratch_buffer_grow_preserve.c
index 2b2b81928..3fe5a0720 100644
--- a/lib/malloc/scratch_buffer_grow_preserve.c
+++ b/lib/malloc/scratch_buffer_grow_preserve.c
@@ -1,5 +1,5 @@
 /* Variable-sized buffer with on-stack default allocation.
-   Copyright (C) 2015-2021 Free Software Foundation, Inc.
+   Copyright (C) 2015-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
diff --git a/lib/malloc/scratch_buffer_set_array_size.c b/lib/malloc/scratch_buffer_set_array_size.c
index a47f9276a..89c37a950 100644
--- a/lib/malloc/scratch_buffer_set_array_size.c
+++ b/lib/malloc/scratch_buffer_set_array_size.c
@@ -1,5 +1,5 @@
 /* Variable-sized buffer with on-stack default allocation.
-   Copyright (C) 2015-2021 Free Software Foundation, Inc.
+   Copyright (C) 2015-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
diff --git a/lib/malloca.c b/lib/malloca.c
index b4884234a..183783a71 100644
--- a/lib/malloca.c
+++ b/lib/malloca.c
@@ -1,5 +1,5 @@
 /* Safe automatic memory allocation.
-   Copyright (C) 2003, 2006-2007, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2006-2007, 2009-2022 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2003, 2018.
 
    This file is free software: you can redistribute it and/or modify
@@ -21,8 +21,9 @@
 /* Specification.  */
 #include "malloca.h"
 
+#include <stdckdint.h>
+
 #include "idx.h"
-#include "intprops.h"
 #include "verify.h"
 
 /* The speed critical point in this file is freea() applied to an alloca()
@@ -50,17 +51,16 @@ mmalloca (size_t n)
   uintptr_t alignment2_mask = 2 * sa_alignment_max - 1;
   int plus = sizeof (small_t) + alignment2_mask;
   idx_t nplus;
-  if (!INT_ADD_WRAPV (n, plus, &nplus) && !xalloc_oversized (nplus, 1))
+  if (!ckd_add (&nplus, n, plus) && !xalloc_oversized (nplus, 1))
     {
       char *mem = (char *) malloc (nplus);
 
       if (mem != NULL)
         {
           uintptr_t umem = (uintptr_t)mem, umemplus;
-          /* The INT_ADD_WRAPV avoids signed integer overflow on
+          /* The ckd_add avoids signed integer overflow on
              theoretical platforms where UINTPTR_MAX <= INT_MAX.  */
-          INT_ADD_WRAPV (umem, sizeof (small_t) + sa_alignment_max - 1,
-                         &umemplus);
+          ckd_add (&umemplus, umem, sizeof (small_t) + sa_alignment_max - 1);
           idx_t offset = ((umemplus & ~alignment2_mask)
                           + sa_alignment_max - umem);
           void *vp = mem + offset;
diff --git a/lib/malloca.h b/lib/malloca.h
index 7eb63d2a7..7ec235f37 100644
--- a/lib/malloca.h
+++ b/lib/malloca.h
@@ -1,5 +1,5 @@
 /* Safe automatic memory allocation.
-   Copyright (C) 2003-2007, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2003-2007, 2009-2022 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2003.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/math.c b/lib/math.c
index 3ffd1d728..1502a1fd6 100644
--- a/lib/math.c
+++ b/lib/math.c
@@ -1,6 +1,6 @@
 /* Inline functions for <math.h>.
 
-   Copyright (C) 2012-2021 Free Software Foundation, Inc.
+   Copyright (C) 2012-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/math.in.h b/lib/math.in.h
index 6a055fbf5..a74a95da3 100644
--- a/lib/math.in.h
+++ b/lib/math.in.h
@@ -1,6 +1,6 @@
 /* A GNU-like <math.h>.
 
-   Copyright (C) 2002-2003, 2007-2021 Free Software Foundation, Inc.
+   Copyright (C) 2002-2003, 2007-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
@@ -56,6 +56,16 @@ _GL_INLINE_HEADER_BEGIN
 # define _GL_MATH_INLINE _GL_INLINE
 #endif
 
+/* The __attribute__ feature is available in gcc versions 2.5 and later.
+   The attribute __const__ was added in gcc 2.95.  */
+#ifndef _GL_ATTRIBUTE_CONST
+# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) || defined __clang__
+#  define _GL_ATTRIBUTE_CONST __attribute__ ((__const__))
+# else
+#  define _GL_ATTRIBUTE_CONST /* empty */
+# endif
+#endif
+
 /* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */
 
 /* The definition of _GL_ARG_NONNULL is copied here.  */
@@ -2423,6 +2433,7 @@ _GL_MATH_CXX_REAL_FLOATING_DECL_1 (isfinite)
      functions.  */
 _GL_MATH_CXX_REAL_FLOATING_DECL_2 (isfinite, rpl_isfinite, bool)
 #    define isfinite rpl_isfinite
+#    define GNULIB_NAMESPACE_LACKS_ISFINITE 1
 #   else
 _GL_MATH_CXX_REAL_FLOATING_DECL_2 (isfinite, isfinite, bool)
 #   endif
@@ -2457,6 +2468,7 @@ _GL_MATH_CXX_REAL_FLOATING_DECL_1 (isinf)
      functions.  */
 _GL_MATH_CXX_REAL_FLOATING_DECL_2 (isinf, rpl_isinf, bool)
 #    define isinf rpl_isinf
+#    define GNULIB_NAMESPACE_LACKS_ISINF 1
 #   else
 _GL_MATH_CXX_REAL_FLOATING_DECL_2 (isinf, isinf, bool)
 #   endif
@@ -2584,6 +2596,7 @@ _GL_MATH_CXX_REAL_FLOATING_DECL_1 (isnan)
      functions.  */
 _GL_MATH_CXX_REAL_FLOATING_DECL_2 (isnan, rpl_isnan, bool)
 #    define isnan rpl_isnan
+#    define GNULIB_NAMESPACE_LACKS_ISNAN 1
 #   else
 _GL_MATH_CXX_REAL_FLOATING_DECL_2 (isnan, isnan, bool)
 #   endif
@@ -2667,6 +2680,7 @@ _GL_MATH_CXX_REAL_FLOATING_DECL_1 (signbit)
      functions.  */
 _GL_MATH_CXX_REAL_FLOATING_DECL_2 (signbit, rpl_signbit, bool)
 #    define signbit rpl_signbit
+#    define GNULIB_NAMESPACE_LACKS_SIGNBIT 1
 #   else
 _GL_MATH_CXX_REAL_FLOATING_DECL_2 (signbit, signbit, bool)
 #   endif
diff --git a/lib/mbrtowc-impl-utf8.h b/lib/mbrtowc-impl-utf8.h
index 330fb1051..8e5ac14ea 100644
--- a/lib/mbrtowc-impl-utf8.h
+++ b/lib/mbrtowc-impl-utf8.h
@@ -1,5 +1,5 @@
 /* Convert multibyte character to wide character.
-   Copyright (C) 1999-2002, 2005-2021 Free Software Foundation, Inc.
+   Copyright (C) 1999-2002, 2005-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/mbrtowc-impl.h b/lib/mbrtowc-impl.h
index bc3e68823..65538e744 100644
--- a/lib/mbrtowc-impl.h
+++ b/lib/mbrtowc-impl.h
@@ -1,5 +1,5 @@
 /* Convert multibyte character to wide character.
-   Copyright (C) 1999-2002, 2005-2021 Free Software Foundation, Inc.
+   Copyright (C) 1999-2002, 2005-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/mbrtowc.c b/lib/mbrtowc.c
index 8832f6e80..4b164edd4 100644
--- a/lib/mbrtowc.c
+++ b/lib/mbrtowc.c
@@ -1,5 +1,5 @@
 /* Convert multibyte character to wide character.
-   Copyright (C) 1999-2002, 2005-2021 Free Software Foundation, Inc.
+   Copyright (C) 1999-2002, 2005-2022 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2008.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/mbsinit.c b/lib/mbsinit.c
index f44015534..9621defc7 100644
--- a/lib/mbsinit.c
+++ b/lib/mbsinit.c
@@ -1,5 +1,5 @@
 /* Test for initial conversion state.
-   Copyright (C) 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2008-2022 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2008.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/mbtowc-impl.h b/lib/mbtowc-impl.h
index 30d715d6a..2b27bafd6 100644
--- a/lib/mbtowc-impl.h
+++ b/lib/mbtowc-impl.h
@@ -1,5 +1,5 @@
 /* Convert multibyte character to wide character.
-   Copyright (C) 2011-2021 Free Software Foundation, Inc.
+   Copyright (C) 2011-2022 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2011.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/mbtowc-lock.c b/lib/mbtowc-lock.c
index 0f7ae6c21..06d32246d 100644
--- a/lib/mbtowc-lock.c
+++ b/lib/mbtowc-lock.c
@@ -1,5 +1,5 @@
 /* Return the internal lock used by mbrtowc and mbrtoc32.
-   Copyright (C) 2019-2021 Free Software Foundation, Inc.
+   Copyright (C) 2019-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/mbtowc-lock.h b/lib/mbtowc-lock.h
index d31b0b6c7..ecfd44e8d 100644
--- a/lib/mbtowc-lock.h
+++ b/lib/mbtowc-lock.h
@@ -1,5 +1,5 @@
 /* Use the internal lock used by mbrtowc and mbrtoc32.
-   Copyright (C) 2019-2021 Free Software Foundation, Inc.
+   Copyright (C) 2019-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/mbtowc.c b/lib/mbtowc.c
index 47b431a42..a9a799510 100644
--- a/lib/mbtowc.c
+++ b/lib/mbtowc.c
@@ -1,5 +1,5 @@
 /* Convert multibyte character to wide character.
-   Copyright (C) 2011-2021 Free Software Foundation, Inc.
+   Copyright (C) 2011-2022 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2011.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/memchr.c b/lib/memchr.c
index 56fd59d79..0ca7b30a4 100644
--- a/lib/memchr.c
+++ b/lib/memchr.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1993, 1996-1997, 1999-2000, 2003-2004, 2006, 2008-2021
+/* Copyright (C) 1991, 1993, 1996-1997, 1999-2000, 2003-2004, 2006, 2008-2022
    Free Software Foundation, Inc.
 
    Based on strlen implementation by Torbjorn Granlund (tege@sics.se),
diff --git a/lib/memchr.valgrind b/lib/memchr.valgrind
index 4f16481ce..cb0f351cc 100644
--- a/lib/memchr.valgrind
+++ b/lib/memchr.valgrind
@@ -1,6 +1,6 @@
 # Suppress a valgrind message about use of uninitialized memory in memchr().
 
-# Copyright (C) 2009-2021 Free Software Foundation, Inc.
+# Copyright (C) 2009-2022 Free Software Foundation, Inc.
 #
 # This file is free software: you can redistribute it and/or modify
 # it under the terms of the GNU Lesser General Public License as
diff --git a/lib/mempcpy.c b/lib/mempcpy.c
index cacacdbc6..9aae418ef 100644
--- a/lib/mempcpy.c
+++ b/lib/mempcpy.c
@@ -1,5 +1,5 @@
 /* Copy memory area and return pointer after last written byte.
-   Copyright (C) 2003, 2007, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2007, 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/minmax.h b/lib/minmax.h
index a03361baf..b4b1345bb 100644
--- a/lib/minmax.h
+++ b/lib/minmax.h
@@ -1,5 +1,5 @@
 /* MIN, MAX macros.
-   Copyright (C) 1995, 1998, 2001, 2003, 2005, 2009-2021 Free Software
+   Copyright (C) 1995, 1998, 2001, 2003, 2005, 2009-2022 Free Software
    Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/mkdir.c b/lib/mkdir.c
index 2766cc786..490170181 100644
--- a/lib/mkdir.c
+++ b/lib/mkdir.c
@@ -1,7 +1,7 @@
 /* On some systems, mkdir ("foo/", 0700) fails because of the trailing
    slash.  On those systems, this wrapper removes the trailing slash.
 
-   Copyright (C) 2001, 2003, 2006, 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2003, 2006, 2008-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
@@ -48,7 +48,7 @@
 /* This function is required at least for NetBSD 1.5.2.  */
 
 int
-rpl_mkdir (char const *dir, mode_t mode maybe_unused)
+rpl_mkdir (char const *dir, maybe_unused mode_t mode)
 {
   int ret_val;
   char *tmp_dir;
diff --git a/lib/mkostemp.c b/lib/mkostemp.c
index 285f1badf..eae289aff 100644
--- a/lib/mkostemp.c
+++ b/lib/mkostemp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998-1999, 2001, 2005-2007, 2009-2021 Free Software
+/* Copyright (C) 1998-1999, 2001, 2005-2007, 2009-2022 Free Software
    Foundation, Inc.
    This file is derived from the one in the GNU C Library.
 
diff --git a/lib/mktime-internal.h b/lib/mktime-internal.h
index 7386625d3..170764eab 100644
--- a/lib/mktime-internal.h
+++ b/lib/mktime-internal.h
@@ -1,5 +1,5 @@
 /* Internals of mktime and related functions
-   Copyright 2016-2021 Free Software Foundation, Inc.
+   Copyright 2016-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Paul Eggert <eggert@cs.ucla.edu>.
 
diff --git a/lib/mktime.c b/lib/mktime.c
index ae721c72e..7dc9d67ef 100644
--- a/lib/mktime.c
+++ b/lib/mktime.c
@@ -1,5 +1,5 @@
 /* Convert a 'struct tm' to a time_t value.
-   Copyright (C) 1993-2021 Free Software Foundation, Inc.
+   Copyright (C) 1993-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Paul Eggert <eggert@twinsun.com>.
 
@@ -429,8 +429,13 @@ __mktime_internal (struct tm *tp,
 	 time with the right value, and use its UTC offset.
 
 	 Heuristic: probe the adjacent timestamps in both directions,
-	 looking for the desired isdst.  This should work for all real
-	 time zone histories in the tz database.  */
+	 looking for the desired isdst.  If none is found within a
+	 reasonable duration bound, assume a one-hour DST difference.
+	 This should work for all real time zone histories in the tz
+	 database.  */
+
+      /* +1 if we wanted standard time but got DST, -1 if the reverse.  */
+      int dst_difference = (isdst == 0) - (tm.tm_isdst == 0);
 
       /* Distance between probes when looking for a DST boundary.  In
 	 tzdata2003a, the shortest period of DST is 601200 seconds
@@ -441,12 +446,14 @@ __mktime_internal (struct tm *tp,
 	 periods when probing.  */
       int stride = 601200;
 
-      /* The longest period of DST in tzdata2003a is 536454000 seconds
-	 (e.g., America/Jujuy starting 1946-10-01 01:00).  The longest
-	 period of non-DST is much longer, but it makes no real sense
-	 to search for more than a year of non-DST, so use the DST
-	 max.  */
-      int duration_max = 536454000;
+      /* In TZDB 2021e, the longest period of DST (or of non-DST), in
+	 which the DST (or adjacent DST) difference is not one hour,
+	 is 457243209 seconds: e.g., America/Cambridge_Bay with leap
+	 seconds, starting 1965-10-31 00:00 in a switch from
+	 double-daylight time (-05) to standard time (-07), and
+	 continuing to 1980-04-27 02:00 in a switch from standard time
+	 (-07) to daylight time (-06).  */
+      int duration_max = 457243209;
 
       /* Search in both directions, so the maximum distance is half
 	 the duration; add the stride to avoid off-by-1 problems.  */
@@ -483,6 +490,11 @@ __mktime_internal (struct tm *tp,
 	      }
 	  }
 
+      /* No unusual DST offset was found nearby.  Assume one-hour DST.  */
+      t += 60 * 60 * dst_difference;
+      if (mktime_min <= t && t <= mktime_max && convert_time (convert, t, &tm))
+	goto offset_found;
+
       __set_errno (EOVERFLOW);
       return -1;
     }
diff --git a/lib/msvc-inval.c b/lib/msvc-inval.c
index a23dac958..d6651caa8 100644
--- a/lib/msvc-inval.c
+++ b/lib/msvc-inval.c
@@ -1,5 +1,5 @@
 /* Invalid parameter handler for MSVC runtime libraries.
-   Copyright (C) 2011-2021 Free Software Foundation, Inc.
+   Copyright (C) 2011-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/msvc-inval.h b/lib/msvc-inval.h
index e115a3514..1230b8994 100644
--- a/lib/msvc-inval.h
+++ b/lib/msvc-inval.h
@@ -1,5 +1,5 @@
 /* Invalid parameter handler for MSVC runtime libraries.
-   Copyright (C) 2011-2021 Free Software Foundation, Inc.
+   Copyright (C) 2011-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/msvc-nothrow.c b/lib/msvc-nothrow.c
index d3c1f54be..aa069643f 100644
--- a/lib/msvc-nothrow.c
+++ b/lib/msvc-nothrow.c
@@ -1,6 +1,6 @@
 /* Wrappers that don't throw invalid parameter notifications
    with MSVC runtime libraries.
-   Copyright (C) 2011-2021 Free Software Foundation, Inc.
+   Copyright (C) 2011-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/msvc-nothrow.h b/lib/msvc-nothrow.h
index 057b5dd8e..53451557e 100644
--- a/lib/msvc-nothrow.h
+++ b/lib/msvc-nothrow.h
@@ -1,6 +1,6 @@
 /* Wrappers that don't throw invalid parameter notifications
    with MSVC runtime libraries.
-   Copyright (C) 2011-2021 Free Software Foundation, Inc.
+   Copyright (C) 2011-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/netdb.in.h b/lib/netdb.in.h
index eb5c960ba..e05cf4b13 100644
--- a/lib/netdb.in.h
+++ b/lib/netdb.in.h
@@ -1,5 +1,5 @@
 /* Provide a netdb.h header file for systems lacking it (read: MinGW).
-   Copyright (C) 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2008-2022 Free Software Foundation, Inc.
    Written by Simon Josefsson.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/netinet_in.in.h b/lib/netinet_in.in.h
index 21f3a64f9..e23807cac 100644
--- a/lib/netinet_in.in.h
+++ b/lib/netinet_in.in.h
@@ -1,5 +1,5 @@
 /* Substitute for <netinet/in.h>.
-   Copyright (C) 2007-2021 Free Software Foundation, Inc.
+   Copyright (C) 2007-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/nl_langinfo-lock.c b/lib/nl_langinfo-lock.c
index fcdf56dc6..c36882d5c 100644
--- a/lib/nl_langinfo-lock.c
+++ b/lib/nl_langinfo-lock.c
@@ -1,5 +1,5 @@
 /* Return the internal lock used by nl_langinfo.
-   Copyright (C) 2019-2021 Free Software Foundation, Inc.
+   Copyright (C) 2019-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/nl_langinfo.c b/lib/nl_langinfo.c
index b481f209d..3fa478223 100644
--- a/lib/nl_langinfo.c
+++ b/lib/nl_langinfo.c
@@ -1,6 +1,6 @@
 /* nl_langinfo() replacement: query locale dependent information.
 
-   Copyright (C) 2007-2021 Free Software Foundation, Inc.
+   Copyright (C) 2007-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/nproc.c b/lib/nproc.c
index e3ddb9288..378d3ff3f 100644
--- a/lib/nproc.c
+++ b/lib/nproc.c
@@ -1,6 +1,6 @@
 /* Detect the number of processors.
 
-   Copyright (C) 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
@@ -307,15 +307,23 @@ num_processors_ignoring_omp (enum nproc_query query)
      NPROC_CURRENT and NPROC_ALL.  */
 
 #if HAVE_SYSCTL && ! defined __GLIBC__ && defined HW_NCPU
-  { /* This works on Mac OS X, FreeBSD, NetBSD, OpenBSD.  */
+  { /* This works on macOS, FreeBSD, NetBSD, OpenBSD.
+       macOS 10.14 does not allow mib to be const.  */
     int nprocs;
     size_t len = sizeof (nprocs);
-    static int mib[2] = { CTL_HW, HW_NCPU };
-
-    if (sysctl (mib, ARRAY_SIZE (mib), &nprocs, &len, NULL, 0) == 0
-        && len == sizeof (nprocs)
-        && 0 < nprocs)
-      return nprocs;
+    static int mib[][2] = {
+# ifdef HW_NCPUONLINE
+      { CTL_HW, HW_NCPUONLINE },
+# endif
+      { CTL_HW, HW_NCPU }
+    };
+    for (int i = 0; i < ARRAY_SIZE (mib); i++)
+      {
+        if (sysctl (mib[i], ARRAY_SIZE (mib[i]), &nprocs, &len, NULL, 0) == 0
+            && len == sizeof (nprocs)
+            && 0 < nprocs)
+          return nprocs;
+      }
   }
 #endif
 
diff --git a/lib/nproc.h b/lib/nproc.h
index d7659a5ca..505351d95 100644
--- a/lib/nproc.h
+++ b/lib/nproc.h
@@ -1,6 +1,6 @@
 /* Detect the number of processors.
 
-   Copyright (C) 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/nstrftime.c b/lib/nstrftime.c
index 7f258e872..c1dd55424 100644
--- a/lib/nstrftime.c
+++ b/lib/nstrftime.c
@@ -1,9 +1,9 @@
-/* Copyright (C) 1991-2021 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    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 3 of the
    License, or (at your option) any later version.
 
    This file is distributed in the hope that it will be useful,
@@ -22,7 +22,7 @@
 # define HAVE_TZNAME 1
 # include "../locale/localeinfo.h"
 #else
-# include <config.h>
+# include <libc-config.h>
 # if FPRINTFTIME
 #  include "fprintftime.h"
 # else
@@ -367,10 +367,7 @@ tm_diff (const struct tm *a, const struct tm *b)
 #define ISO_WEEK1_WDAY 4 /* Thursday */
 #define YDAY_MINIMUM (-366)
 static int iso_week_days (int, int);
-#if defined __GNUC__ || defined __clang__
-__inline__
-#endif
-static int
+static __inline int
 iso_week_days (int yday, int wday)
 {
   /* Add enough to the first operand of % to make it nonnegative.  */
@@ -428,9 +425,7 @@ my_strftime (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
   return __strftime_internal (s, STRFTIME_ARG (maxsize) format, tp, false,
                               0, -1, &tzset_called extra_args LOCALE_ARG);
 }
-#if defined _LIBC && ! FPRINTFTIME
 libc_hidden_def (my_strftime)
-#endif
 
 /* Just like my_strftime, above, but with more parameters.
    UPCASE indicates that the result should be converted to upper case.
@@ -656,6 +651,8 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
 
 #endif /* ! DO_MULTIBYTE */
 
+      char const *percent = f;
+
       /* Check for flags that can modify a format.  */
       while (1)
         {
@@ -757,8 +754,8 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
           while (0)
 
         case L_('%'):
-          if (modifier != 0)
-            goto bad_format;
+          if (f - 1 != percent)
+            goto bad_percent;
           add1 (*f);
           break;
 
@@ -1161,7 +1158,6 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
 
         case L_('q'):           /* GNU extension.  */
           DO_SIGNED_NUMBER (1, false, ((tp->tm_mon * 11) >> 5) + 1);
-          break;
 
         case L_('R'):
           subfmt = L_("%H:%M");
@@ -1472,6 +1468,7 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
           }
 
         case L_('\0'):          /* GNU extension: % at end of format.  */
+        bad_percent:
             --f;
             FALLTHROUGH;
         default:
@@ -1479,12 +1476,7 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
              since this is most likely the right thing to do if a
              multibyte string has been misparsed.  */
         bad_format:
-          {
-            int flen;
-            for (flen = 1; f[1 - flen] != L_('%'); flen++)
-              continue;
-            cpy (flen, &f[1 - flen]);
-          }
+          cpy (f - percent + 1, percent);
           break;
         }
     }
diff --git a/lib/open.c b/lib/open.c
index 372cda881..170bff108 100644
--- a/lib/open.c
+++ b/lib/open.c
@@ -1,5 +1,5 @@
 /* Open a descriptor to a file.
-   Copyright (C) 2007-2021 Free Software Foundation, Inc.
+   Copyright (C) 2007-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/pathmax.h b/lib/pathmax.h
index 716f4a9aa..19b93d7ea 100644
--- a/lib/pathmax.h
+++ b/lib/pathmax.h
@@ -1,5 +1,5 @@
 /* Define PATH_MAX somehow.  Requires sys/types.h.
-   Copyright (C) 1992, 1999, 2001, 2003, 2005, 2009-2021 Free Software
+   Copyright (C) 1992, 1999, 2001, 2003, 2005, 2009-2022 Free Software
    Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/pipe.c b/lib/pipe.c
index fc978f2eb..ce909b9f0 100644
--- a/lib/pipe.c
+++ b/lib/pipe.c
@@ -1,5 +1,5 @@
 /* Create a pipe.
-   Copyright (C) 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/pipe2.c b/lib/pipe2.c
index 9ba8c3b70..400aff001 100644
--- a/lib/pipe2.c
+++ b/lib/pipe2.c
@@ -1,5 +1,5 @@
 /* Create a pipe, with specific opening flags.
-   Copyright (C) 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/poll.c b/lib/poll.c
index 8d5ba9655..9cfde5f81 100644
--- a/lib/poll.c
+++ b/lib/poll.c
@@ -1,7 +1,7 @@
 /* Emulation for poll(2)
    Contributed by Paolo Bonzini.
 
-   Copyright 2001-2003, 2006-2021 Free Software Foundation, Inc.
+   Copyright 2001-2003, 2006-2022 Free Software Foundation, Inc.
 
    This file is part of gnulib.
 
diff --git a/lib/poll.in.h b/lib/poll.in.h
index e94cd31de..1af6a232f 100644
--- a/lib/poll.in.h
+++ b/lib/poll.in.h
@@ -1,7 +1,7 @@
 /* Header for poll(2) emulation
    Contributed by Paolo Bonzini.
 
-   Copyright 2001-2003, 2007, 2009-2021 Free Software Foundation, Inc.
+   Copyright 2001-2003, 2007, 2009-2022 Free Software Foundation, Inc.
 
    This file is part of gnulib.
 
diff --git a/lib/printf-args.c b/lib/printf-args.c
index b822682c3..669c24a40 100644
--- a/lib/printf-args.c
+++ b/lib/printf-args.c
@@ -1,5 +1,5 @@
 /* Decomposed printf argument list.
-   Copyright (C) 1999, 2002-2003, 2005-2007, 2009-2021 Free Software
+   Copyright (C) 1999, 2002-2003, 2005-2007, 2009-2022 Free Software
    Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/printf-args.h b/lib/printf-args.h
index c8d91747b..553fe9619 100644
--- a/lib/printf-args.h
+++ b/lib/printf-args.h
@@ -1,5 +1,5 @@
 /* Decomposed printf argument list.
-   Copyright (C) 1999, 2002-2003, 2006-2007, 2011-2021 Free Software
+   Copyright (C) 1999, 2002-2003, 2006-2007, 2011-2022 Free Software
    Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/printf-parse.c b/lib/printf-parse.c
index f21cc17c0..aab02dc5b 100644
--- a/lib/printf-parse.c
+++ b/lib/printf-parse.c
@@ -1,5 +1,5 @@
 /* Formatted output to strings.
-   Copyright (C) 1999-2000, 2002-2003, 2006-2021 Free Software Foundation, Inc.
+   Copyright (C) 1999-2000, 2002-2003, 2006-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/printf-parse.h b/lib/printf-parse.h
index 77b74093c..b12ccea3c 100644
--- a/lib/printf-parse.h
+++ b/lib/printf-parse.h
@@ -1,5 +1,5 @@
 /* Parse printf format string.
-   Copyright (C) 1999, 2002-2003, 2005, 2007, 2010-2021 Free Software
+   Copyright (C) 1999, 2002-2003, 2005, 2007, 2010-2022 Free Software
    Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/putenv.c b/lib/putenv.c
index 435d10fdc..b0d27e2f6 100644
--- a/lib/putenv.c
+++ b/lib/putenv.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1994, 1997-1998, 2000, 2003-2021 Free Software
+/* Copyright (C) 1991, 1994, 1997-1998, 2000, 2003-2022 Free Software
    Foundation, Inc.
 
    NOTE: The canonical source of this file is maintained with the GNU C
@@ -6,7 +6,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 3 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/raise.c b/lib/raise.c
index 37c100dd8..385ddd384 100644
--- a/lib/raise.c
+++ b/lib/raise.c
@@ -1,6 +1,6 @@
 /* Provide a non-threads replacement for the POSIX raise function.
 
-   Copyright (C) 2002-2003, 2005-2006, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2002-2003, 2005-2006, 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/rawmemchr.c b/lib/rawmemchr.c
index 896d435af..ea68c1bfc 100644
--- a/lib/rawmemchr.c
+++ b/lib/rawmemchr.c
@@ -1,5 +1,5 @@
 /* Searching in a string.
-   Copyright (C) 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2008-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
@@ -22,68 +22,54 @@
 /* A function definition is only needed if HAVE_RAWMEMCHR is not defined.  */
 #if !HAVE_RAWMEMCHR
 
+# include <limits.h>
+# include <stdalign.h>
+# include <stdint.h>
+
+# include "verify.h"
+
 /* Find the first occurrence of C in S.  */
 void *
 rawmemchr (const void *s, int c_in)
 {
-  /* On 32-bit hardware, choosing longword to be a 32-bit unsigned
-     long instead of a 64-bit uintmax_t tends to give better
-     performance.  On 64-bit hardware, unsigned long is generally 64
-     bits already.  Change this typedef to experiment with
-     performance.  */
-  typedef unsigned long int longword;
+  /* Change this typedef to experiment with performance.  */
+  typedef uintptr_t longword;
+  /* If you change the "uintptr_t", you should change UINTPTR_WIDTH to match.
+     This verifies that the type does not have padding bits.  */
+  verify (UINTPTR_WIDTH == UCHAR_WIDTH * sizeof (longword));
 
   const unsigned char *char_ptr;
-  const longword *longword_ptr;
-  longword repeated_one;
-  longword repeated_c;
-  unsigned char c;
-
-  c = (unsigned char) c_in;
+  unsigned char c = c_in;
 
   /* Handle the first few bytes by reading one byte at a time.
      Do this until CHAR_PTR is aligned on a longword boundary.  */
   for (char_ptr = (const unsigned char *) s;
-       (size_t) char_ptr % sizeof (longword) != 0;
+       (uintptr_t) char_ptr % alignof (longword) != 0;
        ++char_ptr)
     if (*char_ptr == c)
       return (void *) char_ptr;
 
-  longword_ptr = (const longword *) char_ptr;
-
-  /* All these elucidatory comments refer to 4-byte longwords,
-     but the theory applies equally well to any size longwords.  */
+  longword const *longword_ptr = s = char_ptr;
 
   /* Compute auxiliary longword values:
      repeated_one is a value which has a 1 in every byte.
      repeated_c has c in every byte.  */
-  repeated_one = 0x01010101;
-  repeated_c = c | (c << 8);
-  repeated_c |= repeated_c << 16;
-  if (0xffffffffU < (longword) -1)
-    {
-      repeated_one |= repeated_one << 31 << 1;
-      repeated_c |= repeated_c << 31 << 1;
-      if (8 < sizeof (longword))
-        {
-          size_t i;
-
-          for (i = 64; i < sizeof (longword) * 8; i *= 2)
-            {
-              repeated_one |= repeated_one << i;
-              repeated_c |= repeated_c << i;
-            }
-        }
-    }
+  longword repeated_one = (longword) -1 / UCHAR_MAX;
+  longword repeated_c = repeated_one * c;
+  longword repeated_hibit = repeated_one * (UCHAR_MAX / 2 + 1);
 
   /* Instead of the traditional loop which tests each byte, we will
-     test a longword at a time.  The tricky part is testing if *any of
-     the four* bytes in the longword in question are equal to NUL or
+     test a longword at a time.  The tricky part is testing if any of
+     the bytes in the longword in question are equal to
      c.  We first use an xor with repeated_c.  This reduces the task
-     to testing whether *any of the four* bytes in longword1 is zero.
+     to testing whether any of the bytes in longword1 is zero.
+
+     (The following comments assume 8-bit bytes, as POSIX requires;
+     the code's use of UCHAR_MAX should work even if bytes have more
+     than 8 bits.)
 
      We compute tmp =
-       ((longword1 - repeated_one) & ~longword1) & (repeated_one << 7).
+       ((longword1 - repeated_one) & ~longword1) & (repeated_one * 0x80).
      That is, we perform the following operations:
        1. Subtract repeated_one.
        2. & ~longword1.
@@ -117,22 +103,20 @@ rawmemchr (const void *s, int c_in)
     {
       longword longword1 = *longword_ptr ^ repeated_c;
 
-      if ((((longword1 - repeated_one) & ~longword1)
-           & (repeated_one << 7)) != 0)
+      if ((((longword1 - repeated_one) & ~longword1) & repeated_hibit) != 0)
         break;
       longword_ptr++;
     }
 
-  char_ptr = (const unsigned char *) longword_ptr;
+  char_ptr = s = longword_ptr;
 
   /* At this point, we know that one of the sizeof (longword) bytes
-     starting at char_ptr is == c.  On little-endian machines, we
+     starting at char_ptr is == c.  If we knew endianness, we
      could determine the first such byte without any further memory
      accesses, just by looking at the tmp result from the last loop
-     iteration.  But this does not work on big-endian machines.
-     Choose code that works in both cases.  */
+     iteration.  However, the following simple and portable code does
+     not attempt this potential optimization.  */
 
-  char_ptr = (unsigned char *) longword_ptr;
   while (*char_ptr != c)
     char_ptr++;
   return (void *) char_ptr;
diff --git a/lib/rawmemchr.valgrind b/lib/rawmemchr.valgrind
index d489c320c..64cf86c84 100644
--- a/lib/rawmemchr.valgrind
+++ b/lib/rawmemchr.valgrind
@@ -1,6 +1,6 @@
 # Suppress a valgrind message about use of uninitialized memory in rawmemchr().
 
-# Copyright (C) 2008-2021 Free Software Foundation, Inc.
+# Copyright (C) 2008-2022 Free Software Foundation, Inc.
 #
 # This file is free software: you can redistribute it and/or modify
 # it under the terms of the GNU Lesser General Public License as
diff --git a/lib/read.c b/lib/read.c
index 840d9ed5a..1bb7d90ce 100644
--- a/lib/read.c
+++ b/lib/read.c
@@ -1,5 +1,5 @@
 /* POSIX compatible read() function.
-   Copyright (C) 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2008-2022 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2011.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/readlink.c b/lib/readlink.c
index d4f4b08e9..ed03cc8de 100644
--- a/lib/readlink.c
+++ b/lib/readlink.c
@@ -1,5 +1,5 @@
 /* Read the contents of a symbolic link.
-   Copyright (C) 2003-2007, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2003-2007, 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
@@ -29,8 +29,8 @@
    such as DJGPP 2.03 and mingw32.  */
 
 ssize_t
-readlink (char const *file, char *buf _GL_UNUSED,
-          size_t bufsize _GL_UNUSED)
+readlink (char const *file, _GL_UNUSED char *buf,
+          _GL_UNUSED size_t bufsize)
 {
   struct stat statbuf;
 
diff --git a/lib/realloc.c b/lib/realloc.c
index af03f0c57..c87838157 100644
--- a/lib/realloc.c
+++ b/lib/realloc.c
@@ -1,6 +1,6 @@
 /* realloc() function that is glibc compatible.
 
-   Copyright (C) 1997, 2003-2004, 2006-2007, 2009-2021 Free Software
+   Copyright (C) 1997, 2003-2004, 2006-2007, 2009-2022 Free Software
    Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/recv.c b/lib/recv.c
index 3eb2b4d4b..4910731ed 100644
--- a/lib/recv.c
+++ b/lib/recv.c
@@ -1,6 +1,6 @@
 /* recv.c --- wrappers for Windows recv function
 
-   Copyright (C) 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2008-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/recvfrom.c b/lib/recvfrom.c
index 25231ffe1..3c9f5b21d 100644
--- a/lib/recvfrom.c
+++ b/lib/recvfrom.c
@@ -1,6 +1,6 @@
 /* recvfrom.c --- wrappers for Windows recvfrom function
 
-   Copyright (C) 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2008-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/regcomp.c b/lib/regcomp.c
index 887e5b506..122c3de58 100644
--- a/lib/regcomp.c
+++ b/lib/regcomp.c
@@ -1,5 +1,5 @@
 /* Extended regular expression matching and search library.
-   Copyright (C) 2002-2021 Free Software Foundation, Inc.
+   Copyright (C) 2002-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
 
@@ -27,14 +27,10 @@ static void re_compile_fastmap_iter (regex_t *bufp,
 				     const re_dfastate_t *init_state,
 				     char *fastmap);
 static reg_errcode_t init_dfa (re_dfa_t *dfa, size_t pat_len);
-#ifdef RE_ENABLE_I18N
 static void free_charset (re_charset_t *cset);
-#endif /* RE_ENABLE_I18N */
 static void free_workarea_compile (regex_t *preg);
 static reg_errcode_t create_initial_state (re_dfa_t *dfa);
-#ifdef RE_ENABLE_I18N
 static void optimize_utf8 (re_dfa_t *dfa);
-#endif
 static reg_errcode_t analyze (regex_t *preg);
 static reg_errcode_t preorder (bin_tree_t *root,
 			       reg_errcode_t (fn (void *, bin_tree_t *)),
@@ -89,7 +85,6 @@ static reg_errcode_t parse_bracket_element (bracket_elem_t *elem,
 static reg_errcode_t parse_bracket_symbol (bracket_elem_t *elem,
 					  re_string_t *regexp,
 					  re_token_t *token);
-#ifdef RE_ENABLE_I18N
 static reg_errcode_t build_equiv_class (bitset_t sbcset,
 					re_charset_t *mbcset,
 					Idx *equiv_class_alloc,
@@ -100,14 +95,6 @@ static reg_errcode_t build_charclass (RE_TRANSLATE_TYPE trans,
 				      Idx *char_class_alloc,
 				      const char *class_name,
 				      reg_syntax_t syntax);
-#else  /* not RE_ENABLE_I18N */
-static reg_errcode_t build_equiv_class (bitset_t sbcset,
-					const unsigned char *name);
-static reg_errcode_t build_charclass (RE_TRANSLATE_TYPE trans,
-				      bitset_t sbcset,
-				      const char *class_name,
-				      reg_syntax_t syntax);
-#endif /* not RE_ENABLE_I18N */
 static bin_tree_t *build_charclass_op (re_dfa_t *dfa,
 				       RE_TRANSLATE_TYPE trans,
 				       const char *class_name,
@@ -279,8 +266,7 @@ re_compile_fastmap (struct re_pattern_buffer *bufp)
 }
 weak_alias (__re_compile_fastmap, re_compile_fastmap)
 
-static inline void
-__attribute__ ((always_inline))
+static __always_inline void
 re_set_fastmap (char *fastmap, bool icase, int ch)
 {
   fastmap[ch] = 1;
@@ -306,7 +292,6 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
       if (type == CHARACTER)
 	{
 	  re_set_fastmap (fastmap, icase, dfa->nodes[node].opr.c);
-#ifdef RE_ENABLE_I18N
 	  if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1)
 	    {
 	      unsigned char buf[MB_LEN_MAX];
@@ -327,7 +312,6 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
 		      != (size_t) -1))
 		re_set_fastmap (fastmap, false, buf[0]);
 	    }
-#endif
 	}
       else if (type == SIMPLE_BRACKET)
 	{
@@ -341,13 +325,12 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
 		  re_set_fastmap (fastmap, icase, ch);
 	    }
 	}
-#ifdef RE_ENABLE_I18N
       else if (type == COMPLEX_BRACKET)
 	{
 	  re_charset_t *cset = dfa->nodes[node].opr.mbcset;
 	  Idx i;
 
-# ifdef _LIBC
+#ifdef _LIBC
 	  /* See if we have to try all bytes which start multiple collation
 	     elements.
 	     e.g. In da_DK, we want to catch 'a' since "aa" is a valid
@@ -363,7 +346,7 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
 		    if (table[i] < 0)
 		      re_set_fastmap (fastmap, icase, i);
 		}
-# endif /* _LIBC */
+#endif /* _LIBC */
 
 	  /* See if we have to start the match at all multibyte characters,
 	     i.e. where we would not find an invalid sequence.  This only
@@ -371,9 +354,9 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
 	     sets, the SIMPLE_BRACKET again suffices.  */
 	  if (dfa->mb_cur_max > 1
 	      && (cset->nchar_classes || cset->non_match || cset->nranges
-# ifdef _LIBC
+#ifdef _LIBC
 		  || cset->nequiv_classes
-# endif /* _LIBC */
+#endif /* _LIBC */
 		 ))
 	    {
 	      unsigned char c = 0;
@@ -406,12 +389,7 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
 		}
 	    }
 	}
-#endif /* RE_ENABLE_I18N */
-      else if (type == OP_PERIOD
-#ifdef RE_ENABLE_I18N
-	       || type == OP_UTF8_PERIOD
-#endif /* RE_ENABLE_I18N */
-	       || type == END_OF_RE)
+      else if (type == OP_PERIOD || type == OP_UTF8_PERIOD || type == END_OF_RE)
 	{
 	  memset (fastmap, '\1', sizeof (char) * SBC_MAX);
 	  if (type == END_OF_RE)
@@ -550,7 +528,6 @@ regerror (int errcode, const regex_t *__restrict preg, char *__restrict errbuf,
 weak_alias (__regerror, regerror)
 
 
-#ifdef RE_ENABLE_I18N
 /* This static array is used for the map to single-byte characters when
    UTF-8 is used.  Otherwise we would allocate memory just to initialize
    it the same all the time.  UTF-8 is the preferred encoding so this is
@@ -558,25 +535,24 @@ weak_alias (__regerror, regerror)
 static const bitset_t utf8_sb_map =
 {
   /* Set the first 128 bits.  */
-# if (defined __GNUC__ || __clang_major__ >= 4) && !defined __STRICT_ANSI__
+#if (defined __GNUC__ || __clang_major__ >= 4) && !defined __STRICT_ANSI__
   [0 ... 0x80 / BITSET_WORD_BITS - 1] = BITSET_WORD_MAX
-# else
-#  if 4 * BITSET_WORD_BITS < ASCII_CHARS
-#   error "bitset_word_t is narrower than 32 bits"
-#  elif 3 * BITSET_WORD_BITS < ASCII_CHARS
+#else
+# if 4 * BITSET_WORD_BITS < ASCII_CHARS
+#  error "bitset_word_t is narrower than 32 bits"
+# elif 3 * BITSET_WORD_BITS < ASCII_CHARS
   BITSET_WORD_MAX, BITSET_WORD_MAX, BITSET_WORD_MAX,
-#  elif 2 * BITSET_WORD_BITS < ASCII_CHARS
+# elif 2 * BITSET_WORD_BITS < ASCII_CHARS
   BITSET_WORD_MAX, BITSET_WORD_MAX,
-#  elif 1 * BITSET_WORD_BITS < ASCII_CHARS
+# elif 1 * BITSET_WORD_BITS < ASCII_CHARS
   BITSET_WORD_MAX,
-#  endif
+# endif
   (BITSET_WORD_MAX
    >> (SBC_MAX % BITSET_WORD_BITS == 0
        ? 0
        : BITSET_WORD_BITS - SBC_MAX % BITSET_WORD_BITS))
-# endif
-};
 #endif
+};
 
 
 static void
@@ -614,10 +590,8 @@ free_dfa_content (re_dfa_t *dfa)
 	re_free (entry->array);
       }
   re_free (dfa->state_table);
-#ifdef RE_ENABLE_I18N
   if (dfa->sb_char != utf8_sb_map)
     re_free (dfa->sb_char);
-#endif
   re_free (dfa->subexp_map);
 #ifdef DEBUG
   re_free (dfa->re_str);
@@ -796,11 +770,9 @@ re_compile_internal (regex_t *preg, const char * pattern, size_t length,
   if (__glibc_unlikely (err != REG_NOERROR))
     goto re_compile_internal_free_return;
 
-#ifdef RE_ENABLE_I18N
   /* If possible, do searching in single byte encoding to speed things up.  */
   if (dfa->is_utf8 && !(syntax & RE_ICASE) && preg->translate == NULL)
     optimize_utf8 (dfa);
-#endif
 
   /* Then create the initial state of the dfa.  */
   err = create_initial_state (dfa);
@@ -830,11 +802,7 @@ init_dfa (re_dfa_t *dfa, size_t pat_len)
 #ifndef _LIBC
   const char *codeset_name;
 #endif
-#ifdef RE_ENABLE_I18N
   size_t max_i18n_object_size = MAX (sizeof (wchar_t), sizeof (wctype_t));
-#else
-  size_t max_i18n_object_size = 0;
-#endif
   size_t max_object_size =
     MAX (sizeof (struct re_state_table_entry),
 	 MAX (sizeof (re_token_t),
@@ -886,7 +854,6 @@ init_dfa (re_dfa_t *dfa, size_t pat_len)
   dfa->map_notascii = 0;
 #endif
 
-#ifdef RE_ENABLE_I18N
   if (dfa->mb_cur_max > 1)
     {
       if (dfa->is_utf8)
@@ -906,14 +873,13 @@ init_dfa (re_dfa_t *dfa, size_t pat_len)
 		wint_t wch = __btowc (ch);
 		if (wch != WEOF)
 		  dfa->sb_char[i] |= (bitset_word_t) 1 << j;
-# ifndef _LIBC
+#ifndef _LIBC
 		if (isascii (ch) && wch != ch)
 		  dfa->map_notascii = 1;
-# endif
+#endif
 	      }
 	}
     }
-#endif
 
   if (__glibc_unlikely (dfa->nodes == NULL || dfa->state_table == NULL))
     return REG_ESPACE;
@@ -933,8 +899,6 @@ init_word_char (re_dfa_t *dfa)
   dfa->word_ops_used = 1;
   if (__glibc_likely (dfa->map_notascii == 0))
     {
-      /* Avoid uint32_t and uint64_t as some non-GCC platforms lack
-	 them, an issue when this code is used in Gnulib.  */
       bitset_word_t bits0 = 0x00000000;
       bitset_word_t bits1 = 0x03ff0000;
       bitset_word_t bits2 = 0x87fffffe;
@@ -1074,7 +1038,6 @@ create_initial_state (re_dfa_t *dfa)
   return REG_NOERROR;
 }
 \f
-#ifdef RE_ENABLE_I18N
 /* If it is possible to do searching in single byte encoding instead of UTF-8
    to speed things up, set dfa->mb_cur_max to 1, clear is_utf8 and change
    DFA nodes where needed.  */
@@ -1154,7 +1117,6 @@ optimize_utf8 (re_dfa_t *dfa)
   dfa->is_utf8 = 0;
   dfa->has_mb_node = dfa->nbackref > 0 || has_period;
 }
-#endif
 \f
 /* Analyze the structure tree, and calculate "first", "next", "edest",
    "eclosure", and "inveclosure".  */
@@ -1792,7 +1754,6 @@ peek_token (re_token_t *token, re_string_t *input, reg_syntax_t syntax)
   token->opr.c = c;
 
   token->word_char = 0;
-#ifdef RE_ENABLE_I18N
   token->mb_partial = 0;
   if (input->mb_cur_max > 1
       && !re_string_first_byte (input, re_string_cur_idx (input)))
@@ -1801,7 +1762,6 @@ peek_token (re_token_t *token, re_string_t *input, reg_syntax_t syntax)
       token->mb_partial = 1;
       return 1;
     }
-#endif
   if (c == '\\')
     {
       unsigned char c2;
@@ -1814,7 +1774,6 @@ peek_token (re_token_t *token, re_string_t *input, reg_syntax_t syntax)
       c2 = re_string_peek_byte_case (input, 1);
       token->opr.c = c2;
       token->type = CHARACTER;
-#ifdef RE_ENABLE_I18N
       if (input->mb_cur_max > 1)
 	{
 	  wint_t wc = re_string_wchar_at (input,
@@ -1822,7 +1781,6 @@ peek_token (re_token_t *token, re_string_t *input, reg_syntax_t syntax)
 	  token->word_char = IS_WIDE_WORD_CHAR (wc) != 0;
 	}
       else
-#endif
 	token->word_char = IS_WORD_CHAR (c2) != 0;
 
       switch (c2)
@@ -1928,14 +1886,12 @@ peek_token (re_token_t *token, re_string_t *input, reg_syntax_t syntax)
     }
 
   token->type = CHARACTER;
-#ifdef RE_ENABLE_I18N
   if (input->mb_cur_max > 1)
     {
       wint_t wc = re_string_wchar_at (input, re_string_cur_idx (input));
       token->word_char = IS_WIDE_WORD_CHAR (wc) != 0;
     }
   else
-#endif
     token->word_char = IS_WORD_CHAR (token->opr.c);
 
   switch (c)
@@ -2027,14 +1983,12 @@ peek_token_bracket (re_token_t *token, re_string_t *input, reg_syntax_t syntax)
   c = re_string_peek_byte (input, 0);
   token->opr.c = c;
 
-#ifdef RE_ENABLE_I18N
   if (input->mb_cur_max > 1
       && !re_string_first_byte (input, re_string_cur_idx (input)))
     {
       token->type = CHARACTER;
       return 1;
     }
-#endif /* RE_ENABLE_I18N */
 
   if (c == '\\' && (syntax & RE_BACKSLASH_ESCAPE_IN_LISTS)
       && re_string_cur_idx (input) + 1 < re_string_length (input))
@@ -2084,15 +2038,25 @@ peek_token_bracket (re_token_t *token, re_string_t *input, reg_syntax_t syntax)
     }
   switch (c)
     {
-    case '-':
-      token->type = OP_CHARSET_RANGE;
-      break;
     case ']':
       token->type = OP_CLOSE_BRACKET;
       break;
     case '^':
       token->type = OP_NON_MATCH_LIST;
       break;
+    case '-':
+      /* In V7 Unix grep and Unix awk and mawk, [...---...]
+         (3 adjacent minus signs) stands for a single minus sign.
+         Support that without breaking anything else.  */
+      if (! (re_string_cur_idx (input) + 2 < re_string_length (input)
+             && re_string_peek_byte (input, 1) == '-'
+             && re_string_peek_byte (input, 2) == '-'))
+        {
+          token->type = OP_CHARSET_RANGE;
+          break;
+        }
+      re_string_skip_bytes (input, 2);
+      FALLTHROUGH;
     default:
       token->type = CHARACTER;
     }
@@ -2256,7 +2220,6 @@ parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token,
 	  *err = REG_ESPACE;
 	  return NULL;
 	}
-#ifdef RE_ENABLE_I18N
       if (dfa->mb_cur_max > 1)
 	{
 	  while (!re_string_eoi (regexp)
@@ -2273,7 +2236,6 @@ parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token,
 		}
 	    }
 	}
-#endif
       break;
 
     case OP_OPEN_SUBEXP:
@@ -2666,40 +2628,30 @@ parse_dup_op (bin_tree_t *elem, re_string_t *regexp, re_dfa_t *dfa,
 
 #ifndef _LIBC
 
-# ifdef RE_ENABLE_I18N
 /* Convert the byte B to the corresponding wide character.  In a
    unibyte locale, treat B as itself.  In a multibyte locale, return
    WEOF if B is an encoding error.  */
 static wint_t
-parse_byte (unsigned char b, re_charset_t *mbcset)
+parse_byte (unsigned char b, re_dfa_t const *dfa)
 {
-  return mbcset == NULL ? b : __btowc (b);
+  return dfa->mb_cur_max > 1 ? __btowc (b) : b;
 }
-# endif
 
-  /* Local function for parse_bracket_exp only used in case of NOT _LIBC.
-     Build the range expression which starts from START_ELEM, and ends
-     at END_ELEM.  The result are written to MBCSET and SBCSET.
-     RANGE_ALLOC is the allocated size of mbcset->range_starts, and
-     mbcset->range_ends, is a pointer argument since we may
-     update it.  */
+/* Local function for parse_bracket_exp used in _LIBC environment.
+   Build the range expression which starts from START_ELEM, and ends
+   at END_ELEM.  The result are written to MBCSET and SBCSET.
+   RANGE_ALLOC is the allocated size of mbcset->range_starts, and
+   mbcset->range_ends, is a pointer argument since we may
+   update it.  */
 
 static reg_errcode_t
-# ifdef RE_ENABLE_I18N
-build_range_exp (const reg_syntax_t syntax,
-                 bitset_t sbcset,
-                 re_charset_t *mbcset,
-                 Idx *range_alloc,
-                 const bracket_elem_t *start_elem,
-                 const bracket_elem_t *end_elem)
-# else /* not RE_ENABLE_I18N */
-build_range_exp (const reg_syntax_t syntax,
-                 bitset_t sbcset,
-                 const bracket_elem_t *start_elem,
-                 const bracket_elem_t *end_elem)
-# endif /* not RE_ENABLE_I18N */
+build_range_exp (bitset_t sbcset, re_charset_t *mbcset, Idx *range_alloc,
+		 bracket_elem_t *start_elem, bracket_elem_t *end_elem,
+		 re_dfa_t *dfa, reg_syntax_t syntax, uint_fast32_t nrules,
+		 const unsigned char *collseqmb, const char *collseqwc,
+		 int_fast32_t table_size, const void *symb_table,
+		 const unsigned char *extra)
 {
-  unsigned int start_ch, end_ch;
   /* Equivalence Classes and Character Classes can't be a range start/end.  */
   if (__glibc_unlikely (start_elem->type == EQUIV_CLASS
 			|| start_elem->type == CHAR_CLASS
@@ -2715,110 +2667,88 @@ build_range_exp (const reg_syntax_t syntax,
 			    && strlen ((char *) end_elem->opr.name) > 1)))
     return REG_ECOLLATE;
 
-# ifdef RE_ENABLE_I18N
-  {
-    wchar_t wc;
-    wint_t start_wc;
-    wint_t end_wc;
-
+  unsigned int
     start_ch = ((start_elem->type == SB_CHAR) ? start_elem->opr.ch
 		: ((start_elem->type == COLL_SYM) ? start_elem->opr.name[0]
-		   : 0));
+		   : 0)),
     end_ch = ((end_elem->type == SB_CHAR) ? end_elem->opr.ch
 	      : ((end_elem->type == COLL_SYM) ? end_elem->opr.name[0]
 		 : 0));
+  wint_t
     start_wc = ((start_elem->type == SB_CHAR || start_elem->type == COLL_SYM)
-		? parse_byte (start_ch, mbcset) : start_elem->opr.wch);
+		? parse_byte (start_ch, dfa) : start_elem->opr.wch),
     end_wc = ((end_elem->type == SB_CHAR || end_elem->type == COLL_SYM)
-	      ? parse_byte (end_ch, mbcset) : end_elem->opr.wch);
-    if (start_wc == WEOF || end_wc == WEOF)
-      return REG_ECOLLATE;
-    else if (__glibc_unlikely ((syntax & RE_NO_EMPTY_RANGES)
-			       && start_wc > end_wc))
-      return REG_ERANGE;
-
-    /* Got valid collation sequence values, add them as a new entry.
-       However, for !_LIBC we have no collation elements: if the
-       character set is single byte, the single byte character set
-       that we build below suffices.  parse_bracket_exp passes
-       no MBCSET if dfa->mb_cur_max == 1.  */
-    if (mbcset)
-      {
-	/* Check the space of the arrays.  */
-	if (__glibc_unlikely (*range_alloc == mbcset->nranges))
-	  {
-	    /* There is not enough space, need realloc.  */
-	    wchar_t *new_array_start, *new_array_end;
-	    Idx new_nranges;
-
-	    /* +1 in case of mbcset->nranges is 0.  */
-	    new_nranges = 2 * mbcset->nranges + 1;
-	    /* Use realloc since mbcset->range_starts and mbcset->range_ends
-	       are NULL if *range_alloc == 0.  */
-	    new_array_start = re_realloc (mbcset->range_starts, wchar_t,
-					  new_nranges);
-	    new_array_end = re_realloc (mbcset->range_ends, wchar_t,
-					new_nranges);
+	      ? parse_byte (end_ch, dfa) : end_elem->opr.wch);
 
-	    if (__glibc_unlikely (new_array_start == NULL
-				  || new_array_end == NULL))
-	      {
-		re_free (new_array_start);
-		re_free (new_array_end);
-		return REG_ESPACE;
-	      }
+  if (start_wc == WEOF || end_wc == WEOF)
+    return REG_ECOLLATE;
+  else if (__glibc_unlikely ((syntax & RE_NO_EMPTY_RANGES)
+                             && start_wc > end_wc))
+    return REG_ERANGE;
 
-	    mbcset->range_starts = new_array_start;
-	    mbcset->range_ends = new_array_end;
-	    *range_alloc = new_nranges;
-	  }
+  /* Got valid collation sequence values, add them as a new entry.
+     However, for !_LIBC we have no collation elements: if the
+     character set is single byte, the single byte character set
+     that we build below suffices.  parse_bracket_exp passes
+     no MBCSET if dfa->mb_cur_max == 1.  */
+  if (dfa->mb_cur_max > 1)
+    {
+      /* Check the space of the arrays.  */
+      if (__glibc_unlikely (*range_alloc == mbcset->nranges))
+        {
+          /* There is not enough space, need realloc.  */
+          wchar_t *new_array_start, *new_array_end;
+          Idx new_nranges;
 
-	mbcset->range_starts[mbcset->nranges] = start_wc;
-	mbcset->range_ends[mbcset->nranges++] = end_wc;
-      }
+          /* +1 in case of mbcset->nranges is 0.  */
+          new_nranges = 2 * mbcset->nranges + 1;
+          /* Use realloc since mbcset->range_starts and mbcset->range_ends
+             are NULL if *range_alloc == 0.  */
+          new_array_start = re_realloc (mbcset->range_starts, wchar_t,
+                                        new_nranges);
+          new_array_end = re_realloc (mbcset->range_ends, wchar_t,
+                                      new_nranges);
+
+          if (__glibc_unlikely (new_array_start == NULL
+                                || new_array_end == NULL))
+            {
+              re_free (new_array_start);
+              re_free (new_array_end);
+              return REG_ESPACE;
+            }
+
+          mbcset->range_starts = new_array_start;
+          mbcset->range_ends = new_array_end;
+          *range_alloc = new_nranges;
+        }
+
+      mbcset->range_starts[mbcset->nranges] = start_wc;
+      mbcset->range_ends[mbcset->nranges++] = end_wc;
+    }
+
+  /* Build the table for single byte characters.  */
+  for (wchar_t wc = 0; wc < SBC_MAX; ++wc)
+    {
+      if (start_wc <= wc && wc <= end_wc)
+        bitset_set (sbcset, wc);
+    }
 
-    /* Build the table for single byte characters.  */
-    for (wc = 0; wc < SBC_MAX; ++wc)
-      {
-	if (start_wc <= wc && wc <= end_wc)
-	  bitset_set (sbcset, wc);
-      }
-  }
-# else /* not RE_ENABLE_I18N */
-  {
-    unsigned int ch;
-    start_ch = ((start_elem->type == SB_CHAR ) ? start_elem->opr.ch
-		: ((start_elem->type == COLL_SYM) ? start_elem->opr.name[0]
-		   : 0));
-    end_ch = ((end_elem->type == SB_CHAR ) ? end_elem->opr.ch
-	      : ((end_elem->type == COLL_SYM) ? end_elem->opr.name[0]
-		 : 0));
-    if (start_ch > end_ch)
-      return REG_ERANGE;
-    /* Build the table for single byte characters.  */
-    for (ch = 0; ch < SBC_MAX; ++ch)
-      if (start_ch <= ch  && ch <= end_ch)
-	bitset_set (sbcset, ch);
-  }
-# endif /* not RE_ENABLE_I18N */
   return REG_NOERROR;
 }
 #endif /* not _LIBC */
 
 #ifndef _LIBC
-/* Helper function for parse_bracket_exp only used in case of NOT _LIBC..
+/* Helper function for parse_bracket_exp only used in case of NOT _LIBC.
    Build the collating element which is represented by NAME.
    The result are written to MBCSET and SBCSET.
    COLL_SYM_ALLOC is the allocated size of mbcset->coll_sym, is a
    pointer argument since we may update it.  */
 
 static reg_errcode_t
-# ifdef RE_ENABLE_I18N
 build_collating_symbol (bitset_t sbcset, re_charset_t *mbcset,
-			Idx *coll_sym_alloc, const unsigned char *name)
-# else /* not RE_ENABLE_I18N */
-build_collating_symbol (bitset_t sbcset, const unsigned char *name)
-# endif /* not RE_ENABLE_I18N */
+			Idx *coll_sym_alloc, const unsigned char *name,
+			uint_fast32_t nrules, int_fast32_t table_size,
+			const void *symb_table, const unsigned char *extra)
 {
   size_t name_len = strlen ((const char *) name);
   if (__glibc_unlikely (name_len != 1))
@@ -2831,271 +2761,280 @@ build_collating_symbol (bitset_t sbcset, const unsigned char *name)
 }
 #endif /* not _LIBC */
 
-/* This function parse bracket expression like "[abc]", "[a-c]",
-   "[[.a-a.]]" etc.  */
-
-static bin_tree_t *
-parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
-		   reg_syntax_t syntax, reg_errcode_t *err)
-{
 #ifdef _LIBC
-  const unsigned char *collseqmb;
-  const char *collseqwc;
-  uint32_t nrules;
-  int32_t table_size;
-  const int32_t *symb_table;
-  const unsigned char *extra;
-
-  /* Local function for parse_bracket_exp used in _LIBC environment.
-     Seek the collating symbol entry corresponding to NAME.
-     Return the index of the symbol in the SYMB_TABLE,
-     or -1 if not found.  */
-
-  auto inline int32_t
-  __attribute__ ((always_inline))
-  seek_collating_symbol_entry (const unsigned char *name, size_t name_len)
-    {
-      int32_t elem;
-
-      for (elem = 0; elem < table_size; elem++)
-	if (symb_table[2 * elem] != 0)
-	  {
-	    int32_t idx = symb_table[2 * elem + 1];
-	    /* Skip the name of collating element name.  */
-	    idx += 1 + extra[idx];
-	    if (/* Compare the length of the name.  */
-		name_len == extra[idx]
-		/* Compare the name.  */
-		&& memcmp (name, &extra[idx + 1], name_len) == 0)
-	      /* Yep, this is the entry.  */
-	      return elem;
-	  }
-      return -1;
-    }
+/* Local function for parse_bracket_exp used in _LIBC environment.
+   Seek the collating symbol entry corresponding to NAME.
+   Return the index of the symbol in the SYMB_TABLE,
+   or -1 if not found.  */
+
+static __always_inline int32_t
+seek_collating_symbol_entry (const unsigned char *name, size_t name_len,
+			     const int32_t *symb_table,
+			     int_fast32_t table_size,
+			     const unsigned char *extra)
+{
+  int_fast32_t elem;
 
-  /* Local function for parse_bracket_exp used in _LIBC environment.
-     Look up the collation sequence value of BR_ELEM.
-     Return the value if succeeded, UINT_MAX otherwise.  */
+  for (elem = 0; elem < table_size; elem++)
+    if (symb_table[2 * elem] != 0)
+      {
+	int32_t idx = symb_table[2 * elem + 1];
+	/* Skip the name of collating element name.  */
+	idx += 1 + extra[idx];
+	if (/* Compare the length of the name.  */
+	    name_len == extra[idx]
+	    /* Compare the name.  */
+	    && memcmp (name, &extra[idx + 1], name_len) == 0)
+	  /* Yep, this is the entry.  */
+	  return elem;
+      }
+  return -1;
+}
 
-  auto inline unsigned int
-  __attribute__ ((always_inline))
-  lookup_collation_sequence_value (bracket_elem_t *br_elem)
+/* Local function for parse_bracket_exp used in _LIBC environment.
+   Look up the collation sequence value of BR_ELEM.
+   Return the value if succeeded, UINT_MAX otherwise.  */
+
+static __always_inline unsigned int
+lookup_collation_sequence_value (bracket_elem_t *br_elem, uint32_t nrules,
+				 const unsigned char *collseqmb,
+				 const char *collseqwc,
+				 int_fast32_t table_size,
+				 const int32_t *symb_table,
+				 const unsigned char *extra)
+{
+  if (br_elem->type == SB_CHAR)
     {
-      if (br_elem->type == SB_CHAR)
-	{
-	  /*
-	  if (MB_CUR_MAX == 1)
-	  */
-	  if (nrules == 0)
-	    return collseqmb[br_elem->opr.ch];
-	  else
-	    {
-	      wint_t wc = __btowc (br_elem->opr.ch);
-	      return __collseq_table_lookup (collseqwc, wc);
-	    }
-	}
-      else if (br_elem->type == MB_CHAR)
+      /* if (MB_CUR_MAX == 1) */
+      if (nrules == 0)
+	return collseqmb[br_elem->opr.ch];
+      else
 	{
-	  if (nrules != 0)
-	    return __collseq_table_lookup (collseqwc, br_elem->opr.wch);
+	  wint_t wc = __btowc (br_elem->opr.ch);
+	  return __collseq_table_lookup (collseqwc, wc);
 	}
-      else if (br_elem->type == COLL_SYM)
+    }
+  else if (br_elem->type == MB_CHAR)
+    {
+      if (nrules != 0)
+	return __collseq_table_lookup (collseqwc, br_elem->opr.wch);
+    }
+  else if (br_elem->type == COLL_SYM)
+    {
+      size_t sym_name_len = strlen ((char *) br_elem->opr.name);
+      if (nrules != 0)
 	{
-	  size_t sym_name_len = strlen ((char *) br_elem->opr.name);
-	  if (nrules != 0)
+	  int32_t elem, idx;
+	  elem = seek_collating_symbol_entry (br_elem->opr.name,
+					      sym_name_len,
+					      symb_table, table_size,
+					      extra);
+	  if (elem != -1)
 	    {
-	      int32_t elem, idx;
-	      elem = seek_collating_symbol_entry (br_elem->opr.name,
-						  sym_name_len);
-	      if (elem != -1)
-		{
-		  /* We found the entry.  */
-		  idx = symb_table[2 * elem + 1];
-		  /* Skip the name of collating element name.  */
-		  idx += 1 + extra[idx];
-		  /* Skip the byte sequence of the collating element.  */
-		  idx += 1 + extra[idx];
-		  /* Adjust for the alignment.  */
-		  idx = (idx + 3) & ~3;
-		  /* Skip the multibyte collation sequence value.  */
-		  idx += sizeof (unsigned int);
-		  /* Skip the wide char sequence of the collating element.  */
-		  idx += sizeof (unsigned int) *
-		    (1 + *(unsigned int *) (extra + idx));
-		  /* Return the collation sequence value.  */
-		  return *(unsigned int *) (extra + idx);
-		}
-	      else if (sym_name_len == 1)
-		{
-		  /* No valid character.  Match it as a single byte
-		     character.  */
-		  return collseqmb[br_elem->opr.name[0]];
-		}
+	      /* We found the entry.  */
+	      idx = symb_table[2 * elem + 1];
+	      /* Skip the name of collating element name.  */
+	      idx += 1 + extra[idx];
+	      /* Skip the byte sequence of the collating element.  */
+	      idx += 1 + extra[idx];
+	      /* Adjust for the alignment.  */
+	      idx = (idx + 3) & ~3;
+	      /* Skip the multibyte collation sequence value.  */
+	      idx += sizeof (unsigned int);
+	      /* Skip the wide char sequence of the collating element.  */
+	      idx += sizeof (unsigned int) *
+		(1 + *(unsigned int *) (extra + idx));
+	      /* Return the collation sequence value.  */
+	      return *(unsigned int *) (extra + idx);
 	    }
 	  else if (sym_name_len == 1)
-	    return collseqmb[br_elem->opr.name[0]];
+	    {
+	      /* No valid character.  Match it as a single byte
+		 character.  */
+	      return collseqmb[br_elem->opr.name[0]];
+	    }
 	}
-      return UINT_MAX;
+      else if (sym_name_len == 1)
+	return collseqmb[br_elem->opr.name[0]];
     }
+  return UINT_MAX;
+}
 
-  /* Local function for parse_bracket_exp used in _LIBC environment.
-     Build the range expression which starts from START_ELEM, and ends
-     at END_ELEM.  The result are written to MBCSET and SBCSET.
-     RANGE_ALLOC is the allocated size of mbcset->range_starts, and
-     mbcset->range_ends, is a pointer argument since we may
-     update it.  */
+/* Local function for parse_bracket_exp used in _LIBC environment.
+   Build the range expression which starts from START_ELEM, and ends
+   at END_ELEM.  The result are written to MBCSET and SBCSET.
+   RANGE_ALLOC is the allocated size of mbcset->range_starts, and
+   mbcset->range_ends, is a pointer argument since we may
+   update it.  */
+
+static __always_inline reg_errcode_t
+build_range_exp (bitset_t sbcset, re_charset_t *mbcset, Idx *range_alloc,
+		 bracket_elem_t *start_elem, bracket_elem_t *end_elem,
+		 re_dfa_t *dfa, reg_syntax_t syntax, uint32_t nrules,
+		 const unsigned char *collseqmb, const char *collseqwc,
+		 int_fast32_t table_size, const int32_t *symb_table,
+		 const unsigned char *extra)
+{
+  unsigned int ch;
+  uint32_t start_collseq;
+  uint32_t end_collseq;
 
-  auto inline reg_errcode_t
-  __attribute__ ((always_inline))
-  build_range_exp (bitset_t sbcset, re_charset_t *mbcset, int *range_alloc,
-		   bracket_elem_t *start_elem, bracket_elem_t *end_elem)
-    {
-      unsigned int ch;
-      uint32_t start_collseq;
-      uint32_t end_collseq;
-
-      /* Equivalence Classes and Character Classes can't be a range
-	 start/end.  */
-      if (__glibc_unlikely (start_elem->type == EQUIV_CLASS
-			    || start_elem->type == CHAR_CLASS
-			    || end_elem->type == EQUIV_CLASS
-			    || end_elem->type == CHAR_CLASS))
-	return REG_ERANGE;
+  /* Equivalence Classes and Character Classes can't be a range
+     start/end.  */
+  if (__glibc_unlikely (start_elem->type == EQUIV_CLASS
+                        || start_elem->type == CHAR_CLASS
+                        || end_elem->type == EQUIV_CLASS
+                        || end_elem->type == CHAR_CLASS))
+    return REG_ERANGE;
 
-      /* FIXME: Implement rational ranges here, too.  */
-      start_collseq = lookup_collation_sequence_value (start_elem);
-      end_collseq = lookup_collation_sequence_value (end_elem);
-      /* Check start/end collation sequence values.  */
-      if (__glibc_unlikely (start_collseq == UINT_MAX
-			    || end_collseq == UINT_MAX))
-	return REG_ECOLLATE;
-      if (__glibc_unlikely ((syntax & RE_NO_EMPTY_RANGES)
-			    && start_collseq > end_collseq))
-	return REG_ERANGE;
+  /* FIXME: Implement rational ranges here, too.  */
+  start_collseq = lookup_collation_sequence_value (start_elem, nrules, collseqmb, collseqwc,
+						   table_size, symb_table, extra);
+  end_collseq = lookup_collation_sequence_value (end_elem, nrules, collseqmb, collseqwc,
+						 table_size, symb_table, extra);
+  /* Check start/end collation sequence values.  */
+  if (__glibc_unlikely (start_collseq == UINT_MAX
+                        || end_collseq == UINT_MAX))
+    return REG_ECOLLATE;
+  if (__glibc_unlikely ((syntax & RE_NO_EMPTY_RANGES)
+                        && start_collseq > end_collseq))
+    return REG_ERANGE;
 
-      /* Got valid collation sequence values, add them as a new entry.
-	 However, if we have no collation elements, and the character set
-	 is single byte, the single byte character set that we
-	 build below suffices. */
-      if (nrules > 0 || dfa->mb_cur_max > 1)
+  /* Got valid collation sequence values, add them as a new entry.
+     However, if we have no collation elements, and the character set
+     is single byte, the single byte character set that we
+     build below suffices. */
+  if (nrules > 0 || dfa->mb_cur_max > 1)
+    {
+      /* Check the space of the arrays.  */
+      if (__glibc_unlikely (*range_alloc == mbcset->nranges))
 	{
-	  /* Check the space of the arrays.  */
-	  if (__glibc_unlikely (*range_alloc == mbcset->nranges))
-	    {
-	      /* There is not enough space, need realloc.  */
-	      uint32_t *new_array_start;
-	      uint32_t *new_array_end;
-	      Idx new_nranges;
-
-	      /* +1 in case of mbcset->nranges is 0.  */
-	      new_nranges = 2 * mbcset->nranges + 1;
-	      new_array_start = re_realloc (mbcset->range_starts, uint32_t,
-					    new_nranges);
-	      new_array_end = re_realloc (mbcset->range_ends, uint32_t,
-					  new_nranges);
-
-	      if (__glibc_unlikely (new_array_start == NULL
-				    || new_array_end == NULL))
-		return REG_ESPACE;
+	  /* There is not enough space, need realloc.  */
+	  uint32_t *new_array_start;
+	  uint32_t *new_array_end;
+	  int new_nranges;
 
-	      mbcset->range_starts = new_array_start;
-	      mbcset->range_ends = new_array_end;
-	      *range_alloc = new_nranges;
-	    }
+	  /* +1 in case of mbcset->nranges is 0.  */
+	  new_nranges = 2 * mbcset->nranges + 1;
+	  new_array_start = re_realloc (mbcset->range_starts, uint32_t,
+					new_nranges);
+	  new_array_end = re_realloc (mbcset->range_ends, uint32_t,
+				      new_nranges);
 
-	  mbcset->range_starts[mbcset->nranges] = start_collseq;
-	  mbcset->range_ends[mbcset->nranges++] = end_collseq;
-	}
+          if (__glibc_unlikely (new_array_start == NULL
+                                || new_array_end == NULL))
+	    return REG_ESPACE;
 
-      /* Build the table for single byte characters.  */
-      for (ch = 0; ch < SBC_MAX; ch++)
-	{
-	  uint32_t ch_collseq;
-	  /*
-	  if (MB_CUR_MAX == 1)
-	  */
-	  if (nrules == 0)
-	    ch_collseq = collseqmb[ch];
-	  else
-	    ch_collseq = __collseq_table_lookup (collseqwc, __btowc (ch));
-	  if (start_collseq <= ch_collseq && ch_collseq <= end_collseq)
-	    bitset_set (sbcset, ch);
+	  mbcset->range_starts = new_array_start;
+	  mbcset->range_ends = new_array_end;
+	  *range_alloc = new_nranges;
 	}
-      return REG_NOERROR;
+
+      mbcset->range_starts[mbcset->nranges] = start_collseq;
+      mbcset->range_ends[mbcset->nranges++] = end_collseq;
     }
 
-  /* Local function for parse_bracket_exp used in _LIBC environment.
-     Build the collating element which is represented by NAME.
-     The result are written to MBCSET and SBCSET.
-     COLL_SYM_ALLOC is the allocated size of mbcset->coll_sym, is a
-     pointer argument since we may update it.  */
+  /* Build the table for single byte characters.  */
+  for (ch = 0; ch < SBC_MAX; ch++)
+    {
+      uint32_t ch_collseq;
+      /* if (MB_CUR_MAX == 1) */
+      if (nrules == 0)
+	ch_collseq = collseqmb[ch];
+      else
+	ch_collseq = __collseq_table_lookup (collseqwc, __btowc (ch));
+      if (start_collseq <= ch_collseq && ch_collseq <= end_collseq)
+	bitset_set (sbcset, ch);
+    }
+  return REG_NOERROR;
+}
 
-  auto inline reg_errcode_t
-  __attribute__ ((always_inline))
-  build_collating_symbol (bitset_t sbcset, re_charset_t *mbcset,
-			  Idx *coll_sym_alloc, const unsigned char *name)
+/* Local function for parse_bracket_exp used in _LIBC environment.
+   Build the collating element which is represented by NAME.
+   The result are written to MBCSET and SBCSET.
+   COLL_SYM_ALLOC is the allocated size of mbcset->coll_sym, is a
+   pointer argument since we may update it.  */
+
+static __always_inline reg_errcode_t
+build_collating_symbol (bitset_t sbcset, re_charset_t *mbcset,
+			Idx *coll_sym_alloc, const unsigned char *name,
+			uint_fast32_t nrules, int_fast32_t table_size,
+			const int32_t *symb_table, const unsigned char *extra)
+{
+  int32_t elem, idx;
+  size_t name_len = strlen ((const char *) name);
+  if (nrules != 0)
     {
-      int32_t elem, idx;
-      size_t name_len = strlen ((const char *) name);
-      if (nrules != 0)
+      elem = seek_collating_symbol_entry (name, name_len, symb_table,
+					  table_size, extra);
+      if (elem != -1)
 	{
-	  elem = seek_collating_symbol_entry (name, name_len);
-	  if (elem != -1)
-	    {
-	      /* We found the entry.  */
-	      idx = symb_table[2 * elem + 1];
-	      /* Skip the name of collating element name.  */
-	      idx += 1 + extra[idx];
-	    }
-	  else if (name_len == 1)
-	    {
-	      /* No valid character, treat it as a normal
-		 character.  */
-	      bitset_set (sbcset, name[0]);
-	      return REG_NOERROR;
-	    }
-	  else
-	    return REG_ECOLLATE;
-
-	  /* Got valid collation sequence, add it as a new entry.  */
-	  /* Check the space of the arrays.  */
-	  if (__glibc_unlikely (*coll_sym_alloc == mbcset->ncoll_syms))
-	    {
-	      /* Not enough, realloc it.  */
-	      /* +1 in case of mbcset->ncoll_syms is 0.  */
-	      Idx new_coll_sym_alloc = 2 * mbcset->ncoll_syms + 1;
-	      /* Use realloc since mbcset->coll_syms is NULL
-		 if *alloc == 0.  */
-	      int32_t *new_coll_syms = re_realloc (mbcset->coll_syms, int32_t,
-						   new_coll_sym_alloc);
-	      if (__glibc_unlikely (new_coll_syms == NULL))
-		return REG_ESPACE;
-	      mbcset->coll_syms = new_coll_syms;
-	      *coll_sym_alloc = new_coll_sym_alloc;
-	    }
-	  mbcset->coll_syms[mbcset->ncoll_syms++] = idx;
+	  /* We found the entry.  */
+	  idx = symb_table[2 * elem + 1];
+	  /* Skip the name of collating element name.  */
+	  idx += 1 + extra[idx];
+	}
+      else if (name_len == 1)
+	{
+	  /* No valid character, treat it as a normal
+	     character.  */
+	  bitset_set (sbcset, name[0]);
 	  return REG_NOERROR;
 	}
       else
+	return REG_ECOLLATE;
+
+      /* Got valid collation sequence, add it as a new entry.  */
+      /* Check the space of the arrays.  */
+      if (__glibc_unlikely (*coll_sym_alloc == mbcset->ncoll_syms))
 	{
-	  if (__glibc_unlikely (name_len != 1))
-	    return REG_ECOLLATE;
-	  else
-	    {
-	      bitset_set (sbcset, name[0]);
-	      return REG_NOERROR;
-	    }
+	  /* Not enough, realloc it.  */
+	  /* +1 in case of mbcset->ncoll_syms is 0.  */
+	  int new_coll_sym_alloc = 2 * mbcset->ncoll_syms + 1;
+	  /* Use realloc since mbcset->coll_syms is NULL
+	     if *alloc == 0.  */
+	  int32_t *new_coll_syms = re_realloc (mbcset->coll_syms, int32_t,
+					       new_coll_sym_alloc);
+          if (__glibc_unlikely (new_coll_syms == NULL))
+	    return REG_ESPACE;
+	  mbcset->coll_syms = new_coll_syms;
+	  *coll_sym_alloc = new_coll_sym_alloc;
 	}
+      mbcset->coll_syms[mbcset->ncoll_syms++] = idx;
+      return REG_NOERROR;
     }
-#endif
+  else
+    {
+      if (__glibc_unlikely (name_len != 1))
+	return REG_ECOLLATE;
+      else
+	{
+	  bitset_set (sbcset, name[0]);
+	  return REG_NOERROR;
+	}
+    }
+}
+#endif /* _LIBC */
+
+/* This function parse bracket expression like "[abc]", "[a-c]",
+   "[[.a-a.]]" etc.  */
+
+static bin_tree_t *
+parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
+		   reg_syntax_t syntax, reg_errcode_t *err)
+{
+  const unsigned char *collseqmb = NULL;
+  const char *collseqwc = NULL;
+  uint_fast32_t nrules = 0;
+  int_fast32_t table_size = 0;
+  const void *symb_table = NULL;
+  const unsigned char *extra = NULL;
 
   re_token_t br_token;
   re_bitset_ptr_t sbcset;
-#ifdef RE_ENABLE_I18N
   re_charset_t *mbcset;
   Idx coll_sym_alloc = 0, range_alloc = 0, mbchar_alloc = 0;
   Idx equiv_class_alloc = 0, char_class_alloc = 0;
-#endif /* not RE_ENABLE_I18N */
   bool non_match = false;
   bin_tree_t *work_tree;
   int token_len;
@@ -3111,26 +3050,17 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
       */
       collseqwc = _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQWC);
       table_size = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_SYMB_HASH_SIZEMB);
-      symb_table = (const int32_t *) _NL_CURRENT (LC_COLLATE,
-						  _NL_COLLATE_SYMB_TABLEMB);
+      symb_table = _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_TABLEMB);
       extra = (const unsigned char *) _NL_CURRENT (LC_COLLATE,
 						   _NL_COLLATE_SYMB_EXTRAMB);
     }
 #endif
   sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1);
-#ifdef RE_ENABLE_I18N
   mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1);
-#endif /* RE_ENABLE_I18N */
-#ifdef RE_ENABLE_I18N
   if (__glibc_unlikely (sbcset == NULL || mbcset == NULL))
-#else
-  if (__glibc_unlikely (sbcset == NULL))
-#endif /* RE_ENABLE_I18N */
     {
       re_free (sbcset);
-#ifdef RE_ENABLE_I18N
       re_free (mbcset);
-#endif
       *err = REG_ESPACE;
       return NULL;
     }
@@ -3143,9 +3073,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
     }
   if (token->type == OP_NON_MATCH_LIST)
     {
-#ifdef RE_ENABLE_I18N
       mbcset->non_match = 1;
-#endif /* not RE_ENABLE_I18N */
       non_match = true;
       if (syntax & RE_HAT_LISTS_NOT_NEWLINE)
 	bitset_set (sbcset, '\n');
@@ -3228,18 +3156,10 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
 
 	  token_len = peek_token_bracket (token, regexp, syntax);
 
-#ifdef _LIBC
 	  *err = build_range_exp (sbcset, mbcset, &range_alloc,
-				  &start_elem, &end_elem);
-#else
-# ifdef RE_ENABLE_I18N
-	  *err = build_range_exp (syntax, sbcset,
-				  dfa->mb_cur_max > 1 ? mbcset : NULL,
-				  &range_alloc, &start_elem, &end_elem);
-# else
-	  *err = build_range_exp (syntax, sbcset, &start_elem, &end_elem);
-# endif
-#endif /* RE_ENABLE_I18N */
+				  &start_elem, &end_elem,
+				  dfa, syntax, nrules, collseqmb, collseqwc,
+				  table_size, symb_table, extra);
 	  if (__glibc_unlikely (*err != REG_NOERROR))
 	    goto parse_bracket_exp_free_return;
 	}
@@ -3250,7 +3170,6 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
 	    case SB_CHAR:
 	      bitset_set (sbcset, start_elem.opr.ch);
 	      break;
-#ifdef RE_ENABLE_I18N
 	    case MB_CHAR:
 	      /* Check whether the array has enough space.  */
 	      if (__glibc_unlikely (mbchar_alloc == mbcset->nmbchars))
@@ -3268,30 +3187,24 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
 		}
 	      mbcset->mbchars[mbcset->nmbchars++] = start_elem.opr.wch;
 	      break;
-#endif /* RE_ENABLE_I18N */
 	    case EQUIV_CLASS:
 	      *err = build_equiv_class (sbcset,
-#ifdef RE_ENABLE_I18N
 					mbcset, &equiv_class_alloc,
-#endif /* RE_ENABLE_I18N */
 					start_elem.opr.name);
 	      if (__glibc_unlikely (*err != REG_NOERROR))
 		goto parse_bracket_exp_free_return;
 	      break;
 	    case COLL_SYM:
 	      *err = build_collating_symbol (sbcset,
-#ifdef RE_ENABLE_I18N
 					     mbcset, &coll_sym_alloc,
-#endif /* RE_ENABLE_I18N */
-					     start_elem.opr.name);
+					     start_elem.opr.name,
+					     nrules, table_size, symb_table, extra);
 	      if (__glibc_unlikely (*err != REG_NOERROR))
 		goto parse_bracket_exp_free_return;
 	      break;
 	    case CHAR_CLASS:
 	      *err = build_charclass (regexp->trans, sbcset,
-#ifdef RE_ENABLE_I18N
 				      mbcset, &char_class_alloc,
-#endif /* RE_ENABLE_I18N */
 				      (const char *) start_elem.opr.name,
 				      syntax);
 	      if (__glibc_unlikely (*err != REG_NOERROR))
@@ -3317,7 +3230,6 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
   if (non_match)
     bitset_not (sbcset);
 
-#ifdef RE_ENABLE_I18N
   /* Ensure only single byte characters are set.  */
   if (dfa->mb_cur_max > 1)
     bitset_mask (sbcset, dfa->sb_char);
@@ -3361,11 +3273,8 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
 	}
     }
   else
-#endif /* not RE_ENABLE_I18N */
     {
-#ifdef RE_ENABLE_I18N
       free_charset (mbcset);
-#endif
       /* Build a tree for simple bracket.  */
       br_token.type = SIMPLE_BRACKET;
       br_token.opr.sbcset = sbcset;
@@ -3379,9 +3288,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
   *err = REG_ESPACE;
  parse_bracket_exp_free_return:
   re_free (sbcset);
-#ifdef RE_ENABLE_I18N
   free_charset (mbcset);
-#endif /* RE_ENABLE_I18N */
   return NULL;
 }
 
@@ -3392,7 +3299,6 @@ parse_bracket_element (bracket_elem_t *elem, re_string_t *regexp,
 		       re_token_t *token, int token_len, re_dfa_t *dfa,
 		       reg_syntax_t syntax, bool accept_hyphen)
 {
-#ifdef RE_ENABLE_I18N
   int cur_char_size;
   cur_char_size = re_string_char_size_at (regexp, re_string_cur_idx (regexp));
   if (cur_char_size > 1)
@@ -3402,7 +3308,6 @@ parse_bracket_element (bracket_elem_t *elem, re_string_t *regexp,
       re_string_skip_bytes (regexp, cur_char_size);
       return REG_NOERROR;
     }
-#endif /* RE_ENABLE_I18N */
   re_string_skip_bytes (regexp, token_len); /* Skip a token.  */
   if (token->type == OP_OPEN_COLL_ELEM || token->type == OP_OPEN_CHAR_CLASS
       || token->type == OP_OPEN_EQUIV_CLASS)
@@ -3475,12 +3380,8 @@ parse_bracket_symbol (bracket_elem_t *elem, re_string_t *regexp,
      is a pointer argument since we may update it.  */
 
 static reg_errcode_t
-#ifdef RE_ENABLE_I18N
 build_equiv_class (bitset_t sbcset, re_charset_t *mbcset,
 		   Idx *equiv_class_alloc, const unsigned char *name)
-#else /* not RE_ENABLE_I18N */
-build_equiv_class (bitset_t sbcset, const unsigned char *name)
-#endif /* not RE_ENABLE_I18N */
 {
 #ifdef _LIBC
   uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
@@ -3560,14 +3461,9 @@ build_equiv_class (bitset_t sbcset, const unsigned char *name)
      is a pointer argument since we may update it.  */
 
 static reg_errcode_t
-#ifdef RE_ENABLE_I18N
 build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset,
 		 re_charset_t *mbcset, Idx *char_class_alloc,
 		 const char *class_name, reg_syntax_t syntax)
-#else /* not RE_ENABLE_I18N */
-build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset,
-		 const char *class_name, reg_syntax_t syntax)
-#endif /* not RE_ENABLE_I18N */
 {
   int i;
   const char *name = class_name;
@@ -3578,7 +3474,6 @@ build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset,
       && (strcmp (name, "upper") == 0 || strcmp (name, "lower") == 0))
     name = "alpha";
 
-#ifdef RE_ENABLE_I18N
   /* Check the space of the arrays.  */
   if (__glibc_unlikely (*char_class_alloc == mbcset->nchar_classes))
     {
@@ -3594,7 +3489,6 @@ build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset,
       *char_class_alloc = new_char_class_alloc;
     }
   mbcset->char_classes[mbcset->nchar_classes++] = __wctype (name);
-#endif /* RE_ENABLE_I18N */
 
 #define BUILD_CHARCLASS_LOOP(ctype_func)	\
   do {						\
@@ -3649,10 +3543,8 @@ build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans,
 		    reg_errcode_t *err)
 {
   re_bitset_ptr_t sbcset;
-#ifdef RE_ENABLE_I18N
   re_charset_t *mbcset;
   Idx alloc = 0;
-#endif /* not RE_ENABLE_I18N */
   reg_errcode_t ret;
   bin_tree_t *tree;
 
@@ -3662,7 +3554,6 @@ build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans,
       *err = REG_ESPACE;
       return NULL;
     }
-#ifdef RE_ENABLE_I18N
   mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1);
   if (__glibc_unlikely (mbcset == NULL))
     {
@@ -3671,21 +3562,14 @@ build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans,
       return NULL;
     }
   mbcset->non_match = non_match;
-#endif /* RE_ENABLE_I18N */
 
   /* We don't care the syntax in this case.  */
-  ret = build_charclass (trans, sbcset,
-#ifdef RE_ENABLE_I18N
-			 mbcset, &alloc,
-#endif /* RE_ENABLE_I18N */
-			 class_name, 0);
+  ret = build_charclass (trans, sbcset, mbcset, &alloc, class_name, 0);
 
   if (__glibc_unlikely (ret != REG_NOERROR))
     {
       re_free (sbcset);
-#ifdef RE_ENABLE_I18N
       free_charset (mbcset);
-#endif /* RE_ENABLE_I18N */
       *err = ret;
       return NULL;
     }
@@ -3697,11 +3581,9 @@ build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans,
   if (non_match)
     bitset_not (sbcset);
 
-#ifdef RE_ENABLE_I18N
   /* Ensure only single byte characters are set.  */
   if (dfa->mb_cur_max > 1)
     bitset_mask (sbcset, dfa->sb_char);
-#endif
 
   /* Build a tree for simple bracket.  */
   re_token_t br_token = { .type = SIMPLE_BRACKET, .opr.sbcset = sbcset };
@@ -3709,7 +3591,6 @@ build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans,
   if (__glibc_unlikely (tree == NULL))
     goto build_word_op_espace;
 
-#ifdef RE_ENABLE_I18N
   if (dfa->mb_cur_max > 1)
     {
       bin_tree_t *mbc_tree;
@@ -3730,15 +3611,10 @@ build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans,
       free_charset (mbcset);
       return tree;
     }
-#else /* not RE_ENABLE_I18N */
-  return tree;
-#endif /* not RE_ENABLE_I18N */
 
  build_word_op_espace:
   re_free (sbcset);
-#ifdef RE_ENABLE_I18N
   free_charset (mbcset);
-#endif /* RE_ENABLE_I18N */
   *err = REG_ESPACE;
   return NULL;
 }
@@ -3771,21 +3647,19 @@ fetch_number (re_string_t *input, re_token_t *token, reg_syntax_t syntax)
   return num;
 }
 \f
-#ifdef RE_ENABLE_I18N
 static void
 free_charset (re_charset_t *cset)
 {
   re_free (cset->mbchars);
-# ifdef _LIBC
+#ifdef _LIBC
   re_free (cset->coll_syms);
   re_free (cset->equiv_classes);
-# endif
+#endif
   re_free (cset->range_starts);
   re_free (cset->range_ends);
   re_free (cset->char_classes);
   re_free (cset);
 }
-#endif /* RE_ENABLE_I18N */
 \f
 /* Functions for binary tree operation.  */
 
@@ -3851,13 +3725,10 @@ mark_opt_subexp (void *extra, bin_tree_t *node)
 static void
 free_token (re_token_t *node)
 {
-#ifdef RE_ENABLE_I18N
   if (node->type == COMPLEX_BRACKET && node->duplicated == 0)
     free_charset (node->opr.mbcset);
-  else
-#endif /* RE_ENABLE_I18N */
-    if (node->type == SIMPLE_BRACKET && node->duplicated == 0)
-      re_free (node->opr.sbcset);
+  else if (node->type == SIMPLE_BRACKET && node->duplicated == 0)
+    re_free (node->opr.sbcset);
 }
 
 /* Worker function for tree walking.  Free the allocated memory inside NODE
diff --git a/lib/regex.c b/lib/regex.c
index 7296be0f0..ff1176782 100644
--- a/lib/regex.c
+++ b/lib/regex.c
@@ -1,5 +1,5 @@
 /* Extended regular expression matching and search library.
-   Copyright (C) 2002-2021 Free Software Foundation, Inc.
+   Copyright (C) 2002-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
 
@@ -24,6 +24,7 @@
 
 # if __GNUC_PREREQ (4, 6)
 #  pragma GCC diagnostic ignored "-Wsuggest-attribute=pure"
+#  pragma GCC diagnostic ignored "-Wvla"
 # endif
 # if __GNUC_PREREQ (4, 3)
 #  pragma GCC diagnostic ignored "-Wold-style-definition"
diff --git a/lib/regex.h b/lib/regex.h
index 8e4ef4557..a7e0bd027 100644
--- a/lib/regex.h
+++ b/lib/regex.h
@@ -1,6 +1,6 @@
 /* Definitions for data structures and routines for the regular
    expression library.
-   Copyright (C) 1985, 1989-2021 Free Software Foundation, Inc.
+   Copyright (C) 1985, 1989-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -522,6 +522,30 @@ typedef struct
 \f
 /* Declarations for routines.  */
 
+#ifndef _REGEX_NELTS
+# if (defined __STDC_VERSION__ && 199901L <= __STDC_VERSION__ \
+	&& !defined __STDC_NO_VLA__)
+#  define _REGEX_NELTS(n) n
+# else
+#  define _REGEX_NELTS(n)
+# endif
+#endif
+
+#if defined __GNUC__ && 4 < __GNUC__ + (6 <= __GNUC_MINOR__)
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wvla"
+#endif
+
+#ifndef _Attr_access_
+# ifdef __attr_access
+#  define _Attr_access_(arg) __attr_access (arg)
+# elif defined __GNUC__ && 10 <= __GNUC__
+#  define _Attr_access_(x) __attribute__ ((__access__ x))
+# else
+#  define _Attr_access_(x)
+# endif
+#endif
+
 #ifdef __USE_GNU
 /* Sets the current default syntax to SYNTAX, and return the old syntax.
    You can also simply assign to the 're_syntax_options' variable.  */
@@ -536,7 +560,8 @@ extern reg_syntax_t re_set_syntax (reg_syntax_t __syntax);
    'regcomp', with a malloc'ed value, or set to NULL before calling
    'regfree'.  */
 extern const char *re_compile_pattern (const char *__pattern, size_t __length,
-				       struct re_pattern_buffer *__buffer);
+				       struct re_pattern_buffer *__buffer)
+    _Attr_access_ ((__read_only__, 1, 2));
 
 
 /* Compile a fastmap for the compiled pattern in BUFFER; used to
@@ -553,7 +578,8 @@ extern int re_compile_fastmap (struct re_pattern_buffer *__buffer);
 extern regoff_t re_search (struct re_pattern_buffer *__buffer,
 			   const char *__String, regoff_t __length,
 			   regoff_t __start, regoff_t __range,
-			   struct re_registers *__regs);
+			   struct re_registers *__regs)
+    _Attr_access_ ((__read_only__, 2, 3));
 
 
 /* Like 're_search', but search in the concatenation of STRING1 and
@@ -563,14 +589,17 @@ extern regoff_t re_search_2 (struct re_pattern_buffer *__buffer,
 			     const char *__string2, regoff_t __length2,
 			     regoff_t __start, regoff_t __range,
 			     struct re_registers *__regs,
-			     regoff_t __stop);
+			     regoff_t __stop)
+    _Attr_access_ ((__read_only__, 2, 3))
+    _Attr_access_ ((__read_only__, 4, 5));
 
 
 /* Like 're_search', but return how many characters in STRING the regexp
    in BUFFER matched, starting at position START.  */
 extern regoff_t re_match (struct re_pattern_buffer *__buffer,
 			  const char *__String, regoff_t __length,
-			  regoff_t __start, struct re_registers *__regs);
+			  regoff_t __start, struct re_registers *__regs)
+    _Attr_access_ ((__read_only__, 2, 3));
 
 
 /* Relates to 're_match' as 're_search_2' relates to 're_search'.  */
@@ -578,7 +607,9 @@ extern regoff_t re_match_2 (struct re_pattern_buffer *__buffer,
 			    const char *__string1, regoff_t __length1,
 			    const char *__string2, regoff_t __length2,
 			    regoff_t __start, struct re_registers *__regs,
-			    regoff_t __stop);
+			    regoff_t __stop)
+    _Attr_access_ ((__read_only__, 2, 3))
+    _Attr_access_ ((__read_only__, 4, 5));
 
 
 /* Set REGS to hold NUM_REGS registers, storing them in STARTS and
@@ -647,14 +678,19 @@ extern int regcomp (regex_t *_Restrict_ __preg,
 
 extern int regexec (const regex_t *_Restrict_ __preg,
 		    const char *_Restrict_ __String, size_t __nmatch,
-		    regmatch_t __pmatch[_Restrict_arr_],
+		    regmatch_t __pmatch[_Restrict_arr_
+					_REGEX_NELTS (__nmatch)],
 		    int __eflags);
 
 extern size_t regerror (int __errcode, const regex_t *_Restrict_ __preg,
-			char *_Restrict_ __errbuf, size_t __errbuf_size);
+			char *_Restrict_ __errbuf, size_t __errbuf_size)
+    _Attr_access_ ((__write_only__, 3, 4));
 
 extern void regfree (regex_t *__preg);
 
+#if defined __GNUC__ && 4 < __GNUC__ + (6 <= __GNUC_MINOR__)
+# pragma GCC diagnostic pop
+#endif
 
 #ifdef __cplusplus
 }
diff --git a/lib/regex_internal.c b/lib/regex_internal.c
index aefcfa2f5..0e6919f34 100644
--- a/lib/regex_internal.c
+++ b/lib/regex_internal.c
@@ -1,5 +1,5 @@
 /* Extended regular expression matching and search library.
-   Copyright (C) 2002-2021 Free Software Foundation, Inc.
+   Copyright (C) 2002-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
 
@@ -30,10 +30,8 @@ static re_dfastate_t *create_cd_newstate (const re_dfa_t *dfa,
 					  re_hashval_t hash);
 static reg_errcode_t re_string_realloc_buffers (re_string_t *pstr,
 						Idx new_buf_len);
-#ifdef RE_ENABLE_I18N
 static void build_wcs_buffer (re_string_t *pstr);
 static reg_errcode_t build_wcs_upper_buffer (re_string_t *pstr);
-#endif /* RE_ENABLE_I18N */
 static void build_upper_buffer (re_string_t *pstr);
 static void re_string_translate_buffer (re_string_t *pstr);
 static unsigned int re_string_context_at (const re_string_t *input, Idx idx,
@@ -91,7 +89,6 @@ re_string_construct (re_string_t *pstr, const char *str, Idx len,
 
   if (icase)
     {
-#ifdef RE_ENABLE_I18N
       if (dfa->mb_cur_max > 1)
 	{
 	  while (1)
@@ -109,16 +106,13 @@ re_string_construct (re_string_t *pstr, const char *str, Idx len,
 	    }
 	}
       else
-#endif /* RE_ENABLE_I18N  */
 	build_upper_buffer (pstr);
     }
   else
     {
-#ifdef RE_ENABLE_I18N
       if (dfa->mb_cur_max > 1)
 	build_wcs_buffer (pstr);
       else
-#endif /* RE_ENABLE_I18N  */
 	{
 	  if (trans != NULL)
 	    re_string_translate_buffer (pstr);
@@ -139,7 +133,6 @@ static reg_errcode_t
 __attribute_warn_unused_result__
 re_string_realloc_buffers (re_string_t *pstr, Idx new_buf_len)
 {
-#ifdef RE_ENABLE_I18N
   if (pstr->mb_cur_max > 1)
     {
       wint_t *new_wcs;
@@ -162,7 +155,6 @@ re_string_realloc_buffers (re_string_t *pstr, Idx new_buf_len)
 	  pstr->offsets = new_offsets;
 	}
     }
-#endif /* RE_ENABLE_I18N  */
   if (pstr->mbs_allocated)
     {
       unsigned char *new_mbs = re_realloc (pstr->mbs, unsigned char,
@@ -194,7 +186,6 @@ re_string_construct_common (const char *str, Idx len, re_string_t *pstr,
   pstr->raw_stop = pstr->stop;
 }
 
-#ifdef RE_ENABLE_I18N
 
 /* Build wide character buffer PSTR->WCS.
    If the byte sequence of the string are:
@@ -530,7 +521,6 @@ re_string_skip_chars (re_string_t *pstr, Idx new_raw_idx, wint_t *last_wc)
   *last_wc = wc;
   return rawbuf_idx;
 }
-#endif /* RE_ENABLE_I18N  */
 
 /* Build the buffer PSTR->MBS, and apply the translation if we need.
    This function is used in case of REG_ICASE.  */
@@ -585,10 +575,8 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
   else
     {
       /* Reset buffer.  */
-#ifdef RE_ENABLE_I18N
       if (pstr->mb_cur_max > 1)
 	memset (&pstr->cur_state, '\0', sizeof (mbstate_t));
-#endif /* RE_ENABLE_I18N */
       pstr->len = pstr->raw_len;
       pstr->stop = pstr->raw_stop;
       pstr->valid_len = 0;
@@ -608,7 +596,6 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
       if (__glibc_likely (offset < pstr->valid_raw_len))
 	{
 	  /* Yes, move them to the front of the buffer.  */
-#ifdef RE_ENABLE_I18N
 	  if (__glibc_unlikely (pstr->offsets_needed))
 	    {
 	      Idx low = 0, high = pstr->valid_len, mid;
@@ -672,15 +659,12 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
 		}
 	    }
 	  else
-#endif
 	    {
 	      pstr->tip_context = re_string_context_at (pstr, offset - 1,
 							eflags);
-#ifdef RE_ENABLE_I18N
 	      if (pstr->mb_cur_max > 1)
 		memmove (pstr->wcs, pstr->wcs + offset,
 			 (pstr->valid_len - offset) * sizeof (wint_t));
-#endif /* RE_ENABLE_I18N */
 	      if (__glibc_unlikely (pstr->mbs_allocated))
 		memmove (pstr->mbs, pstr->mbs + offset,
 			 pstr->valid_len - offset);
@@ -691,7 +675,6 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
 	}
       else
 	{
-#ifdef RE_ENABLE_I18N
 	  /* No, skip all characters until IDX.  */
 	  Idx prev_valid_len = pstr->valid_len;
 
@@ -701,9 +684,7 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
 	      pstr->stop = pstr->raw_stop - idx + offset;
 	      pstr->offsets_needed = 0;
 	    }
-#endif
 	  pstr->valid_len = 0;
-#ifdef RE_ENABLE_I18N
 	  if (pstr->mb_cur_max > 1)
 	    {
 	      Idx wcs_idx;
@@ -787,7 +768,6 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
 	      pstr->valid_raw_len = pstr->valid_len;
 	    }
 	  else
-#endif /* RE_ENABLE_I18N */
 	    {
 	      int c = pstr->raw_mbs[pstr->raw_mbs_idx + offset - 1];
 	      pstr->valid_raw_len = 0;
@@ -807,7 +787,6 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
   pstr->stop -= offset;
 
   /* Then build the buffers.  */
-#ifdef RE_ENABLE_I18N
   if (pstr->mb_cur_max > 1)
     {
       if (pstr->icase)
@@ -820,7 +799,6 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
 	build_wcs_buffer (pstr);
     }
   else
-#endif /* RE_ENABLE_I18N */
     if (__glibc_unlikely (pstr->mbs_allocated))
       {
 	if (pstr->icase)
@@ -846,28 +824,22 @@ re_string_peek_byte_case (const re_string_t *pstr, Idx idx)
   if (__glibc_likely (!pstr->mbs_allocated))
     return re_string_peek_byte (pstr, idx);
 
-#ifdef RE_ENABLE_I18N
   if (pstr->mb_cur_max > 1
       && ! re_string_is_single_byte_char (pstr, pstr->cur_idx + idx))
     return re_string_peek_byte (pstr, idx);
-#endif
 
   off = pstr->cur_idx + idx;
-#ifdef RE_ENABLE_I18N
   if (pstr->offsets_needed)
     off = pstr->offsets[off];
-#endif
 
   ch = pstr->raw_mbs[pstr->raw_mbs_idx + off];
 
-#ifdef RE_ENABLE_I18N
   /* Ensure that e.g. for tr_TR.UTF-8 BACKSLASH DOTLESS SMALL LETTER I
      this function returns CAPITAL LETTER I instead of first byte of
      DOTLESS SMALL LETTER I.  The latter would confuse the parser,
      since peek_byte_case doesn't advance cur_idx in any way.  */
   if (pstr->offsets_needed && !isascii (ch))
     return re_string_peek_byte (pstr, idx);
-#endif
 
   return ch;
 }
@@ -878,7 +850,6 @@ re_string_fetch_byte_case (re_string_t *pstr)
   if (__glibc_likely (!pstr->mbs_allocated))
     return re_string_fetch_byte (pstr);
 
-#ifdef RE_ENABLE_I18N
   if (pstr->offsets_needed)
     {
       Idx off;
@@ -904,7 +875,6 @@ re_string_fetch_byte_case (re_string_t *pstr)
 			    re_string_char_size_at (pstr, pstr->cur_idx));
       return ch;
     }
-#endif
 
   return pstr->raw_mbs[pstr->raw_mbs_idx + pstr->cur_idx++];
 }
@@ -912,10 +882,8 @@ re_string_fetch_byte_case (re_string_t *pstr)
 static void
 re_string_destruct (re_string_t *pstr)
 {
-#ifdef RE_ENABLE_I18N
   re_free (pstr->wcs);
   re_free (pstr->offsets);
-#endif /* RE_ENABLE_I18N  */
   if (pstr->mbs_allocated)
     re_free (pstr->mbs);
 }
@@ -933,7 +901,6 @@ re_string_context_at (const re_string_t *input, Idx idx, int eflags)
   if (__glibc_unlikely (idx == input->len))
     return ((eflags & REG_NOTEOL) ? CONTEXT_ENDBUF
 	    : CONTEXT_NEWLINE | CONTEXT_ENDBUF);
-#ifdef RE_ENABLE_I18N
   if (input->mb_cur_max > 1)
     {
       wint_t wc;
@@ -953,7 +920,6 @@ re_string_context_at (const re_string_t *input, Idx idx, int eflags)
 	      ? CONTEXT_NEWLINE : 0);
     }
   else
-#endif
     {
       c = re_string_byte_at (input, idx);
       if (bitset_contain (input->word_char, c))
@@ -1430,32 +1396,28 @@ re_dfa_add_node (re_dfa_t *dfa, re_token_t token)
       if (__glibc_unlikely (new_nodes == NULL))
 	return -1;
       dfa->nodes = new_nodes;
+      dfa->nodes_alloc = new_nodes_alloc;
       new_nexts = re_realloc (dfa->nexts, Idx, new_nodes_alloc);
+      if (new_nexts != NULL)
+	dfa->nexts = new_nexts;
       new_indices = re_realloc (dfa->org_indices, Idx, new_nodes_alloc);
+      if (new_indices != NULL)
+	dfa->org_indices = new_indices;
       new_edests = re_realloc (dfa->edests, re_node_set, new_nodes_alloc);
+      if (new_edests != NULL)
+	dfa->edests = new_edests;
       new_eclosures = re_realloc (dfa->eclosures, re_node_set, new_nodes_alloc);
+      if (new_eclosures != NULL)
+	dfa->eclosures = new_eclosures;
       if (__glibc_unlikely (new_nexts == NULL || new_indices == NULL
 			    || new_edests == NULL || new_eclosures == NULL))
-	{
-	   re_free (new_nexts);
-	   re_free (new_indices);
-	   re_free (new_edests);
-	   re_free (new_eclosures);
-	   return -1;
-	}
-      dfa->nexts = new_nexts;
-      dfa->org_indices = new_indices;
-      dfa->edests = new_edests;
-      dfa->eclosures = new_eclosures;
-      dfa->nodes_alloc = new_nodes_alloc;
+	return -1;
     }
   dfa->nodes[dfa->nodes_len] = token;
   dfa->nodes[dfa->nodes_len].constraint = 0;
-#ifdef RE_ENABLE_I18N
   dfa->nodes[dfa->nodes_len].accept_mb =
     ((token.type == OP_PERIOD && dfa->mb_cur_max > 1)
      || token.type == COMPLEX_BRACKET);
-#endif
   dfa->nexts[dfa->nodes_len] = -1;
   re_node_set_init_empty (dfa->edests + dfa->nodes_len);
   re_node_set_init_empty (dfa->eclosures + dfa->nodes_len);
@@ -1651,9 +1613,7 @@ create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
       re_token_type_t type = node->type;
       if (type == CHARACTER && !node->constraint)
 	continue;
-#ifdef RE_ENABLE_I18N
       newstate->accept_mb |= node->accept_mb;
-#endif /* RE_ENABLE_I18N */
 
       /* If the state has the halt node, the state is a halt state.  */
       if (type == END_OF_RE)
@@ -1705,9 +1665,7 @@ create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
 
       if (type == CHARACTER && !constraint)
 	continue;
-#ifdef RE_ENABLE_I18N
       newstate->accept_mb |= node->accept_mb;
-#endif /* RE_ENABLE_I18N */
 
       /* If the state has the halt node, the state is a halt state.  */
       if (type == END_OF_RE)
diff --git a/lib/regex_internal.h b/lib/regex_internal.h
index 1245e782f..57a455b1f 100644
--- a/lib/regex_internal.h
+++ b/lib/regex_internal.h
@@ -1,5 +1,5 @@
 /* Extended regular expression matching and search library.
-   Copyright (C) 2002-2021 Free Software Foundation, Inc.
+   Copyright (C) 2002-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
 
@@ -116,10 +116,6 @@
 # define gettext_noop(String) String
 #endif
 
-#if (defined MB_CUR_MAX && HAVE_WCTYPE_H && HAVE_ISWCTYPE) || _LIBC
-# define RE_ENABLE_I18N
-#endif
-
 /* Number of ASCII characters.  */
 #define ASCII_CHARS 0x80
 
@@ -150,6 +146,11 @@
 # define __regfree regfree
 #endif /* not _LIBC */
 
+/* Types related to integers.  Unless protected by #ifdef _LIBC, the
+   regex code should avoid exact-width types like int32_t and uint64_t
+   as some non-GCC platforms lack them, an issue when this code is
+   used in Gnulib.  */
+
 #ifndef SSIZE_MAX
 # define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2))
 #endif
@@ -246,10 +247,8 @@ typedef enum
   SIMPLE_BRACKET = 3,
   OP_BACK_REF = 4,
   OP_PERIOD = 5,
-#ifdef RE_ENABLE_I18N
   COMPLEX_BRACKET = 6,
   OP_UTF8_PERIOD = 7,
-#endif /* RE_ENABLE_I18N */
 
   /* We define EPSILON_BIT as a macro so that OP_OPEN_SUBEXP is used
      when the debugger shows values of this enum type.  */
@@ -287,30 +286,29 @@ typedef enum
 
 } re_token_type_t;
 
-#ifdef RE_ENABLE_I18N
 typedef struct
 {
   /* Multibyte characters.  */
   wchar_t *mbchars;
 
+#ifdef _LIBC
   /* Collating symbols.  */
-# ifdef _LIBC
   int32_t *coll_syms;
-# endif
+#endif
 
+#ifdef _LIBC
   /* Equivalence classes. */
-# ifdef _LIBC
   int32_t *equiv_classes;
-# endif
+#endif
 
   /* Range expressions. */
-# ifdef _LIBC
+#ifdef _LIBC
   uint32_t *range_starts;
   uint32_t *range_ends;
-# else /* not _LIBC */
+#else
   wchar_t *range_starts;
   wchar_t *range_ends;
-# endif /* not _LIBC */
+#endif
 
   /* Character classes. */
   wctype_t *char_classes;
@@ -333,7 +331,6 @@ typedef struct
   /* # of character classes. */
   Idx nchar_classes;
 } re_charset_t;
-#endif /* RE_ENABLE_I18N */
 
 typedef struct
 {
@@ -341,9 +338,7 @@ typedef struct
   {
     unsigned char c;		/* for CHARACTER */
     re_bitset_ptr_t sbcset;	/* for SIMPLE_BRACKET */
-#ifdef RE_ENABLE_I18N
     re_charset_t *mbcset;	/* for COMPLEX_BRACKET */
-#endif /* RE_ENABLE_I18N */
     Idx idx;			/* for BACK_REF */
     re_context_type ctx_type;	/* for ANCHOR */
   } opr;
@@ -355,12 +350,10 @@ typedef struct
   unsigned int constraint : 10;	/* context constraint */
   unsigned int duplicated : 1;
   unsigned int opt_subexp : 1;
-#ifdef RE_ENABLE_I18N
   unsigned int accept_mb : 1;
   /* These 2 bits can be moved into the union if needed (e.g. if running out
      of bits; move opr.c to opr.c.c and move the flags to opr.c.flags).  */
   unsigned int mb_partial : 1;
-#endif
   unsigned int word_char : 1;
 } re_token_t;
 
@@ -375,12 +368,10 @@ struct re_string_t
      REG_ICASE, upper cases of the string are stored, otherwise MBS points
      the same address that RAW_MBS points.  */
   unsigned char *mbs;
-#ifdef RE_ENABLE_I18N
   /* Store the wide character string which is corresponding to MBS.  */
   wint_t *wcs;
   Idx *offsets;
   mbstate_t cur_state;
-#endif
   /* Index in RAW_MBS.  Each character mbs[i] corresponds to
      raw_mbs[raw_mbs_idx + i].  */
   Idx raw_mbs_idx;
@@ -779,7 +770,6 @@ bitset_mask (bitset_t dest, const bitset_t src)
     dest[bitset_i] &= src[bitset_i];
 }
 
-#ifdef RE_ENABLE_I18N
 /* Functions for re_string.  */
 static int
 __attribute__ ((pure, unused))
@@ -803,15 +793,15 @@ re_string_wchar_at (const re_string_t *pstr, Idx idx)
   return (wint_t) pstr->wcs[idx];
 }
 
-# ifdef _LIBC
-#  include <locale/weight.h>
-# endif
+#ifdef _LIBC
+# include <locale/weight.h>
+#endif
 
 static int
 __attribute__ ((pure, unused))
 re_string_elem_size_at (const re_string_t *pstr, Idx idx)
 {
-# ifdef _LIBC
+#ifdef _LIBC
   const unsigned char *p, *extra;
   const int32_t *table, *indirect;
   uint_fast32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
@@ -827,11 +817,10 @@ re_string_elem_size_at (const re_string_t *pstr, Idx idx)
       findidx (table, indirect, extra, &p, pstr->len - idx);
       return p - pstr->mbs - idx;
     }
-  else
-# endif /* _LIBC */
-    return 1;
+#endif /* _LIBC */
+
+  return 1;
 }
-#endif /* RE_ENABLE_I18N */
 
 #ifdef _LIBC
 # if __GNUC__ >= 7
diff --git a/lib/regexec.c b/lib/regexec.c
index 5e4eb497a..521cb0284 100644
--- a/lib/regexec.c
+++ b/lib/regexec.c
@@ -1,5 +1,5 @@
 /* Extended regular expression matching and search library.
-   Copyright (C) 2002-2021 Free Software Foundation, Inc.
+   Copyright (C) 2002-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
 
@@ -67,11 +67,9 @@ static reg_errcode_t set_regs (const regex_t *preg,
 			       bool fl_backtrack);
 static reg_errcode_t free_fail_stack_return (struct re_fail_stack_t *fs);
 
-#ifdef RE_ENABLE_I18N
 static int sift_states_iter_mb (const re_match_context_t *mctx,
 				re_sift_context_t *sctx,
 				Idx node_idx, Idx str_idx, Idx max_str_idx);
-#endif /* RE_ENABLE_I18N */
 static reg_errcode_t sift_states_backward (const re_match_context_t *mctx,
 					   re_sift_context_t *sctx);
 static reg_errcode_t build_sifted_states (const re_match_context_t *mctx,
@@ -123,10 +121,8 @@ static re_dfastate_t *transit_state_sb (reg_errcode_t *err,
 					re_match_context_t *mctx,
 					re_dfastate_t *pstate);
 #endif
-#ifdef RE_ENABLE_I18N
 static reg_errcode_t transit_state_mb (re_match_context_t *mctx,
 				       re_dfastate_t *pstate);
-#endif /* RE_ENABLE_I18N */
 static reg_errcode_t transit_state_bkref (re_match_context_t *mctx,
 					  const re_node_set *nodes);
 static reg_errcode_t get_subexp (re_match_context_t *mctx,
@@ -156,14 +152,12 @@ static reg_errcode_t expand_bkref_cache (re_match_context_t *mctx,
 					 re_node_set *cur_nodes, Idx cur_str,
 					 Idx subexp_num, int type);
 static bool build_trtable (const re_dfa_t *dfa, re_dfastate_t *state);
-#ifdef RE_ENABLE_I18N
 static int check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx,
 				    const re_string_t *input, Idx idx);
-# ifdef _LIBC
+#ifdef _LIBC
 static unsigned int find_collation_sequence_value (const unsigned char *mbs,
 						   size_t name_len);
-# endif /* _LIBC */
-#endif /* RE_ENABLE_I18N */
+#endif
 static Idx group_nodes_into_DFAstates (const re_dfa_t *dfa,
 				       const re_dfastate_t *state,
 				       re_node_set *states_node,
@@ -191,7 +185,7 @@ static reg_errcode_t extend_buffers (re_match_context_t *mctx, int min_len);
 
 int
 regexec (const regex_t *__restrict preg, const char *__restrict string,
-	 size_t nmatch, regmatch_t pmatch[], int eflags)
+	 size_t nmatch, regmatch_t pmatch[_REGEX_NELTS (nmatch)], int eflags)
 {
   reg_errcode_t err;
   Idx start, length;
@@ -235,7 +229,7 @@ int
 attribute_compat_text_section
 __compat_regexec (const regex_t *__restrict preg,
 		  const char *__restrict string, size_t nmatch,
-		  regmatch_t pmatch[], int eflags)
+		  regmatch_t pmatch[_REGEX_NELTS (nmatch)], int eflags)
 {
   return regexec (preg, string, nmatch, pmatch,
 		  eflags & (REG_NOTBOL | REG_NOTEOL));
@@ -758,10 +752,9 @@ re_search_internal (const regex_t *preg, const char *string, Idx length,
 
 		  offset = match_first - mctx.input.raw_mbs_idx;
 		}
-	      /* If MATCH_FIRST is out of the buffer, leave it as '\0'.
-		 Note that MATCH_FIRST must not be smaller than 0.  */
-	      ch = (match_first >= length
-		    ? 0 : re_string_byte_at (&mctx.input, offset));
+	      /* Use buffer byte if OFFSET is in buffer, otherwise '\0'.  */
+	      ch = (offset < mctx.input.valid_len
+		    ? re_string_byte_at (&mctx.input, offset) : 0);
 	      if (fastmap[ch])
 		break;
 	      match_first += incr;
@@ -780,12 +773,10 @@ re_search_internal (const regex_t *preg, const char *string, Idx length,
       if (__glibc_unlikely (err != REG_NOERROR))
 	goto free_return;
 
-#ifdef RE_ENABLE_I18N
-     /* Don't consider this char as a possible match start if it part,
-	yet isn't the head, of a multibyte character.  */
+      /* Don't consider this char as a possible match start if it part,
+         yet isn't the head, of a multibyte character.  */
       if (!sb && !re_string_first_byte (&mctx.input, 0))
 	continue;
-#endif
 
       /* It seems to be appropriate one, then use the matcher.  */
       /* We assume that the matching starts from 0.  */
@@ -859,7 +850,6 @@ re_search_internal (const regex_t *preg, const char *string, Idx length,
       for (reg_idx = 0; reg_idx < nmatch; ++reg_idx)
 	if (pmatch[reg_idx].rm_so != -1)
 	  {
-#ifdef RE_ENABLE_I18N
 	    if (__glibc_unlikely (mctx.input.offsets_needed != 0))
 	      {
 		pmatch[reg_idx].rm_so =
@@ -871,9 +861,6 @@ re_search_internal (const regex_t *preg, const char *string, Idx length,
 		   ? mctx.input.valid_raw_len
 		   : mctx.input.offsets[pmatch[reg_idx].rm_eo]);
 	      }
-#else
-	    DEBUG_ASSERT (mctx.input.offsets_needed == 0);
-#endif
 	    pmatch[reg_idx].rm_so += match_first;
 	    pmatch[reg_idx].rm_eo += match_first;
 	  }
@@ -997,8 +984,7 @@ prune_impossible_nodes (re_match_context_t *mctx)
    We must select appropriate initial state depending on the context,
    since initial states may have constraints like "\<", "^", etc..  */
 
-static inline re_dfastate_t *
-__attribute__ ((always_inline))
+static __always_inline re_dfastate_t *
 acquire_init_state_context (reg_errcode_t *err, const re_match_context_t *mctx,
 			    Idx idx)
 {
@@ -1262,12 +1248,9 @@ proceed_next_node (const re_match_context_t *mctx, Idx nregs, regmatch_t *regs,
       Idx naccepted = 0;
       re_token_type_t type = dfa->nodes[node].type;
 
-#ifdef RE_ENABLE_I18N
       if (dfa->nodes[node].accept_mb)
 	naccepted = check_node_accept_bytes (dfa, node, &mctx->input, *pidx);
-      else
-#endif /* RE_ENABLE_I18N */
-      if (type == OP_BACK_REF)
+      else if (type == OP_BACK_REF)
 	{
 	  Idx subexp_idx = dfa->nodes[node].opr.idx + 1;
 	  if (subexp_idx < nregs)
@@ -1325,8 +1308,8 @@ push_fail_stack (struct re_fail_stack_t *fs, Idx str_idx, Idx dest_node,
 		 re_node_set *eps_via_nodes)
 {
   reg_errcode_t err;
-  Idx num = fs->num++;
-  if (fs->num == fs->alloc)
+  Idx num = fs->num;
+  if (num == fs->alloc)
     {
       struct re_fail_stack_ent_t *new_array;
       new_array = re_realloc (fs->stack, struct re_fail_stack_ent_t,
@@ -1341,6 +1324,7 @@ push_fail_stack (struct re_fail_stack_t *fs, Idx str_idx, Idx dest_node,
   fs->stack[num].regs = re_malloc (regmatch_t, 2 * nregs);
   if (fs->stack[num].regs == NULL)
     return REG_ESPACE;
+  fs->num = num + 1;
   memcpy (fs->stack[num].regs, regs, sizeof (regmatch_t) * nregs);
   memcpy (fs->stack[num].regs + nregs, prevregs, sizeof (regmatch_t) * nregs);
   err = re_node_set_init_copy (&fs->stack[num].eps_via_nodes, eps_via_nodes);
@@ -1635,12 +1619,10 @@ build_sifted_states (const re_match_context_t *mctx, re_sift_context_t *sctx,
       bool ok;
       DEBUG_ASSERT (!IS_EPSILON_NODE (dfa->nodes[prev_node].type));
 
-#ifdef RE_ENABLE_I18N
       /* If the node may accept "multi byte".  */
       if (dfa->nodes[prev_node].accept_mb)
 	naccepted = sift_states_iter_mb (mctx, sctx, prev_node,
 					 str_idx, sctx->last_str_idx);
-#endif /* RE_ENABLE_I18N */
 
       /* We don't check backreferences here.
 	 See update_cur_sifted_state().  */
@@ -1689,6 +1671,7 @@ clean_state_log_if_needed (re_match_context_t *mctx, Idx next_state_log_idx)
 
   if (top < next_state_log_idx)
     {
+      DEBUG_ASSERT (mctx->state_log != NULL);
       memset (mctx->state_log + top + 1, '\0',
 	      sizeof (re_dfastate_t *) * (next_state_log_idx - top));
       mctx->state_log_top = next_state_log_idx;
@@ -2177,7 +2160,6 @@ sift_states_bkref (const re_match_context_t *mctx, re_sift_context_t *sctx,
 }
 
 
-#ifdef RE_ENABLE_I18N
 static int
 sift_states_iter_mb (const re_match_context_t *mctx, re_sift_context_t *sctx,
 		     Idx node_idx, Idx str_idx, Idx max_str_idx)
@@ -2197,8 +2179,6 @@ sift_states_iter_mb (const re_match_context_t *mctx, re_sift_context_t *sctx,
      'naccepted' bytes input.  */
   return naccepted;
 }
-#endif /* RE_ENABLE_I18N */
-
 \f
 /* Functions for state transition.  */
 
@@ -2216,7 +2196,6 @@ transit_state (reg_errcode_t *err, re_match_context_t *mctx,
   re_dfastate_t **trtable;
   unsigned char ch;
 
-#ifdef RE_ENABLE_I18N
   /* If the current state can accept multibyte.  */
   if (__glibc_unlikely (state->accept_mb))
     {
@@ -2224,7 +2203,6 @@ transit_state (reg_errcode_t *err, re_match_context_t *mctx,
       if (__glibc_unlikely (*err != REG_NOERROR))
 	return NULL;
     }
-#endif /* RE_ENABLE_I18N */
 
   /* Then decide the next state with the single byte.  */
 #if 0
@@ -2445,7 +2423,6 @@ transit_state_sb (reg_errcode_t *err, re_match_context_t *mctx,
 }
 #endif
 
-#ifdef RE_ENABLE_I18N
 static reg_errcode_t
 transit_state_mb (re_match_context_t *mctx, re_dfastate_t *pstate)
 {
@@ -2513,7 +2490,6 @@ transit_state_mb (re_match_context_t *mctx, re_dfastate_t *pstate)
     }
   return REG_NOERROR;
 }
-#endif /* RE_ENABLE_I18N */
 
 static reg_errcode_t
 transit_state_bkref (re_match_context_t *mctx, const re_node_set *nodes)
@@ -3003,9 +2979,7 @@ check_arrival_add_next_nodes (re_match_context_t *mctx, Idx str_idx,
   const re_dfa_t *const dfa = mctx->dfa;
   bool ok;
   Idx cur_idx;
-#ifdef RE_ENABLE_I18N
   reg_errcode_t err = REG_NOERROR;
-#endif
   re_node_set union_set;
   re_node_set_init_empty (&union_set);
   for (cur_idx = 0; cur_idx < cur_nodes->nelem; ++cur_idx)
@@ -3014,7 +2988,6 @@ check_arrival_add_next_nodes (re_match_context_t *mctx, Idx str_idx,
       Idx cur_node = cur_nodes->elems[cur_idx];
       DEBUG_ASSERT (!IS_EPSILON_NODE (dfa->nodes[cur_node].type));
 
-#ifdef RE_ENABLE_I18N
       /* If the node may accept "multi byte".  */
       if (dfa->nodes[cur_node].accept_mb)
 	{
@@ -3052,7 +3025,7 @@ check_arrival_add_next_nodes (re_match_context_t *mctx, Idx str_idx,
 		}
 	    }
 	}
-#endif /* RE_ENABLE_I18N */
+
       if (naccepted
 	  || check_node_accept (mctx, dfa->nodes + cur_node, str_idx))
 	{
@@ -3476,18 +3449,15 @@ group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state,
 	}
       else if (type == OP_PERIOD)
 	{
-#ifdef RE_ENABLE_I18N
 	  if (dfa->mb_cur_max > 1)
 	    bitset_merge (accepts, dfa->sb_char);
 	  else
-#endif
 	    bitset_set_all (accepts);
 	  if (!(dfa->syntax & RE_DOT_NEWLINE))
 	    bitset_clear (accepts, '\n');
 	  if (dfa->syntax & RE_DOT_NOT_NULL)
 	    bitset_clear (accepts, '\0');
 	}
-#ifdef RE_ENABLE_I18N
       else if (type == OP_UTF8_PERIOD)
 	{
 	  if (ASCII_CHARS % BITSET_WORD_BITS == 0)
@@ -3499,7 +3469,6 @@ group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state,
 	  if (dfa->syntax & RE_DOT_NOT_NULL)
 	    bitset_clear (accepts, '\0');
 	}
-#endif
       else
 	continue;
 
@@ -3530,12 +3499,10 @@ group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state,
 		  bitset_empty (accepts);
 		  continue;
 		}
-#ifdef RE_ENABLE_I18N
 	      if (dfa->mb_cur_max > 1)
 		for (j = 0; j < BITSET_WORDS; ++j)
 		  any_set |= (accepts[j] &= (dfa->word_char[j] | ~dfa->sb_char[j]));
 	      else
-#endif
 		for (j = 0; j < BITSET_WORDS; ++j)
 		  any_set |= (accepts[j] &= dfa->word_char[j]);
 	      if (!any_set)
@@ -3549,12 +3516,10 @@ group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state,
 		  bitset_empty (accepts);
 		  continue;
 		}
-#ifdef RE_ENABLE_I18N
 	      if (dfa->mb_cur_max > 1)
 		for (j = 0; j < BITSET_WORDS; ++j)
 		  any_set |= (accepts[j] &= ~(dfa->word_char[j] & dfa->sb_char[j]));
 	      else
-#endif
 		for (j = 0; j < BITSET_WORDS; ++j)
 		  any_set |= (accepts[j] &= ~dfa->word_char[j]);
 	      if (!any_set)
@@ -3631,7 +3596,6 @@ group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state,
   return -1;
 }
 
-#ifdef RE_ENABLE_I18N
 /* Check how many bytes the node 'dfa->nodes[node_idx]' accepts.
    Return the number of the bytes the node accepts.
    STR_IDX is the current index of the input string.
@@ -3640,9 +3604,9 @@ group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state,
    one collating element like '.', '[a-z]', opposite to the other nodes
    can only accept one byte.  */
 
-# ifdef _LIBC
-#  include <locale/weight.h>
-# endif
+#ifdef _LIBC
+# include <locale/weight.h>
+#endif
 
 static int
 check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx,
@@ -3726,12 +3690,12 @@ check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx,
   if (node->type == COMPLEX_BRACKET)
     {
       const re_charset_t *cset = node->opr.mbcset;
-# ifdef _LIBC
+#ifdef _LIBC
       const unsigned char *pin
 	= ((const unsigned char *) re_string_get_buffer (input) + str_idx);
       Idx j;
       uint32_t nrules;
-# endif /* _LIBC */
+#endif
       int match_len = 0;
       wchar_t wc = ((cset->nranges || cset->nchar_classes || cset->nmbchars)
 		    ? re_string_wchar_at (input, str_idx) : 0);
@@ -3754,7 +3718,7 @@ check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx,
 	    }
 	}
 
-# ifdef _LIBC
+#ifdef _LIBC
       nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
       if (nrules != 0)
 	{
@@ -3843,7 +3807,7 @@ check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx,
 	    }
 	}
       else
-# endif /* _LIBC */
+#endif /* _LIBC */
 	{
 	  /* match with range expression?  */
 	  for (i = 0; i < cset->nranges; ++i)
@@ -3869,7 +3833,7 @@ check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx,
   return 0;
 }
 
-# ifdef _LIBC
+#ifdef _LIBC
 static unsigned int
 find_collation_sequence_value (const unsigned char *mbs, size_t mbs_len)
 {
@@ -3927,8 +3891,7 @@ find_collation_sequence_value (const unsigned char *mbs, size_t mbs_len)
       return UINT_MAX;
     }
 }
-# endif /* _LIBC */
-#endif /* RE_ENABLE_I18N */
+#endif /* _LIBC */
 
 /* Check whether the node accepts the byte which is IDX-th
    byte of the INPUT.  */
@@ -3951,12 +3914,10 @@ check_node_accept (const re_match_context_t *mctx, const re_token_t *node,
         return false;
       break;
 
-#ifdef RE_ENABLE_I18N
     case OP_UTF8_PERIOD:
       if (ch >= ASCII_CHARS)
         return false;
       FALLTHROUGH;
-#endif
     case OP_PERIOD:
       if ((ch == '\n' && !(mctx->dfa->syntax & RE_DOT_NEWLINE))
 	  || (ch == '\0' && (mctx->dfa->syntax & RE_DOT_NOT_NULL)))
@@ -4017,7 +3978,6 @@ extend_buffers (re_match_context_t *mctx, int min_len)
   /* Then reconstruct the buffers.  */
   if (pstr->icase)
     {
-#ifdef RE_ENABLE_I18N
       if (pstr->mb_cur_max > 1)
 	{
 	  ret = build_wcs_upper_buffer (pstr);
@@ -4025,16 +3985,13 @@ extend_buffers (re_match_context_t *mctx, int min_len)
 	    return ret;
 	}
       else
-#endif /* RE_ENABLE_I18N  */
 	build_upper_buffer (pstr);
     }
   else
     {
-#ifdef RE_ENABLE_I18N
       if (pstr->mb_cur_max > 1)
 	build_wcs_buffer (pstr);
       else
-#endif /* RE_ENABLE_I18N  */
 	{
 	  if (pstr->trans != NULL)
 	    re_string_translate_buffer (pstr);
diff --git a/lib/rename.c b/lib/rename.c
index a3b7dc641..119abe5c2 100644
--- a/lib/rename.c
+++ b/lib/rename.c
@@ -1,6 +1,6 @@
 /* Work around rename bugs in some systems.
 
-   Copyright (C) 2001-2003, 2005-2006, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2001-2003, 2005-2006, 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
@@ -287,7 +287,7 @@ rpl_rename (char const *src, char const *dst)
   char *dst_temp = (char *) dst;
   bool src_slash;
   bool dst_slash;
-  bool dst_exists _GL_UNUSED;
+  _GL_UNUSED bool dst_exists;
   int ret_val = -1;
   int rename_errno = ENOTDIR;
   struct stat src_st;
diff --git a/lib/rmdir.c b/lib/rmdir.c
index 6295e4125..8c8b75e04 100644
--- a/lib/rmdir.c
+++ b/lib/rmdir.c
@@ -1,6 +1,6 @@
 /* Work around rmdir bugs.
 
-   Copyright (C) 1988, 1990, 1999, 2003-2006, 2009-2021 Free Software
+   Copyright (C) 1988, 1990, 1999, 2003-2006, 2009-2022 Free Software
    Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/round.c b/lib/round.c
index 552505042..7e62feeb5 100644
--- a/lib/round.c
+++ b/lib/round.c
@@ -1,9 +1,9 @@
 /* Round toward nearest, breaking ties away from zero.
-   Copyright (C) 2007, 2010-2021 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2010-2022 Free Software Foundation, Inc.
 
    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 3 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/safe-read.c b/lib/safe-read.c
index e187b1258..04ffa7b84 100644
--- a/lib/safe-read.c
+++ b/lib/safe-read.c
@@ -1,6 +1,6 @@
 /* An interface to read and write that retries after interrupts.
 
-   Copyright (C) 1993-1994, 1998, 2002-2006, 2009-2021 Free Software
+   Copyright (C) 1993-1994, 1998, 2002-2006, 2009-2022 Free Software
    Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/safe-read.h b/lib/safe-read.h
index 111aff5c4..a39bb984c 100644
--- a/lib/safe-read.h
+++ b/lib/safe-read.h
@@ -1,5 +1,5 @@
 /* An interface to read() that retries after interrupts.
-   Copyright (C) 2002, 2006, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2006, 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/safe-write.c b/lib/safe-write.c
index 494de1495..b779b36e7 100644
--- a/lib/safe-write.c
+++ b/lib/safe-write.c
@@ -1,5 +1,5 @@
 /* An interface to write that retries after interrupts.
-   Copyright (C) 2002, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/safe-write.h b/lib/safe-write.h
index 25d8c710c..a5a6c90bc 100644
--- a/lib/safe-write.h
+++ b/lib/safe-write.h
@@ -1,5 +1,5 @@
 /* An interface to write() that retries after interrupts.
-   Copyright (C) 2002, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/same-inode.h b/lib/same-inode.h
index c7277779a..f65f3d039 100644
--- a/lib/same-inode.h
+++ b/lib/same-inode.h
@@ -1,6 +1,6 @@
 /* Determine whether two stat buffers are known to refer to the same file.
 
-   Copyright (C) 2006, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2006, 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/sched.h b/lib/sched.h
new file mode 100644
index 000000000..223718750
--- /dev/null
+++ b/lib/sched.h
@@ -0,0 +1,580 @@
+/* DO NOT EDIT! GENERATED AUTOMATICALLY! */
+/* A GNU-like <sched.h>.
+   Copyright (C) 2008-2022 Free Software Foundation, Inc.
+
+   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 2.1 of the
+   License, or (at your option) any later version.
+
+   This file 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+#ifndef _GL_SCHED_H
+
+#if __GNUC__ >= 3
+#pragma GCC system_header
+#endif
+
+
+/* The include_next requires a split double-inclusion guard.  */
+#if 1
+# if 1
+#  include <sys/cdefs.h>
+# endif
+# include_next <sched.h>
+#endif
+
+#ifndef _GL_SCHED_H
+#define _GL_SCHED_H
+
+/* Get pid_t.
+   This is needed on glibc 2.11 (see
+   glibc bug <https://sourceware.org/bugzilla/show_bug.cgi?id=13198>)
+   and Mac OS X 10.5.  */
+#include <sys/types.h>
+
+#ifdef __KLIBC__
+/* On OS/2 kLIBC, struct sched_param is in spawn.h.  */
+# include <spawn.h>
+#endif
+
+#ifdef __VMS
+/* On OpenVMS, struct sched_param is in <pthread.h>.  */
+# include <pthread.h>
+#endif
+
+/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */
+/* C++ compatible function declaration macros.
+   Copyright (C) 2010-2022 Free Software Foundation, Inc.
+
+   This program 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 2 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+#ifndef _GL_CXXDEFS_H
+#define _GL_CXXDEFS_H
+
+/* Begin/end the GNULIB_NAMESPACE namespace.  */
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+# define _GL_BEGIN_NAMESPACE namespace GNULIB_NAMESPACE {
+# define _GL_END_NAMESPACE }
+#else
+# define _GL_BEGIN_NAMESPACE
+# define _GL_END_NAMESPACE
+#endif
+
+/* The three most frequent use cases of these macros are:
+
+   * For providing a substitute for a function that is missing on some
+     platforms, but is declared and works fine on the platforms on which
+     it exists:
+
+       #if @GNULIB_FOO@
+       # if !@HAVE_FOO@
+       _GL_FUNCDECL_SYS (foo, ...);
+       # endif
+       _GL_CXXALIAS_SYS (foo, ...);
+       _GL_CXXALIASWARN (foo);
+       #elif defined GNULIB_POSIXCHECK
+       ...
+       #endif
+
+   * For providing a replacement for a function that exists on all platforms,
+     but is broken/insufficient and needs to be replaced on some platforms:
+
+       #if @GNULIB_FOO@
+       # if @REPLACE_FOO@
+       #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+       #   undef foo
+       #   define foo rpl_foo
+       #  endif
+       _GL_FUNCDECL_RPL (foo, ...);
+       _GL_CXXALIAS_RPL (foo, ...);
+       # else
+       _GL_CXXALIAS_SYS (foo, ...);
+       # endif
+       _GL_CXXALIASWARN (foo);
+       #elif defined GNULIB_POSIXCHECK
+       ...
+       #endif
+
+   * For providing a replacement for a function that exists on some platforms
+     but is broken/insufficient and needs to be replaced on some of them and
+     is additionally either missing or undeclared on some other platforms:
+
+       #if @GNULIB_FOO@
+       # if @REPLACE_FOO@
+       #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+       #   undef foo
+       #   define foo rpl_foo
+       #  endif
+       _GL_FUNCDECL_RPL (foo, ...);
+       _GL_CXXALIAS_RPL (foo, ...);
+       # else
+       #  if !@HAVE_FOO@   or   if !@HAVE_DECL_FOO@
+       _GL_FUNCDECL_SYS (foo, ...);
+       #  endif
+       _GL_CXXALIAS_SYS (foo, ...);
+       # endif
+       _GL_CXXALIASWARN (foo);
+       #elif defined GNULIB_POSIXCHECK
+       ...
+       #endif
+*/
+
+/* _GL_EXTERN_C declaration;
+   performs the declaration with C linkage.  */
+#if defined __cplusplus
+# define _GL_EXTERN_C extern "C"
+#else
+# define _GL_EXTERN_C extern
+#endif
+
+/* _GL_FUNCDECL_RPL (func, rettype, parameters_and_attributes);
+   declares a replacement function, named rpl_func, with the given prototype,
+   consisting of return type, parameters, and attributes.
+   Example:
+     _GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...)
+                                  _GL_ARG_NONNULL ((1)));
+ */
+#define _GL_FUNCDECL_RPL(func,rettype,parameters_and_attributes) \
+  _GL_FUNCDECL_RPL_1 (rpl_##func, rettype, parameters_and_attributes)
+#define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters_and_attributes) \
+  _GL_EXTERN_C rettype rpl_func parameters_and_attributes
+
+/* _GL_FUNCDECL_SYS (func, rettype, parameters_and_attributes);
+   declares the system function, named func, with the given prototype,
+   consisting of return type, parameters, and attributes.
+   Example:
+     _GL_FUNCDECL_SYS (open, int, (const char *filename, int flags, ...)
+                                  _GL_ARG_NONNULL ((1)));
+ */
+#define _GL_FUNCDECL_SYS(func,rettype,parameters_and_attributes) \
+  _GL_EXTERN_C rettype func parameters_and_attributes
+
+/* _GL_CXXALIAS_RPL (func, rettype, parameters);
+   declares a C++ alias called GNULIB_NAMESPACE::func
+   that redirects to rpl_func, if GNULIB_NAMESPACE is defined.
+   Example:
+     _GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...));
+
+   Wrapping rpl_func in an object with an inline conversion operator
+   avoids a reference to rpl_func unless GNULIB_NAMESPACE::func is
+   actually used in the program.  */
+#define _GL_CXXALIAS_RPL(func,rettype,parameters) \
+  _GL_CXXALIAS_RPL_1 (func, rpl_##func, rettype, parameters)
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \
+    namespace GNULIB_NAMESPACE                                \
+    {                                                         \
+      static const struct _gl_ ## func ## _wrapper            \
+      {                                                       \
+        typedef rettype (*type) parameters;                   \
+                                                              \
+        inline operator type () const                         \
+        {                                                     \
+          return ::rpl_func;                                  \
+        }                                                     \
+      } func = {};                                            \
+    }                                                         \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#else
+# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#endif
+
+/* _GL_CXXALIAS_MDA (func, rettype, parameters);
+   is to be used when func is a Microsoft deprecated alias, on native Windows.
+   It declares a C++ alias called GNULIB_NAMESPACE::func
+   that redirects to _func, if GNULIB_NAMESPACE is defined.
+   Example:
+     _GL_CXXALIAS_MDA (open, int, (const char *filename, int flags, ...));
+ */
+#define _GL_CXXALIAS_MDA(func,rettype,parameters) \
+  _GL_CXXALIAS_RPL_1 (func, _##func, rettype, parameters)
+
+/* _GL_CXXALIAS_RPL_CAST_1 (func, rpl_func, rettype, parameters);
+   is like  _GL_CXXALIAS_RPL_1 (func, rpl_func, rettype, parameters);
+   except that the C function rpl_func may have a slightly different
+   declaration.  A cast is used to silence the "invalid conversion" error
+   that would otherwise occur.  */
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \
+    namespace GNULIB_NAMESPACE                                     \
+    {                                                              \
+      static const struct _gl_ ## func ## _wrapper                 \
+      {                                                            \
+        typedef rettype (*type) parameters;                        \
+                                                                   \
+        inline operator type () const                              \
+        {                                                          \
+          return reinterpret_cast<type>(::rpl_func);               \
+        }                                                          \
+      } func = {};                                                 \
+    }                                                              \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#else
+# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#endif
+
+/* _GL_CXXALIAS_MDA_CAST (func, rettype, parameters);
+   is like  _GL_CXXALIAS_MDA (func, rettype, parameters);
+   except that the C function func may have a slightly different declaration.
+   A cast is used to silence the "invalid conversion" error that would
+   otherwise occur.  */
+#define _GL_CXXALIAS_MDA_CAST(func,rettype,parameters) \
+  _GL_CXXALIAS_RPL_CAST_1 (func, _##func, rettype, parameters)
+
+/* _GL_CXXALIAS_SYS (func, rettype, parameters);
+   declares a C++ alias called GNULIB_NAMESPACE::func
+   that redirects to the system provided function func, if GNULIB_NAMESPACE
+   is defined.
+   Example:
+     _GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...));
+
+   Wrapping func in an object with an inline conversion operator
+   avoids a reference to func unless GNULIB_NAMESPACE::func is
+   actually used in the program.  */
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+# define _GL_CXXALIAS_SYS(func,rettype,parameters)            \
+    namespace GNULIB_NAMESPACE                                \
+    {                                                         \
+      static const struct _gl_ ## func ## _wrapper            \
+      {                                                       \
+        typedef rettype (*type) parameters;                   \
+                                                              \
+        inline operator type () const                         \
+        {                                                     \
+          return ::func;                                      \
+        }                                                     \
+      } func = {};                                            \
+    }                                                         \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#else
+# define _GL_CXXALIAS_SYS(func,rettype,parameters) \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#endif
+
+/* _GL_CXXALIAS_SYS_CAST (func, rettype, parameters);
+   is like  _GL_CXXALIAS_SYS (func, rettype, parameters);
+   except that the C function func may have a slightly different declaration.
+   A cast is used to silence the "invalid conversion" error that would
+   otherwise occur.  */
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \
+    namespace GNULIB_NAMESPACE                          \
+    {                                                   \
+      static const struct _gl_ ## func ## _wrapper      \
+      {                                                 \
+        typedef rettype (*type) parameters;             \
+                                                        \
+        inline operator type () const                   \
+        {                                               \
+          return reinterpret_cast<type>(::func);        \
+        }                                               \
+      } func = {};                                      \
+    }                                                   \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#else
+# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#endif
+
+/* _GL_CXXALIAS_SYS_CAST2 (func, rettype, parameters, rettype2, parameters2);
+   is like  _GL_CXXALIAS_SYS (func, rettype, parameters);
+   except that the C function is picked among a set of overloaded functions,
+   namely the one with rettype2 and parameters2.  Two consecutive casts
+   are used to silence the "cannot find a match" and "invalid conversion"
+   errors that would otherwise occur.  */
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+  /* The outer cast must be a reinterpret_cast.
+     The inner cast: When the function is defined as a set of overloaded
+     functions, it works as a static_cast<>, choosing the designated variant.
+     When the function is defined as a single variant, it works as a
+     reinterpret_cast<>. The parenthesized cast syntax works both ways.  */
+# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \
+    namespace GNULIB_NAMESPACE                                                \
+    {                                                                         \
+      static const struct _gl_ ## func ## _wrapper                            \
+      {                                                                       \
+        typedef rettype (*type) parameters;                                   \
+                                                                              \
+        inline operator type () const                                         \
+        {                                                                     \
+          return reinterpret_cast<type>((rettype2 (*) parameters2)(::func));  \
+        }                                                                     \
+      } func = {};                                                            \
+    }                                                                         \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#else
+# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#endif
+
+/* _GL_CXXALIASWARN (func);
+   causes a warning to be emitted when ::func is used but not when
+   GNULIB_NAMESPACE::func is used.  func must be defined without overloaded
+   variants.  */
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+# define _GL_CXXALIASWARN(func) \
+   _GL_CXXALIASWARN_1 (func, GNULIB_NAMESPACE)
+# define _GL_CXXALIASWARN_1(func,namespace) \
+   _GL_CXXALIASWARN_2 (func, namespace)
+/* To work around GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,
+   we enable the warning only when not optimizing.  */
+# if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__)
+#  define _GL_CXXALIASWARN_2(func,namespace) \
+    _GL_WARN_ON_USE (func, \
+                     "The symbol ::" #func " refers to the system function. " \
+                     "Use " #namespace "::" #func " instead.")
+# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
+#  define _GL_CXXALIASWARN_2(func,namespace) \
+     extern __typeof__ (func) func
+# else
+#  define _GL_CXXALIASWARN_2(func,namespace) \
+     _GL_EXTERN_C int _gl_cxxalias_dummy
+# endif
+#else
+# define _GL_CXXALIASWARN(func) \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#endif
+
+/* _GL_CXXALIASWARN1 (func, rettype, parameters_and_attributes);
+   causes a warning to be emitted when the given overloaded variant of ::func
+   is used but not when GNULIB_NAMESPACE::func is used.  */
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \
+   _GL_CXXALIASWARN1_1 (func, rettype, parameters_and_attributes, \
+                        GNULIB_NAMESPACE)
+# define _GL_CXXALIASWARN1_1(func,rettype,parameters_and_attributes,namespace) \
+   _GL_CXXALIASWARN1_2 (func, rettype, parameters_and_attributes, namespace)
+/* To work around GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,
+   we enable the warning only when not optimizing.  */
+# if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__)
+#  define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
+    _GL_WARN_ON_USE_CXX (func, rettype, rettype, parameters_and_attributes, \
+                         "The symbol ::" #func " refers to the system function. " \
+                         "Use " #namespace "::" #func " instead.")
+# else
+#  define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
+     _GL_EXTERN_C int _gl_cxxalias_dummy
+# endif
+#else
+# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#endif
+
+#endif /* _GL_CXXDEFS_H */
+
+/* The definition of _GL_WARN_ON_USE is copied here.  */
+/* A C macro for emitting warnings if a function is used.
+   Copyright (C) 2010-2022 Free Software Foundation, Inc.
+
+   This program 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 2 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+/* _GL_WARN_ON_USE (function, "literal string") issues a declaration
+   for FUNCTION which will then trigger a compiler warning containing
+   the text of "literal string" anywhere that function is called, if
+   supported by the compiler.  If the compiler does not support this
+   feature, the macro expands to an unused extern declaration.
+
+   _GL_WARN_ON_USE_ATTRIBUTE ("literal string") expands to the
+   attribute used in _GL_WARN_ON_USE.  If the compiler does not support
+   this feature, it expands to empty.
+
+   These macros are useful for marking a function as a potential
+   portability trap, with the intent that "literal string" include
+   instructions on the replacement function that should be used
+   instead.
+   _GL_WARN_ON_USE is for functions with 'extern' linkage.
+   _GL_WARN_ON_USE_ATTRIBUTE is for functions with 'static' or 'inline'
+   linkage.
+
+   However, one of the reasons that a function is a portability trap is
+   if it has the wrong signature.  Declaring FUNCTION with a different
+   signature in C is a compilation error, so this macro must use the
+   same type as any existing declaration so that programs that avoid
+   the problematic FUNCTION do not fail to compile merely because they
+   included a header that poisoned the function.  But this implies that
+   _GL_WARN_ON_USE is only safe to use if FUNCTION is known to already
+   have a declaration.  Use of this macro implies that there must not
+   be any other macro hiding the declaration of FUNCTION; but
+   undefining FUNCTION first is part of the poisoning process anyway
+   (although for symbols that are provided only via a macro, the result
+   is a compilation error rather than a warning containing
+   "literal string").  Also note that in C++, it is only safe to use if
+   FUNCTION has no overloads.
+
+   For an example, it is possible to poison 'getline' by:
+   - adding a call to gl_WARN_ON_USE_PREPARE([[#include <stdio.h>]],
+     [getline]) in configure.ac, which potentially defines
+     HAVE_RAW_DECL_GETLINE
+   - adding this code to a header that wraps the system <stdio.h>:
+     #undef getline
+     #if HAVE_RAW_DECL_GETLINE
+     _GL_WARN_ON_USE (getline, "getline is required by POSIX 2008, but"
+       "not universally present; use the gnulib module getline");
+     #endif
+
+   It is not possible to directly poison global variables.  But it is
+   possible to write a wrapper accessor function, and poison that
+   (less common usage, like &environ, will cause a compilation error
+   rather than issue the nice warning, but the end result of informing
+   the developer about their portability problem is still achieved):
+     #if HAVE_RAW_DECL_ENVIRON
+     static char ***
+     rpl_environ (void) { return &environ; }
+     _GL_WARN_ON_USE (rpl_environ, "environ is not always properly declared");
+     # undef environ
+     # define environ (*rpl_environ ())
+     #endif
+   or better (avoiding contradictory use of 'static' and 'extern'):
+     #if HAVE_RAW_DECL_ENVIRON
+     static char ***
+     _GL_WARN_ON_USE_ATTRIBUTE ("environ is not always properly declared")
+     rpl_environ (void) { return &environ; }
+     # undef environ
+     # define environ (*rpl_environ ())
+     #endif
+   */
+#ifndef _GL_WARN_ON_USE
+
+# if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)
+/* A compiler attribute is available in gcc versions 4.3.0 and later.  */
+#  define _GL_WARN_ON_USE(function, message) \
+_GL_WARN_EXTERN_C __typeof__ (function) function __attribute__ ((__warning__ (message)))
+#  define _GL_WARN_ON_USE_ATTRIBUTE(message) \
+  __attribute__ ((__warning__ (message)))
+# elif __clang_major__ >= 4
+/* Another compiler attribute is available in clang.  */
+#  define _GL_WARN_ON_USE(function, message) \
+_GL_WARN_EXTERN_C __typeof__ (function) function \
+  __attribute__ ((__diagnose_if__ (1, message, "warning")))
+#  define _GL_WARN_ON_USE_ATTRIBUTE(message) \
+  __attribute__ ((__diagnose_if__ (1, message, "warning")))
+# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
+/* Verify the existence of the function.  */
+#  define _GL_WARN_ON_USE(function, message) \
+_GL_WARN_EXTERN_C __typeof__ (function) function
+#  define _GL_WARN_ON_USE_ATTRIBUTE(message)
+# else /* Unsupported.  */
+#  define _GL_WARN_ON_USE(function, message) \
+_GL_WARN_EXTERN_C int _gl_warn_on_use
+#  define _GL_WARN_ON_USE_ATTRIBUTE(message)
+# endif
+#endif
+
+/* _GL_WARN_ON_USE_CXX (function, rettype_gcc, rettype_clang, parameters_and_attributes, "message")
+   is like _GL_WARN_ON_USE (function, "message"), except that in C++ mode the
+   function is declared with the given prototype, consisting of return type,
+   parameters, and attributes.
+   This variant is useful for overloaded functions in C++. _GL_WARN_ON_USE does
+   not work in this case.  */
+#ifndef _GL_WARN_ON_USE_CXX
+# if !defined __cplusplus
+#  define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \
+     _GL_WARN_ON_USE (function, msg)
+# else
+#  if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)
+/* A compiler attribute is available in gcc versions 4.3.0 and later.  */
+#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \
+extern rettype_gcc function parameters_and_attributes \
+  __attribute__ ((__warning__ (msg)))
+#  elif __clang_major__ >= 4
+/* Another compiler attribute is available in clang.  */
+#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \
+extern rettype_clang function parameters_and_attributes \
+  __attribute__ ((__diagnose_if__ (1, msg, "warning")))
+#  elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
+/* Verify the existence of the function.  */
+#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \
+extern rettype_gcc function parameters_and_attributes
+#  else /* Unsupported.  */
+#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \
+_GL_WARN_EXTERN_C int _gl_warn_on_use
+#  endif
+# endif
+#endif
+
+/* _GL_WARN_EXTERN_C declaration;
+   performs the declaration with C linkage.  */
+#ifndef _GL_WARN_EXTERN_C
+# if defined __cplusplus
+#  define _GL_WARN_EXTERN_C extern "C"
+# else
+#  define _GL_WARN_EXTERN_C extern
+# endif
+#endif
+
+#if !1
+
+# if !GNULIB_defined_struct_sched_param
+struct sched_param
+{
+  int sched_priority;
+};
+#  define GNULIB_defined_struct_sched_param 1
+# endif
+
+#endif
+
+#if !(defined SCHED_FIFO && defined SCHED_RR && defined SCHED_OTHER)
+# define SCHED_FIFO   1
+# define SCHED_RR     2
+# define SCHED_OTHER  0
+#endif
+
+#if 0
+# if 0
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef sched_yield
+#   define sched_yield rpl_sched_yield
+#  endif
+_GL_FUNCDECL_RPL (sched_yield, int, (void));
+_GL_CXXALIAS_RPL (sched_yield, int, (void));
+# else
+#  if !1
+_GL_FUNCDECL_SYS (sched_yield, int, (void));
+#  endif
+_GL_CXXALIAS_SYS (sched_yield, int, (void));
+# endif
+# if __GLIBC__ >= 2
+_GL_CXXALIASWARN (sched_yield);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef sched_yield
+# if HAVE_RAW_DECL_SCHED_YIELD
+_GL_WARN_ON_USE (sched_yield, "sched_yield is not portable - "
+                 "use gnulib module sched_yield for portability");
+# endif
+#endif
+
+#endif /* _GL_SCHED_H */
+#endif /* _GL_SCHED_H */
diff --git a/lib/sched.in.h b/lib/sched.in.h
new file mode 100644
index 000000000..d19c5022a
--- /dev/null
+++ b/lib/sched.in.h
@@ -0,0 +1,99 @@
+/* A GNU-like <sched.h>.
+   Copyright (C) 2008-2022 Free Software Foundation, Inc.
+
+   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 2.1 of the
+   License, or (at your option) any later version.
+
+   This file 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+#ifndef _@GUARD_PREFIX@_SCHED_H
+
+#if __GNUC__ >= 3
+@PRAGMA_SYSTEM_HEADER@
+#endif
+@PRAGMA_COLUMNS@
+
+/* The include_next requires a split double-inclusion guard.  */
+#if @HAVE_SCHED_H@
+# if @HAVE_SYS_CDEFS_H@
+#  include <sys/cdefs.h>
+# endif
+# @INCLUDE_NEXT@ @NEXT_SCHED_H@
+#endif
+
+#ifndef _@GUARD_PREFIX@_SCHED_H
+#define _@GUARD_PREFIX@_SCHED_H
+
+/* Get pid_t.
+   This is needed on glibc 2.11 (see
+   glibc bug <https://sourceware.org/bugzilla/show_bug.cgi?id=13198>)
+   and Mac OS X 10.5.  */
+#include <sys/types.h>
+
+#ifdef __KLIBC__
+/* On OS/2 kLIBC, struct sched_param is in spawn.h.  */
+# include <spawn.h>
+#endif
+
+#ifdef __VMS
+/* On OpenVMS, struct sched_param is in <pthread.h>.  */
+# include <pthread.h>
+#endif
+
+/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */
+
+/* The definition of _GL_WARN_ON_USE is copied here.  */
+
+#if !@HAVE_STRUCT_SCHED_PARAM@
+
+# if !GNULIB_defined_struct_sched_param
+struct sched_param
+{
+  int sched_priority;
+};
+#  define GNULIB_defined_struct_sched_param 1
+# endif
+
+#endif
+
+#if !(defined SCHED_FIFO && defined SCHED_RR && defined SCHED_OTHER)
+# define SCHED_FIFO   1
+# define SCHED_RR     2
+# define SCHED_OTHER  0
+#endif
+
+#if @GNULIB_SCHED_YIELD@
+# if @REPLACE_SCHED_YIELD@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef sched_yield
+#   define sched_yield rpl_sched_yield
+#  endif
+_GL_FUNCDECL_RPL (sched_yield, int, (void));
+_GL_CXXALIAS_RPL (sched_yield, int, (void));
+# else
+#  if !@HAVE_SCHED_YIELD@
+_GL_FUNCDECL_SYS (sched_yield, int, (void));
+#  endif
+_GL_CXXALIAS_SYS (sched_yield, int, (void));
+# endif
+# if __GLIBC__ >= 2
+_GL_CXXALIASWARN (sched_yield);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef sched_yield
+# if HAVE_RAW_DECL_SCHED_YIELD
+_GL_WARN_ON_USE (sched_yield, "sched_yield is not portable - "
+                 "use gnulib module sched_yield for portability");
+# endif
+#endif
+
+#endif /* _@GUARD_PREFIX@_SCHED_H */
+#endif /* _@GUARD_PREFIX@_SCHED_H */
diff --git a/lib/scratch_buffer.h b/lib/scratch_buffer.h
index 88735771d..f4fe5e8d3 100644
--- a/lib/scratch_buffer.h
+++ b/lib/scratch_buffer.h
@@ -1,5 +1,5 @@
 /* Variable-sized buffer with on-stack default allocation.
-   Copyright (C) 2017-2021 Free Software Foundation, Inc.
+   Copyright (C) 2017-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/select.c b/lib/select.c
index eddac4b61..c24249822 100644
--- a/lib/select.c
+++ b/lib/select.c
@@ -1,7 +1,7 @@
 /* Emulation for select(2)
    Contributed by Paolo Bonzini.
 
-   Copyright 2008-2021 Free Software Foundation, Inc.
+   Copyright 2008-2022 Free Software Foundation, Inc.
 
    This file is part of gnulib.
 
diff --git a/lib/send.c b/lib/send.c
index 58cb70b56..5510c0c04 100644
--- a/lib/send.c
+++ b/lib/send.c
@@ -1,6 +1,6 @@
 /* send.c --- wrappers for Windows send function
 
-   Copyright (C) 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2008-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/sendto.c b/lib/sendto.c
index 029ccd69f..01163a633 100644
--- a/lib/sendto.c
+++ b/lib/sendto.c
@@ -1,6 +1,6 @@
 /* sendto.c --- wrappers for Windows sendto function
 
-   Copyright (C) 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2008-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/setenv.c b/lib/setenv.c
index 3ad3477e9..ebfd4e550 100644
--- a/lib/setenv.c
+++ b/lib/setenv.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1995-2003, 2005-2021 Free Software Foundation, Inc.
+/* Copyright (C) 1992, 1995-2003, 2005-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/setlocale-lock.c b/lib/setlocale-lock.c
index 53e231c6c..4e7540e1f 100644
--- a/lib/setlocale-lock.c
+++ b/lib/setlocale-lock.c
@@ -1,5 +1,5 @@
 /* Return the internal lock used by setlocale_null_r.
-   Copyright (C) 2019-2021 Free Software Foundation, Inc.
+   Copyright (C) 2019-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/setlocale_null.c b/lib/setlocale_null.c
index dbfda25c5..778429b94 100644
--- a/lib/setlocale_null.c
+++ b/lib/setlocale_null.c
@@ -1,5 +1,5 @@
 /* Query the name of the current global locale.
-   Copyright (C) 2019-2021 Free Software Foundation, Inc.
+   Copyright (C) 2019-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/setlocale_null.h b/lib/setlocale_null.h
index 00c42e2aa..d1921b09b 100644
--- a/lib/setlocale_null.h
+++ b/lib/setlocale_null.h
@@ -1,5 +1,5 @@
 /* Query the name of the current global locale.
-   Copyright (C) 2019-2021 Free Software Foundation, Inc.
+   Copyright (C) 2019-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/setsockopt.c b/lib/setsockopt.c
index 10b1e9061..2811c19af 100644
--- a/lib/setsockopt.c
+++ b/lib/setsockopt.c
@@ -1,6 +1,6 @@
 /* setsockopt.c --- wrappers for Windows setsockopt function
 
-   Copyright (C) 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2008-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/shutdown.c b/lib/shutdown.c
index 70c927c6a..170d8710e 100644
--- a/lib/shutdown.c
+++ b/lib/shutdown.c
@@ -1,6 +1,6 @@
 /* shutdown.c --- wrappers for Windows shutdown function
 
-   Copyright (C) 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2008-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/signal.in.h b/lib/signal.in.h
index 275da8c81..640b5022f 100644
--- a/lib/signal.in.h
+++ b/lib/signal.in.h
@@ -1,6 +1,6 @@
 /* A GNU-like <signal.h>.
 
-   Copyright (C) 2006-2021 Free Software Foundation, Inc.
+   Copyright (C) 2006-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/signbitd.c b/lib/signbitd.c
index 22597719f..776dd732b 100644
--- a/lib/signbitd.c
+++ b/lib/signbitd.c
@@ -1,5 +1,5 @@
 /* signbit() macro: Determine the sign bit of a floating-point number.
-   Copyright (C) 2007-2021 Free Software Foundation, Inc.
+   Copyright (C) 2007-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/signbitf.c b/lib/signbitf.c
index b196d9ab5..0adf0011a 100644
--- a/lib/signbitf.c
+++ b/lib/signbitf.c
@@ -1,5 +1,5 @@
 /* signbit() macro: Determine the sign bit of a floating-point number.
-   Copyright (C) 2007, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/signbitl.c b/lib/signbitl.c
index f73802d1a..865d27652 100644
--- a/lib/signbitl.c
+++ b/lib/signbitl.c
@@ -1,5 +1,5 @@
 /* signbit() macro: Determine the sign bit of a floating-point number.
-   Copyright (C) 2007, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/size_max.h b/lib/size_max.h
index 1186ba95d..dee2b8eea 100644
--- a/lib/size_max.h
+++ b/lib/size_max.h
@@ -1,5 +1,5 @@
 /* size_max.h -- declare SIZE_MAX through system headers
-   Copyright (C) 2005-2006, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2005-2006, 2009-2022 Free Software Foundation, Inc.
    Written by Simon Josefsson.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/snprintf.c b/lib/snprintf.c
index a589cf1a6..3d87854e9 100644
--- a/lib/snprintf.c
+++ b/lib/snprintf.c
@@ -1,5 +1,5 @@
 /* Formatted output to strings.
-   Copyright (C) 2004, 2006-2021 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2006-2022 Free Software Foundation, Inc.
    Written by Simon Josefsson and Paul Eggert.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/socket.c b/lib/socket.c
index 0f2e6ff91..49e013c7a 100644
--- a/lib/socket.c
+++ b/lib/socket.c
@@ -1,6 +1,6 @@
 /* socket.c --- wrappers for Windows socket function
 
-   Copyright (C) 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2008-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/sockets.c b/lib/sockets.c
index 934da73d2..31b430296 100644
--- a/lib/sockets.c
+++ b/lib/sockets.c
@@ -1,6 +1,6 @@
 /* sockets.c --- wrappers for Windows socket functions
 
-   Copyright (C) 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2008-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
@@ -113,7 +113,7 @@ static int initialized_sockets_version /* = 0 */;
 #endif /* WINDOWS_SOCKETS */
 
 int
-gl_sockets_startup (int version _GL_UNUSED)
+gl_sockets_startup (_GL_UNUSED int version)
 {
 #if WINDOWS_SOCKETS
   if (version > initialized_sockets_version)
diff --git a/lib/sockets.h b/lib/sockets.h
index e70c2bbfd..75e49fce0 100644
--- a/lib/sockets.h
+++ b/lib/sockets.h
@@ -1,6 +1,6 @@
 /* sockets.h - wrappers for Windows socket functions
 
-   Copyright (C) 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2008-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/spawn.c b/lib/spawn.c
new file mode 100644
index 000000000..bb2308dfc
--- /dev/null
+++ b/lib/spawn.c
@@ -0,0 +1,34 @@
+/* Copyright (C) 2000, 2009-2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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 2.1 of the
+   License, or (at your option) any later version.
+
+   This file 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include <spawn.h>
+
+#include "spawn_int.h"
+
+/* Spawn a new process executing PATH with the attributes describes in *ATTRP.
+   Before running the process perform the actions described in FILE-ACTIONS. */
+int
+posix_spawn (pid_t *pid, const char *path,
+             const posix_spawn_file_actions_t *file_actions,
+             const posix_spawnattr_t *attrp, char *const argv[],
+             char *const envp[])
+{
+  return __spawni (pid, path, file_actions, attrp,
+                   (const char * const *) argv, (const char * const *) envp, 0);
+}
diff --git a/lib/spawn.h b/lib/spawn.h
new file mode 100644
index 000000000..c0757d3e4
--- /dev/null
+++ b/lib/spawn.h
@@ -0,0 +1,1499 @@
+/* DO NOT EDIT! GENERATED AUTOMATICALLY! */
+/* Definitions for POSIX spawn interface.
+   Copyright (C) 2000, 2003-2004, 2008-2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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 2.1 of the
+   License, or (at your option) any later version.
+
+   This file 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+#if __GNUC__ >= 3
+#pragma GCC system_header
+#endif
+
+
+#if defined _GL_ALREADY_INCLUDING_SPAWN_H
+/* Special invocation convention:
+   On OS/2 kLIBC, <spawn.h> includes <signal.h>. Then <signal.h> ->
+   <pthread.h> -> <sched.h> -> <spawn.h> are included by GNULIB.
+   In this situation, struct sched_param is not yet defined.  */
+
+#include_next <spawn.h>
+
+#else
+
+#ifndef _GL_SPAWN_H
+/* Normal invocation convention.  */
+
+/* The include_next requires a split double-inclusion guard.  */
+#if 1
+
+# define _GL_ALREADY_INCLUDING_SPAWN_H
+
+# include_next <spawn.h>
+
+# define _GL_ALREADY_INCLUDING_SPAWN_H
+
+#endif
+
+#ifndef _GL_SPAWN_H
+#define _GL_SPAWN_H
+
+/* Get definitions of 'struct sched_param' and 'sigset_t'.
+   But avoid namespace pollution on glibc systems.  */
+#if !(defined __GLIBC__ && !defined __UCLIBC__)
+# include <sched.h>
+# include <signal.h>
+#endif
+
+#include <sys/types.h>
+
+#ifndef __THROW
+# define __THROW
+#endif
+
+/* For plain 'restrict', use glibc's __restrict if defined.
+   Otherwise, GCC 2.95 and later have "__restrict"; C99 compilers have
+   "restrict", and "configure" may have defined "restrict".
+   Other compilers use __restrict, __restrict__, and _Restrict, and
+   'configure' might #define 'restrict' to those words, so pick a
+   different name.  */
+#ifndef _Restrict_
+# if defined __restrict \
+     || 2 < __GNUC__ + (95 <= __GNUC_MINOR__) \
+     || __clang_major__ >= 3
+#  define _Restrict_ __restrict
+# elif 199901L <= __STDC_VERSION__ || defined restrict
+#  define _Restrict_ restrict
+# else
+#  define _Restrict_
+# endif
+#endif
+/* For the ISO C99 syntax
+     array_name[restrict]
+   use glibc's __restrict_arr if available.
+   Otherwise, GCC 3.1 and clang support this syntax (but not in C++ mode).
+   Other ISO C99 compilers support it as well.  */
+#ifndef _Restrict_arr_
+# ifdef __restrict_arr
+#  define _Restrict_arr_ __restrict_arr
+# elif ((199901L <= __STDC_VERSION__ \
+         || 3 < __GNUC__ + (1 <= __GNUC_MINOR__) \
+         || __clang_major__ >= 3) \
+        && !defined __cplusplus)
+#  define _Restrict_arr_ _Restrict_
+# else
+#  define _Restrict_arr_
+# endif
+#endif
+
+/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */
+/* C++ compatible function declaration macros.
+   Copyright (C) 2010-2022 Free Software Foundation, Inc.
+
+   This program 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 2 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+#ifndef _GL_CXXDEFS_H
+#define _GL_CXXDEFS_H
+
+/* Begin/end the GNULIB_NAMESPACE namespace.  */
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+# define _GL_BEGIN_NAMESPACE namespace GNULIB_NAMESPACE {
+# define _GL_END_NAMESPACE }
+#else
+# define _GL_BEGIN_NAMESPACE
+# define _GL_END_NAMESPACE
+#endif
+
+/* The three most frequent use cases of these macros are:
+
+   * For providing a substitute for a function that is missing on some
+     platforms, but is declared and works fine on the platforms on which
+     it exists:
+
+       #if @GNULIB_FOO@
+       # if !@HAVE_FOO@
+       _GL_FUNCDECL_SYS (foo, ...);
+       # endif
+       _GL_CXXALIAS_SYS (foo, ...);
+       _GL_CXXALIASWARN (foo);
+       #elif defined GNULIB_POSIXCHECK
+       ...
+       #endif
+
+   * For providing a replacement for a function that exists on all platforms,
+     but is broken/insufficient and needs to be replaced on some platforms:
+
+       #if @GNULIB_FOO@
+       # if @REPLACE_FOO@
+       #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+       #   undef foo
+       #   define foo rpl_foo
+       #  endif
+       _GL_FUNCDECL_RPL (foo, ...);
+       _GL_CXXALIAS_RPL (foo, ...);
+       # else
+       _GL_CXXALIAS_SYS (foo, ...);
+       # endif
+       _GL_CXXALIASWARN (foo);
+       #elif defined GNULIB_POSIXCHECK
+       ...
+       #endif
+
+   * For providing a replacement for a function that exists on some platforms
+     but is broken/insufficient and needs to be replaced on some of them and
+     is additionally either missing or undeclared on some other platforms:
+
+       #if @GNULIB_FOO@
+       # if @REPLACE_FOO@
+       #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+       #   undef foo
+       #   define foo rpl_foo
+       #  endif
+       _GL_FUNCDECL_RPL (foo, ...);
+       _GL_CXXALIAS_RPL (foo, ...);
+       # else
+       #  if !@HAVE_FOO@   or   if !@HAVE_DECL_FOO@
+       _GL_FUNCDECL_SYS (foo, ...);
+       #  endif
+       _GL_CXXALIAS_SYS (foo, ...);
+       # endif
+       _GL_CXXALIASWARN (foo);
+       #elif defined GNULIB_POSIXCHECK
+       ...
+       #endif
+*/
+
+/* _GL_EXTERN_C declaration;
+   performs the declaration with C linkage.  */
+#if defined __cplusplus
+# define _GL_EXTERN_C extern "C"
+#else
+# define _GL_EXTERN_C extern
+#endif
+
+/* _GL_FUNCDECL_RPL (func, rettype, parameters_and_attributes);
+   declares a replacement function, named rpl_func, with the given prototype,
+   consisting of return type, parameters, and attributes.
+   Example:
+     _GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...)
+                                  _GL_ARG_NONNULL ((1)));
+ */
+#define _GL_FUNCDECL_RPL(func,rettype,parameters_and_attributes) \
+  _GL_FUNCDECL_RPL_1 (rpl_##func, rettype, parameters_and_attributes)
+#define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters_and_attributes) \
+  _GL_EXTERN_C rettype rpl_func parameters_and_attributes
+
+/* _GL_FUNCDECL_SYS (func, rettype, parameters_and_attributes);
+   declares the system function, named func, with the given prototype,
+   consisting of return type, parameters, and attributes.
+   Example:
+     _GL_FUNCDECL_SYS (open, int, (const char *filename, int flags, ...)
+                                  _GL_ARG_NONNULL ((1)));
+ */
+#define _GL_FUNCDECL_SYS(func,rettype,parameters_and_attributes) \
+  _GL_EXTERN_C rettype func parameters_and_attributes
+
+/* _GL_CXXALIAS_RPL (func, rettype, parameters);
+   declares a C++ alias called GNULIB_NAMESPACE::func
+   that redirects to rpl_func, if GNULIB_NAMESPACE is defined.
+   Example:
+     _GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...));
+
+   Wrapping rpl_func in an object with an inline conversion operator
+   avoids a reference to rpl_func unless GNULIB_NAMESPACE::func is
+   actually used in the program.  */
+#define _GL_CXXALIAS_RPL(func,rettype,parameters) \
+  _GL_CXXALIAS_RPL_1 (func, rpl_##func, rettype, parameters)
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \
+    namespace GNULIB_NAMESPACE                                \
+    {                                                         \
+      static const struct _gl_ ## func ## _wrapper            \
+      {                                                       \
+        typedef rettype (*type) parameters;                   \
+                                                              \
+        inline operator type () const                         \
+        {                                                     \
+          return ::rpl_func;                                  \
+        }                                                     \
+      } func = {};                                            \
+    }                                                         \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#else
+# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#endif
+
+/* _GL_CXXALIAS_MDA (func, rettype, parameters);
+   is to be used when func is a Microsoft deprecated alias, on native Windows.
+   It declares a C++ alias called GNULIB_NAMESPACE::func
+   that redirects to _func, if GNULIB_NAMESPACE is defined.
+   Example:
+     _GL_CXXALIAS_MDA (open, int, (const char *filename, int flags, ...));
+ */
+#define _GL_CXXALIAS_MDA(func,rettype,parameters) \
+  _GL_CXXALIAS_RPL_1 (func, _##func, rettype, parameters)
+
+/* _GL_CXXALIAS_RPL_CAST_1 (func, rpl_func, rettype, parameters);
+   is like  _GL_CXXALIAS_RPL_1 (func, rpl_func, rettype, parameters);
+   except that the C function rpl_func may have a slightly different
+   declaration.  A cast is used to silence the "invalid conversion" error
+   that would otherwise occur.  */
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \
+    namespace GNULIB_NAMESPACE                                     \
+    {                                                              \
+      static const struct _gl_ ## func ## _wrapper                 \
+      {                                                            \
+        typedef rettype (*type) parameters;                        \
+                                                                   \
+        inline operator type () const                              \
+        {                                                          \
+          return reinterpret_cast<type>(::rpl_func);               \
+        }                                                          \
+      } func = {};                                                 \
+    }                                                              \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#else
+# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#endif
+
+/* _GL_CXXALIAS_MDA_CAST (func, rettype, parameters);
+   is like  _GL_CXXALIAS_MDA (func, rettype, parameters);
+   except that the C function func may have a slightly different declaration.
+   A cast is used to silence the "invalid conversion" error that would
+   otherwise occur.  */
+#define _GL_CXXALIAS_MDA_CAST(func,rettype,parameters) \
+  _GL_CXXALIAS_RPL_CAST_1 (func, _##func, rettype, parameters)
+
+/* _GL_CXXALIAS_SYS (func, rettype, parameters);
+   declares a C++ alias called GNULIB_NAMESPACE::func
+   that redirects to the system provided function func, if GNULIB_NAMESPACE
+   is defined.
+   Example:
+     _GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...));
+
+   Wrapping func in an object with an inline conversion operator
+   avoids a reference to func unless GNULIB_NAMESPACE::func is
+   actually used in the program.  */
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+# define _GL_CXXALIAS_SYS(func,rettype,parameters)            \
+    namespace GNULIB_NAMESPACE                                \
+    {                                                         \
+      static const struct _gl_ ## func ## _wrapper            \
+      {                                                       \
+        typedef rettype (*type) parameters;                   \
+                                                              \
+        inline operator type () const                         \
+        {                                                     \
+          return ::func;                                      \
+        }                                                     \
+      } func = {};                                            \
+    }                                                         \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#else
+# define _GL_CXXALIAS_SYS(func,rettype,parameters) \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#endif
+
+/* _GL_CXXALIAS_SYS_CAST (func, rettype, parameters);
+   is like  _GL_CXXALIAS_SYS (func, rettype, parameters);
+   except that the C function func may have a slightly different declaration.
+   A cast is used to silence the "invalid conversion" error that would
+   otherwise occur.  */
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \
+    namespace GNULIB_NAMESPACE                          \
+    {                                                   \
+      static const struct _gl_ ## func ## _wrapper      \
+      {                                                 \
+        typedef rettype (*type) parameters;             \
+                                                        \
+        inline operator type () const                   \
+        {                                               \
+          return reinterpret_cast<type>(::func);        \
+        }                                               \
+      } func = {};                                      \
+    }                                                   \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#else
+# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#endif
+
+/* _GL_CXXALIAS_SYS_CAST2 (func, rettype, parameters, rettype2, parameters2);
+   is like  _GL_CXXALIAS_SYS (func, rettype, parameters);
+   except that the C function is picked among a set of overloaded functions,
+   namely the one with rettype2 and parameters2.  Two consecutive casts
+   are used to silence the "cannot find a match" and "invalid conversion"
+   errors that would otherwise occur.  */
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+  /* The outer cast must be a reinterpret_cast.
+     The inner cast: When the function is defined as a set of overloaded
+     functions, it works as a static_cast<>, choosing the designated variant.
+     When the function is defined as a single variant, it works as a
+     reinterpret_cast<>. The parenthesized cast syntax works both ways.  */
+# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \
+    namespace GNULIB_NAMESPACE                                                \
+    {                                                                         \
+      static const struct _gl_ ## func ## _wrapper                            \
+      {                                                                       \
+        typedef rettype (*type) parameters;                                   \
+                                                                              \
+        inline operator type () const                                         \
+        {                                                                     \
+          return reinterpret_cast<type>((rettype2 (*) parameters2)(::func));  \
+        }                                                                     \
+      } func = {};                                                            \
+    }                                                                         \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#else
+# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#endif
+
+/* _GL_CXXALIASWARN (func);
+   causes a warning to be emitted when ::func is used but not when
+   GNULIB_NAMESPACE::func is used.  func must be defined without overloaded
+   variants.  */
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+# define _GL_CXXALIASWARN(func) \
+   _GL_CXXALIASWARN_1 (func, GNULIB_NAMESPACE)
+# define _GL_CXXALIASWARN_1(func,namespace) \
+   _GL_CXXALIASWARN_2 (func, namespace)
+/* To work around GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,
+   we enable the warning only when not optimizing.  */
+# if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__)
+#  define _GL_CXXALIASWARN_2(func,namespace) \
+    _GL_WARN_ON_USE (func, \
+                     "The symbol ::" #func " refers to the system function. " \
+                     "Use " #namespace "::" #func " instead.")
+# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
+#  define _GL_CXXALIASWARN_2(func,namespace) \
+     extern __typeof__ (func) func
+# else
+#  define _GL_CXXALIASWARN_2(func,namespace) \
+     _GL_EXTERN_C int _gl_cxxalias_dummy
+# endif
+#else
+# define _GL_CXXALIASWARN(func) \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#endif
+
+/* _GL_CXXALIASWARN1 (func, rettype, parameters_and_attributes);
+   causes a warning to be emitted when the given overloaded variant of ::func
+   is used but not when GNULIB_NAMESPACE::func is used.  */
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \
+   _GL_CXXALIASWARN1_1 (func, rettype, parameters_and_attributes, \
+                        GNULIB_NAMESPACE)
+# define _GL_CXXALIASWARN1_1(func,rettype,parameters_and_attributes,namespace) \
+   _GL_CXXALIASWARN1_2 (func, rettype, parameters_and_attributes, namespace)
+/* To work around GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,
+   we enable the warning only when not optimizing.  */
+# if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__)
+#  define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
+    _GL_WARN_ON_USE_CXX (func, rettype, rettype, parameters_and_attributes, \
+                         "The symbol ::" #func " refers to the system function. " \
+                         "Use " #namespace "::" #func " instead.")
+# else
+#  define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
+     _GL_EXTERN_C int _gl_cxxalias_dummy
+# endif
+#else
+# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#endif
+
+#endif /* _GL_CXXDEFS_H */
+
+/* The definition of _GL_ARG_NONNULL is copied here.  */
+/* A C macro for declaring that specific arguments must not be NULL.
+   Copyright (C) 2009-2022 Free Software Foundation, Inc.
+
+   This program 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 2 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+/* _GL_ARG_NONNULL((n,...,m)) tells the compiler and static analyzer tools
+   that the values passed as arguments n, ..., m must be non-NULL pointers.
+   n = 1 stands for the first argument, n = 2 for the second argument etc.  */
+#ifndef _GL_ARG_NONNULL
+# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || defined __clang__
+#  define _GL_ARG_NONNULL(params) __attribute__ ((__nonnull__ params))
+# else
+#  define _GL_ARG_NONNULL(params)
+# endif
+#endif
+
+/* The definition of _GL_WARN_ON_USE is copied here.  */
+/* A C macro for emitting warnings if a function is used.
+   Copyright (C) 2010-2022 Free Software Foundation, Inc.
+
+   This program 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 2 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+/* _GL_WARN_ON_USE (function, "literal string") issues a declaration
+   for FUNCTION which will then trigger a compiler warning containing
+   the text of "literal string" anywhere that function is called, if
+   supported by the compiler.  If the compiler does not support this
+   feature, the macro expands to an unused extern declaration.
+
+   _GL_WARN_ON_USE_ATTRIBUTE ("literal string") expands to the
+   attribute used in _GL_WARN_ON_USE.  If the compiler does not support
+   this feature, it expands to empty.
+
+   These macros are useful for marking a function as a potential
+   portability trap, with the intent that "literal string" include
+   instructions on the replacement function that should be used
+   instead.
+   _GL_WARN_ON_USE is for functions with 'extern' linkage.
+   _GL_WARN_ON_USE_ATTRIBUTE is for functions with 'static' or 'inline'
+   linkage.
+
+   However, one of the reasons that a function is a portability trap is
+   if it has the wrong signature.  Declaring FUNCTION with a different
+   signature in C is a compilation error, so this macro must use the
+   same type as any existing declaration so that programs that avoid
+   the problematic FUNCTION do not fail to compile merely because they
+   included a header that poisoned the function.  But this implies that
+   _GL_WARN_ON_USE is only safe to use if FUNCTION is known to already
+   have a declaration.  Use of this macro implies that there must not
+   be any other macro hiding the declaration of FUNCTION; but
+   undefining FUNCTION first is part of the poisoning process anyway
+   (although for symbols that are provided only via a macro, the result
+   is a compilation error rather than a warning containing
+   "literal string").  Also note that in C++, it is only safe to use if
+   FUNCTION has no overloads.
+
+   For an example, it is possible to poison 'getline' by:
+   - adding a call to gl_WARN_ON_USE_PREPARE([[#include <stdio.h>]],
+     [getline]) in configure.ac, which potentially defines
+     HAVE_RAW_DECL_GETLINE
+   - adding this code to a header that wraps the system <stdio.h>:
+     #undef getline
+     #if HAVE_RAW_DECL_GETLINE
+     _GL_WARN_ON_USE (getline, "getline is required by POSIX 2008, but"
+       "not universally present; use the gnulib module getline");
+     #endif
+
+   It is not possible to directly poison global variables.  But it is
+   possible to write a wrapper accessor function, and poison that
+   (less common usage, like &environ, will cause a compilation error
+   rather than issue the nice warning, but the end result of informing
+   the developer about their portability problem is still achieved):
+     #if HAVE_RAW_DECL_ENVIRON
+     static char ***
+     rpl_environ (void) { return &environ; }
+     _GL_WARN_ON_USE (rpl_environ, "environ is not always properly declared");
+     # undef environ
+     # define environ (*rpl_environ ())
+     #endif
+   or better (avoiding contradictory use of 'static' and 'extern'):
+     #if HAVE_RAW_DECL_ENVIRON
+     static char ***
+     _GL_WARN_ON_USE_ATTRIBUTE ("environ is not always properly declared")
+     rpl_environ (void) { return &environ; }
+     # undef environ
+     # define environ (*rpl_environ ())
+     #endif
+   */
+#ifndef _GL_WARN_ON_USE
+
+# if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)
+/* A compiler attribute is available in gcc versions 4.3.0 and later.  */
+#  define _GL_WARN_ON_USE(function, message) \
+_GL_WARN_EXTERN_C __typeof__ (function) function __attribute__ ((__warning__ (message)))
+#  define _GL_WARN_ON_USE_ATTRIBUTE(message) \
+  __attribute__ ((__warning__ (message)))
+# elif __clang_major__ >= 4
+/* Another compiler attribute is available in clang.  */
+#  define _GL_WARN_ON_USE(function, message) \
+_GL_WARN_EXTERN_C __typeof__ (function) function \
+  __attribute__ ((__diagnose_if__ (1, message, "warning")))
+#  define _GL_WARN_ON_USE_ATTRIBUTE(message) \
+  __attribute__ ((__diagnose_if__ (1, message, "warning")))
+# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
+/* Verify the existence of the function.  */
+#  define _GL_WARN_ON_USE(function, message) \
+_GL_WARN_EXTERN_C __typeof__ (function) function
+#  define _GL_WARN_ON_USE_ATTRIBUTE(message)
+# else /* Unsupported.  */
+#  define _GL_WARN_ON_USE(function, message) \
+_GL_WARN_EXTERN_C int _gl_warn_on_use
+#  define _GL_WARN_ON_USE_ATTRIBUTE(message)
+# endif
+#endif
+
+/* _GL_WARN_ON_USE_CXX (function, rettype_gcc, rettype_clang, parameters_and_attributes, "message")
+   is like _GL_WARN_ON_USE (function, "message"), except that in C++ mode the
+   function is declared with the given prototype, consisting of return type,
+   parameters, and attributes.
+   This variant is useful for overloaded functions in C++. _GL_WARN_ON_USE does
+   not work in this case.  */
+#ifndef _GL_WARN_ON_USE_CXX
+# if !defined __cplusplus
+#  define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \
+     _GL_WARN_ON_USE (function, msg)
+# else
+#  if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)
+/* A compiler attribute is available in gcc versions 4.3.0 and later.  */
+#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \
+extern rettype_gcc function parameters_and_attributes \
+  __attribute__ ((__warning__ (msg)))
+#  elif __clang_major__ >= 4
+/* Another compiler attribute is available in clang.  */
+#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \
+extern rettype_clang function parameters_and_attributes \
+  __attribute__ ((__diagnose_if__ (1, msg, "warning")))
+#  elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
+/* Verify the existence of the function.  */
+#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \
+extern rettype_gcc function parameters_and_attributes
+#  else /* Unsupported.  */
+#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \
+_GL_WARN_EXTERN_C int _gl_warn_on_use
+#  endif
+# endif
+#endif
+
+/* _GL_WARN_EXTERN_C declaration;
+   performs the declaration with C linkage.  */
+#ifndef _GL_WARN_EXTERN_C
+# if defined __cplusplus
+#  define _GL_WARN_EXTERN_C extern "C"
+# else
+#  define _GL_WARN_EXTERN_C extern
+# endif
+#endif
+
+
+/* Data structure to contain attributes for thread creation.  */
+#if 0 || (1 && !1)
+# define posix_spawnattr_t rpl_posix_spawnattr_t
+#endif
+#if 0 || !1 || !1
+# if !GNULIB_defined_posix_spawnattr_t
+typedef struct
+{
+  short int _flags;
+  pid_t _pgrp;
+  sigset_t _sd;
+  sigset_t _ss;
+  struct sched_param _sp;
+  int _policy;
+  int __pad[16];
+} posix_spawnattr_t;
+#  define GNULIB_defined_posix_spawnattr_t 1
+# endif
+#endif
+
+
+/* Data structure to contain information about the actions to be
+   performed in the new process with respect to file descriptors.  */
+#if 0 || (1 && !1)
+# define posix_spawn_file_actions_t rpl_posix_spawn_file_actions_t
+#endif
+#if 0 || !1 || !1
+# if !GNULIB_defined_posix_spawn_file_actions_t
+typedef struct
+{
+  int _allocated;
+  int _used;
+  struct __spawn_action *_actions;
+  int __pad[16];
+} posix_spawn_file_actions_t;
+#  define GNULIB_defined_posix_spawn_file_actions_t 1
+# endif
+#endif
+
+
+/* Flags to be set in the 'posix_spawnattr_t'.  */
+#if 1
+/* Use the values from the system, but provide the missing ones.  */
+# ifndef POSIX_SPAWN_SETSCHEDPARAM
+#  define POSIX_SPAWN_SETSCHEDPARAM 0
+# endif
+# ifndef POSIX_SPAWN_SETSCHEDULER
+#  define POSIX_SPAWN_SETSCHEDULER 0
+# endif
+#else
+# if 0
+/* Use the values from the system, for better compatibility.  */
+/* But this implementation does not support AIX extensions.  */
+#  undef POSIX_SPAWN_FORK_HANDLERS
+# else
+#  define POSIX_SPAWN_RESETIDS           0x01
+#  define POSIX_SPAWN_SETPGROUP          0x02
+#  define POSIX_SPAWN_SETSIGDEF          0x04
+#  define POSIX_SPAWN_SETSIGMASK         0x08
+#  define POSIX_SPAWN_SETSCHEDPARAM      0x10
+#  define POSIX_SPAWN_SETSCHEDULER       0x20
+# endif
+#endif
+/* A GNU extension.  Use the next free bit position.  */
+#ifndef POSIX_SPAWN_USEVFORK
+# define POSIX_SPAWN_USEVFORK \
+  ((POSIX_SPAWN_RESETIDS | (POSIX_SPAWN_RESETIDS - 1)                     \
+    | POSIX_SPAWN_SETPGROUP | (POSIX_SPAWN_SETPGROUP - 1)                 \
+    | POSIX_SPAWN_SETSIGDEF | (POSIX_SPAWN_SETSIGDEF - 1)                 \
+    | POSIX_SPAWN_SETSIGMASK | (POSIX_SPAWN_SETSIGMASK - 1)               \
+    | POSIX_SPAWN_SETSCHEDPARAM                                           \
+    | (POSIX_SPAWN_SETSCHEDPARAM > 0 ? POSIX_SPAWN_SETSCHEDPARAM - 1 : 0) \
+    | POSIX_SPAWN_SETSCHEDULER                                            \
+    | (POSIX_SPAWN_SETSCHEDULER > 0 ? POSIX_SPAWN_SETSCHEDULER - 1 : 0))  \
+   + 1)
+#endif
+#if !GNULIB_defined_verify_POSIX_SPAWN_USEVFORK_no_overlap
+typedef int verify_POSIX_SPAWN_USEVFORK_no_overlap
+            [(((POSIX_SPAWN_RESETIDS | POSIX_SPAWN_SETPGROUP
+                | POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK
+                | POSIX_SPAWN_SETSCHEDPARAM | POSIX_SPAWN_SETSCHEDULER)
+               & POSIX_SPAWN_USEVFORK)
+              == 0)
+             ? 1 : -1];
+# define GNULIB_defined_verify_POSIX_SPAWN_USEVFORK_no_overlap 1
+#endif
+
+
+#if 0
+/* Spawn a new process executing PATH with the attributes describes in *ATTRP.
+   Before running the process perform the actions described in FILE-ACTIONS.
+
+   This function is a possible cancellation points and therefore not
+   marked with __THROW. */
+# if 0
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawn rpl_posix_spawn
+#  endif
+_GL_FUNCDECL_RPL (posix_spawn, int,
+                  (pid_t *_Restrict_ __pid,
+                   const char *_Restrict_ __path,
+                   const posix_spawn_file_actions_t *_Restrict_ __file_actions,
+                   const posix_spawnattr_t *_Restrict_ __attrp,
+                   char *const argv[_Restrict_arr_],
+                   char *const envp[_Restrict_arr_])
+                  _GL_ARG_NONNULL ((2, 5, 6)));
+_GL_CXXALIAS_RPL (posix_spawn, int,
+                  (pid_t *_Restrict_ __pid,
+                   const char *_Restrict_ __path,
+                   const posix_spawn_file_actions_t *_Restrict_ __file_actions,
+                   const posix_spawnattr_t *_Restrict_ __attrp,
+                   char *const argv[_Restrict_arr_],
+                   char *const envp[_Restrict_arr_]));
+# else
+#  if !1
+_GL_FUNCDECL_SYS (posix_spawn, int,
+                  (pid_t *_Restrict_ __pid,
+                   const char *_Restrict_ __path,
+                   const posix_spawn_file_actions_t *_Restrict_ __file_actions,
+                   const posix_spawnattr_t *_Restrict_ __attrp,
+                   char *const argv[_Restrict_arr_],
+                   char *const envp[_Restrict_arr_])
+                  _GL_ARG_NONNULL ((2, 5, 6)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawn, int,
+                  (pid_t *_Restrict_ __pid,
+                   const char *_Restrict_ __path,
+                   const posix_spawn_file_actions_t *_Restrict_ __file_actions,
+                   const posix_spawnattr_t *_Restrict_ __attrp,
+                   char *const argv[_Restrict_arr_],
+                   char *const envp[_Restrict_arr_]));
+# endif
+_GL_CXXALIASWARN (posix_spawn);
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawn
+# if HAVE_RAW_DECL_POSIX_SPAWN
+_GL_WARN_ON_USE (posix_spawn, "posix_spawn is unportable - "
+                 "use gnulib module posix_spawn for portability");
+# endif
+#endif
+
+#if 1
+/* Similar to 'posix_spawn' but search for FILE in the PATH.
+
+   This function is a possible cancellation points and therefore not
+   marked with __THROW.  */
+# if 0
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawnp rpl_posix_spawnp
+#  endif
+_GL_FUNCDECL_RPL (posix_spawnp, int,
+                  (pid_t *__pid, const char *__file,
+                   const posix_spawn_file_actions_t *__file_actions,
+                   const posix_spawnattr_t *__attrp,
+                   char *const argv[], char *const envp[])
+                  _GL_ARG_NONNULL ((2, 5, 6)));
+_GL_CXXALIAS_RPL (posix_spawnp, int,
+                  (pid_t *__pid, const char *__file,
+                   const posix_spawn_file_actions_t *__file_actions,
+                   const posix_spawnattr_t *__attrp,
+                   char *const argv[], char *const envp[]));
+# else
+#  if !1
+_GL_FUNCDECL_SYS (posix_spawnp, int,
+                  (pid_t *__pid, const char *__file,
+                   const posix_spawn_file_actions_t *__file_actions,
+                   const posix_spawnattr_t *__attrp,
+                   char *const argv[], char *const envp[])
+                  _GL_ARG_NONNULL ((2, 5, 6)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawnp, int,
+                  (pid_t *__pid, const char *__file,
+                   const posix_spawn_file_actions_t *__file_actions,
+                   const posix_spawnattr_t *__attrp,
+                   char *const argv[], char *const envp[]));
+# endif
+_GL_CXXALIASWARN (posix_spawnp);
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawnp
+# if HAVE_RAW_DECL_POSIX_SPAWNP
+_GL_WARN_ON_USE (posix_spawnp, "posix_spawnp is unportable - "
+                 "use gnulib module posix_spawnp for portability");
+# endif
+#endif
+
+
+#if 0
+/* Initialize data structure with attributes for 'spawn' to default values.  */
+# if 0
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawnattr_init rpl_posix_spawnattr_init
+#  endif
+_GL_FUNCDECL_RPL (posix_spawnattr_init, int, (posix_spawnattr_t *__attr)
+                                             __THROW _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (posix_spawnattr_init, int, (posix_spawnattr_t *__attr));
+# else
+#  if !1
+_GL_FUNCDECL_SYS (posix_spawnattr_init, int, (posix_spawnattr_t *__attr)
+                                             __THROW _GL_ARG_NONNULL ((1)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawnattr_init, int, (posix_spawnattr_t *__attr));
+# endif
+_GL_CXXALIASWARN (posix_spawnattr_init);
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawnattr_init
+# if HAVE_RAW_DECL_POSIX_SPAWNATTR_INIT
+_GL_WARN_ON_USE (posix_spawnattr_init, "posix_spawnattr_init is unportable - "
+                 "use gnulib module posix_spawnattr_init for portability");
+# endif
+#endif
+
+#if 0
+/* Free resources associated with ATTR.  */
+# if 0
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawnattr_destroy rpl_posix_spawnattr_destroy
+#  endif
+_GL_FUNCDECL_RPL (posix_spawnattr_destroy, int, (posix_spawnattr_t *__attr)
+                                                __THROW _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (posix_spawnattr_destroy, int, (posix_spawnattr_t *__attr));
+# else
+#  if !1
+_GL_FUNCDECL_SYS (posix_spawnattr_destroy, int, (posix_spawnattr_t *__attr)
+                                                __THROW _GL_ARG_NONNULL ((1)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawnattr_destroy, int, (posix_spawnattr_t *__attr));
+# endif
+_GL_CXXALIASWARN (posix_spawnattr_destroy);
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawnattr_destroy
+# if HAVE_RAW_DECL_POSIX_SPAWNATTR_DESTROY
+_GL_WARN_ON_USE (posix_spawnattr_destroy,
+                 "posix_spawnattr_destroy is unportable - "
+                 "use gnulib module posix_spawnattr_destroy for portability");
+# endif
+#endif
+
+#if 0
+/* Store signal mask for signals with default handling from ATTR in
+   SIGDEFAULT.  */
+# if 0
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawnattr_getsigdefault rpl_posix_spawnattr_getsigdefault
+#  endif
+_GL_FUNCDECL_RPL (posix_spawnattr_getsigdefault, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   sigset_t *_Restrict_ __sigdefault)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (posix_spawnattr_getsigdefault, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   sigset_t *_Restrict_ __sigdefault));
+# else
+#  if !1
+_GL_FUNCDECL_SYS (posix_spawnattr_getsigdefault, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   sigset_t *_Restrict_ __sigdefault)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawnattr_getsigdefault, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   sigset_t *_Restrict_ __sigdefault));
+# endif
+_GL_CXXALIASWARN (posix_spawnattr_getsigdefault);
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawnattr_getsigdefault
+# if HAVE_RAW_DECL_POSIX_SPAWNATTR_GETSIGDEFAULT
+_GL_WARN_ON_USE (posix_spawnattr_getsigdefault,
+                 "posix_spawnattr_getsigdefault is unportable - "
+                 "use gnulib module posix_spawnattr_getsigdefault for portability");
+# endif
+#endif
+
+#if 0
+/* Set signal mask for signals with default handling in ATTR to SIGDEFAULT.  */
+# if 0
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawnattr_setsigdefault rpl_posix_spawnattr_setsigdefault
+#  endif
+_GL_FUNCDECL_RPL (posix_spawnattr_setsigdefault, int,
+                  (posix_spawnattr_t *_Restrict_ __attr,
+                   const sigset_t *_Restrict_ __sigdefault)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (posix_spawnattr_setsigdefault, int,
+                  (posix_spawnattr_t *_Restrict_ __attr,
+                   const sigset_t *_Restrict_ __sigdefault));
+# else
+#  if !1
+_GL_FUNCDECL_SYS (posix_spawnattr_setsigdefault, int,
+                  (posix_spawnattr_t *_Restrict_ __attr,
+                   const sigset_t *_Restrict_ __sigdefault)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawnattr_setsigdefault, int,
+                  (posix_spawnattr_t *_Restrict_ __attr,
+                   const sigset_t *_Restrict_ __sigdefault));
+# endif
+_GL_CXXALIASWARN (posix_spawnattr_setsigdefault);
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawnattr_setsigdefault
+# if HAVE_RAW_DECL_POSIX_SPAWNATTR_SETSIGDEFAULT
+_GL_WARN_ON_USE (posix_spawnattr_setsigdefault,
+                 "posix_spawnattr_setsigdefault is unportable - "
+                 "use gnulib module posix_spawnattr_setsigdefault for portability");
+# endif
+#endif
+
+#if 0
+/* Store signal mask for the new process from ATTR in SIGMASK.  */
+# if 0
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawnattr_getsigmask rpl_posix_spawnattr_getsigmask
+#  endif
+_GL_FUNCDECL_RPL (posix_spawnattr_getsigmask, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   sigset_t *_Restrict_ __sigmask)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (posix_spawnattr_getsigmask, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   sigset_t *_Restrict_ __sigmask));
+# else
+#  if !1
+_GL_FUNCDECL_SYS (posix_spawnattr_getsigmask, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   sigset_t *_Restrict_ __sigmask)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawnattr_getsigmask, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   sigset_t *_Restrict_ __sigmask));
+# endif
+_GL_CXXALIASWARN (posix_spawnattr_getsigmask);
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawnattr_getsigmask
+# if HAVE_RAW_DECL_POSIX_SPAWNATTR_GETSIGMASK
+_GL_WARN_ON_USE (posix_spawnattr_getsigmask,
+                 "posix_spawnattr_getsigmask is unportable - "
+                 "use gnulib module posix_spawnattr_getsigmask for portability");
+# endif
+#endif
+
+#if 0
+/* Set signal mask for the new process in ATTR to SIGMASK.  */
+# if 0
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawnattr_setsigmask rpl_posix_spawnattr_setsigmask
+#  endif
+_GL_FUNCDECL_RPL (posix_spawnattr_setsigmask, int,
+                  (posix_spawnattr_t *_Restrict_ __attr,
+                   const sigset_t *_Restrict_ __sigmask)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (posix_spawnattr_setsigmask, int,
+                  (posix_spawnattr_t *_Restrict_ __attr,
+                   const sigset_t *_Restrict_ __sigmask));
+# else
+#  if !1
+_GL_FUNCDECL_SYS (posix_spawnattr_setsigmask, int,
+                  (posix_spawnattr_t *_Restrict_ __attr,
+                   const sigset_t *_Restrict_ __sigmask)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawnattr_setsigmask, int,
+                  (posix_spawnattr_t *_Restrict_ __attr,
+                   const sigset_t *_Restrict_ __sigmask));
+# endif
+_GL_CXXALIASWARN (posix_spawnattr_setsigmask);
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawnattr_setsigmask
+# if HAVE_RAW_DECL_POSIX_SPAWNATTR_SETSIGMASK
+_GL_WARN_ON_USE (posix_spawnattr_setsigmask,
+                 "posix_spawnattr_setsigmask is unportable - "
+                 "use gnulib module posix_spawnattr_setsigmask for portability");
+# endif
+#endif
+
+#if 0
+/* Get flag word from the attribute structure.  */
+# if 0
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawnattr_getflags rpl_posix_spawnattr_getflags
+#  endif
+_GL_FUNCDECL_RPL (posix_spawnattr_getflags, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   short int *_Restrict_ __flags)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (posix_spawnattr_getflags, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   short int *_Restrict_ __flags));
+# else
+#  if !1
+_GL_FUNCDECL_SYS (posix_spawnattr_getflags, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   short int *_Restrict_ __flags)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawnattr_getflags, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   short int *_Restrict_ __flags));
+# endif
+_GL_CXXALIASWARN (posix_spawnattr_getflags);
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawnattr_getflags
+# if HAVE_RAW_DECL_POSIX_SPAWNATTR_GETFLAGS
+_GL_WARN_ON_USE (posix_spawnattr_getflags,
+                 "posix_spawnattr_getflags is unportable - "
+                 "use gnulib module posix_spawnattr_getflags for portability");
+# endif
+#endif
+
+#if 0
+/* Store flags in the attribute structure.  */
+# if 0
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawnattr_setflags rpl_posix_spawnattr_setflags
+#  endif
+_GL_FUNCDECL_RPL (posix_spawnattr_setflags, int,
+                  (posix_spawnattr_t *__attr, short int __flags)
+                  __THROW _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (posix_spawnattr_setflags, int,
+                  (posix_spawnattr_t *__attr, short int __flags));
+# else
+#  if !1
+_GL_FUNCDECL_SYS (posix_spawnattr_setflags, int,
+                  (posix_spawnattr_t *__attr, short int __flags)
+                  __THROW _GL_ARG_NONNULL ((1)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawnattr_setflags, int,
+                  (posix_spawnattr_t *__attr, short int __flags));
+# endif
+_GL_CXXALIASWARN (posix_spawnattr_setflags);
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawnattr_setflags
+# if HAVE_RAW_DECL_POSIX_SPAWNATTR_SETFLAGS
+_GL_WARN_ON_USE (posix_spawnattr_setflags,
+                 "posix_spawnattr_setflags is unportable - "
+                 "use gnulib module posix_spawnattr_setflags for portability");
+# endif
+#endif
+
+#if 0
+/* Get process group ID from the attribute structure.  */
+# if 0
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawnattr_getpgroup rpl_posix_spawnattr_getpgroup
+#  endif
+_GL_FUNCDECL_RPL (posix_spawnattr_getpgroup, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   pid_t *_Restrict_ __pgroup)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (posix_spawnattr_getpgroup, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   pid_t *_Restrict_ __pgroup));
+# else
+#  if !1
+_GL_FUNCDECL_SYS (posix_spawnattr_getpgroup, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   pid_t *_Restrict_ __pgroup)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawnattr_getpgroup, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   pid_t *_Restrict_ __pgroup));
+# endif
+_GL_CXXALIASWARN (posix_spawnattr_getpgroup);
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawnattr_getpgroup
+# if HAVE_RAW_DECL_POSIX_SPAWNATTR_GETPGROUP
+_GL_WARN_ON_USE (posix_spawnattr_getpgroup,
+                 "posix_spawnattr_getpgroup is unportable - "
+                 "use gnulib module posix_spawnattr_getpgroup for portability");
+# endif
+#endif
+
+#if 0
+/* Store process group ID in the attribute structure.  */
+# if 0
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawnattr_setpgroup rpl_posix_spawnattr_setpgroup
+#  endif
+_GL_FUNCDECL_RPL (posix_spawnattr_setpgroup, int,
+                  (posix_spawnattr_t *__attr, pid_t __pgroup)
+                  __THROW _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (posix_spawnattr_setpgroup, int,
+                  (posix_spawnattr_t *__attr, pid_t __pgroup));
+# else
+#  if !1
+_GL_FUNCDECL_SYS (posix_spawnattr_setpgroup, int,
+                  (posix_spawnattr_t *__attr, pid_t __pgroup)
+                  __THROW _GL_ARG_NONNULL ((1)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawnattr_setpgroup, int,
+                  (posix_spawnattr_t *__attr, pid_t __pgroup));
+# endif
+_GL_CXXALIASWARN (posix_spawnattr_setpgroup);
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawnattr_setpgroup
+# if HAVE_RAW_DECL_POSIX_SPAWNATTR_SETPGROUP
+_GL_WARN_ON_USE (posix_spawnattr_setpgroup,
+                 "posix_spawnattr_setpgroup is unportable - "
+                 "use gnulib module posix_spawnattr_setpgroup for portability");
+# endif
+#endif
+
+#if 0
+/* Get scheduling policy from the attribute structure.  */
+# if 0
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawnattr_getschedpolicy rpl_posix_spawnattr_getschedpolicy
+#  endif
+_GL_FUNCDECL_RPL (posix_spawnattr_getschedpolicy, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   int *_Restrict_ __schedpolicy)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (posix_spawnattr_getschedpolicy, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   int *_Restrict_ __schedpolicy));
+# else
+#  if !1 || POSIX_SPAWN_SETSCHEDULER == 0
+_GL_FUNCDECL_SYS (posix_spawnattr_getschedpolicy, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   int *_Restrict_ __schedpolicy)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawnattr_getschedpolicy, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   int *_Restrict_ __schedpolicy));
+# endif
+# if __GLIBC__ >= 2
+_GL_CXXALIASWARN (posix_spawnattr_getschedpolicy);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawnattr_getschedpolicy
+# if HAVE_RAW_DECL_POSIX_SPAWNATTR_GETSCHEDPOLICY
+_GL_WARN_ON_USE (posix_spawnattr_getschedpolicy,
+                 "posix_spawnattr_getschedpolicy is unportable - "
+                 "use gnulib module posix_spawnattr_getschedpolicy for portability");
+# endif
+#endif
+
+#if 0
+/* Store scheduling policy in the attribute structure.  */
+# if 0
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawnattr_setschedpolicy rpl_posix_spawnattr_setschedpolicy
+#  endif
+_GL_FUNCDECL_RPL (posix_spawnattr_setschedpolicy, int,
+                  (posix_spawnattr_t *__attr, int __schedpolicy)
+                  __THROW _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (posix_spawnattr_setschedpolicy, int,
+                  (posix_spawnattr_t *__attr, int __schedpolicy));
+# else
+#  if !1 || POSIX_SPAWN_SETSCHEDULER == 0
+_GL_FUNCDECL_SYS (posix_spawnattr_setschedpolicy, int,
+                  (posix_spawnattr_t *__attr, int __schedpolicy)
+                  __THROW _GL_ARG_NONNULL ((1)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawnattr_setschedpolicy, int,
+                  (posix_spawnattr_t *__attr, int __schedpolicy));
+# endif
+# if __GLIBC__ >= 2
+_GL_CXXALIASWARN (posix_spawnattr_setschedpolicy);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawnattr_setschedpolicy
+# if HAVE_RAW_DECL_POSIX_SPAWNATTR_SETSCHEDPOLICY
+_GL_WARN_ON_USE (posix_spawnattr_setschedpolicy,
+                 "posix_spawnattr_setschedpolicy is unportable - "
+                 "use gnulib module posix_spawnattr_setschedpolicy for portability");
+# endif
+#endif
+
+#if 0
+/* Get scheduling parameters from the attribute structure.  */
+# if 0
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawnattr_getschedparam rpl_posix_spawnattr_getschedparam
+#  endif
+_GL_FUNCDECL_RPL (posix_spawnattr_getschedparam, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   struct sched_param *_Restrict_ __schedparam)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (posix_spawnattr_getschedparam, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   struct sched_param *_Restrict_ __schedparam));
+# else
+#  if !1 || POSIX_SPAWN_SETSCHEDPARAM == 0
+_GL_FUNCDECL_SYS (posix_spawnattr_getschedparam, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   struct sched_param *_Restrict_ __schedparam)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawnattr_getschedparam, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   struct sched_param *_Restrict_ __schedparam));
+# endif
+# if __GLIBC__ >= 2
+_GL_CXXALIASWARN (posix_spawnattr_getschedparam);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawnattr_getschedparam
+# if HAVE_RAW_DECL_POSIX_SPAWNATTR_GETSCHEDPARAM
+_GL_WARN_ON_USE (posix_spawnattr_getschedparam,
+                 "posix_spawnattr_getschedparam is unportable - "
+                 "use gnulib module posix_spawnattr_getschedparam for portability");
+# endif
+#endif
+
+#if 0
+/* Store scheduling parameters in the attribute structure.  */
+# if 0
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawnattr_setschedparam rpl_posix_spawnattr_setschedparam
+#  endif
+_GL_FUNCDECL_RPL (posix_spawnattr_setschedparam, int,
+                  (posix_spawnattr_t *_Restrict_ __attr,
+                   const struct sched_param *_Restrict_ __schedparam)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (posix_spawnattr_setschedparam, int,
+                  (posix_spawnattr_t *_Restrict_ __attr,
+                   const struct sched_param *_Restrict_ __schedparam));
+# else
+#  if !1 || POSIX_SPAWN_SETSCHEDPARAM == 0
+_GL_FUNCDECL_SYS (posix_spawnattr_setschedparam, int,
+                  (posix_spawnattr_t *_Restrict_ __attr,
+                   const struct sched_param *_Restrict_ __schedparam)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawnattr_setschedparam, int,
+                  (posix_spawnattr_t *_Restrict_ __attr,
+                   const struct sched_param *_Restrict_ __schedparam));
+# endif
+# if __GLIBC__ >= 2
+_GL_CXXALIASWARN (posix_spawnattr_setschedparam);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawnattr_setschedparam
+# if HAVE_RAW_DECL_POSIX_SPAWNATTR_SETSCHEDPARAM
+_GL_WARN_ON_USE (posix_spawnattr_setschedparam,
+                 "posix_spawnattr_setschedparam is unportable - "
+                 "use gnulib module posix_spawnattr_setschedparam for portability");
+# endif
+#endif
+
+
+#if 0
+/* Initialize data structure for file attribute for 'spawn' call.  */
+# if 0
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawn_file_actions_init rpl_posix_spawn_file_actions_init
+#  endif
+_GL_FUNCDECL_RPL (posix_spawn_file_actions_init, int,
+                  (posix_spawn_file_actions_t *__file_actions)
+                  __THROW _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (posix_spawn_file_actions_init, int,
+                  (posix_spawn_file_actions_t *__file_actions));
+# else
+#  if !1
+_GL_FUNCDECL_SYS (posix_spawn_file_actions_init, int,
+                  (posix_spawn_file_actions_t *__file_actions)
+                  __THROW _GL_ARG_NONNULL ((1)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawn_file_actions_init, int,
+                  (posix_spawn_file_actions_t *__file_actions));
+# endif
+_GL_CXXALIASWARN (posix_spawn_file_actions_init);
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawn_file_actions_init
+# if HAVE_RAW_DECL_POSIX_SPAWN_FILE_ACTIONS_INIT
+_GL_WARN_ON_USE (posix_spawn_file_actions_init,
+                 "posix_spawn_file_actions_init is unportable - "
+                 "use gnulib module posix_spawn_file_actions_init for portability");
+# endif
+#endif
+
+#if 0
+/* Free resources associated with FILE-ACTIONS.  */
+# if 0
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawn_file_actions_destroy rpl_posix_spawn_file_actions_destroy
+#  endif
+_GL_FUNCDECL_RPL (posix_spawn_file_actions_destroy, int,
+                  (posix_spawn_file_actions_t *__file_actions)
+                  __THROW _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (posix_spawn_file_actions_destroy, int,
+                  (posix_spawn_file_actions_t *__file_actions));
+# else
+#  if !1
+_GL_FUNCDECL_SYS (posix_spawn_file_actions_destroy, int,
+                  (posix_spawn_file_actions_t *__file_actions)
+                  __THROW _GL_ARG_NONNULL ((1)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawn_file_actions_destroy, int,
+                  (posix_spawn_file_actions_t *__file_actions));
+# endif
+_GL_CXXALIASWARN (posix_spawn_file_actions_destroy);
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawn_file_actions_destroy
+# if HAVE_RAW_DECL_POSIX_SPAWN_FILE_ACTIONS_DESTROY
+_GL_WARN_ON_USE (posix_spawn_file_actions_destroy,
+                 "posix_spawn_file_actions_destroy is unportable - "
+                 "use gnulib module posix_spawn_file_actions_destroy for portability");
+# endif
+#endif
+
+#if 0
+/* Add an action to FILE-ACTIONS which tells the implementation to call
+   'open' for the given file during the 'spawn' call.  */
+# if 0
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawn_file_actions_addopen rpl_posix_spawn_file_actions_addopen
+#  endif
+_GL_FUNCDECL_RPL (posix_spawn_file_actions_addopen, int,
+                  (posix_spawn_file_actions_t *_Restrict_ __file_actions,
+                   int __fd,
+                   const char *_Restrict_ __path, int __oflag, mode_t __mode)
+                  __THROW _GL_ARG_NONNULL ((1, 3)));
+_GL_CXXALIAS_RPL (posix_spawn_file_actions_addopen, int,
+                  (posix_spawn_file_actions_t *_Restrict_ __file_actions,
+                   int __fd,
+                   const char *_Restrict_ __path, int __oflag, mode_t __mode));
+# else
+#  if !1
+_GL_FUNCDECL_SYS (posix_spawn_file_actions_addopen, int,
+                  (posix_spawn_file_actions_t *_Restrict_ __file_actions,
+                   int __fd,
+                   const char *_Restrict_ __path, int __oflag, mode_t __mode)
+                  __THROW _GL_ARG_NONNULL ((1, 3)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawn_file_actions_addopen, int,
+                  (posix_spawn_file_actions_t *_Restrict_ __file_actions,
+                   int __fd,
+                   const char *_Restrict_ __path, int __oflag, mode_t __mode));
+# endif
+# if __GLIBC__ >= 2
+_GL_CXXALIASWARN (posix_spawn_file_actions_addopen);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawn_file_actions_addopen
+# if HAVE_RAW_DECL_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN
+_GL_WARN_ON_USE (posix_spawn_file_actions_addopen,
+                 "posix_spawn_file_actions_addopen is unportable - "
+                 "use gnulib module posix_spawn_file_actions_addopen for portability");
+# endif
+#endif
+
+#if 0
+/* Add an action to FILE-ACTIONS which tells the implementation to call
+   'close' for the given file descriptor during the 'spawn' call.  */
+# if 0
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawn_file_actions_addclose rpl_posix_spawn_file_actions_addclose
+#  endif
+_GL_FUNCDECL_RPL (posix_spawn_file_actions_addclose, int,
+                  (posix_spawn_file_actions_t *__file_actions, int __fd)
+                  __THROW _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (posix_spawn_file_actions_addclose, int,
+                  (posix_spawn_file_actions_t *__file_actions, int __fd));
+# else
+#  if !1
+_GL_FUNCDECL_SYS (posix_spawn_file_actions_addclose, int,
+                  (posix_spawn_file_actions_t *__file_actions, int __fd)
+                  __THROW _GL_ARG_NONNULL ((1)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawn_file_actions_addclose, int,
+                  (posix_spawn_file_actions_t *__file_actions, int __fd));
+# endif
+# if __GLIBC__ >= 2
+_GL_CXXALIASWARN (posix_spawn_file_actions_addclose);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawn_file_actions_addclose
+# if HAVE_RAW_DECL_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE
+_GL_WARN_ON_USE (posix_spawn_file_actions_addclose,
+                 "posix_spawn_file_actions_addclose is unportable - "
+                 "use gnulib module posix_spawn_file_actions_addclose for portability");
+# endif
+#endif
+
+#if 0
+/* Add an action to FILE-ACTIONS which tells the implementation to call
+   'dup2' for the given file descriptors during the 'spawn' call.  */
+# if 0
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawn_file_actions_adddup2 rpl_posix_spawn_file_actions_adddup2
+#  endif
+_GL_FUNCDECL_RPL (posix_spawn_file_actions_adddup2, int,
+                  (posix_spawn_file_actions_t *__file_actions,
+                   int __fd, int __newfd)
+                  __THROW _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (posix_spawn_file_actions_adddup2, int,
+                  (posix_spawn_file_actions_t *__file_actions,
+                   int __fd, int __newfd));
+# else
+#  if !1
+_GL_FUNCDECL_SYS (posix_spawn_file_actions_adddup2, int,
+                  (posix_spawn_file_actions_t *__file_actions,
+                   int __fd, int __newfd)
+                  __THROW _GL_ARG_NONNULL ((1)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawn_file_actions_adddup2, int,
+                  (posix_spawn_file_actions_t *__file_actions,
+                   int __fd, int __newfd));
+# endif
+# if __GLIBC__ >= 2
+_GL_CXXALIASWARN (posix_spawn_file_actions_adddup2);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawn_file_actions_adddup2
+# if HAVE_RAW_DECL_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2
+_GL_WARN_ON_USE (posix_spawn_file_actions_adddup2,
+                 "posix_spawn_file_actions_adddup2 is unportable - "
+                 "use gnulib module posix_spawn_file_actions_adddup2 for portability");
+# endif
+#endif
+
+#if 0
+/* Add an action to FILE-ACTIONS which tells the implementation to call
+   'chdir' to the given directory during the 'spawn' call.  */
+# if 0
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawn_file_actions_addchdir rpl_posix_spawn_file_actions_addchdir
+#  endif
+_GL_FUNCDECL_RPL (posix_spawn_file_actions_addchdir, int,
+                  (posix_spawn_file_actions_t *_Restrict_ __file_actions,
+                   const char *_Restrict_ __path)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (posix_spawn_file_actions_addchdir, int,
+                  (posix_spawn_file_actions_t *_Restrict_ __file_actions,
+                   const char *_Restrict_ __path));
+# else
+#  if !1
+_GL_FUNCDECL_SYS (posix_spawn_file_actions_addchdir, int,
+                  (posix_spawn_file_actions_t *_Restrict_ __file_actions,
+                   const char *_Restrict_ __path)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawn_file_actions_addchdir, int,
+                  (posix_spawn_file_actions_t *_Restrict_ __file_actions,
+                   const char *_Restrict_ __path));
+# endif
+_GL_CXXALIASWARN (posix_spawn_file_actions_addchdir);
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawn_file_actions_addchdir
+# if HAVE_RAW_DECL_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR
+_GL_WARN_ON_USE (posix_spawn_file_actions_addchdir,
+                 "posix_spawn_file_actions_addchdir is unportable - "
+                 "use gnulib module posix_spawn_file_actions_addchdir for portability");
+# endif
+#endif
+
+#if 0
+/* Add an action to FILE-ACTIONS which tells the implementation to call
+   'fchdir' to the given directory during the 'spawn' call.  */
+# if 0
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawn_file_actions_addfchdir rpl_posix_spawn_file_actions_addfchdir
+#  endif
+_GL_FUNCDECL_RPL (posix_spawn_file_actions_addfchdir, int,
+                  (posix_spawn_file_actions_t *_Restrict_ __file_actions,
+                   int __fd)
+                  __THROW _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (posix_spawn_file_actions_addfchdir, int,
+                  (posix_spawn_file_actions_t *_Restrict_ __file_actions,
+                   int __fd));
+# else
+#  if !1
+_GL_FUNCDECL_SYS (posix_spawn_file_actions_addfchdir, int,
+                  (posix_spawn_file_actions_t *_Restrict_ __file_actions,
+                   int __fd)
+                  __THROW _GL_ARG_NONNULL ((1)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawn_file_actions_addfchdir, int,
+                  (posix_spawn_file_actions_t *_Restrict_ __file_actions,
+                   int __fd));
+# endif
+_GL_CXXALIASWARN (posix_spawn_file_actions_addfchdir);
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawn_file_actions_addfchdir
+# if HAVE_RAW_DECL_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR
+_GL_WARN_ON_USE (posix_spawn_file_actions_addfchdir,
+                 "posix_spawn_file_actions_addfchdir is unportable - "
+                 "use gnulib module posix_spawn_file_actions_addfchdir for portability");
+# endif
+#endif
+
+
+#endif /* _GL_SPAWN_H */
+#endif /* _GL_SPAWN_H */
+#endif
diff --git a/lib/spawn.in.h b/lib/spawn.in.h
new file mode 100644
index 000000000..c1acf6043
--- /dev/null
+++ b/lib/spawn.in.h
@@ -0,0 +1,992 @@
+/* Definitions for POSIX spawn interface.
+   Copyright (C) 2000, 2003-2004, 2008-2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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 2.1 of the
+   License, or (at your option) any later version.
+
+   This file 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+#if __GNUC__ >= 3
+@PRAGMA_SYSTEM_HEADER@
+#endif
+@PRAGMA_COLUMNS@
+
+#if defined _GL_ALREADY_INCLUDING_SPAWN_H
+/* Special invocation convention:
+   On OS/2 kLIBC, <spawn.h> includes <signal.h>. Then <signal.h> ->
+   <pthread.h> -> <sched.h> -> <spawn.h> are included by GNULIB.
+   In this situation, struct sched_param is not yet defined.  */
+
+#@INCLUDE_NEXT@ @NEXT_SPAWN_H@
+
+#else
+
+#ifndef _@GUARD_PREFIX@_SPAWN_H
+/* Normal invocation convention.  */
+
+/* The include_next requires a split double-inclusion guard.  */
+#if @HAVE_SPAWN_H@
+
+# define _GL_ALREADY_INCLUDING_SPAWN_H
+
+# @INCLUDE_NEXT@ @NEXT_SPAWN_H@
+
+# define _GL_ALREADY_INCLUDING_SPAWN_H
+
+#endif
+
+#ifndef _@GUARD_PREFIX@_SPAWN_H
+#define _@GUARD_PREFIX@_SPAWN_H
+
+/* Get definitions of 'struct sched_param' and 'sigset_t'.
+   But avoid namespace pollution on glibc systems.  */
+#if !(defined __GLIBC__ && !defined __UCLIBC__)
+# include <sched.h>
+# include <signal.h>
+#endif
+
+#include <sys/types.h>
+
+#ifndef __THROW
+# define __THROW
+#endif
+
+/* For plain 'restrict', use glibc's __restrict if defined.
+   Otherwise, GCC 2.95 and later have "__restrict"; C99 compilers have
+   "restrict", and "configure" may have defined "restrict".
+   Other compilers use __restrict, __restrict__, and _Restrict, and
+   'configure' might #define 'restrict' to those words, so pick a
+   different name.  */
+#ifndef _Restrict_
+# if defined __restrict \
+     || 2 < __GNUC__ + (95 <= __GNUC_MINOR__) \
+     || __clang_major__ >= 3
+#  define _Restrict_ __restrict
+# elif 199901L <= __STDC_VERSION__ || defined restrict
+#  define _Restrict_ restrict
+# else
+#  define _Restrict_
+# endif
+#endif
+/* For the ISO C99 syntax
+     array_name[restrict]
+   use glibc's __restrict_arr if available.
+   Otherwise, GCC 3.1 and clang support this syntax (but not in C++ mode).
+   Other ISO C99 compilers support it as well.  */
+#ifndef _Restrict_arr_
+# ifdef __restrict_arr
+#  define _Restrict_arr_ __restrict_arr
+# elif ((199901L <= __STDC_VERSION__ \
+         || 3 < __GNUC__ + (1 <= __GNUC_MINOR__) \
+         || __clang_major__ >= 3) \
+        && !defined __cplusplus)
+#  define _Restrict_arr_ _Restrict_
+# else
+#  define _Restrict_arr_
+# endif
+#endif
+
+/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */
+
+/* The definition of _GL_ARG_NONNULL is copied here.  */
+
+/* The definition of _GL_WARN_ON_USE is copied here.  */
+
+
+/* Data structure to contain attributes for thread creation.  */
+#if @REPLACE_POSIX_SPAWN@ || (@HAVE_POSIX_SPAWNATTR_T@ && !@HAVE_POSIX_SPAWN@)
+# define posix_spawnattr_t rpl_posix_spawnattr_t
+#endif
+#if @REPLACE_POSIX_SPAWN@ || !@HAVE_POSIX_SPAWNATTR_T@ || !@HAVE_POSIX_SPAWN@
+# if !GNULIB_defined_posix_spawnattr_t
+typedef struct
+{
+  short int _flags;
+  pid_t _pgrp;
+  sigset_t _sd;
+  sigset_t _ss;
+  struct sched_param _sp;
+  int _policy;
+  int __pad[16];
+} posix_spawnattr_t;
+#  define GNULIB_defined_posix_spawnattr_t 1
+# endif
+#endif
+
+
+/* Data structure to contain information about the actions to be
+   performed in the new process with respect to file descriptors.  */
+#if @REPLACE_POSIX_SPAWN@ || (@HAVE_POSIX_SPAWN_FILE_ACTIONS_T@ && !@HAVE_POSIX_SPAWN@)
+# define posix_spawn_file_actions_t rpl_posix_spawn_file_actions_t
+#endif
+#if @REPLACE_POSIX_SPAWN@ || !@HAVE_POSIX_SPAWN_FILE_ACTIONS_T@ || !@HAVE_POSIX_SPAWN@
+# if !GNULIB_defined_posix_spawn_file_actions_t
+typedef struct
+{
+  int _allocated;
+  int _used;
+  struct __spawn_action *_actions;
+  int __pad[16];
+} posix_spawn_file_actions_t;
+#  define GNULIB_defined_posix_spawn_file_actions_t 1
+# endif
+#endif
+
+
+/* Flags to be set in the 'posix_spawnattr_t'.  */
+#if @HAVE_POSIX_SPAWN@
+/* Use the values from the system, but provide the missing ones.  */
+# ifndef POSIX_SPAWN_SETSCHEDPARAM
+#  define POSIX_SPAWN_SETSCHEDPARAM 0
+# endif
+# ifndef POSIX_SPAWN_SETSCHEDULER
+#  define POSIX_SPAWN_SETSCHEDULER 0
+# endif
+#else
+# if @REPLACE_POSIX_SPAWN@
+/* Use the values from the system, for better compatibility.  */
+/* But this implementation does not support AIX extensions.  */
+#  undef POSIX_SPAWN_FORK_HANDLERS
+# else
+#  define POSIX_SPAWN_RESETIDS           0x01
+#  define POSIX_SPAWN_SETPGROUP          0x02
+#  define POSIX_SPAWN_SETSIGDEF          0x04
+#  define POSIX_SPAWN_SETSIGMASK         0x08
+#  define POSIX_SPAWN_SETSCHEDPARAM      0x10
+#  define POSIX_SPAWN_SETSCHEDULER       0x20
+# endif
+#endif
+/* A GNU extension.  Use the next free bit position.  */
+#ifndef POSIX_SPAWN_USEVFORK
+# define POSIX_SPAWN_USEVFORK \
+  ((POSIX_SPAWN_RESETIDS | (POSIX_SPAWN_RESETIDS - 1)                     \
+    | POSIX_SPAWN_SETPGROUP | (POSIX_SPAWN_SETPGROUP - 1)                 \
+    | POSIX_SPAWN_SETSIGDEF | (POSIX_SPAWN_SETSIGDEF - 1)                 \
+    | POSIX_SPAWN_SETSIGMASK | (POSIX_SPAWN_SETSIGMASK - 1)               \
+    | POSIX_SPAWN_SETSCHEDPARAM                                           \
+    | (POSIX_SPAWN_SETSCHEDPARAM > 0 ? POSIX_SPAWN_SETSCHEDPARAM - 1 : 0) \
+    | POSIX_SPAWN_SETSCHEDULER                                            \
+    | (POSIX_SPAWN_SETSCHEDULER > 0 ? POSIX_SPAWN_SETSCHEDULER - 1 : 0))  \
+   + 1)
+#endif
+#if !GNULIB_defined_verify_POSIX_SPAWN_USEVFORK_no_overlap
+typedef int verify_POSIX_SPAWN_USEVFORK_no_overlap
+            [(((POSIX_SPAWN_RESETIDS | POSIX_SPAWN_SETPGROUP
+                | POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK
+                | POSIX_SPAWN_SETSCHEDPARAM | POSIX_SPAWN_SETSCHEDULER)
+               & POSIX_SPAWN_USEVFORK)
+              == 0)
+             ? 1 : -1];
+# define GNULIB_defined_verify_POSIX_SPAWN_USEVFORK_no_overlap 1
+#endif
+
+
+#if @GNULIB_POSIX_SPAWN@
+/* Spawn a new process executing PATH with the attributes describes in *ATTRP.
+   Before running the process perform the actions described in FILE-ACTIONS.
+
+   This function is a possible cancellation points and therefore not
+   marked with __THROW. */
+# if @REPLACE_POSIX_SPAWN@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawn rpl_posix_spawn
+#  endif
+_GL_FUNCDECL_RPL (posix_spawn, int,
+                  (pid_t *_Restrict_ __pid,
+                   const char *_Restrict_ __path,
+                   const posix_spawn_file_actions_t *_Restrict_ __file_actions,
+                   const posix_spawnattr_t *_Restrict_ __attrp,
+                   char *const argv[_Restrict_arr_],
+                   char *const envp[_Restrict_arr_])
+                  _GL_ARG_NONNULL ((2, 5, 6)));
+_GL_CXXALIAS_RPL (posix_spawn, int,
+                  (pid_t *_Restrict_ __pid,
+                   const char *_Restrict_ __path,
+                   const posix_spawn_file_actions_t *_Restrict_ __file_actions,
+                   const posix_spawnattr_t *_Restrict_ __attrp,
+                   char *const argv[_Restrict_arr_],
+                   char *const envp[_Restrict_arr_]));
+# else
+#  if !@HAVE_POSIX_SPAWN@
+_GL_FUNCDECL_SYS (posix_spawn, int,
+                  (pid_t *_Restrict_ __pid,
+                   const char *_Restrict_ __path,
+                   const posix_spawn_file_actions_t *_Restrict_ __file_actions,
+                   const posix_spawnattr_t *_Restrict_ __attrp,
+                   char *const argv[_Restrict_arr_],
+                   char *const envp[_Restrict_arr_])
+                  _GL_ARG_NONNULL ((2, 5, 6)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawn, int,
+                  (pid_t *_Restrict_ __pid,
+                   const char *_Restrict_ __path,
+                   const posix_spawn_file_actions_t *_Restrict_ __file_actions,
+                   const posix_spawnattr_t *_Restrict_ __attrp,
+                   char *const argv[_Restrict_arr_],
+                   char *const envp[_Restrict_arr_]));
+# endif
+_GL_CXXALIASWARN (posix_spawn);
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawn
+# if HAVE_RAW_DECL_POSIX_SPAWN
+_GL_WARN_ON_USE (posix_spawn, "posix_spawn is unportable - "
+                 "use gnulib module posix_spawn for portability");
+# endif
+#endif
+
+#if @GNULIB_POSIX_SPAWNP@
+/* Similar to 'posix_spawn' but search for FILE in the PATH.
+
+   This function is a possible cancellation points and therefore not
+   marked with __THROW.  */
+# if @REPLACE_POSIX_SPAWN@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawnp rpl_posix_spawnp
+#  endif
+_GL_FUNCDECL_RPL (posix_spawnp, int,
+                  (pid_t *__pid, const char *__file,
+                   const posix_spawn_file_actions_t *__file_actions,
+                   const posix_spawnattr_t *__attrp,
+                   char *const argv[], char *const envp[])
+                  _GL_ARG_NONNULL ((2, 5, 6)));
+_GL_CXXALIAS_RPL (posix_spawnp, int,
+                  (pid_t *__pid, const char *__file,
+                   const posix_spawn_file_actions_t *__file_actions,
+                   const posix_spawnattr_t *__attrp,
+                   char *const argv[], char *const envp[]));
+# else
+#  if !@HAVE_POSIX_SPAWN@
+_GL_FUNCDECL_SYS (posix_spawnp, int,
+                  (pid_t *__pid, const char *__file,
+                   const posix_spawn_file_actions_t *__file_actions,
+                   const posix_spawnattr_t *__attrp,
+                   char *const argv[], char *const envp[])
+                  _GL_ARG_NONNULL ((2, 5, 6)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawnp, int,
+                  (pid_t *__pid, const char *__file,
+                   const posix_spawn_file_actions_t *__file_actions,
+                   const posix_spawnattr_t *__attrp,
+                   char *const argv[], char *const envp[]));
+# endif
+_GL_CXXALIASWARN (posix_spawnp);
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawnp
+# if HAVE_RAW_DECL_POSIX_SPAWNP
+_GL_WARN_ON_USE (posix_spawnp, "posix_spawnp is unportable - "
+                 "use gnulib module posix_spawnp for portability");
+# endif
+#endif
+
+
+#if @GNULIB_POSIX_SPAWNATTR_INIT@
+/* Initialize data structure with attributes for 'spawn' to default values.  */
+# if @REPLACE_POSIX_SPAWN@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawnattr_init rpl_posix_spawnattr_init
+#  endif
+_GL_FUNCDECL_RPL (posix_spawnattr_init, int, (posix_spawnattr_t *__attr)
+                                             __THROW _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (posix_spawnattr_init, int, (posix_spawnattr_t *__attr));
+# else
+#  if !@HAVE_POSIX_SPAWN@
+_GL_FUNCDECL_SYS (posix_spawnattr_init, int, (posix_spawnattr_t *__attr)
+                                             __THROW _GL_ARG_NONNULL ((1)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawnattr_init, int, (posix_spawnattr_t *__attr));
+# endif
+_GL_CXXALIASWARN (posix_spawnattr_init);
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawnattr_init
+# if HAVE_RAW_DECL_POSIX_SPAWNATTR_INIT
+_GL_WARN_ON_USE (posix_spawnattr_init, "posix_spawnattr_init is unportable - "
+                 "use gnulib module posix_spawnattr_init for portability");
+# endif
+#endif
+
+#if @GNULIB_POSIX_SPAWNATTR_DESTROY@
+/* Free resources associated with ATTR.  */
+# if @REPLACE_POSIX_SPAWN@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawnattr_destroy rpl_posix_spawnattr_destroy
+#  endif
+_GL_FUNCDECL_RPL (posix_spawnattr_destroy, int, (posix_spawnattr_t *__attr)
+                                                __THROW _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (posix_spawnattr_destroy, int, (posix_spawnattr_t *__attr));
+# else
+#  if !@HAVE_POSIX_SPAWN@
+_GL_FUNCDECL_SYS (posix_spawnattr_destroy, int, (posix_spawnattr_t *__attr)
+                                                __THROW _GL_ARG_NONNULL ((1)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawnattr_destroy, int, (posix_spawnattr_t *__attr));
+# endif
+_GL_CXXALIASWARN (posix_spawnattr_destroy);
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawnattr_destroy
+# if HAVE_RAW_DECL_POSIX_SPAWNATTR_DESTROY
+_GL_WARN_ON_USE (posix_spawnattr_destroy,
+                 "posix_spawnattr_destroy is unportable - "
+                 "use gnulib module posix_spawnattr_destroy for portability");
+# endif
+#endif
+
+#if @GNULIB_POSIX_SPAWNATTR_GETSIGDEFAULT@
+/* Store signal mask for signals with default handling from ATTR in
+   SIGDEFAULT.  */
+# if @REPLACE_POSIX_SPAWN@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawnattr_getsigdefault rpl_posix_spawnattr_getsigdefault
+#  endif
+_GL_FUNCDECL_RPL (posix_spawnattr_getsigdefault, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   sigset_t *_Restrict_ __sigdefault)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (posix_spawnattr_getsigdefault, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   sigset_t *_Restrict_ __sigdefault));
+# else
+#  if !@HAVE_POSIX_SPAWN@
+_GL_FUNCDECL_SYS (posix_spawnattr_getsigdefault, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   sigset_t *_Restrict_ __sigdefault)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawnattr_getsigdefault, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   sigset_t *_Restrict_ __sigdefault));
+# endif
+_GL_CXXALIASWARN (posix_spawnattr_getsigdefault);
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawnattr_getsigdefault
+# if HAVE_RAW_DECL_POSIX_SPAWNATTR_GETSIGDEFAULT
+_GL_WARN_ON_USE (posix_spawnattr_getsigdefault,
+                 "posix_spawnattr_getsigdefault is unportable - "
+                 "use gnulib module posix_spawnattr_getsigdefault for portability");
+# endif
+#endif
+
+#if @GNULIB_POSIX_SPAWNATTR_SETSIGDEFAULT@
+/* Set signal mask for signals with default handling in ATTR to SIGDEFAULT.  */
+# if @REPLACE_POSIX_SPAWN@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawnattr_setsigdefault rpl_posix_spawnattr_setsigdefault
+#  endif
+_GL_FUNCDECL_RPL (posix_spawnattr_setsigdefault, int,
+                  (posix_spawnattr_t *_Restrict_ __attr,
+                   const sigset_t *_Restrict_ __sigdefault)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (posix_spawnattr_setsigdefault, int,
+                  (posix_spawnattr_t *_Restrict_ __attr,
+                   const sigset_t *_Restrict_ __sigdefault));
+# else
+#  if !@HAVE_POSIX_SPAWN@
+_GL_FUNCDECL_SYS (posix_spawnattr_setsigdefault, int,
+                  (posix_spawnattr_t *_Restrict_ __attr,
+                   const sigset_t *_Restrict_ __sigdefault)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawnattr_setsigdefault, int,
+                  (posix_spawnattr_t *_Restrict_ __attr,
+                   const sigset_t *_Restrict_ __sigdefault));
+# endif
+_GL_CXXALIASWARN (posix_spawnattr_setsigdefault);
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawnattr_setsigdefault
+# if HAVE_RAW_DECL_POSIX_SPAWNATTR_SETSIGDEFAULT
+_GL_WARN_ON_USE (posix_spawnattr_setsigdefault,
+                 "posix_spawnattr_setsigdefault is unportable - "
+                 "use gnulib module posix_spawnattr_setsigdefault for portability");
+# endif
+#endif
+
+#if @GNULIB_POSIX_SPAWNATTR_GETSIGMASK@
+/* Store signal mask for the new process from ATTR in SIGMASK.  */
+# if @REPLACE_POSIX_SPAWN@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawnattr_getsigmask rpl_posix_spawnattr_getsigmask
+#  endif
+_GL_FUNCDECL_RPL (posix_spawnattr_getsigmask, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   sigset_t *_Restrict_ __sigmask)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (posix_spawnattr_getsigmask, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   sigset_t *_Restrict_ __sigmask));
+# else
+#  if !@HAVE_POSIX_SPAWN@
+_GL_FUNCDECL_SYS (posix_spawnattr_getsigmask, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   sigset_t *_Restrict_ __sigmask)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawnattr_getsigmask, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   sigset_t *_Restrict_ __sigmask));
+# endif
+_GL_CXXALIASWARN (posix_spawnattr_getsigmask);
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawnattr_getsigmask
+# if HAVE_RAW_DECL_POSIX_SPAWNATTR_GETSIGMASK
+_GL_WARN_ON_USE (posix_spawnattr_getsigmask,
+                 "posix_spawnattr_getsigmask is unportable - "
+                 "use gnulib module posix_spawnattr_getsigmask for portability");
+# endif
+#endif
+
+#if @GNULIB_POSIX_SPAWNATTR_SETSIGMASK@
+/* Set signal mask for the new process in ATTR to SIGMASK.  */
+# if @REPLACE_POSIX_SPAWN@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawnattr_setsigmask rpl_posix_spawnattr_setsigmask
+#  endif
+_GL_FUNCDECL_RPL (posix_spawnattr_setsigmask, int,
+                  (posix_spawnattr_t *_Restrict_ __attr,
+                   const sigset_t *_Restrict_ __sigmask)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (posix_spawnattr_setsigmask, int,
+                  (posix_spawnattr_t *_Restrict_ __attr,
+                   const sigset_t *_Restrict_ __sigmask));
+# else
+#  if !@HAVE_POSIX_SPAWN@
+_GL_FUNCDECL_SYS (posix_spawnattr_setsigmask, int,
+                  (posix_spawnattr_t *_Restrict_ __attr,
+                   const sigset_t *_Restrict_ __sigmask)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawnattr_setsigmask, int,
+                  (posix_spawnattr_t *_Restrict_ __attr,
+                   const sigset_t *_Restrict_ __sigmask));
+# endif
+_GL_CXXALIASWARN (posix_spawnattr_setsigmask);
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawnattr_setsigmask
+# if HAVE_RAW_DECL_POSIX_SPAWNATTR_SETSIGMASK
+_GL_WARN_ON_USE (posix_spawnattr_setsigmask,
+                 "posix_spawnattr_setsigmask is unportable - "
+                 "use gnulib module posix_spawnattr_setsigmask for portability");
+# endif
+#endif
+
+#if @GNULIB_POSIX_SPAWNATTR_GETFLAGS@
+/* Get flag word from the attribute structure.  */
+# if @REPLACE_POSIX_SPAWN@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawnattr_getflags rpl_posix_spawnattr_getflags
+#  endif
+_GL_FUNCDECL_RPL (posix_spawnattr_getflags, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   short int *_Restrict_ __flags)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (posix_spawnattr_getflags, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   short int *_Restrict_ __flags));
+# else
+#  if !@HAVE_POSIX_SPAWN@
+_GL_FUNCDECL_SYS (posix_spawnattr_getflags, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   short int *_Restrict_ __flags)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawnattr_getflags, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   short int *_Restrict_ __flags));
+# endif
+_GL_CXXALIASWARN (posix_spawnattr_getflags);
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawnattr_getflags
+# if HAVE_RAW_DECL_POSIX_SPAWNATTR_GETFLAGS
+_GL_WARN_ON_USE (posix_spawnattr_getflags,
+                 "posix_spawnattr_getflags is unportable - "
+                 "use gnulib module posix_spawnattr_getflags for portability");
+# endif
+#endif
+
+#if @GNULIB_POSIX_SPAWNATTR_SETFLAGS@
+/* Store flags in the attribute structure.  */
+# if @REPLACE_POSIX_SPAWN@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawnattr_setflags rpl_posix_spawnattr_setflags
+#  endif
+_GL_FUNCDECL_RPL (posix_spawnattr_setflags, int,
+                  (posix_spawnattr_t *__attr, short int __flags)
+                  __THROW _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (posix_spawnattr_setflags, int,
+                  (posix_spawnattr_t *__attr, short int __flags));
+# else
+#  if !@HAVE_POSIX_SPAWN@
+_GL_FUNCDECL_SYS (posix_spawnattr_setflags, int,
+                  (posix_spawnattr_t *__attr, short int __flags)
+                  __THROW _GL_ARG_NONNULL ((1)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawnattr_setflags, int,
+                  (posix_spawnattr_t *__attr, short int __flags));
+# endif
+_GL_CXXALIASWARN (posix_spawnattr_setflags);
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawnattr_setflags
+# if HAVE_RAW_DECL_POSIX_SPAWNATTR_SETFLAGS
+_GL_WARN_ON_USE (posix_spawnattr_setflags,
+                 "posix_spawnattr_setflags is unportable - "
+                 "use gnulib module posix_spawnattr_setflags for portability");
+# endif
+#endif
+
+#if @GNULIB_POSIX_SPAWNATTR_GETPGROUP@
+/* Get process group ID from the attribute structure.  */
+# if @REPLACE_POSIX_SPAWN@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawnattr_getpgroup rpl_posix_spawnattr_getpgroup
+#  endif
+_GL_FUNCDECL_RPL (posix_spawnattr_getpgroup, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   pid_t *_Restrict_ __pgroup)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (posix_spawnattr_getpgroup, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   pid_t *_Restrict_ __pgroup));
+# else
+#  if !@HAVE_POSIX_SPAWN@
+_GL_FUNCDECL_SYS (posix_spawnattr_getpgroup, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   pid_t *_Restrict_ __pgroup)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawnattr_getpgroup, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   pid_t *_Restrict_ __pgroup));
+# endif
+_GL_CXXALIASWARN (posix_spawnattr_getpgroup);
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawnattr_getpgroup
+# if HAVE_RAW_DECL_POSIX_SPAWNATTR_GETPGROUP
+_GL_WARN_ON_USE (posix_spawnattr_getpgroup,
+                 "posix_spawnattr_getpgroup is unportable - "
+                 "use gnulib module posix_spawnattr_getpgroup for portability");
+# endif
+#endif
+
+#if @GNULIB_POSIX_SPAWNATTR_SETPGROUP@
+/* Store process group ID in the attribute structure.  */
+# if @REPLACE_POSIX_SPAWN@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawnattr_setpgroup rpl_posix_spawnattr_setpgroup
+#  endif
+_GL_FUNCDECL_RPL (posix_spawnattr_setpgroup, int,
+                  (posix_spawnattr_t *__attr, pid_t __pgroup)
+                  __THROW _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (posix_spawnattr_setpgroup, int,
+                  (posix_spawnattr_t *__attr, pid_t __pgroup));
+# else
+#  if !@HAVE_POSIX_SPAWN@
+_GL_FUNCDECL_SYS (posix_spawnattr_setpgroup, int,
+                  (posix_spawnattr_t *__attr, pid_t __pgroup)
+                  __THROW _GL_ARG_NONNULL ((1)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawnattr_setpgroup, int,
+                  (posix_spawnattr_t *__attr, pid_t __pgroup));
+# endif
+_GL_CXXALIASWARN (posix_spawnattr_setpgroup);
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawnattr_setpgroup
+# if HAVE_RAW_DECL_POSIX_SPAWNATTR_SETPGROUP
+_GL_WARN_ON_USE (posix_spawnattr_setpgroup,
+                 "posix_spawnattr_setpgroup is unportable - "
+                 "use gnulib module posix_spawnattr_setpgroup for portability");
+# endif
+#endif
+
+#if @GNULIB_POSIX_SPAWNATTR_GETSCHEDPOLICY@
+/* Get scheduling policy from the attribute structure.  */
+# if @REPLACE_POSIX_SPAWN@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawnattr_getschedpolicy rpl_posix_spawnattr_getschedpolicy
+#  endif
+_GL_FUNCDECL_RPL (posix_spawnattr_getschedpolicy, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   int *_Restrict_ __schedpolicy)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (posix_spawnattr_getschedpolicy, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   int *_Restrict_ __schedpolicy));
+# else
+#  if !@HAVE_POSIX_SPAWN@ || POSIX_SPAWN_SETSCHEDULER == 0
+_GL_FUNCDECL_SYS (posix_spawnattr_getschedpolicy, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   int *_Restrict_ __schedpolicy)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawnattr_getschedpolicy, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   int *_Restrict_ __schedpolicy));
+# endif
+# if __GLIBC__ >= 2
+_GL_CXXALIASWARN (posix_spawnattr_getschedpolicy);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawnattr_getschedpolicy
+# if HAVE_RAW_DECL_POSIX_SPAWNATTR_GETSCHEDPOLICY
+_GL_WARN_ON_USE (posix_spawnattr_getschedpolicy,
+                 "posix_spawnattr_getschedpolicy is unportable - "
+                 "use gnulib module posix_spawnattr_getschedpolicy for portability");
+# endif
+#endif
+
+#if @GNULIB_POSIX_SPAWNATTR_SETSCHEDPOLICY@
+/* Store scheduling policy in the attribute structure.  */
+# if @REPLACE_POSIX_SPAWN@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawnattr_setschedpolicy rpl_posix_spawnattr_setschedpolicy
+#  endif
+_GL_FUNCDECL_RPL (posix_spawnattr_setschedpolicy, int,
+                  (posix_spawnattr_t *__attr, int __schedpolicy)
+                  __THROW _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (posix_spawnattr_setschedpolicy, int,
+                  (posix_spawnattr_t *__attr, int __schedpolicy));
+# else
+#  if !@HAVE_POSIX_SPAWN@ || POSIX_SPAWN_SETSCHEDULER == 0
+_GL_FUNCDECL_SYS (posix_spawnattr_setschedpolicy, int,
+                  (posix_spawnattr_t *__attr, int __schedpolicy)
+                  __THROW _GL_ARG_NONNULL ((1)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawnattr_setschedpolicy, int,
+                  (posix_spawnattr_t *__attr, int __schedpolicy));
+# endif
+# if __GLIBC__ >= 2
+_GL_CXXALIASWARN (posix_spawnattr_setschedpolicy);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawnattr_setschedpolicy
+# if HAVE_RAW_DECL_POSIX_SPAWNATTR_SETSCHEDPOLICY
+_GL_WARN_ON_USE (posix_spawnattr_setschedpolicy,
+                 "posix_spawnattr_setschedpolicy is unportable - "
+                 "use gnulib module posix_spawnattr_setschedpolicy for portability");
+# endif
+#endif
+
+#if @GNULIB_POSIX_SPAWNATTR_GETSCHEDPARAM@
+/* Get scheduling parameters from the attribute structure.  */
+# if @REPLACE_POSIX_SPAWN@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawnattr_getschedparam rpl_posix_spawnattr_getschedparam
+#  endif
+_GL_FUNCDECL_RPL (posix_spawnattr_getschedparam, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   struct sched_param *_Restrict_ __schedparam)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (posix_spawnattr_getschedparam, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   struct sched_param *_Restrict_ __schedparam));
+# else
+#  if !@HAVE_POSIX_SPAWN@ || POSIX_SPAWN_SETSCHEDPARAM == 0
+_GL_FUNCDECL_SYS (posix_spawnattr_getschedparam, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   struct sched_param *_Restrict_ __schedparam)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawnattr_getschedparam, int,
+                  (const posix_spawnattr_t *_Restrict_ __attr,
+                   struct sched_param *_Restrict_ __schedparam));
+# endif
+# if __GLIBC__ >= 2
+_GL_CXXALIASWARN (posix_spawnattr_getschedparam);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawnattr_getschedparam
+# if HAVE_RAW_DECL_POSIX_SPAWNATTR_GETSCHEDPARAM
+_GL_WARN_ON_USE (posix_spawnattr_getschedparam,
+                 "posix_spawnattr_getschedparam is unportable - "
+                 "use gnulib module posix_spawnattr_getschedparam for portability");
+# endif
+#endif
+
+#if @GNULIB_POSIX_SPAWNATTR_SETSCHEDPARAM@
+/* Store scheduling parameters in the attribute structure.  */
+# if @REPLACE_POSIX_SPAWN@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawnattr_setschedparam rpl_posix_spawnattr_setschedparam
+#  endif
+_GL_FUNCDECL_RPL (posix_spawnattr_setschedparam, int,
+                  (posix_spawnattr_t *_Restrict_ __attr,
+                   const struct sched_param *_Restrict_ __schedparam)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (posix_spawnattr_setschedparam, int,
+                  (posix_spawnattr_t *_Restrict_ __attr,
+                   const struct sched_param *_Restrict_ __schedparam));
+# else
+#  if !@HAVE_POSIX_SPAWN@ || POSIX_SPAWN_SETSCHEDPARAM == 0
+_GL_FUNCDECL_SYS (posix_spawnattr_setschedparam, int,
+                  (posix_spawnattr_t *_Restrict_ __attr,
+                   const struct sched_param *_Restrict_ __schedparam)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawnattr_setschedparam, int,
+                  (posix_spawnattr_t *_Restrict_ __attr,
+                   const struct sched_param *_Restrict_ __schedparam));
+# endif
+# if __GLIBC__ >= 2
+_GL_CXXALIASWARN (posix_spawnattr_setschedparam);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawnattr_setschedparam
+# if HAVE_RAW_DECL_POSIX_SPAWNATTR_SETSCHEDPARAM
+_GL_WARN_ON_USE (posix_spawnattr_setschedparam,
+                 "posix_spawnattr_setschedparam is unportable - "
+                 "use gnulib module posix_spawnattr_setschedparam for portability");
+# endif
+#endif
+
+
+#if @GNULIB_POSIX_SPAWN_FILE_ACTIONS_INIT@
+/* Initialize data structure for file attribute for 'spawn' call.  */
+# if @REPLACE_POSIX_SPAWN@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawn_file_actions_init rpl_posix_spawn_file_actions_init
+#  endif
+_GL_FUNCDECL_RPL (posix_spawn_file_actions_init, int,
+                  (posix_spawn_file_actions_t *__file_actions)
+                  __THROW _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (posix_spawn_file_actions_init, int,
+                  (posix_spawn_file_actions_t *__file_actions));
+# else
+#  if !@HAVE_POSIX_SPAWN@
+_GL_FUNCDECL_SYS (posix_spawn_file_actions_init, int,
+                  (posix_spawn_file_actions_t *__file_actions)
+                  __THROW _GL_ARG_NONNULL ((1)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawn_file_actions_init, int,
+                  (posix_spawn_file_actions_t *__file_actions));
+# endif
+_GL_CXXALIASWARN (posix_spawn_file_actions_init);
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawn_file_actions_init
+# if HAVE_RAW_DECL_POSIX_SPAWN_FILE_ACTIONS_INIT
+_GL_WARN_ON_USE (posix_spawn_file_actions_init,
+                 "posix_spawn_file_actions_init is unportable - "
+                 "use gnulib module posix_spawn_file_actions_init for portability");
+# endif
+#endif
+
+#if @GNULIB_POSIX_SPAWN_FILE_ACTIONS_DESTROY@
+/* Free resources associated with FILE-ACTIONS.  */
+# if @REPLACE_POSIX_SPAWN@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawn_file_actions_destroy rpl_posix_spawn_file_actions_destroy
+#  endif
+_GL_FUNCDECL_RPL (posix_spawn_file_actions_destroy, int,
+                  (posix_spawn_file_actions_t *__file_actions)
+                  __THROW _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (posix_spawn_file_actions_destroy, int,
+                  (posix_spawn_file_actions_t *__file_actions));
+# else
+#  if !@HAVE_POSIX_SPAWN@
+_GL_FUNCDECL_SYS (posix_spawn_file_actions_destroy, int,
+                  (posix_spawn_file_actions_t *__file_actions)
+                  __THROW _GL_ARG_NONNULL ((1)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawn_file_actions_destroy, int,
+                  (posix_spawn_file_actions_t *__file_actions));
+# endif
+_GL_CXXALIASWARN (posix_spawn_file_actions_destroy);
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawn_file_actions_destroy
+# if HAVE_RAW_DECL_POSIX_SPAWN_FILE_ACTIONS_DESTROY
+_GL_WARN_ON_USE (posix_spawn_file_actions_destroy,
+                 "posix_spawn_file_actions_destroy is unportable - "
+                 "use gnulib module posix_spawn_file_actions_destroy for portability");
+# endif
+#endif
+
+#if @GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN@
+/* Add an action to FILE-ACTIONS which tells the implementation to call
+   'open' for the given file during the 'spawn' call.  */
+# if @REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawn_file_actions_addopen rpl_posix_spawn_file_actions_addopen
+#  endif
+_GL_FUNCDECL_RPL (posix_spawn_file_actions_addopen, int,
+                  (posix_spawn_file_actions_t *_Restrict_ __file_actions,
+                   int __fd,
+                   const char *_Restrict_ __path, int __oflag, mode_t __mode)
+                  __THROW _GL_ARG_NONNULL ((1, 3)));
+_GL_CXXALIAS_RPL (posix_spawn_file_actions_addopen, int,
+                  (posix_spawn_file_actions_t *_Restrict_ __file_actions,
+                   int __fd,
+                   const char *_Restrict_ __path, int __oflag, mode_t __mode));
+# else
+#  if !@HAVE_POSIX_SPAWN@
+_GL_FUNCDECL_SYS (posix_spawn_file_actions_addopen, int,
+                  (posix_spawn_file_actions_t *_Restrict_ __file_actions,
+                   int __fd,
+                   const char *_Restrict_ __path, int __oflag, mode_t __mode)
+                  __THROW _GL_ARG_NONNULL ((1, 3)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawn_file_actions_addopen, int,
+                  (posix_spawn_file_actions_t *_Restrict_ __file_actions,
+                   int __fd,
+                   const char *_Restrict_ __path, int __oflag, mode_t __mode));
+# endif
+# if __GLIBC__ >= 2
+_GL_CXXALIASWARN (posix_spawn_file_actions_addopen);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawn_file_actions_addopen
+# if HAVE_RAW_DECL_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN
+_GL_WARN_ON_USE (posix_spawn_file_actions_addopen,
+                 "posix_spawn_file_actions_addopen is unportable - "
+                 "use gnulib module posix_spawn_file_actions_addopen for portability");
+# endif
+#endif
+
+#if @GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE@
+/* Add an action to FILE-ACTIONS which tells the implementation to call
+   'close' for the given file descriptor during the 'spawn' call.  */
+# if @REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawn_file_actions_addclose rpl_posix_spawn_file_actions_addclose
+#  endif
+_GL_FUNCDECL_RPL (posix_spawn_file_actions_addclose, int,
+                  (posix_spawn_file_actions_t *__file_actions, int __fd)
+                  __THROW _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (posix_spawn_file_actions_addclose, int,
+                  (posix_spawn_file_actions_t *__file_actions, int __fd));
+# else
+#  if !@HAVE_POSIX_SPAWN@
+_GL_FUNCDECL_SYS (posix_spawn_file_actions_addclose, int,
+                  (posix_spawn_file_actions_t *__file_actions, int __fd)
+                  __THROW _GL_ARG_NONNULL ((1)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawn_file_actions_addclose, int,
+                  (posix_spawn_file_actions_t *__file_actions, int __fd));
+# endif
+# if __GLIBC__ >= 2
+_GL_CXXALIASWARN (posix_spawn_file_actions_addclose);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawn_file_actions_addclose
+# if HAVE_RAW_DECL_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE
+_GL_WARN_ON_USE (posix_spawn_file_actions_addclose,
+                 "posix_spawn_file_actions_addclose is unportable - "
+                 "use gnulib module posix_spawn_file_actions_addclose for portability");
+# endif
+#endif
+
+#if @GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2@
+/* Add an action to FILE-ACTIONS which tells the implementation to call
+   'dup2' for the given file descriptors during the 'spawn' call.  */
+# if @REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawn_file_actions_adddup2 rpl_posix_spawn_file_actions_adddup2
+#  endif
+_GL_FUNCDECL_RPL (posix_spawn_file_actions_adddup2, int,
+                  (posix_spawn_file_actions_t *__file_actions,
+                   int __fd, int __newfd)
+                  __THROW _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (posix_spawn_file_actions_adddup2, int,
+                  (posix_spawn_file_actions_t *__file_actions,
+                   int __fd, int __newfd));
+# else
+#  if !@HAVE_POSIX_SPAWN@
+_GL_FUNCDECL_SYS (posix_spawn_file_actions_adddup2, int,
+                  (posix_spawn_file_actions_t *__file_actions,
+                   int __fd, int __newfd)
+                  __THROW _GL_ARG_NONNULL ((1)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawn_file_actions_adddup2, int,
+                  (posix_spawn_file_actions_t *__file_actions,
+                   int __fd, int __newfd));
+# endif
+# if __GLIBC__ >= 2
+_GL_CXXALIASWARN (posix_spawn_file_actions_adddup2);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawn_file_actions_adddup2
+# if HAVE_RAW_DECL_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2
+_GL_WARN_ON_USE (posix_spawn_file_actions_adddup2,
+                 "posix_spawn_file_actions_adddup2 is unportable - "
+                 "use gnulib module posix_spawn_file_actions_adddup2 for portability");
+# endif
+#endif
+
+#if @GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR@
+/* Add an action to FILE-ACTIONS which tells the implementation to call
+   'chdir' to the given directory during the 'spawn' call.  */
+# if @REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawn_file_actions_addchdir rpl_posix_spawn_file_actions_addchdir
+#  endif
+_GL_FUNCDECL_RPL (posix_spawn_file_actions_addchdir, int,
+                  (posix_spawn_file_actions_t *_Restrict_ __file_actions,
+                   const char *_Restrict_ __path)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (posix_spawn_file_actions_addchdir, int,
+                  (posix_spawn_file_actions_t *_Restrict_ __file_actions,
+                   const char *_Restrict_ __path));
+# else
+#  if !@HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR@
+_GL_FUNCDECL_SYS (posix_spawn_file_actions_addchdir, int,
+                  (posix_spawn_file_actions_t *_Restrict_ __file_actions,
+                   const char *_Restrict_ __path)
+                  __THROW _GL_ARG_NONNULL ((1, 2)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawn_file_actions_addchdir, int,
+                  (posix_spawn_file_actions_t *_Restrict_ __file_actions,
+                   const char *_Restrict_ __path));
+# endif
+_GL_CXXALIASWARN (posix_spawn_file_actions_addchdir);
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawn_file_actions_addchdir
+# if HAVE_RAW_DECL_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR
+_GL_WARN_ON_USE (posix_spawn_file_actions_addchdir,
+                 "posix_spawn_file_actions_addchdir is unportable - "
+                 "use gnulib module posix_spawn_file_actions_addchdir for portability");
+# endif
+#endif
+
+#if @GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR@
+/* Add an action to FILE-ACTIONS which tells the implementation to call
+   'fchdir' to the given directory during the 'spawn' call.  */
+# if @REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define posix_spawn_file_actions_addfchdir rpl_posix_spawn_file_actions_addfchdir
+#  endif
+_GL_FUNCDECL_RPL (posix_spawn_file_actions_addfchdir, int,
+                  (posix_spawn_file_actions_t *_Restrict_ __file_actions,
+                   int __fd)
+                  __THROW _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (posix_spawn_file_actions_addfchdir, int,
+                  (posix_spawn_file_actions_t *_Restrict_ __file_actions,
+                   int __fd));
+# else
+#  if !@HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR@
+_GL_FUNCDECL_SYS (posix_spawn_file_actions_addfchdir, int,
+                  (posix_spawn_file_actions_t *_Restrict_ __file_actions,
+                   int __fd)
+                  __THROW _GL_ARG_NONNULL ((1)));
+#  endif
+_GL_CXXALIAS_SYS (posix_spawn_file_actions_addfchdir, int,
+                  (posix_spawn_file_actions_t *_Restrict_ __file_actions,
+                   int __fd));
+# endif
+_GL_CXXALIASWARN (posix_spawn_file_actions_addfchdir);
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawn_file_actions_addfchdir
+# if HAVE_RAW_DECL_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR
+_GL_WARN_ON_USE (posix_spawn_file_actions_addfchdir,
+                 "posix_spawn_file_actions_addfchdir is unportable - "
+                 "use gnulib module posix_spawn_file_actions_addfchdir for portability");
+# endif
+#endif
+
+
+#endif /* _@GUARD_PREFIX@_SPAWN_H */
+#endif /* _@GUARD_PREFIX@_SPAWN_H */
+#endif
diff --git a/lib/spawn_int.h b/lib/spawn_int.h
new file mode 100644
index 000000000..93f2b751f
--- /dev/null
+++ b/lib/spawn_int.h
@@ -0,0 +1,72 @@
+/* Copyright (C) 2000, 2008-2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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 2.1 of the
+   License, or (at your option) any later version.
+
+   This file 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+#include <sys/types.h>
+
+/* Data structure to contain the action information.  */
+struct __spawn_action
+{
+  enum
+  {
+    spawn_do_close,
+    spawn_do_dup2,
+    spawn_do_open,
+    spawn_do_chdir,
+    spawn_do_fchdir
+  } tag;
+
+  union
+  {
+    struct
+    {
+      int fd;
+    } close_action;
+    struct
+    {
+      int fd;
+      int newfd;
+    } dup2_action;
+    struct
+    {
+      int fd;
+      char *path;
+      int oflag;
+      mode_t mode;
+    } open_action;
+    struct
+    {
+      char *path;
+    } chdir_action;
+    struct
+    {
+      int fd;
+    } fchdir_action;
+  } action;
+};
+
+#if !_LIBC
+# define __posix_spawn_file_actions_realloc gl_posix_spawn_file_actions_realloc
+#endif
+extern int __posix_spawn_file_actions_realloc (posix_spawn_file_actions_t *
+                                               file_actions);
+
+#if !_LIBC
+# define __spawni gl_posix_spawn_internal
+#endif
+extern int __spawni (pid_t *pid, const char *path,
+                     const posix_spawn_file_actions_t *file_actions,
+                     const posix_spawnattr_t *attrp, const char *const argv[],
+                     const char *const envp[], int use_path);
diff --git a/lib/spawni.c b/lib/spawni.c
new file mode 100644
index 000000000..9bca2002b
--- /dev/null
+++ b/lib/spawni.c
@@ -0,0 +1,965 @@
+/* Guts of POSIX spawn interface.  Generic POSIX.1 version.
+   Copyright (C) 2000-2006, 2008-2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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 2.1 of the
+   License, or (at your option) any later version.
+
+   This file 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include <spawn.h>
+#include "spawn_int.h"
+
+#include <alloca.h>
+#include <errno.h>
+
+#include <fcntl.h>
+#ifndef O_LARGEFILE
+# define O_LARGEFILE 0
+#endif
+
+#if _LIBC || HAVE_PATHS_H
+# include <paths.h>
+#else
+# define _PATH_BSHELL BOURNE_SHELL
+#endif
+
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#if _LIBC
+# include <not-cancel.h>
+#else
+# define close_not_cancel close
+# define open_not_cancel open
+#endif
+
+#if _LIBC
+# include <local-setxid.h>
+#else
+# if !HAVE_SETEUID
+#  define seteuid(id) setresuid (-1, id, -1)
+# endif
+# if !HAVE_SETEGID
+#  define setegid(id) setresgid (-1, id, -1)
+# endif
+# define local_seteuid(id) seteuid (id)
+# define local_setegid(id) setegid (id)
+#endif
+
+#if _LIBC
+# define alloca __alloca
+# define execve __execve
+# define dup2 __dup2
+# define fork __fork
+# define getgid __getgid
+# define getuid __getuid
+# define sched_setparam __sched_setparam
+# define sched_setscheduler __sched_setscheduler
+# define setpgid __setpgid
+# define sigaction __sigaction
+# define sigismember __sigismember
+# define sigprocmask __sigprocmask
+# define strchrnul __strchrnul
+# define vfork __vfork
+#endif
+
+
+/* The Unix standard contains a long explanation of the way to signal
+   an error after the fork() was successful.  Since no new wait status
+   was wanted there is no way to signal an error using one of the
+   available methods.  The committee chose to signal an error by a
+   normal program exit with the exit code 127.  */
+#define SPAWN_ERROR     127
+
+
+#if defined _WIN32 && ! defined __CYGWIN__
+/* Native Windows API.  */
+
+/* Get declarations of the native Windows API functions.  */
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+
+# include <stdbool.h>
+# include <stdio.h>
+
+# include "filename.h"
+# include "concat-filename.h"
+# include "findprog.h"
+# include "malloca.h"
+# include "windows-spawn.h"
+
+/* Don't assume that UNICODE is not defined.  */
+# undef CreateFile
+# define CreateFile CreateFileA
+# undef STARTUPINFO
+# define STARTUPINFO STARTUPINFOA
+# undef CreateProcess
+# define CreateProcess CreateProcessA
+
+/* Grows inh_handles->count so that it becomes > newfd.
+   Returns 0 upon success.  In case of failure, -1 is returned, with errno set.
+ */
+static int
+grow_inheritable_handles (struct inheritable_handles *inh_handles, int newfd)
+{
+  if (inh_handles->allocated <= newfd)
+    {
+      size_t new_allocated = 2 * inh_handles->allocated + 1;
+      if (new_allocated <= newfd)
+        new_allocated = newfd + 1;
+      HANDLE *new_handles_array =
+        (HANDLE *)
+        realloc (inh_handles->handles, new_allocated * sizeof (HANDLE));
+      if (new_handles_array == NULL)
+        {
+          errno = ENOMEM;
+          return -1;
+        }
+      unsigned char *new_flags_array =
+        (unsigned char *)
+        realloc (inh_handles->flags, new_allocated * sizeof (unsigned char));
+      if (new_flags_array == NULL)
+        {
+          free (new_handles_array);
+          errno = ENOMEM;
+          return -1;
+        }
+      inh_handles->allocated = new_allocated;
+      inh_handles->handles = new_handles_array;
+      inh_handles->flags = new_flags_array;
+    }
+
+  HANDLE *handles = inh_handles->handles;
+
+  for (; inh_handles->count <= newfd; inh_handles->count++)
+    handles[inh_handles->count] = INVALID_HANDLE_VALUE;
+
+  return 0;
+}
+
+/* Reduces inh_handles->count to the minimum needed.  */
+static void
+shrink_inheritable_handles (struct inheritable_handles *inh_handles)
+{
+  HANDLE *handles = inh_handles->handles;
+
+  while (inh_handles->count > 3
+         && handles[inh_handles->count - 1] == INVALID_HANDLE_VALUE)
+    inh_handles->count--;
+}
+
+/* Closes all handles in inh_handles.  */
+static void
+close_inheritable_handles (struct inheritable_handles *inh_handles)
+{
+  HANDLE *handles = inh_handles->handles;
+  size_t handles_count = inh_handles->count;
+  unsigned int fd;
+
+  for (fd = 0; fd < handles_count; fd++)
+    {
+      HANDLE handle = handles[fd];
+
+      if (handle != INVALID_HANDLE_VALUE)
+        CloseHandle (handle);
+    }
+}
+
+/* Tests whether a memory region, starting at P and N bytes long, contains only
+   zeroes.  */
+static bool
+memiszero (const void *p, size_t n)
+{
+  const char *cp = p;
+  for (; n > 0; cp++, n--)
+    if (*cp != 0)
+      return 0;
+  return 1;
+}
+
+/* Tests whether *S contains no signals.  */
+static bool
+sigisempty (const sigset_t *s)
+{
+  return memiszero (s, sizeof (sigset_t));
+}
+
+/* Opens a HANDLE to a file.
+   Upon failure, returns INVALID_HANDLE_VALUE with errno set.  */
+static HANDLE
+open_handle (const char *name, int flags, mode_t mode)
+{
+  /* To ease portability.  Like in open.c.  */
+  if (strcmp (name, "/dev/null") == 0)
+    name = "NUL";
+
+  /* POSIX <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13>
+     specifies: "More than two leading <slash> characters shall be treated as
+     a single <slash> character."  */
+  if (ISSLASH (name[0]) && ISSLASH (name[1]) && ISSLASH (name[2]))
+    {
+      name += 2;
+      while (ISSLASH (name[1]))
+        name++;
+    }
+
+  size_t len = strlen (name);
+  size_t drive_prefix_len = (HAS_DEVICE (name) ? 2 : 0);
+
+  /* Remove trailing slashes (except the very first one, at position
+     drive_prefix_len), but remember their presence.  */
+  size_t rlen;
+  bool check_dir = false;
+
+  rlen = len;
+  while (rlen > drive_prefix_len && ISSLASH (name[rlen-1]))
+    {
+      check_dir = true;
+      if (rlen == drive_prefix_len + 1)
+        break;
+      rlen--;
+    }
+
+  /* Handle '' and 'C:'.  */
+  if (!check_dir && rlen == drive_prefix_len)
+    {
+      errno = ENOENT;
+      return INVALID_HANDLE_VALUE;
+    }
+
+  /* Handle '\\'.  */
+  if (rlen == 1 && ISSLASH (name[0]) && len >= 2)
+    {
+      errno = ENOENT;
+      return INVALID_HANDLE_VALUE;
+    }
+
+  const char *rname;
+  char *malloca_rname;
+  if (rlen == len)
+    {
+      rname = name;
+      malloca_rname = NULL;
+    }
+  else
+    {
+      malloca_rname = malloca (rlen + 1);
+      if (malloca_rname == NULL)
+        {
+          errno = ENOMEM;
+          return INVALID_HANDLE_VALUE;
+        }
+      memcpy (malloca_rname, name, rlen);
+      malloca_rname[rlen] = '\0';
+      rname = malloca_rname;
+    }
+
+  /* For the meaning of the flags, see
+     <https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/open-wopen>  */
+  /* Open a handle to the file.
+     CreateFile
+     <https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-createfilea>
+     <https://docs.microsoft.com/en-us/windows/desktop/FileIO/creating-and-opening-files>  */
+  HANDLE handle =
+    CreateFile (rname,
+                ((flags & (O_WRONLY | O_RDWR)) != 0
+                 ? GENERIC_READ | GENERIC_WRITE
+                 : GENERIC_READ),
+                FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+                NULL,
+                ((flags & O_CREAT) != 0
+                 ? ((flags & O_EXCL) != 0
+                    ? CREATE_NEW
+                    : ((flags & O_TRUNC) != 0 ? CREATE_ALWAYS : OPEN_ALWAYS))
+                 : ((flags & O_TRUNC) != 0
+                    ? TRUNCATE_EXISTING
+                    : OPEN_EXISTING)),
+                /* FILE_FLAG_BACKUP_SEMANTICS is useful for opening directories,
+                   which is out-of-scope here.  */
+                /* FILE_FLAG_POSIX_SEMANTICS (treat file names that differ only
+                   in case as different) makes sense only when applied to *all*
+                   filesystem operations.  */
+                /* FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_POSIX_SEMANTICS */
+                FILE_ATTRIBUTE_NORMAL
+                | ((flags & O_TEMPORARY) != 0 ? FILE_FLAG_DELETE_ON_CLOSE : 0)
+                | ((flags & O_SEQUENTIAL ) != 0 ? FILE_FLAG_SEQUENTIAL_SCAN : 0)
+                | ((flags & O_RANDOM) != 0 ? FILE_FLAG_RANDOM_ACCESS : 0),
+                NULL);
+  if (handle == INVALID_HANDLE_VALUE)
+    switch (GetLastError ())
+      {
+      /* Some of these errors probably cannot happen with the specific flags
+         that we pass to CreateFile.  But who knows...  */
+      case ERROR_FILE_NOT_FOUND: /* The last component of rname does not exist.  */
+      case ERROR_PATH_NOT_FOUND: /* Some directory component in rname does not exist.  */
+      case ERROR_BAD_PATHNAME:   /* rname is such as '\\server'.  */
+      case ERROR_BAD_NETPATH:    /* rname is such as '\\nonexistentserver\share'.  */
+      case ERROR_BAD_NET_NAME:   /* rname is such as '\\server\nonexistentshare'.  */
+      case ERROR_INVALID_NAME:   /* rname contains wildcards, misplaced colon, etc.  */
+      case ERROR_DIRECTORY:
+        errno = ENOENT;
+        break;
+
+      case ERROR_ACCESS_DENIED:  /* rname is such as 'C:\System Volume Information\foo'.  */
+      case ERROR_SHARING_VIOLATION: /* rname is such as 'C:\pagefile.sys'.  */
+                                    /* XXX map to EACCES or EPERM? */
+        errno = EACCES;
+        break;
+
+      case ERROR_OUTOFMEMORY:
+        errno = ENOMEM;
+        break;
+
+      case ERROR_WRITE_PROTECT:
+        errno = EROFS;
+        break;
+
+      case ERROR_WRITE_FAULT:
+      case ERROR_READ_FAULT:
+      case ERROR_GEN_FAILURE:
+        errno = EIO;
+        break;
+
+      case ERROR_BUFFER_OVERFLOW:
+      case ERROR_FILENAME_EXCED_RANGE:
+        errno = ENAMETOOLONG;
+        break;
+
+      case ERROR_DELETE_PENDING: /* XXX map to EACCES or EPERM? */
+        errno = EPERM;
+        break;
+
+      default:
+        errno = EINVAL;
+        break;
+      }
+
+  if (malloca_rname != NULL)
+    {
+      int saved_errno = errno;
+      freea (malloca_rname);
+      errno = saved_errno;
+    }
+  return handle;
+}
+
+/* Executes an 'open' action.
+   Returns 0 upon success.  In case of failure, -1 is returned, with errno set.
+ */
+static int
+do_open (struct inheritable_handles *inh_handles, int newfd,
+         const char *filename, const char *directory,
+         int flags, mode_t mode, HANDLE curr_process)
+{
+  if (!(newfd >= 0 && newfd < _getmaxstdio ()))
+    {
+      errno = EBADF;
+      return -1;
+    }
+  if (grow_inheritable_handles (inh_handles, newfd) < 0)
+    return -1;
+  if (inh_handles->handles[newfd] != INVALID_HANDLE_VALUE
+      && !CloseHandle (inh_handles->handles[newfd]))
+    {
+      errno = EIO;
+      return -1;
+    }
+  if (filename == NULL)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+  char *filename_to_free = NULL;
+  if (directory != NULL && IS_RELATIVE_FILE_NAME (filename))
+    {
+      char *real_filename = concatenated_filename (directory, filename, NULL);
+      if (real_filename == NULL)
+        {
+          errno = ENOMEM;
+          return -1;
+        }
+      filename = real_filename;
+      filename_to_free = real_filename;
+    }
+  HANDLE handle = open_handle (filename, flags, mode);
+  if (handle == INVALID_HANDLE_VALUE)
+    {
+      free (filename_to_free);
+      return -1;
+    }
+  free (filename_to_free);
+  /* Duplicate the handle, so that it becomes inheritable.  */
+  if (!DuplicateHandle (curr_process, handle,
+                        curr_process, &inh_handles->handles[newfd],
+                        0, TRUE,
+                        DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
+    {
+      errno = EBADF; /* arbitrary */
+      return -1;
+    }
+  inh_handles->flags[newfd] = ((flags & O_APPEND) != 0 ? 32 : 0);
+  return 0;
+}
+
+/* Executes a 'dup2' action.
+   Returns 0 upon success.  In case of failure, -1 is returned, with errno set.
+ */
+static int
+do_dup2 (struct inheritable_handles *inh_handles, int oldfd, int newfd,
+         HANDLE curr_process)
+{
+  if (!(oldfd >= 0 && oldfd < inh_handles->count
+        && inh_handles->handles[oldfd] != INVALID_HANDLE_VALUE))
+    {
+      errno = EBADF;
+      return -1;
+    }
+  if (!(newfd >= 0 && newfd < _getmaxstdio ()))
+    {
+      errno = EBADF;
+      return -1;
+    }
+  if (newfd != oldfd)
+    {
+      if (grow_inheritable_handles (inh_handles, newfd) < 0)
+        return -1;
+      if (inh_handles->handles[newfd] != INVALID_HANDLE_VALUE
+          && !CloseHandle (inh_handles->handles[newfd]))
+        {
+          errno = EIO;
+          return -1;
+        }
+      /* Duplicate the handle, so that it a forthcoming do_close action on oldfd
+         has no effect on newfd.  */
+      if (!DuplicateHandle (curr_process, inh_handles->handles[oldfd],
+                            curr_process, &inh_handles->handles[newfd],
+                            0, TRUE, DUPLICATE_SAME_ACCESS))
+        {
+          errno = EBADF; /* arbitrary */
+          return -1;
+        }
+      inh_handles->flags[newfd] = 0;
+    }
+  return 0;
+}
+
+/* Executes a 'close' action.
+   Returns 0 upon success.  In case of failure, -1 is returned, with errno set.
+ */
+static int
+do_close (struct inheritable_handles *inh_handles, int fd)
+{
+  if (!(fd >= 0 && fd < inh_handles->count
+        && inh_handles->handles[fd] != INVALID_HANDLE_VALUE))
+    {
+      errno = EBADF;
+      return -1;
+    }
+  if (!CloseHandle (inh_handles->handles[fd]))
+    {
+      errno = EIO;
+      return -1;
+    }
+  inh_handles->handles[fd] = INVALID_HANDLE_VALUE;
+  return 0;
+}
+
+int
+__spawni (pid_t *pid, const char *prog_filename,
+          const posix_spawn_file_actions_t *file_actions,
+          const posix_spawnattr_t *attrp, const char *const prog_argv[],
+          const char *const envp[], int use_path)
+{
+  /* Validate the arguments.  */
+  if (prog_filename == NULL
+      || (attrp != NULL
+          && ((attrp->_flags & ~POSIX_SPAWN_SETPGROUP) != 0
+              || attrp->_pgrp != 0
+              || ! sigisempty (&attrp->_sd)
+              || ! sigisempty (&attrp->_ss)
+              || attrp->_sp.sched_priority != 0
+              || attrp->_policy != 0)))
+    return EINVAL;
+
+  /* Process group handling:
+     Native Windows does not have the concept of process group, but it has the
+     concept of a console attached to a process.
+     So, we interpret the three cases as follows:
+       - Flag POSIX_SPAWN_SETPGROUP not set: Means, the child process is in the
+         same process group as the parent process.  We interpret this as a
+         request to reuse the same console.
+       - Flag POSIX_SPAWN_SETPGROUP set with attrp->_pgrp == 0: Means the child
+         process starts a process group of its own.  See
+         <https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_spawnattr_getpgroup.html>
+         <https://pubs.opengroup.org/onlinepubs/9699919799/functions/setpgrp.html>
+         We interpret this as a request to detach from the current console.
+       - Flag POSIX_SPAWN_SETPGROUP set with attrp->_pgrp != 0: Means the child
+         process joins another, existing process group.  See
+         <https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_spawnattr_getpgroup.html>
+         <https://pubs.opengroup.org/onlinepubs/9699919799/functions/setpgid.html>
+         We don't support this case; it produces error EINVAL above.  */
+  /* <https://docs.microsoft.com/en-us/windows/win32/procthread/process-creation-flags>  */
+  DWORD process_creation_flags =
+    (attrp != NULL && (attrp->_flags & POSIX_SPAWN_SETPGROUP) != 0 ? DETACHED_PROCESS : 0);
+
+  char *argv_mem_to_free;
+  const char **argv = prepare_spawn (prog_argv, &argv_mem_to_free);
+  if (argv == NULL)
+    return errno; /* errno is set here */
+  argv++;
+
+  /* Compose the command.  */
+  char *command = compose_command (argv);
+  if (command == NULL)
+    {
+      free (argv_mem_to_free);
+      return ENOMEM;
+    }
+
+  /* Copy *ENVP into a contiguous block of memory.  */
+  char *envblock;
+  if (envp == NULL)
+    envblock = NULL;
+  else
+    {
+      envblock = compose_envblock (envp);
+      if (envblock == NULL)
+        {
+          free (command);
+          free (argv_mem_to_free);
+          return ENOMEM;
+        }
+    }
+
+  /* Set up the array of handles to inherit.
+     Duplicate each handle, so that a spawn_do_close action (below) has no
+     effect on the file descriptors of the current process.  Alternatively,
+     we could store, for each handle, a bit that tells whether it is shared
+     with the current process.  But this is simpler.  */
+  struct inheritable_handles inh_handles;
+  if (init_inheritable_handles (&inh_handles, true) < 0)
+    goto failed_1;
+
+  /* Directory in which to execute the new process.  */
+  const char *directory = NULL;
+
+  /* Execute the file_actions, modifying the inh_handles instead of the
+     file descriptors of the current process.  */
+  if (file_actions != NULL)
+    {
+      HANDLE curr_process = GetCurrentProcess ();
+      int cnt;
+
+      for (cnt = 0; cnt < file_actions->_used; ++cnt)
+        {
+          struct __spawn_action *action = &file_actions->_actions[cnt];
+
+          switch (action->tag)
+            {
+            case spawn_do_close:
+              {
+                int fd = action->action.close_action.fd;
+                if (do_close (&inh_handles, fd) < 0)
+                  goto failed_2;
+              }
+              break;
+
+            case spawn_do_open:
+              {
+                int newfd = action->action.open_action.fd;
+                const char *filename = action->action.open_action.path;
+                int flags = action->action.open_action.oflag;
+                mode_t mode = action->action.open_action.mode;
+                if (do_open (&inh_handles, newfd, filename, directory,
+                             flags, mode, curr_process)
+                    < 0)
+                  goto failed_2;
+              }
+              break;
+
+            case spawn_do_dup2:
+              {
+                int oldfd = action->action.dup2_action.fd;
+                int newfd = action->action.dup2_action.newfd;
+                if (do_dup2 (&inh_handles, oldfd, newfd, curr_process) < 0)
+                  goto failed_2;
+              }
+              break;
+
+            case spawn_do_chdir:
+              {
+                char *newdir = action->action.chdir_action.path;
+                if (directory != NULL && IS_RELATIVE_FILE_NAME (newdir))
+                  {
+                    newdir = concatenated_filename (directory, newdir, NULL);
+                    if (newdir == NULL)
+                      {
+                        errno = ENOMEM;
+                        goto failed_2;
+                      }
+                  }
+                directory = newdir;
+              }
+              break;
+
+            case spawn_do_fchdir:
+              /* Not supported in this implementation.  */
+              errno = EINVAL;
+              goto failed_2;
+            }
+        }
+    }
+
+  /* Reduce inh_handles.count to the minimum needed.  */
+  shrink_inheritable_handles (&inh_handles);
+
+  /* CreateProcess
+     <https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessa>  */
+  /* STARTUPINFO
+     <https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/ns-processthreadsapi-startupinfoa>  */
+  STARTUPINFO sinfo;
+  sinfo.cb = sizeof (STARTUPINFO);
+  sinfo.lpReserved = NULL;
+  sinfo.lpDesktop = NULL;
+  sinfo.lpTitle = NULL;
+  if (compose_handles_block (&inh_handles, &sinfo) < 0)
+    goto failed_2;
+
+  /* Perform the PATH search now, considering the final DIRECTORY.  */
+  char *resolved_prog_filename_to_free = NULL;
+  {
+    const char *resolved_prog_filename =
+      find_in_given_path (prog_filename, use_path ? getenv ("PATH") : "",
+                          directory, false);
+    if (resolved_prog_filename == NULL)
+      goto failed_3;
+    if (resolved_prog_filename != prog_filename)
+      resolved_prog_filename_to_free = (char *) resolved_prog_filename;
+    prog_filename = resolved_prog_filename;
+  }
+
+  PROCESS_INFORMATION pinfo;
+  if (!CreateProcess (prog_filename, command, NULL, NULL, TRUE,
+                      process_creation_flags, envblock, directory, &sinfo,
+                      &pinfo))
+    {
+      DWORD error = GetLastError ();
+
+      free (resolved_prog_filename_to_free);
+      free (sinfo.lpReserved2);
+      close_inheritable_handles (&inh_handles);
+      free_inheritable_handles (&inh_handles);
+      free (envblock);
+      free (command);
+      free (argv_mem_to_free);
+
+      return convert_CreateProcess_error (error);
+    }
+
+  if (pinfo.hThread)
+    CloseHandle (pinfo.hThread);
+
+  free (resolved_prog_filename_to_free);
+  free (sinfo.lpReserved2);
+  close_inheritable_handles (&inh_handles);
+  free_inheritable_handles (&inh_handles);
+  free (envblock);
+  free (command);
+  free (argv_mem_to_free);
+
+  if (pid != NULL)
+    *pid = (intptr_t) pinfo.hProcess;
+  return 0;
+
+ failed_3:
+  {
+    int saved_errno = errno;
+    free (sinfo.lpReserved2);
+    close_inheritable_handles (&inh_handles);
+    free_inheritable_handles (&inh_handles);
+    free (envblock);
+    free (command);
+    free (argv_mem_to_free);
+    return saved_errno;
+  }
+
+ failed_2:
+  {
+    int saved_errno = errno;
+    close_inheritable_handles (&inh_handles);
+    free_inheritable_handles (&inh_handles);
+    free (envblock);
+    free (command);
+    free (argv_mem_to_free);
+    return saved_errno;
+  }
+
+ failed_1:
+  free (envblock);
+  free (command);
+  free (argv_mem_to_free);
+  return errno;
+}
+
+#else
+
+
+/* Spawn a new process executing PATH with the attributes describes in *ATTRP.
+   Before running the process perform the actions described in FILE-ACTIONS. */
+int
+__spawni (pid_t *pid, const char *file,
+          const posix_spawn_file_actions_t *file_actions,
+          const posix_spawnattr_t *attrp, const char *const argv[],
+          const char *const envp[], int use_path)
+{
+  pid_t new_pid;
+  char *path, *p, *name;
+  size_t len;
+  size_t pathlen;
+
+  /* Do this once.  */
+  short int flags = attrp == NULL ? 0 : attrp->_flags;
+
+  /* Avoid gcc warning
+       "variable 'flags' might be clobbered by 'longjmp' or 'vfork'"  */
+  (void) &flags;
+
+  /* Generate the new process.  */
+#if HAVE_VFORK
+  if ((flags & POSIX_SPAWN_USEVFORK) != 0
+      /* If no major work is done, allow using vfork.  Note that we
+         might perform the path searching.  But this would be done by
+         a call to execvp(), too, and such a call must be OK according
+         to POSIX.  */
+      || ((flags & (POSIX_SPAWN_SETSIGMASK | POSIX_SPAWN_SETSIGDEF
+                    | POSIX_SPAWN_SETSCHEDPARAM | POSIX_SPAWN_SETSCHEDULER
+                    | POSIX_SPAWN_SETPGROUP | POSIX_SPAWN_RESETIDS)) == 0
+          && file_actions == NULL))
+    new_pid = vfork ();
+  else
+#endif
+    new_pid = fork ();
+
+  if (new_pid != 0)
+    {
+      if (new_pid < 0)
+        return errno;
+
+      /* The call was successful.  Store the PID if necessary.  */
+      if (pid != NULL)
+        *pid = new_pid;
+
+      return 0;
+    }
+
+  /* Set signal mask.  */
+  if ((flags & POSIX_SPAWN_SETSIGMASK) != 0
+      && sigprocmask (SIG_SETMASK, &attrp->_ss, NULL) != 0)
+    _exit (SPAWN_ERROR);
+
+  /* Set signal default action.  */
+  if ((flags & POSIX_SPAWN_SETSIGDEF) != 0)
+    {
+      /* We have to iterate over all signals.  This could possibly be
+         done better but it requires system specific solutions since
+         the sigset_t data type can be very different on different
+         architectures.  */
+      int sig;
+      struct sigaction sa;
+
+      memset (&sa, '\0', sizeof (sa));
+      sa.sa_handler = SIG_DFL;
+
+      for (sig = 1; sig <= NSIG; ++sig)
+        if (sigismember (&attrp->_sd, sig) != 0
+            && sigaction (sig, &sa, NULL) != 0)
+          _exit (SPAWN_ERROR);
+
+    }
+
+#if (_LIBC ? defined _POSIX_PRIORITY_SCHEDULING : HAVE_SCHED_SETPARAM && HAVE_SCHED_SETSCHEDULER)
+  /* Set the scheduling algorithm and parameters.  */
+  if ((flags & (POSIX_SPAWN_SETSCHEDPARAM | POSIX_SPAWN_SETSCHEDULER))
+      == POSIX_SPAWN_SETSCHEDPARAM)
+    {
+      if (sched_setparam (0, &attrp->_sp) == -1)
+        _exit (SPAWN_ERROR);
+    }
+  else if ((flags & POSIX_SPAWN_SETSCHEDULER) != 0)
+    {
+      if (sched_setscheduler (0, attrp->_policy,
+                              (flags & POSIX_SPAWN_SETSCHEDPARAM) != 0
+                              ? &attrp->_sp : NULL) == -1)
+        _exit (SPAWN_ERROR);
+    }
+#endif
+
+  /* Set the process group ID.  */
+  if ((flags & POSIX_SPAWN_SETPGROUP) != 0
+      && setpgid (0, attrp->_pgrp) != 0)
+    _exit (SPAWN_ERROR);
+
+  /* Set the effective user and group IDs.  */
+  if ((flags & POSIX_SPAWN_RESETIDS) != 0
+      && (local_seteuid (getuid ()) != 0
+          || local_setegid (getgid ()) != 0))
+    _exit (SPAWN_ERROR);
+
+  /* Execute the file actions.  */
+  if (file_actions != NULL)
+    {
+      int cnt;
+
+      for (cnt = 0; cnt < file_actions->_used; ++cnt)
+        {
+          struct __spawn_action *action = &file_actions->_actions[cnt];
+
+          switch (action->tag)
+            {
+            case spawn_do_close:
+              if (close_not_cancel (action->action.close_action.fd) != 0)
+                /* Signal the error.  */
+                _exit (SPAWN_ERROR);
+              break;
+
+            case spawn_do_open:
+              {
+                int new_fd = open_not_cancel (action->action.open_action.path,
+                                              action->action.open_action.oflag
+                                              | O_LARGEFILE,
+                                              action->action.open_action.mode);
+
+                if (new_fd == -1)
+                  /* The 'open' call failed.  */
+                  _exit (SPAWN_ERROR);
+
+                /* Make sure the desired file descriptor is used.  */
+                if (new_fd != action->action.open_action.fd)
+                  {
+                    if (dup2 (new_fd, action->action.open_action.fd)
+                        != action->action.open_action.fd)
+                      /* The 'dup2' call failed.  */
+                      _exit (SPAWN_ERROR);
+
+                    if (close_not_cancel (new_fd) != 0)
+                      /* The 'close' call failed.  */
+                      _exit (SPAWN_ERROR);
+                  }
+              }
+              break;
+
+            case spawn_do_dup2:
+              if (dup2 (action->action.dup2_action.fd,
+                        action->action.dup2_action.newfd)
+                  != action->action.dup2_action.newfd)
+                /* The 'dup2' call failed.  */
+                _exit (SPAWN_ERROR);
+              break;
+
+            case spawn_do_chdir:
+              if (chdir (action->action.chdir_action.path) < 0)
+                /* The 'chdir' call failed.  */
+                _exit (SPAWN_ERROR);
+              break;
+
+            case spawn_do_fchdir:
+              if (fchdir (action->action.fchdir_action.fd) < 0)
+                /* The 'fchdir' call failed.  */
+                _exit (SPAWN_ERROR);
+              break;
+            }
+        }
+    }
+
+  if (! use_path || strchr (file, '/') != NULL)
+    {
+      /* The FILE parameter is actually a path.  */
+      execve (file, (char * const *) argv, (char * const *) envp);
+
+      /* Oh, oh.  'execve' returns.  This is bad.  */
+      _exit (SPAWN_ERROR);
+    }
+
+  /* We have to search for FILE on the path.  */
+  path = getenv ("PATH");
+  if (path == NULL)
+    {
+#if HAVE_CONFSTR
+      /* There is no 'PATH' in the environment.
+         The default search path is the current directory
+         followed by the path 'confstr' returns for '_CS_PATH'.  */
+      len = confstr (_CS_PATH, (char *) NULL, 0);
+      path = (char *) alloca (1 + len);
+      path[0] = ':';
+      (void) confstr (_CS_PATH, path + 1, len);
+#else
+      /* Pretend that the PATH contains only the current directory.  */
+      path = "";
+#endif
+    }
+
+  len = strlen (file) + 1;
+  pathlen = strlen (path);
+  name = alloca (pathlen + len + 1);
+  /* Copy the file name at the top.  */
+  name = (char *) memcpy (name + pathlen + 1, file, len);
+  /* And add the slash.  */
+  *--name = '/';
+
+  p = path;
+  do
+    {
+      char *startp;
+
+      path = p;
+      p = strchrnul (path, ':');
+
+      if (p == path)
+        /* Two adjacent colons, or a colon at the beginning or the end
+           of 'PATH' means to search the current directory.  */
+        startp = name + 1;
+      else
+        startp = (char *) memcpy (name - (p - path), path, p - path);
+
+      /* Try to execute this name.  If it works, execv will not return.  */
+      execve (startp, (char * const *) argv, (char * const *) envp);
+
+      switch (errno)
+        {
+        case EACCES:
+        case ENOENT:
+        case ESTALE:
+        case ENOTDIR:
+          /* Those errors indicate the file is missing or not executable
+             by us, in which case we want to just try the next path
+             directory.  */
+          break;
+
+        default:
+          /* Some other error means we found an executable file, but
+             something went wrong executing it; return the error to our
+             caller.  */
+          _exit (SPAWN_ERROR);
+        }
+    }
+  while (*p++ != '\0');
+
+  /* Return with an error.  */
+  _exit (SPAWN_ERROR);
+}
+
+#endif
diff --git a/lib/spawnp.c b/lib/spawnp.c
new file mode 100644
index 000000000..27d9e1692
--- /dev/null
+++ b/lib/spawnp.c
@@ -0,0 +1,34 @@
+/* Copyright (C) 2000, 2009-2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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 2.1 of the
+   License, or (at your option) any later version.
+
+   This file 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include <spawn.h>
+
+#include "spawn_int.h"
+
+/* Spawn a new process executing FILE with the attributes describes in *ATTRP.
+   Before running the process perform the actions described in FILE-ACTIONS. */
+int
+posix_spawnp (pid_t *pid, const char *file,
+              const posix_spawn_file_actions_t *file_actions,
+              const posix_spawnattr_t *attrp, char *const argv[],
+              char *const envp[])
+{
+  return __spawni (pid, file, file_actions, attrp,
+                   (const char * const *) argv, (const char * const *) envp, 1);
+}
diff --git a/lib/stat-time.c b/lib/stat-time.c
index 7b9279269..3d48a2b5b 100644
--- a/lib/stat-time.c
+++ b/lib/stat-time.c
@@ -1,6 +1,6 @@
 /* stat-related time functions.
 
-   Copyright (C) 2012-2021 Free Software Foundation, Inc.
+   Copyright (C) 2012-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/stat-time.h b/lib/stat-time.h
index fe3483d63..6b0088e32 100644
--- a/lib/stat-time.h
+++ b/lib/stat-time.h
@@ -1,6 +1,6 @@
 /* stat-related time functions.
 
-   Copyright (C) 2005, 2007, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2005, 2007, 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
@@ -102,7 +102,7 @@ get_stat_mtime_ns (struct stat const *st)
 
 /* Return the nanosecond component of *ST's birth time.  */
 _GL_STAT_TIME_INLINE long int _GL_ATTRIBUTE_PURE
-get_stat_birthtime_ns (struct stat const *st _GL_UNUSED)
+get_stat_birthtime_ns (_GL_UNUSED struct stat const *st)
 {
 # if defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC
   return STAT_TIMESPEC (st, st_birthtim).tv_nsec;
@@ -158,7 +158,7 @@ get_stat_mtime (struct stat const *st)
 /* Return *ST's birth time, if available; otherwise return a value
    with tv_sec and tv_nsec both equal to -1.  */
 _GL_STAT_TIME_INLINE struct timespec _GL_ATTRIBUTE_PURE
-get_stat_birthtime (struct stat const *st _GL_UNUSED)
+get_stat_birthtime (_GL_UNUSED struct stat const *st)
 {
   struct timespec t;
 
@@ -208,7 +208,7 @@ get_stat_birthtime (struct stat const *st _GL_UNUSED)
    errno to EOVERFLOW if normalization overflowed.  This function
    is intended to be private to this .h file.  */
 _GL_STAT_TIME_INLINE int
-stat_time_normalize (int result, struct stat *st _GL_UNUSED)
+stat_time_normalize (int result, _GL_UNUSED struct stat *st)
 {
 #if defined __sun && defined STAT_TIMESPEC
   if (result == 0)
diff --git a/lib/stat-w32.c b/lib/stat-w32.c
index 4164199b6..c1a292397 100644
--- a/lib/stat-w32.c
+++ b/lib/stat-w32.c
@@ -1,5 +1,5 @@
 /* Core of implementation of fstat and stat for native Windows.
-   Copyright (C) 2017-2021 Free Software Foundation, Inc.
+   Copyright (C) 2017-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/stat-w32.h b/lib/stat-w32.h
index 5b56c09dd..0f79d6141 100644
--- a/lib/stat-w32.h
+++ b/lib/stat-w32.h
@@ -1,5 +1,5 @@
 /* Core of implementation of fstat and stat for native Windows.
-   Copyright (C) 2017-2021 Free Software Foundation, Inc.
+   Copyright (C) 2017-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/stat.c b/lib/stat.c
index bc9a767d3..574489ac7 100644
--- a/lib/stat.c
+++ b/lib/stat.c
@@ -1,5 +1,5 @@
 /* Work around platform bugs in stat.
-   Copyright (C) 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/stdalign.in.h b/lib/stdalign.in.h
index 592d58e37..3b117df11 100644
--- a/lib/stdalign.in.h
+++ b/lib/stdalign.in.h
@@ -1,6 +1,6 @@
 /* A substitute for ISO C11 <stdalign.h>.
 
-   Copyright 2011-2021 Free Software Foundation, Inc.
+   Copyright 2011-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/stdbool.h b/lib/stdbool.h
new file mode 100644
index 000000000..193e4a534
--- /dev/null
+++ b/lib/stdbool.h
@@ -0,0 +1,116 @@
+/* DO NOT EDIT! GENERATED AUTOMATICALLY! */
+/* Copyright (C) 2001-2003, 2006-2022 Free Software Foundation, Inc.
+   Written by Bruno Haible <haible@clisp.cons.org>, 2001.
+
+   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 2.1 of the
+   License, or (at your option) any later version.
+
+   This file 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+#ifndef _GL_STDBOOL_H
+#define _GL_STDBOOL_H
+
+/* ISO C 99 <stdbool.h> for platforms that lack it.  */
+
+/* Usage suggestions:
+
+   Programs that use <stdbool.h> should be aware of some limitations
+   and standards compliance issues.
+
+   Standards compliance:
+
+       - <stdbool.h> must be #included before 'bool', 'false', 'true'
+         can be used.
+
+       - You cannot assume that sizeof (bool) == 1.
+
+       - Programs should not undefine the macros bool, true, and false,
+         as C99 lists that as an "obsolescent feature".
+
+   Limitations of this substitute, when used in a C89 environment:
+
+       - <stdbool.h> must be #included before the '_Bool' type can be used.
+
+       - You cannot assume that _Bool is a typedef; it might be a macro.
+
+       - Bit-fields of type 'bool' are not supported.  Portable code
+         should use 'unsigned int foo : 1;' rather than 'bool foo : 1;'.
+
+       - In C99, casts and automatic conversions to '_Bool' or 'bool' are
+         performed in such a way that every nonzero value gets converted
+         to 'true', and zero gets converted to 'false'.  This doesn't work
+         with this substitute.  With this substitute, only the values 0 and 1
+         give the expected result when converted to _Bool' or 'bool'.
+
+       - C99 allows the use of (_Bool)0.0 in constant expressions, but
+         this substitute cannot always provide this property.
+
+   Also, it is suggested that programs use 'bool' rather than '_Bool';
+   this isn't required, but 'bool' is more common.  */
+
+
+/* 7.16. Boolean type and values */
+
+#ifdef __cplusplus
+# define _Bool bool
+# define bool bool
+#else
+# if !defined __GNUC__
+   /* If 1:
+        Some HP-UX cc and AIX IBM C compiler versions have compiler bugs when
+        the built-in _Bool type is used.  See
+          https://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html
+          https://lists.gnu.org/r/bug-coreutils/2005-11/msg00161.html
+          https://lists.gnu.org/r/bug-coreutils/2005-10/msg00086.html
+        Similar bugs are likely with other compilers as well; this file
+        wouldn't be used if <stdbool.h> was working.
+        So we override the _Bool type.
+      If !1:
+        Need to define _Bool ourselves. As 'signed char' or as an enum type?
+        Use of a typedef, with SunPRO C, leads to a stupid
+          "warning: _Bool is a keyword in ISO C99".
+        Use of an enum type, with IRIX cc, leads to a stupid
+          "warning(1185): enumerated type mixed with another type".
+        Even the existence of an enum type, without a typedef,
+          "Invalid enumerator. (badenum)" with HP-UX cc on Tru64.
+        The only benefit of the enum, debuggability, is not important
+        with these compilers.  So use 'signed char' and no enum.  */
+#  define _Bool signed char
+# else
+   /* With this compiler, trust the _Bool type if the compiler has it.  */
+#  if !1
+   /* For the sake of symbolic names in gdb, define true and false as
+      enum constants, not only as macros.
+      It is tempting to write
+         typedef enum { false = 0, true = 1 } _Bool;
+      so that gdb prints values of type 'bool' symbolically.  But then
+      values of type '_Bool' might promote to 'int' or 'unsigned int'
+      (see ISO C 99 6.7.2.2.(4)); however, '_Bool' must promote to 'int'
+      (see ISO C 99 6.3.1.1.(2)).  So add a negative value to the
+      enum; this ensures that '_Bool' promotes to 'int'.  */
+typedef enum { _Bool_must_promote_to_int = -1, false = 0, true = 1 } _Bool;
+#  endif
+# endif
+# define bool _Bool
+#endif
+
+/* The other macros must be usable in preprocessor directives.  */
+#ifdef __cplusplus
+# define false false
+# define true true
+#else
+# define false 0
+# define true 1
+#endif
+
+#define __bool_true_false_are_defined 1
+
+#endif /* _GL_STDBOOL_H */
diff --git a/lib/stdbool.in.h b/lib/stdbool.in.h
index 2a1992da8..2fa46724b 100644
--- a/lib/stdbool.in.h
+++ b/lib/stdbool.in.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2003, 2006-2021 Free Software Foundation, Inc.
+/* Copyright (C) 2001-2003, 2006-2022 Free Software Foundation, Inc.
    Written by Bruno Haible <haible@clisp.cons.org>, 2001.
 
    This file is free software: you can redistribute it and/or modify
@@ -58,27 +58,11 @@
 
 /* 7.16. Boolean type and values */
 
-/* BeOS <sys/socket.h> already #defines false 0, true 1.  We use the same
-   definitions below, but temporarily we have to #undef them.  */
-#if defined __BEOS__ && !defined __HAIKU__
-# include <OS.h> /* defines bool but not _Bool */
-# undef false
-# undef true
-#endif
-
 #ifdef __cplusplus
 # define _Bool bool
 # define bool bool
 #else
-# if defined __BEOS__ && !defined __HAIKU__
-  /* A compiler known to have 'bool'.  */
-  /* If the compiler already has both 'bool' and '_Bool', we can assume they
-     are the same types.  */
-#  if !@HAVE__BOOL@
-typedef bool _Bool;
-#  endif
-# else
-#  if !defined __GNUC__
+# if !defined __GNUC__
    /* If @HAVE__BOOL@:
         Some HP-UX cc and AIX IBM C compiler versions have compiler bugs when
         the built-in _Bool type is used.  See
@@ -98,10 +82,10 @@ typedef bool _Bool;
           "Invalid enumerator. (badenum)" with HP-UX cc on Tru64.
         The only benefit of the enum, debuggability, is not important
         with these compilers.  So use 'signed char' and no enum.  */
-#   define _Bool signed char
-#  else
+#  define _Bool signed char
+# else
    /* With this compiler, trust the _Bool type if the compiler has it.  */
-#   if !@HAVE__BOOL@
+#  if !@HAVE__BOOL@
    /* For the sake of symbolic names in gdb, define true and false as
       enum constants, not only as macros.
       It is tempting to write
@@ -112,7 +96,6 @@ typedef bool _Bool;
       (see ISO C 99 6.3.1.1.(2)).  So add a negative value to the
       enum; this ensures that '_Bool' promotes to 'int'.  */
 typedef enum { _Bool_must_promote_to_int = -1, false = 0, true = 1 } _Bool;
-#   endif
 #  endif
 # endif
 # define bool _Bool
diff --git a/lib/stdckdint.h b/lib/stdckdint.h
new file mode 100644
index 000000000..8eeac9094
--- /dev/null
+++ b/lib/stdckdint.h
@@ -0,0 +1,38 @@
+/* DO NOT EDIT! GENERATED AUTOMATICALLY! */
+/* stdckdint.h -- checked integer arithmetic
+
+   Copyright 2022 Free Software Foundation, Inc.
+
+   This program 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 2.1 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+#ifndef _GL_STDCKDINT_H
+#define _GL_STDCKDINT_H
+
+#include "intprops-internal.h"
+
+#include <stdbool.h>
+
+/* Store into *R the low-order bits of A + B, A - B, A * B, respectively.
+   Return 1 if the result overflows, 0 otherwise.
+   A, B, and *R can have any integer type other than char, bool, a
+   bit-precise integer type, or an enumeration type.
+
+   These are like the standard macros introduced in C23, except that
+   arguments should not have side effects.  */
+
+#define ckd_add(r, a, b) ((bool) _GL_INT_ADD_WRAPV (a, b, r))
+#define ckd_sub(r, a, b) ((bool) _GL_INT_SUBTRACT_WRAPV (a, b, r))
+#define ckd_mul(r, a, b) ((bool) _GL_INT_MULTIPLY_WRAPV (a, b, r))
+
+#endif /* _GL_STDCKDINT_H */
diff --git a/lib/stdckdint.in.h b/lib/stdckdint.in.h
new file mode 100644
index 000000000..90fa62e59
--- /dev/null
+++ b/lib/stdckdint.in.h
@@ -0,0 +1,37 @@
+/* stdckdint.h -- checked integer arithmetic
+
+   Copyright 2022 Free Software Foundation, Inc.
+
+   This program 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 2.1 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+#ifndef _GL_STDCKDINT_H
+#define _GL_STDCKDINT_H
+
+#include "intprops-internal.h"
+
+#include <stdbool.h>
+
+/* Store into *R the low-order bits of A + B, A - B, A * B, respectively.
+   Return 1 if the result overflows, 0 otherwise.
+   A, B, and *R can have any integer type other than char, bool, a
+   bit-precise integer type, or an enumeration type.
+
+   These are like the standard macros introduced in C23, except that
+   arguments should not have side effects.  */
+
+#define ckd_add(r, a, b) ((bool) _GL_INT_ADD_WRAPV (a, b, r))
+#define ckd_sub(r, a, b) ((bool) _GL_INT_SUBTRACT_WRAPV (a, b, r))
+#define ckd_mul(r, a, b) ((bool) _GL_INT_MULTIPLY_WRAPV (a, b, r))
+
+#endif /* _GL_STDCKDINT_H */
diff --git a/lib/stddef.in.h b/lib/stddef.in.h
index 42290d448..5c9a747d7 100644
--- a/lib/stddef.in.h
+++ b/lib/stddef.in.h
@@ -1,6 +1,6 @@
 /* A substitute for POSIX 2008 <stddef.h>, for platforms that have issues.
 
-   Copyright (C) 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/stdint.in.h b/lib/stdint.in.h
index 85c5418f1..eaa7874f5 100644
--- a/lib/stdint.in.h
+++ b/lib/stdint.in.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2002, 2004-2021 Free Software Foundation, Inc.
+/* Copyright (C) 2001-2002, 2004-2022 Free Software Foundation, Inc.
    Written by Paul Eggert, Bruno Haible, Sam Steingold, Peter Burwood.
    This file is part of gnulib.
 
diff --git a/lib/stdio-read.c b/lib/stdio-read.c
new file mode 100644
index 000000000..85efa0d44
--- /dev/null
+++ b/lib/stdio-read.c
@@ -0,0 +1,168 @@
+/* POSIX compatible FILE stream read function.
+   Copyright (C) 2008-2022 Free Software Foundation, Inc.
+   Written by Bruno Haible <bruno@clisp.org>, 2011.
+
+   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 2.1 of the
+   License, or (at your option) any later version.
+
+   This file 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include <stdio.h>
+
+/* Replace these functions only if module 'nonblocking' is requested.  */
+#if GNULIB_NONBLOCKING
+
+/* On native Windows platforms, when read() is called on a non-blocking pipe
+   with an empty buffer, ReadFile() fails with error GetLastError() =
+   ERROR_NO_DATA, and read() in consequence fails with error EINVAL.  This
+   read() function is at the basis of the function which fills the buffer of
+   a FILE stream.  */
+
+# if defined _WIN32 && ! defined __CYGWIN__
+
+#  include <errno.h>
+#  include <io.h>
+
+#  define WIN32_LEAN_AND_MEAN  /* avoid including junk */
+#  include <windows.h>
+
+#  if GNULIB_MSVC_NOTHROW
+#   include "msvc-nothrow.h"
+#  else
+#   include <io.h>
+#  endif
+
+/* Don't assume that UNICODE is not defined.  */
+#  undef GetNamedPipeHandleState
+#  define GetNamedPipeHandleState GetNamedPipeHandleStateA
+
+#  define CALL_WITH_ERRNO_FIX(RETTYPE, EXPRESSION, FAILED) \
+  if (ferror (stream))                                                        \
+    return (EXPRESSION);                                                      \
+  else                                                                        \
+    {                                                                         \
+      RETTYPE ret;                                                            \
+      SetLastError (0);                                                       \
+      ret = (EXPRESSION);                                                     \
+      if (FAILED)                                                             \
+        {                                                                     \
+          if (GetLastError () == ERROR_NO_DATA && ferror (stream))            \
+            {                                                                 \
+              int fd = fileno (stream);                                       \
+              if (fd >= 0)                                                    \
+                {                                                             \
+                  HANDLE h = (HANDLE) _get_osfhandle (fd);                    \
+                  if (GetFileType (h) == FILE_TYPE_PIPE)                      \
+                    {                                                         \
+                      /* h is a pipe or socket.  */                           \
+                      DWORD state;                                            \
+                      if (GetNamedPipeHandleState (h, &state, NULL, NULL,     \
+                                                   NULL, NULL, 0)             \
+                          && (state & PIPE_NOWAIT) != 0)                      \
+                        /* h is a pipe in non-blocking mode.                  \
+                           Change errno from EINVAL to EAGAIN.  */            \
+                        errno = EAGAIN;                                       \
+                    }                                                         \
+                }                                                             \
+            }                                                                 \
+        }                                                                     \
+      return ret;                                                             \
+    }
+
+/* Enable this function definition only if gnulib's <stdio.h> has prepared it.
+   Otherwise we get a function definition conflict with mingw64's <stdio.h>.  */
+#  if GNULIB_SCANF
+int
+scanf (const char *format, ...)
+{
+  int retval;
+  va_list args;
+
+  va_start (args, format);
+  retval = vfscanf (stdin, format, args);
+  va_end (args);
+
+  return retval;
+}
+#  endif
+
+/* Enable this function definition only if gnulib's <stdio.h> has prepared it.
+   Otherwise we get a function definition conflict with mingw64's <stdio.h>.  */
+#  if GNULIB_FSCANF
+int
+fscanf (FILE *stream, const char *format, ...)
+{
+  int retval;
+  va_list args;
+
+  va_start (args, format);
+  retval = vfscanf (stream, format, args);
+  va_end (args);
+
+  return retval;
+}
+#  endif
+
+/* Enable this function definition only if gnulib's <stdio.h> has prepared it.
+   Otherwise we get a function definition conflict with mingw64's <stdio.h>.  */
+#  if GNULIB_VSCANF
+int
+vscanf (const char *format, va_list args)
+{
+  return vfscanf (stdin, format, args);
+}
+#  endif
+
+/* Enable this function definition only if gnulib's <stdio.h> has prepared it.
+   Otherwise we get a function definition conflict with mingw64's <stdio.h>.  */
+#  if GNULIB_VFSCANF
+int
+vfscanf (FILE *stream, const char *format, va_list args)
+#undef vfscanf
+{
+  CALL_WITH_ERRNO_FIX (int, vfscanf (stream, format, args), ret == EOF)
+}
+#  endif
+
+int
+getchar (void)
+{
+  return fgetc (stdin);
+}
+
+int
+fgetc (FILE *stream)
+#undef fgetc
+{
+  CALL_WITH_ERRNO_FIX (int, fgetc (stream), ret == EOF)
+}
+
+char *
+fgets (char *s, int n, FILE *stream)
+#undef fgets
+{
+  CALL_WITH_ERRNO_FIX (char *, fgets (s, n, stream), ret == NULL)
+}
+
+/* We intentionally don't bother to fix gets.  */
+
+size_t
+fread (void *ptr, size_t s, size_t n, FILE *stream)
+#undef fread
+{
+  CALL_WITH_ERRNO_FIX (size_t, fread (ptr, s, n, stream), ret < n)
+}
+
+# endif
+#endif
diff --git a/lib/stdio-write.c b/lib/stdio-write.c
new file mode 100644
index 000000000..82facf545
--- /dev/null
+++ b/lib/stdio-write.c
@@ -0,0 +1,206 @@
+/* POSIX compatible FILE stream write function.
+   Copyright (C) 2008-2022 Free Software Foundation, Inc.
+   Written by Bruno Haible <bruno@clisp.org>, 2008.
+
+   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 2.1 of the
+   License, or (at your option) any later version.
+
+   This file 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include <stdio.h>
+
+/* Replace these functions only if module 'nonblocking' or module 'sigpipe' is
+   requested.  */
+#if GNULIB_NONBLOCKING || GNULIB_SIGPIPE
+
+/* On native Windows platforms, SIGPIPE does not exist.  When write() is
+   called on a pipe with no readers, WriteFile() fails with error
+   GetLastError() = ERROR_NO_DATA, and write() in consequence fails with
+   error EINVAL.  This write() function is at the basis of the function
+   which flushes the buffer of a FILE stream.  */
+
+# if defined _WIN32 && ! defined __CYGWIN__
+
+#  include <errno.h>
+#  include <signal.h>
+#  include <io.h>
+
+#  define WIN32_LEAN_AND_MEAN  /* avoid including junk */
+#  include <windows.h>
+
+#  if GNULIB_MSVC_NOTHROW
+#   include "msvc-nothrow.h"
+#  else
+#   include <io.h>
+#  endif
+
+/* Don't assume that UNICODE is not defined.  */
+#  undef GetNamedPipeHandleState
+#  define GetNamedPipeHandleState GetNamedPipeHandleStateA
+
+#  if GNULIB_NONBLOCKING
+#   define CLEAR_ERRNO \
+      errno = 0;
+#   define HANDLE_ENOSPC \
+          if (errno == ENOSPC && ferror (stream))                             \
+            {                                                                 \
+              int fd = fileno (stream);                                       \
+              if (fd >= 0)                                                    \
+                {                                                             \
+                  HANDLE h = (HANDLE) _get_osfhandle (fd);                    \
+                  if (GetFileType (h) == FILE_TYPE_PIPE)                      \
+                    {                                                         \
+                      /* h is a pipe or socket.  */                           \
+                      DWORD state;                                            \
+                      if (GetNamedPipeHandleState (h, &state, NULL, NULL,     \
+                                                   NULL, NULL, 0)             \
+                          && (state & PIPE_NOWAIT) != 0)                      \
+                        /* h is a pipe in non-blocking mode.                  \
+                           Change errno from ENOSPC to EAGAIN.  */            \
+                        errno = EAGAIN;                                       \
+                    }                                                         \
+                }                                                             \
+            }                                                                 \
+          else
+#  else
+#   define CLEAR_ERRNO
+#   define HANDLE_ENOSPC
+#  endif
+
+#  if GNULIB_SIGPIPE
+#   define CLEAR_LastError \
+      SetLastError (0);
+#   define HANDLE_ERROR_NO_DATA \
+          if (GetLastError () == ERROR_NO_DATA && ferror (stream))            \
+            {                                                                 \
+              int fd = fileno (stream);                                       \
+              if (fd >= 0                                                     \
+                  && GetFileType ((HANDLE) _get_osfhandle (fd))               \
+                     == FILE_TYPE_PIPE)                                       \
+                {                                                             \
+                  /* Try to raise signal SIGPIPE.  */                         \
+                  raise (SIGPIPE);                                            \
+                  /* If it is currently blocked or ignored, change errno from \
+                     EINVAL to EPIPE.  */                                     \
+                  errno = EPIPE;                                              \
+                }                                                             \
+            }                                                                 \
+          else
+#  else
+#   define CLEAR_LastError
+#   define HANDLE_ERROR_NO_DATA
+#  endif
+
+#  define CALL_WITH_SIGPIPE_EMULATION(RETTYPE, EXPRESSION, FAILED) \
+  if (ferror (stream))                                                        \
+    return (EXPRESSION);                                                      \
+  else                                                                        \
+    {                                                                         \
+      RETTYPE ret;                                                            \
+      CLEAR_ERRNO                                                             \
+      CLEAR_LastError                                                         \
+      ret = (EXPRESSION);                                                     \
+      if (FAILED)                                                             \
+        {                                                                     \
+          HANDLE_ENOSPC                                                       \
+          HANDLE_ERROR_NO_DATA                                                \
+          ;                                                                   \
+        }                                                                     \
+      return ret;                                                             \
+    }
+
+#  if !REPLACE_PRINTF_POSIX /* avoid collision with printf.c */
+int
+printf (const char *format, ...)
+{
+  int retval;
+  va_list args;
+
+  va_start (args, format);
+  retval = vfprintf (stdout, format, args);
+  va_end (args);
+
+  return retval;
+}
+#  endif
+
+#  if !REPLACE_FPRINTF_POSIX /* avoid collision with fprintf.c */
+int
+fprintf (FILE *stream, const char *format, ...)
+{
+  int retval;
+  va_list args;
+
+  va_start (args, format);
+  retval = vfprintf (stream, format, args);
+  va_end (args);
+
+  return retval;
+}
+#  endif
+
+#  if !REPLACE_VPRINTF_POSIX /* avoid collision with vprintf.c */
+int
+vprintf (const char *format, va_list args)
+{
+  return vfprintf (stdout, format, args);
+}
+#  endif
+
+#  if !REPLACE_VFPRINTF_POSIX /* avoid collision with vfprintf.c */
+int
+vfprintf (FILE *stream, const char *format, va_list args)
+#undef vfprintf
+{
+  CALL_WITH_SIGPIPE_EMULATION (int, vfprintf (stream, format, args), ret == EOF)
+}
+#  endif
+
+int
+putchar (int c)
+{
+  return fputc (c, stdout);
+}
+
+int
+fputc (int c, FILE *stream)
+#undef fputc
+{
+  CALL_WITH_SIGPIPE_EMULATION (int, fputc (c, stream), ret == EOF)
+}
+
+int
+fputs (const char *string, FILE *stream)
+#undef fputs
+{
+  CALL_WITH_SIGPIPE_EMULATION (int, fputs (string, stream), ret == EOF)
+}
+
+int
+puts (const char *string)
+#undef puts
+{
+  FILE *stream = stdout;
+  CALL_WITH_SIGPIPE_EMULATION (int, puts (string), ret == EOF)
+}
+
+size_t
+fwrite (const void *ptr, size_t s, size_t n, FILE *stream)
+#undef fwrite
+{
+  CALL_WITH_SIGPIPE_EMULATION (size_t, fwrite (ptr, s, n, stream), ret < n)
+}
+
+# endif
+#endif
diff --git a/lib/stdio.in.h b/lib/stdio.in.h
index f1bf81732..7b36dac2f 100644
--- a/lib/stdio.in.h
+++ b/lib/stdio.in.h
@@ -1,6 +1,6 @@
 /* A GNU-like <stdio.h>.
 
-   Copyright (C) 2004, 2007-2021 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2007-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
@@ -56,6 +56,52 @@
    May also define off_t to a 64-bit type on native Windows.  */
 #include <sys/types.h>
 
+/* Solaris 10 and NetBSD 7.0 declare renameat in <unistd.h>, not in <stdio.h>.  */
+/* But in any case avoid namespace pollution on glibc systems.  */
+#if (@GNULIB_RENAMEAT@ || defined GNULIB_POSIXCHECK) && (defined __sun || defined __NetBSD__) \
+    && ! defined __GLIBC__
+# include <unistd.h>
+#endif
+
+/* Android 4.3 declares renameat in <sys/stat.h>, not in <stdio.h>.  */
+/* But in any case avoid namespace pollution on glibc systems.  */
+#if (@GNULIB_RENAMEAT@ || defined GNULIB_POSIXCHECK) && defined __ANDROID__ \
+    && ! defined __GLIBC__
+# include <sys/stat.h>
+#endif
+
+/* MSVC declares 'perror' in <stdlib.h>, not in <stdio.h>.  We must include
+   it before we  #define perror rpl_perror.  */
+/* But in any case avoid namespace pollution on glibc systems.  */
+#if (@GNULIB_PERROR@ || defined GNULIB_POSIXCHECK) \
+    && (defined _WIN32 && ! defined __CYGWIN__) \
+    && ! defined __GLIBC__
+# include <stdlib.h>
+#endif
+
+/* MSVC declares 'remove' in <io.h>, not in <stdio.h>.  We must include
+   it before we  #define remove rpl_remove.  */
+/* MSVC declares 'rename' in <io.h>, not in <stdio.h>.  We must include
+   it before we  #define rename rpl_rename.  */
+/* But in any case avoid namespace pollution on glibc systems.  */
+#if (@GNULIB_REMOVE@ || @GNULIB_RENAME@ || defined GNULIB_POSIXCHECK) \
+    && (defined _WIN32 && ! defined __CYGWIN__) \
+    && ! defined __GLIBC__
+# include <io.h>
+#endif
+
+
+/* _GL_ATTRIBUTE_DEALLOC (F, I) declares that the function returns pointers
+   that can be freed by passing them as the Ith argument to the
+   function F.  */
+#ifndef _GL_ATTRIBUTE_DEALLOC
+# if __GNUC__ >= 11
+#  define _GL_ATTRIBUTE_DEALLOC(f, i) __attribute__ ((__malloc__ (f, i)))
+# else
+#  define _GL_ATTRIBUTE_DEALLOC(f, i)
+# endif
+#endif
+
 /* The __attribute__ feature is available in gcc versions 2.5 and later.
    The __-protected variants of the attributes 'format' and 'printf' are
    accepted by gcc versions 2.6.4 (effectively 2.7) and later.
@@ -127,41 +173,6 @@
 #define _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM(formatstring_parameter, first_argument) \
   _GL_ATTRIBUTE_FORMAT ((__scanf__, formatstring_parameter, first_argument))
 
-/* Solaris 10 and NetBSD 7.0 declare renameat in <unistd.h>, not in <stdio.h>.  */
-/* But in any case avoid namespace pollution on glibc systems.  */
-#if (@GNULIB_RENAMEAT@ || defined GNULIB_POSIXCHECK) && (defined __sun || defined __NetBSD__) \
-    && ! defined __GLIBC__
-# include <unistd.h>
-#endif
-
-/* Android 4.3 declares renameat in <sys/stat.h>, not in <stdio.h>.  */
-/* But in any case avoid namespace pollution on glibc systems.  */
-#if (@GNULIB_RENAMEAT@ || defined GNULIB_POSIXCHECK) && defined __ANDROID__ \
-    && ! defined __GLIBC__
-# include <sys/stat.h>
-#endif
-
-/* MSVC declares 'perror' in <stdlib.h>, not in <stdio.h>.  We must include
-   it before we  #define perror rpl_perror.  */
-/* But in any case avoid namespace pollution on glibc systems.  */
-#if (@GNULIB_PERROR@ || defined GNULIB_POSIXCHECK) \
-    && (defined _WIN32 && ! defined __CYGWIN__) \
-    && ! defined __GLIBC__
-# include <stdlib.h>
-#endif
-
-/* MSVC declares 'remove' in <io.h>, not in <stdio.h>.  We must include
-   it before we  #define remove rpl_remove.  */
-/* MSVC declares 'rename' in <io.h>, not in <stdio.h>.  We must include
-   it before we  #define rename rpl_rename.  */
-/* But in any case avoid namespace pollution on glibc systems.  */
-#if (@GNULIB_REMOVE@ || @GNULIB_RENAME@ || defined GNULIB_POSIXCHECK) \
-    && (defined _WIN32 && ! defined __CYGWIN__) \
-    && ! defined __GLIBC__
-# include <io.h>
-#endif
-
-
 /* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */
 
 /* The definition of _GL_ARG_NONNULL is copied here.  */
@@ -388,7 +399,8 @@ _GL_CXXALIASWARN (fileno);
 #endif
 
 #if @GNULIB_FOPEN@
-# if @REPLACE_FOPEN@
+# if (@GNULIB_FOPEN@ && @REPLACE_FOPEN@) \
+     || (@GNULIB_FOPEN_GNU@ && @REPLACE_FOPEN_FOR_FOPEN_GNU@)
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
 #   undef fopen
 #   define fopen rpl_fopen
diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h
index d86a88071..a86643c3c 100644
--- a/lib/stdlib.in.h
+++ b/lib/stdlib.in.h
@@ -1,6 +1,6 @@
 /* A GNU-like <stdlib.h>.
 
-   Copyright (C) 1995, 2001-2004, 2006-2021 Free Software Foundation, Inc.
+   Copyright (C) 1995, 2001-2004, 2006-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
@@ -99,6 +99,35 @@ struct random_data
 # include <unistd.h>
 #endif
 
+/* _GL_ATTRIBUTE_DEALLOC (F, I) declares that the function returns pointers
+   that can be freed by passing them as the Ith argument to the
+   function F.  */
+#ifndef _GL_ATTRIBUTE_DEALLOC
+# if __GNUC__ >= 11
+#  define _GL_ATTRIBUTE_DEALLOC(f, i) __attribute__ ((__malloc__ (f, i)))
+# else
+#  define _GL_ATTRIBUTE_DEALLOC(f, i)
+# endif
+#endif
+
+/* _GL_ATTRIBUTE_DEALLOC_FREE declares that the function returns pointers that
+   can be freed via 'free'; it can be used only after declaring 'free'.  */
+/* Applies to: functions.  Cannot be used on inline functions.  */
+#ifndef _GL_ATTRIBUTE_DEALLOC_FREE
+# define _GL_ATTRIBUTE_DEALLOC_FREE _GL_ATTRIBUTE_DEALLOC (free, 1)
+#endif
+
+/* _GL_ATTRIBUTE_MALLOC declares that the function returns a pointer to freshly
+   allocated memory.  */
+/* Applies to: functions.  */
+#ifndef _GL_ATTRIBUTE_MALLOC
+# if __GNUC__ >= 3 || defined __clang__
+#  define _GL_ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
+# else
+#  define _GL_ATTRIBUTE_MALLOC
+# endif
+#endif
+
 /* The __attribute__ feature is available in gcc versions 2.5 and later.
    The attribute __pure__ was added in gcc 2.96.  */
 #ifndef _GL_ATTRIBUTE_PURE
@@ -155,7 +184,11 @@ _GL_WARN_ON_USE (_Exit, "_Exit is unportable - "
 #   undef free
 #   define free rpl_free
 #  endif
+#  if defined __cplusplus && (__GLIBC__ + (__GLIBC_MINOR__ >= 14) > 2)
+_GL_FUNCDECL_RPL (free, void, (void *ptr) throw ());
+#  else
 _GL_FUNCDECL_RPL (free, void, (void *ptr));
+#  endif
 _GL_CXXALIAS_RPL (free, void, (void *ptr));
 # else
 _GL_CXXALIAS_SYS (free, void, (void *ptr));
@@ -231,7 +264,8 @@ _GL_WARN_ON_USE (atoll, "atoll is unportable - "
 #endif
 
 #if @GNULIB_CALLOC_POSIX@
-# if @REPLACE_CALLOC@
+# if (@GNULIB_CALLOC_POSIX@ && @REPLACE_CALLOC_FOR_CALLOC_POSIX@) \
+     || (@GNULIB_CALLOC_GNU@ && @REPLACE_CALLOC_FOR_CALLOC_GNU@)
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
 #   undef calloc
 #   define calloc rpl_calloc
@@ -445,7 +479,8 @@ _GL_WARN_ON_USE (grantpt, "grantpt is not portable - "
    by never specifying a zero size), so it does not need malloc or
    realloc to be redefined.  */
 #if @GNULIB_MALLOC_POSIX@
-# if @REPLACE_MALLOC@
+# if (@GNULIB_MALLOC_POSIX@ && @REPLACE_MALLOC_FOR_MALLOC_POSIX@) \
+     || (@GNULIB_MALLOC_GNU@ && @REPLACE_MALLOC_FOR_MALLOC_GNU@)
 #  if !((defined __cplusplus && defined GNULIB_NAMESPACE) \
         || _GL_USE_STDLIB_ALLOC)
 #   undef malloc
@@ -799,29 +834,35 @@ _GL_CXXALIASWARN (putenv);
 /* Sort an array of NMEMB elements, starting at address BASE, each element
    occupying SIZE bytes, in ascending order according to the comparison
    function COMPARE.  */
+# ifdef __cplusplus
+extern "C" {
+# endif
+# if !GNULIB_defined_qsort_r_fn_types
+typedef int (*_gl_qsort_r_compar_fn) (void const *, void const *, void *);
+#  define GNULIB_defined_qsort_r_fn_types 1
+# endif
+# ifdef __cplusplus
+}
+# endif
 # if @REPLACE_QSORT_R@
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
 #   undef qsort_r
 #   define qsort_r rpl_qsort_r
 #  endif
 _GL_FUNCDECL_RPL (qsort_r, void, (void *base, size_t nmemb, size_t size,
-                                  int (*compare) (void const *, void const *,
-                                                  void *),
+                                  _gl_qsort_r_compar_fn compare,
                                   void *arg) _GL_ARG_NONNULL ((1, 4)));
 _GL_CXXALIAS_RPL (qsort_r, void, (void *base, size_t nmemb, size_t size,
-                                  int (*compare) (void const *, void const *,
-                                                  void *),
+                                  _gl_qsort_r_compar_fn compare,
                                   void *arg));
 # else
 #  if !@HAVE_QSORT_R@
 _GL_FUNCDECL_SYS (qsort_r, void, (void *base, size_t nmemb, size_t size,
-                                  int (*compare) (void const *, void const *,
-                                                  void *),
+                                  _gl_qsort_r_compar_fn compare,
                                   void *arg) _GL_ARG_NONNULL ((1, 4)));
 #  endif
 _GL_CXXALIAS_SYS (qsort_r, void, (void *base, size_t nmemb, size_t size,
-                                  int (*compare) (void const *, void const *,
-                                                  void *),
+                                  _gl_qsort_r_compar_fn compare,
                                   void *arg));
 # endif
 _GL_CXXALIASWARN (qsort_r);
@@ -1072,7 +1113,8 @@ _GL_WARN_ON_USE (setstate_r, "setstate_r is unportable - "
 
 
 #if @GNULIB_REALLOC_POSIX@
-# if @REPLACE_REALLOC@
+# if (@GNULIB_REALLOC_POSIX@ && @REPLACE_REALLOC_FOR_REALLOC_POSIX@) \
+     || (@GNULIB_REALLOC_GNU@ && @REPLACE_REALLOC_FOR_REALLOC_GNU@)
 #  if !((defined __cplusplus && defined GNULIB_NAMESPACE) \
         || _GL_USE_STDLIB_ALLOC)
 #   undef realloc
diff --git a/lib/stpcpy.c b/lib/stpcpy.c
new file mode 100644
index 000000000..434f84ae7
--- /dev/null
+++ b/lib/stpcpy.c
@@ -0,0 +1,49 @@
+/* stpcpy.c -- copy a string and return pointer to end of new string
+   Copyright (C) 1992, 1995, 1997-1998, 2006, 2009-2022 Free Software
+   Foundation, Inc.
+
+   NOTE: The canonical source of this file is maintained with the GNU C Library.
+   Bugs can be reported to bug-glibc@prep.ai.mit.edu.
+
+   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 2.1 of the
+   License, or (at your option) any later version.
+
+   This file 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+#include <string.h>
+
+#undef __stpcpy
+#ifdef _LIBC
+# undef stpcpy
+#endif
+
+#ifndef weak_alias
+# define __stpcpy stpcpy
+#endif
+
+/* Copy SRC to DEST, returning the address of the terminating '\0' in DEST.  */
+char *
+__stpcpy (char *dest, const char *src)
+{
+  register char *d = dest;
+  register const char *s = src;
+
+  do
+    *d++ = *s;
+  while (*s++ != '\0');
+
+  return d - 1;
+}
+#ifdef weak_alias
+weak_alias (__stpcpy, stpcpy)
+#endif
diff --git a/lib/strchrnul.c b/lib/strchrnul.c
new file mode 100644
index 000000000..2141b3e19
--- /dev/null
+++ b/lib/strchrnul.c
@@ -0,0 +1,142 @@
+/* Searching in a string.
+   Copyright (C) 2003, 2007-2022 Free Software Foundation, Inc.
+
+   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 2.1 of the
+   License, or (at your option) any later version.
+
+   This file 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include <string.h>
+
+/* Find the first occurrence of C in S or the final NUL byte.  */
+char *
+strchrnul (const char *s, int c_in)
+{
+  /* On 32-bit hardware, choosing longword to be a 32-bit unsigned
+     long instead of a 64-bit uintmax_t tends to give better
+     performance.  On 64-bit hardware, unsigned long is generally 64
+     bits already.  Change this typedef to experiment with
+     performance.  */
+  typedef unsigned long int longword;
+
+  const unsigned char *char_ptr;
+  const longword *longword_ptr;
+  longword repeated_one;
+  longword repeated_c;
+  unsigned char c;
+
+  c = (unsigned char) c_in;
+  if (!c)
+    return rawmemchr (s, 0);
+
+  /* Handle the first few bytes by reading one byte at a time.
+     Do this until CHAR_PTR is aligned on a longword boundary.  */
+  for (char_ptr = (const unsigned char *) s;
+       (size_t) char_ptr % sizeof (longword) != 0;
+       ++char_ptr)
+    if (!*char_ptr || *char_ptr == c)
+      return (char *) char_ptr;
+
+  longword_ptr = (const longword *) char_ptr;
+
+  /* All these elucidatory comments refer to 4-byte longwords,
+     but the theory applies equally well to any size longwords.  */
+
+  /* Compute auxiliary longword values:
+     repeated_one is a value which has a 1 in every byte.
+     repeated_c has c in every byte.  */
+  repeated_one = 0x01010101;
+  repeated_c = c | (c << 8);
+  repeated_c |= repeated_c << 16;
+  if (0xffffffffU < (longword) -1)
+    {
+      repeated_one |= repeated_one << 31 << 1;
+      repeated_c |= repeated_c << 31 << 1;
+      if (8 < sizeof (longword))
+        {
+          size_t i;
+
+          for (i = 64; i < sizeof (longword) * 8; i *= 2)
+            {
+              repeated_one |= repeated_one << i;
+              repeated_c |= repeated_c << i;
+            }
+        }
+    }
+
+  /* Instead of the traditional loop which tests each byte, we will
+     test a longword at a time.  The tricky part is testing if *any of
+     the four* bytes in the longword in question are equal to NUL or
+     c.  We first use an xor with repeated_c.  This reduces the task
+     to testing whether *any of the four* bytes in longword1 or
+     longword2 is zero.
+
+     Let's consider longword1.  We compute tmp =
+       ((longword1 - repeated_one) & ~longword1) & (repeated_one << 7).
+     That is, we perform the following operations:
+       1. Subtract repeated_one.
+       2. & ~longword1.
+       3. & a mask consisting of 0x80 in every byte.
+     Consider what happens in each byte:
+       - If a byte of longword1 is zero, step 1 and 2 transform it into 0xff,
+         and step 3 transforms it into 0x80.  A carry can also be propagated
+         to more significant bytes.
+       - If a byte of longword1 is nonzero, let its lowest 1 bit be at
+         position k (0 <= k <= 7); so the lowest k bits are 0.  After step 1,
+         the byte ends in a single bit of value 0 and k bits of value 1.
+         After step 2, the result is just k bits of value 1: 2^k - 1.  After
+         step 3, the result is 0.  And no carry is produced.
+     So, if longword1 has only non-zero bytes, tmp is zero.
+     Whereas if longword1 has a zero byte, call j the position of the least
+     significant zero byte.  Then the result has a zero at positions 0, ...,
+     j-1 and a 0x80 at position j.  We cannot predict the result at the more
+     significant bytes (positions j+1..3), but it does not matter since we
+     already have a non-zero bit at position 8*j+7.
+
+     The test whether any byte in longword1 or longword2 is zero is equivalent
+     to testing whether tmp1 is nonzero or tmp2 is nonzero.  We can combine
+     this into a single test, whether (tmp1 | tmp2) is nonzero.
+
+     This test can read more than one byte beyond the end of a string,
+     depending on where the terminating NUL is encountered.  However,
+     this is considered safe since the initialization phase ensured
+     that the read will be aligned, therefore, the read will not cross
+     page boundaries and will not cause a fault.  */
+
+  while (1)
+    {
+      longword longword1 = *longword_ptr ^ repeated_c;
+      longword longword2 = *longword_ptr;
+
+      if (((((longword1 - repeated_one) & ~longword1)
+            | ((longword2 - repeated_one) & ~longword2))
+           & (repeated_one << 7)) != 0)
+        break;
+      longword_ptr++;
+    }
+
+  char_ptr = (const unsigned char *) longword_ptr;
+
+  /* At this point, we know that one of the sizeof (longword) bytes
+     starting at char_ptr is == 0 or == c.  On little-endian machines,
+     we could determine the first such byte without any further memory
+     accesses, just by looking at the tmp result from the last loop
+     iteration.  But this does not work on big-endian machines.
+     Choose code that works in both cases.  */
+
+  char_ptr = (unsigned char *) longword_ptr;
+  while (*char_ptr && (*char_ptr != c))
+    char_ptr++;
+  return (char *) char_ptr;
+}
diff --git a/lib/strchrnul.valgrind b/lib/strchrnul.valgrind
new file mode 100644
index 000000000..1cf50ec8d
--- /dev/null
+++ b/lib/strchrnul.valgrind
@@ -0,0 +1,28 @@
+# Suppress a valgrind message about use of uninitialized memory in strchrnul().
+
+# Copyright (C) 2008-2022 Free Software Foundation, Inc.
+#
+# 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 2.1 of the
+# License, or (at your option) any later version.
+#
+# This file 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+# This use is OK because it provides only a speedup.
+{
+    strchrnul-value4
+    Memcheck:Value4
+    fun:strchrnul
+}
+{
+    strchrnul-value8
+    Memcheck:Value8
+    fun:strchrnul
+}
diff --git a/lib/strdup.c b/lib/strdup.c
index e5d4d75c8..2a0df023c 100644
--- a/lib/strdup.c
+++ b/lib/strdup.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1996-1998, 2002-2004, 2006-2007, 2009-2021 Free Software
+/* Copyright (C) 1991, 1996-1998, 2002-2004, 2006-2007, 2009-2022 Free Software
    Foundation, Inc.
 
    This file is part of the GNU C Library.
diff --git a/lib/streq.h b/lib/streq.h
index adabd158e..49f73c1b9 100644
--- a/lib/streq.h
+++ b/lib/streq.h
@@ -1,5 +1,5 @@
 /* Optimized string comparison.
-   Copyright (C) 2001-2002, 2007, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2001-2002, 2007, 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/strftime.h b/lib/strftime.h
index 790a80ed8..a9847084f 100644
--- a/lib/strftime.h
+++ b/lib/strftime.h
@@ -1,10 +1,10 @@
 /* declarations for strftime.c
 
-   Copyright (C) 2002, 2004, 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004, 2008-2022 Free Software Foundation, Inc.
 
    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 3 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/striconveh.c b/lib/striconveh.c
index 78a5e0296..5b60a7e0a 100644
--- a/lib/striconveh.c
+++ b/lib/striconveh.c
@@ -1,5 +1,5 @@
 /* Character set conversion with error handling.
-   Copyright (C) 2001-2021 Free Software Foundation, Inc.
+   Copyright (C) 2001-2022 Free Software Foundation, Inc.
    Written by Bruno Haible and Simon Josefsson.
 
    This file is free software: you can redistribute it and/or modify
@@ -457,13 +457,18 @@ mem_cd_iconveh_internal (const char *src, size_t srclen,
                 if (cd2 == (iconv_t)(-1))
                   {
                     /* TO_CODESET is UTF-8.  */
-                    /* Error handling can produce up to 1 byte of output.  */
-                    if (length + 1 + extra_alloc > allocated)
+                    /* Error handling can produce up to 1 or 3 bytes of
+                       output.  */
+                    size_t extra_need =
+                      (handler == iconveh_replacement_character ? 3 : 1);
+                    if (length + extra_need + extra_alloc > allocated)
                       {
                         char *memory;
 
                         allocated = 2 * allocated;
-                        if (length + 1 + extra_alloc > allocated)
+                        if (length + extra_need + extra_alloc > allocated)
+                          allocated = 2 * allocated;
+                        if (length + extra_need + extra_alloc > allocated)
                           abort ();
                         if (result == initial_result)
                           memory = (char *) malloc (allocated);
@@ -482,7 +487,7 @@ mem_cd_iconveh_internal (const char *src, size_t srclen,
                         grow = false;
                       }
                     /* The input is invalid in FROM_CODESET.  Eat up one byte
-                       and emit a question mark.  */
+                       and emit a replacement character or a question mark.  */
                     if (!incremented)
                       {
                         if (insize == 0)
@@ -490,8 +495,19 @@ mem_cd_iconveh_internal (const char *src, size_t srclen,
                         inptr++;
                         insize--;
                       }
-                    result[length] = '?';
-                    length++;
+                    if (handler == iconveh_replacement_character)
+                      {
+                        /* U+FFFD in UTF-8 encoding.  */
+                        result[length+0] = '\357';
+                        result[length+1] = '\277';
+                        result[length+2] = '\275';
+                        length += 3;
+                      }
+                    else
+                      {
+                        result[length] = '?';
+                        length++;
+                      }
                   }
                 else
                   goto indirectly;
@@ -594,7 +610,7 @@ mem_cd_iconveh_internal (const char *src, size_t srclen,
   {
     const bool slowly = (offsets != NULL || handler == iconveh_error);
 # define utf8bufsize 4096 /* may also be smaller or larger than tmpbufsize */
-    char utf8buf[utf8bufsize + 1];
+    char utf8buf[utf8bufsize + 3];
     size_t utf8len = 0;
     const char *in1ptr = src;
     size_t in1size = srclen;
@@ -682,8 +698,8 @@ mem_cd_iconveh_internal (const char *src, size_t srclen,
             && errno == EILSEQ && handler != iconveh_error)
           {
             /* The input is invalid in FROM_CODESET.  Eat up one byte and
-               emit a question mark.  Room for the question mark was allocated
-               at the end of utf8buf.  */
+               emit a U+FFFD character or a question mark.  Room for this
+               character was allocated at the end of utf8buf.  */
             if (!incremented1)
               {
                 if (in1size == 0)
@@ -691,7 +707,16 @@ mem_cd_iconveh_internal (const char *src, size_t srclen,
                 in1ptr++;
                 in1size--;
               }
-            *out1ptr++ = '?';
+            if (handler == iconveh_replacement_character)
+              {
+                /* U+FFFD in UTF-8 encoding.  */
+                out1ptr[0] = '\357';
+                out1ptr[1] = '\277';
+                out1ptr[2] = '\275';
+                out1ptr += 3;
+              }
+            else
+              *out1ptr++ = '?';
             res1 = 0;
           }
         errno1 = errno;
@@ -756,7 +781,7 @@ mem_cd_iconveh_internal (const char *src, size_t srclen,
                       break;
                     else if (errno == EILSEQ && handler != iconveh_error)
                       {
-                        /* Error handling can produce up to 10 bytes of ASCII
+                        /* Error handling can produce up to 10 bytes of UTF-8
                            output.  But TO_CODESET may be UCS-2, UTF-16 or
                            UCS-4, so use CD2 here as well.  */
                         char scratchbuf[10];
@@ -804,6 +829,14 @@ mem_cd_iconveh_internal (const char *src, size_t srclen,
                             scratchbuf[scratchlen++] = hex[(uc>>4) & 15];
                             scratchbuf[scratchlen++] = hex[uc & 15];
                           }
+                        else if (handler == iconveh_replacement_character)
+                          {
+                            /* U+FFFD in UTF-8 encoding.  */
+                            scratchbuf[0] = '\357';
+                            scratchbuf[1] = '\277';
+                            scratchbuf[2] = '\275';
+                            scratchlen = 3;
+                          }
                         else
                           {
                             scratchbuf[0] = '?';
@@ -813,9 +846,45 @@ mem_cd_iconveh_internal (const char *src, size_t srclen,
                         inptr = scratchbuf;
                         insize = scratchlen;
                         if (cd2 != (iconv_t)(-1))
-                          res = iconv (cd2,
-                                       (ICONV_CONST char **) &inptr, &insize,
-                                       &out2ptr, &out2size);
+                          {
+                            char *out2ptr_try = out2ptr;
+                            size_t out2size_try = out2size;
+                            res = iconv (cd2,
+                                         (ICONV_CONST char **) &inptr, &insize,
+                                         &out2ptr_try, &out2size_try);
+                            if (handler == iconveh_replacement_character
+                                && (res == (size_t)(-1)
+                                    ? errno == EILSEQ
+                                    /* FreeBSD iconv(), NetBSD iconv(), and
+                                       Solaris 11 iconv() insert a '?' if they
+                                       cannot convert.  This is what we want.
+                                       But IRIX iconv() inserts a NUL byte if it
+                                       cannot convert.
+                                       And musl libc iconv() inserts a '*' if it
+                                       cannot convert.  */
+                                    : (res > 0
+                                       && !(out2ptr_try - out2ptr == 1
+                                            && *out2ptr == '?'))))
+                              {
+                                /* The iconv() call failed.
+                                   U+FFFD can't be converted to TO_CODESET.
+                                   Use '?' instead.  */
+                                scratchbuf[0] = '?';
+                                scratchlen = 1;
+                                inptr = scratchbuf;
+                                insize = scratchlen;
+                                res = iconv (cd2,
+                                             (ICONV_CONST char **) &inptr, &insize,
+                                             &out2ptr, &out2size);
+                              }
+                            else
+                              {
+                                /* Accept the results of the iconv() call.  */
+                                out2ptr = out2ptr_try;
+                                out2size = out2size_try;
+                                res = 0;
+                              }
+                          }
                         else
                           {
                             /* TO_CODESET is UTF-8.  */
@@ -880,9 +949,10 @@ mem_cd_iconveh_internal (const char *src, size_t srclen,
                             length = out2ptr - result;
                           }
 # if !defined _LIBICONV_VERSION && !(defined __GLIBC__ && !defined __UCLIBC__)
-                        /* Irix iconv() inserts a NUL byte if it cannot convert.
-                           NetBSD iconv() inserts a question mark if it cannot
-                           convert.
+                        /* IRIX iconv() inserts a NUL byte if it cannot convert.
+                           FreeBSD iconv(), NetBSD iconv(), and Solaris 11
+                           iconv() insert a '?' if they cannot convert.
+                           musl libc iconv() inserts a '*' if it cannot convert.
                            Only GNU libiconv and GNU libc are known to prefer
                            to fail rather than doing a lossy conversion.  */
                         if (res != (size_t)(-1) && res > 0)
diff --git a/lib/striconveh.h b/lib/striconveh.h
index 60c632928..e152a046f 100644
--- a/lib/striconveh.h
+++ b/lib/striconveh.h
@@ -1,5 +1,5 @@
 /* Character set conversion with error handling.
-   Copyright (C) 2001-2007, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2001-2007, 2009-2022 Free Software Foundation, Inc.
    Written by Bruno Haible and Simon Josefsson.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/string.in.h b/lib/string.in.h
index b043c7522..3996da9fc 100644
--- a/lib/string.in.h
+++ b/lib/string.in.h
@@ -1,6 +1,6 @@
 /* A GNU-like <string.h>.
 
-   Copyright (C) 1995-1996, 2001-2021 Free Software Foundation, Inc.
+   Copyright (C) 1995-1996, 2001-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
@@ -47,24 +47,11 @@
 /* NetBSD 5.0 mis-defines NULL.  */
 #include <stddef.h>
 
-/* Get free().  */
-#include <stdlib.h>
-
 /* MirBSD defines mbslen as a macro.  */
 #if @GNULIB_MBSLEN@ && defined __MirBSD__
 # include <wchar.h>
 #endif
 
-/* The __attribute__ feature is available in gcc versions 2.5 and later.
-   The attribute __pure__ was added in gcc 2.96.  */
-#ifndef _GL_ATTRIBUTE_PURE
-# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) || defined __clang__
-#  define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__))
-# else
-#  define _GL_ATTRIBUTE_PURE /* empty */
-# endif
-#endif
-
 /* NetBSD 5.0 declares strsignal in <unistd.h>, not in <string.h>.  */
 /* But in any case avoid namespace pollution on glibc systems.  */
 #if (@GNULIB_STRSIGNAL@ || defined GNULIB_POSIXCHECK) && defined __NetBSD__ \
@@ -80,12 +67,90 @@
 # include <strings.h>
 #endif
 
+/* _GL_ATTRIBUTE_DEALLOC (F, I) declares that the function returns pointers
+   that can be freed by passing them as the Ith argument to the
+   function F.  */
+#ifndef _GL_ATTRIBUTE_DEALLOC
+# if __GNUC__ >= 11
+#  define _GL_ATTRIBUTE_DEALLOC(f, i) __attribute__ ((__malloc__ (f, i)))
+# else
+#  define _GL_ATTRIBUTE_DEALLOC(f, i)
+# endif
+#endif
+
+/* _GL_ATTRIBUTE_DEALLOC_FREE declares that the function returns pointers that
+   can be freed via 'free'; it can be used only after declaring 'free'.  */
+/* Applies to: functions.  Cannot be used on inline functions.  */
+#ifndef _GL_ATTRIBUTE_DEALLOC_FREE
+# define _GL_ATTRIBUTE_DEALLOC_FREE _GL_ATTRIBUTE_DEALLOC (free, 1)
+#endif
+
+/* _GL_ATTRIBUTE_MALLOC declares that the function returns a pointer to freshly
+   allocated memory.  */
+/* Applies to: functions.  */
+#ifndef _GL_ATTRIBUTE_MALLOC
+# if __GNUC__ >= 3 || defined __clang__
+#  define _GL_ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
+# else
+#  define _GL_ATTRIBUTE_MALLOC
+# endif
+#endif
+
+/* The __attribute__ feature is available in gcc versions 2.5 and later.
+   The attribute __pure__ was added in gcc 2.96.  */
+#ifndef _GL_ATTRIBUTE_PURE
+# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) || defined __clang__
+#  define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__))
+# else
+#  define _GL_ATTRIBUTE_PURE /* empty */
+# endif
+#endif
+
 /* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */
 
 /* The definition of _GL_ARG_NONNULL is copied here.  */
 
 /* The definition of _GL_WARN_ON_USE is copied here.  */
 
+/* Make _GL_ATTRIBUTE_DEALLOC_FREE work, even though <stdlib.h> may not have
+   been included yet.  */
+#if @GNULIB_FREE_POSIX@
+# if (@REPLACE_FREE@ && !defined free \
+      && !(defined __cplusplus && defined GNULIB_NAMESPACE))
+/* We can't do '#define free rpl_free' here.  */
+_GL_EXTERN_C void rpl_free (void *);
+#  undef _GL_ATTRIBUTE_DEALLOC_FREE
+#  define _GL_ATTRIBUTE_DEALLOC_FREE _GL_ATTRIBUTE_DEALLOC (rpl_free, 1)
+# else
+#  if defined _MSC_VER && !defined free
+_GL_EXTERN_C
+#   if defined _DLL
+     __declspec (dllimport)
+#   endif
+     void __cdecl free (void *);
+#  else
+#   if defined __cplusplus && (__GLIBC__ + (__GLIBC_MINOR__ >= 14) > 2)
+_GL_EXTERN_C void free (void *) throw ();
+#   else
+_GL_EXTERN_C void free (void *);
+#   endif
+#  endif
+# endif
+#else
+# if defined _MSC_VER && !defined free
+_GL_EXTERN_C
+#   if defined _DLL
+     __declspec (dllimport)
+#   endif
+     void __cdecl free (void *);
+# else
+#  if defined __cplusplus && (__GLIBC__ + (__GLIBC_MINOR__ >= 14) > 2)
+_GL_EXTERN_C void free (void *) throw ();
+#  else
+_GL_EXTERN_C void free (void *);
+#  endif
+# endif
+#endif
 
 /* Clear a block of memory.  The compiler will not delete a call to
    this function, even if the block is dead after the call.  */
@@ -181,10 +246,11 @@ _GL_CXXALIAS_SYS_CAST2 (memchr,
                         void const *, (void const *__s, int __c, size_t __n));
 # endif
 # if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \
-     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))
-_GL_CXXALIASWARN1 (memchr, void *, (void *__s, int __c, size_t __n));
+     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) \
+         || defined __clang__)
+_GL_CXXALIASWARN1 (memchr, void *, (void *__s, int __c, size_t __n) throw ());
 _GL_CXXALIASWARN1 (memchr, void const *,
-                   (void const *__s, int __c, size_t __n));
+                   (void const *__s, int __c, size_t __n) throw ());
 # elif __GLIBC__ >= 2
 _GL_CXXALIASWARN (memchr);
 # endif
@@ -266,9 +332,10 @@ _GL_CXXALIAS_SYS_CAST2 (memrchr,
                         void *, (void const *, int, size_t),
                         void const *, (void const *, int, size_t));
 # if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \
-     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))
-_GL_CXXALIASWARN1 (memrchr, void *, (void *, int, size_t));
-_GL_CXXALIASWARN1 (memrchr, void const *, (void const *, int, size_t));
+     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) \
+         || defined __clang__)
+_GL_CXXALIASWARN1 (memrchr, void *, (void *, int, size_t) throw ());
+_GL_CXXALIASWARN1 (memrchr, void const *, (void const *, int, size_t) throw ());
 # else
 _GL_CXXALIASWARN (memrchr);
 # endif
@@ -296,9 +363,11 @@ _GL_CXXALIAS_SYS_CAST2 (rawmemchr,
                         void *, (void const *__s, int __c_in),
                         void const *, (void const *__s, int __c_in));
 # if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \
-     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))
-_GL_CXXALIASWARN1 (rawmemchr, void *, (void *__s, int __c_in));
-_GL_CXXALIASWARN1 (rawmemchr, void const *, (void const *__s, int __c_in));
+     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) \
+         || defined __clang__)
+_GL_CXXALIASWARN1 (rawmemchr, void *, (void *__s, int __c_in) throw ());
+_GL_CXXALIASWARN1 (rawmemchr, void const *,
+                   (void const *__s, int __c_in) throw ());
 # else
 _GL_CXXALIASWARN (rawmemchr);
 # endif
@@ -400,9 +469,11 @@ _GL_CXXALIAS_SYS_CAST2 (strchrnul,
                         char const *, (char const *__s, int __c_in));
 # endif
 # if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \
-     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))
-_GL_CXXALIASWARN1 (strchrnul, char *, (char *__s, int __c_in));
-_GL_CXXALIASWARN1 (strchrnul, char const *, (char const *__s, int __c_in));
+     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) \
+         || defined __clang__)
+_GL_CXXALIASWARN1 (strchrnul, char *, (char *__s, int __c_in) throw ());
+_GL_CXXALIASWARN1 (strchrnul, char const *,
+                   (char const *__s, int __c_in) throw ());
 # else
 _GL_CXXALIASWARN (strchrnul);
 # endif
@@ -514,22 +585,35 @@ _GL_WARN_ON_USE (strncat, "strncat is unportable - "
 #   undef strndup
 #   define strndup rpl_strndup
 #  endif
-_GL_FUNCDECL_RPL (strndup, char *, (char const *__s, size_t __n)
-                                   _GL_ARG_NONNULL ((1)));
+_GL_FUNCDECL_RPL (strndup, char *,
+                  (char const *__s, size_t __n)
+                  _GL_ARG_NONNULL ((1))
+                  _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE);
 _GL_CXXALIAS_RPL (strndup, char *, (char const *__s, size_t __n));
 # else
-#  if ! @HAVE_DECL_STRNDUP@
-_GL_FUNCDECL_SYS (strndup, char *, (char const *__s, size_t __n)
-                                   _GL_ARG_NONNULL ((1)));
+#  if !@HAVE_DECL_STRNDUP@ || (__GNUC__ >= 11 && !defined strndup)
+_GL_FUNCDECL_SYS (strndup, char *,
+                  (char const *__s, size_t __n)
+                  _GL_ARG_NONNULL ((1))
+                  _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE);
 #  endif
 _GL_CXXALIAS_SYS (strndup, char *, (char const *__s, size_t __n));
 # endif
 _GL_CXXALIASWARN (strndup);
-#elif defined GNULIB_POSIXCHECK
-# undef strndup
-# if HAVE_RAW_DECL_STRNDUP
+#else
+# if __GNUC__ >= 11 && !defined strndup
+/* For -Wmismatched-dealloc: Associate strndup with free or rpl_free.  */
+_GL_FUNCDECL_SYS (strndup, char *,
+                  (char const *__s, size_t __n)
+                  _GL_ARG_NONNULL ((1))
+                  _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE);
+# endif
+# if defined GNULIB_POSIXCHECK
+#  undef strndup
+#  if HAVE_RAW_DECL_STRNDUP
 _GL_WARN_ON_USE (strndup, "strndup is unportable - "
                  "use gnulib module strndup for portability");
+#  endif
 # endif
 #endif
 
@@ -589,10 +673,11 @@ _GL_CXXALIAS_SYS_CAST2 (strpbrk,
                         char *, (char const *__s, char const *__accept),
                         const char *, (char const *__s, char const *__accept));
 # if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \
-     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))
-_GL_CXXALIASWARN1 (strpbrk, char *, (char *__s, char const *__accept));
+     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) \
+         || defined __clang__)
+_GL_CXXALIASWARN1 (strpbrk, char *, (char *__s, char const *__accept) throw ());
 _GL_CXXALIASWARN1 (strpbrk, char const *,
-                   (char const *__s, char const *__accept));
+                   (char const *__s, char const *__accept) throw ());
 # elif __GLIBC__ >= 2
 _GL_CXXALIASWARN (strpbrk);
 # endif
@@ -697,10 +782,12 @@ _GL_CXXALIAS_SYS_CAST2 (strstr,
                         const char *, (const char *haystack, const char *needle));
 # endif
 # if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \
-     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))
-_GL_CXXALIASWARN1 (strstr, char *, (char *haystack, const char *needle));
+     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) \
+         || defined __clang__)
+_GL_CXXALIASWARN1 (strstr, char *,
+                   (char *haystack, const char *needle) throw ());
 _GL_CXXALIASWARN1 (strstr, const char *,
-                   (const char *haystack, const char *needle));
+                   (const char *haystack, const char *needle) throw ());
 # elif __GLIBC__ >= 2
 _GL_CXXALIASWARN (strstr);
 # endif
@@ -746,10 +833,12 @@ _GL_CXXALIAS_SYS_CAST2 (strcasestr,
                         const char *, (const char *haystack, const char *needle));
 # endif
 # if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \
-     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))
-_GL_CXXALIASWARN1 (strcasestr, char *, (char *haystack, const char *needle));
+     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) \
+         || defined __clang__)
+_GL_CXXALIASWARN1 (strcasestr, char *,
+                   (char *haystack, const char *needle) throw ());
 _GL_CXXALIASWARN1 (strcasestr, const char *,
-                   (const char *haystack, const char *needle));
+                   (const char *haystack, const char *needle) throw ());
 # else
 _GL_CXXALIASWARN (strcasestr);
 # endif
diff --git a/lib/stripslash.c b/lib/stripslash.c
index 99bfbe66b..aee89b78d 100644
--- a/lib/stripslash.c
+++ b/lib/stripslash.c
@@ -1,6 +1,6 @@
 /* stripslash.c -- remove redundant trailing slashes from a file name
 
-   Copyright (C) 1990, 2001, 2003-2006, 2009-2021 Free Software Foundation,
+   Copyright (C) 1990, 2001, 2003-2006, 2009-2022 Free Software Foundation,
    Inc.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/sys-limits.h b/lib/sys-limits.h
index 2d9784d1b..d154f0b23 100644
--- a/lib/sys-limits.h
+++ b/lib/sys-limits.h
@@ -1,6 +1,6 @@
 /* System call limits
 
-   Copyright 2018-2021 Free Software Foundation, Inc.
+   Copyright 2018-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/sys_file.in.h b/lib/sys_file.in.h
index 41660822b..1ae54f85a 100644
--- a/lib/sys_file.in.h
+++ b/lib/sys_file.in.h
@@ -1,6 +1,6 @@
 /* Provide a more complete sys/file.h.
 
-   Copyright (C) 2007-2021 Free Software Foundation, Inc.
+   Copyright (C) 2007-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/sys_random.in.h b/lib/sys_random.in.h
index 1abd6c544..e730e6139 100644
--- a/lib/sys_random.in.h
+++ b/lib/sys_random.in.h
@@ -1,5 +1,5 @@
 /* Substitute for <sys/random.h>.
-   Copyright (C) 2020-2021 Free Software Foundation, Inc.
+   Copyright (C) 2020-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
@@ -23,8 +23,10 @@
 
 #if @HAVE_SYS_RANDOM_H@
 
-/* On uClibc, <sys/random.h> assumes prior inclusion of <stddef.h>.  */
-# if defined __UCLIBC__
+/* On uClibc < 1.0.35, <sys/random.h> assumes prior inclusion of <stddef.h>.
+   Do not use __UCLIBC__ here, as it might not be defined yet.
+   But avoid namespace pollution on glibc systems.  */
+# ifndef __GLIBC__
 #  include <stddef.h>
 # endif
 /* On Mac OS X 10.5, <sys/random.h> assumes prior inclusion of <sys/types.h>.
diff --git a/lib/sys_select.in.h b/lib/sys_select.in.h
index f8ef648d4..2bd0e0f79 100644
--- a/lib/sys_select.in.h
+++ b/lib/sys_select.in.h
@@ -1,5 +1,5 @@
 /* Substitute for <sys/select.h>.
-   Copyright (C) 2007-2021 Free Software Foundation, Inc.
+   Copyright (C) 2007-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
@@ -21,7 +21,7 @@
 
 /* On OSF/1 and Solaris 2.6, <sys/types.h> and <sys/time.h>
    both include <sys/select.h>.
-   On Cygwin, <sys/time.h> includes <sys/select.h>.
+   On Cygwin and OpenBSD, <sys/time.h> includes <sys/select.h>.
    Simply delegate to the system's header in this case.  */
 #if (@HAVE_SYS_SELECT_H@                                                \
      && !defined _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_TYPES_H             \
@@ -39,6 +39,7 @@
            || (!defined _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_TIME_H       \
                && ((defined __osf__ && defined _SYS_TIME_H_             \
                     && defined _OSF_SOURCE)                             \
+                   || (defined __OpenBSD__ && defined _SYS_TIME_H_)     \
                    || (defined __sun && defined _SYS_TIME_H             \
                        && (! (defined _XOPEN_SOURCE                     \
                               || defined _POSIX_C_SOURCE)               \
@@ -278,9 +279,13 @@ _GL_FUNCDECL_SYS (pselect, int,
                   (int, fd_set *restrict, fd_set *restrict, fd_set *restrict,
                    struct timespec const *restrict, const sigset_t *restrict));
 #  endif
-_GL_CXXALIAS_SYS (pselect, int,
-                  (int, fd_set *restrict, fd_set *restrict, fd_set *restrict,
-                   struct timespec const *restrict, const sigset_t *restrict));
+/* Need to cast, because on AIX 7, the second, third, fourth argument may be
+                        void *restrict,   void *restrict,   void *restrict.  */
+_GL_CXXALIAS_SYS_CAST (pselect, int,
+                       (int,
+                        fd_set *restrict, fd_set *restrict, fd_set *restrict,
+                        struct timespec const *restrict,
+                        const sigset_t *restrict));
 # endif
 _GL_CXXALIASWARN (pselect);
 #elif defined GNULIB_POSIXCHECK
diff --git a/lib/sys_socket.c b/lib/sys_socket.c
index d90b32c97..0bfd60f2f 100644
--- a/lib/sys_socket.c
+++ b/lib/sys_socket.c
@@ -1,6 +1,6 @@
 /* Inline functions for <sys/socket.h>.
 
-   Copyright (C) 2012-2021 Free Software Foundation, Inc.
+   Copyright (C) 2012-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/sys_socket.in.h b/lib/sys_socket.in.h
index 0a2c57db5..acdf7eee5 100644
--- a/lib/sys_socket.in.h
+++ b/lib/sys_socket.in.h
@@ -1,6 +1,6 @@
 /* Provide a sys/socket header file for systems lacking it (read: MinGW)
    and for systems where it is incomplete.
-   Copyright (C) 2005-2021 Free Software Foundation, Inc.
+   Copyright (C) 2005-2022 Free Software Foundation, Inc.
    Written by Simon Josefsson.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/sys_stat.in.h b/lib/sys_stat.in.h
index babe3dba3..714c3cb18 100644
--- a/lib/sys_stat.in.h
+++ b/lib/sys_stat.in.h
@@ -1,5 +1,5 @@
 /* Provide a more complete sys/stat.h header file.
-   Copyright (C) 2005-2021 Free Software Foundation, Inc.
+   Copyright (C) 2005-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
@@ -391,7 +391,33 @@ struct stat
 #endif
 
 
-#if @GNULIB_MDA_CHMOD@
+#if @GNULIB_CHMOD@
+# if @REPLACE_CHMOD@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef chmod
+#   define chmod rpl_chmod
+#  endif
+_GL_FUNCDECL_RPL (chmod, int, (const char *filename, mode_t mode)
+                               _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (chmod, int, (const char *filename, mode_t mode));
+# elif defined _WIN32 && !defined __CYGWIN__
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef chmod
+#   define chmod _chmod
+#  endif
+/* Need to cast, because in mingw the last argument is 'int mode'.  */
+_GL_CXXALIAS_MDA_CAST (chmod, int, (const char *filename, mode_t mode));
+# else
+_GL_CXXALIAS_SYS (chmod, int, (const char *filename, mode_t mode));
+# endif
+_GL_CXXALIASWARN (chmod);
+#elif defined GNULIB_POSIXCHECK
+# undef chmod
+# if HAVE_RAW_DECL_CHMOD
+_GL_WARN_ON_USE (chmod, "chmod has portability problems - "
+                 "use gnulib module chmod for portability");
+# endif
+#elif @GNULIB_MDA_CHMOD@
 /* On native Windows, map 'chmod' to '_chmod', so that -loldnames is not
    required.  In C++ with GNULIB_NAMESPACE, avoid differences between
    platforms by defining GNULIB_NAMESPACE::chmod always.  */
diff --git a/lib/sys_time.in.h b/lib/sys_time.in.h
index 8035fbe7e..87db1a887 100644
--- a/lib/sys_time.in.h
+++ b/lib/sys_time.in.h
@@ -1,6 +1,6 @@
 /* Provide a more complete sys/time.h.
 
-   Copyright (C) 2007-2021 Free Software Foundation, Inc.
+   Copyright (C) 2007-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/sys_times.in.h b/lib/sys_times.in.h
index 85b728f00..01b58a4ac 100644
--- a/lib/sys_times.in.h
+++ b/lib/sys_times.in.h
@@ -1,5 +1,5 @@
 /* Provide a sys/times.h header file.
-   Copyright (C) 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2008-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/sys_types.in.h b/lib/sys_types.in.h
index 2079d72ef..698e88d63 100644
--- a/lib/sys_types.in.h
+++ b/lib/sys_types.in.h
@@ -1,6 +1,6 @@
 /* Provide a more complete sys/types.h.
 
-   Copyright (C) 2011-2021 Free Software Foundation, Inc.
+   Copyright (C) 2011-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/sys_uio.in.h b/lib/sys_uio.in.h
index 507ab011b..788d461f1 100644
--- a/lib/sys_uio.in.h
+++ b/lib/sys_uio.in.h
@@ -1,5 +1,5 @@
 /* Substitute for <sys/uio.h>.
-   Copyright (C) 2011-2021 Free Software Foundation, Inc.
+   Copyright (C) 2011-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/tempname.c b/lib/tempname.c
index 5f804b38d..11b4796b3 100644
--- a/lib/tempname.c
+++ b/lib/tempname.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2021 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -20,16 +20,10 @@
 # include "tempname.h"
 #endif
 
-#include <sys/types.h>
-#include <assert.h>
 #include <stdbool.h>
-
 #include <errno.h>
 
 #include <stdio.h>
-#ifndef P_tmpdir
-# define P_tmpdir "/tmp"
-#endif
 #ifndef TMP_MAX
 # define TMP_MAX 238328
 #endif
@@ -43,27 +37,23 @@
 # error report this to bug-gnulib@gnu.org
 #endif
 
-#include <stddef.h>
 #include <stdlib.h>
 #include <string.h>
 
 #include <fcntl.h>
-#include <stdalign.h>
 #include <stdint.h>
 #include <sys/random.h>
 #include <sys/stat.h>
 #include <time.h>
 
 #if _LIBC
-# define struct_stat64 struct stat64
-# define __secure_getenv __libc_secure_getenv
+# define struct_stat64 struct __stat64_t64
 #else
 # define struct_stat64 struct stat
 # define __gen_tempname gen_tempname
 # define __mkdir mkdir
 # define __open open
-# define __lstat64(file, buf) lstat (file, buf)
-# define __stat64(file, buf) stat (file, buf)
+# define __lstat64_time64(file, buf) lstat (file, buf)
 # define __getrandom getrandom
 # define __clock_gettime64 clock_gettime
 # define __timespec64 timespec
@@ -77,94 +67,56 @@ typedef uint_fast64_t random_value;
 #define BASE_62_DIGITS 10 /* 62**10 < UINT_FAST64_MAX */
 #define BASE_62_POWER (62LL * 62 * 62 * 62 * 62 * 62 * 62 * 62 * 62 * 62)
 
+/* Return the result of mixing the entropy from R and S.
+   Assume that R and S are not particularly random,
+   and that the result should look randomish to an untrained eye.  */
+
 static random_value
-random_bits (random_value var, bool use_getrandom)
+mix_random_values (random_value r, random_value s)
 {
-  random_value r;
-  /* Without GRND_NONBLOCK it can be blocked for minutes on some systems.  */
-  if (use_getrandom && __getrandom (&r, sizeof r, GRND_NONBLOCK) == sizeof r)
-    return r;
-#if _LIBC || (defined CLOCK_MONOTONIC && HAVE_CLOCK_GETTIME)
-  /* Add entropy if getrandom did not work.  */
-  struct __timespec64 tv;
-  __clock_gettime64 (CLOCK_MONOTONIC, &tv);
-  var ^= tv.tv_nsec;
-#endif
-  return 2862933555777941757 * var + 3037000493;
+  /* As this code is used only when high-quality randomness is neither
+     available nor necessary, there is no need for fancier polynomials
+     such as those in the Linux kernel's 'random' driver.  */
+  return (2862933555777941757 * r + 3037000493) ^ s;
 }
 
-#if _LIBC
-/* Return nonzero if DIR is an existent directory.  */
-static int
-direxists (const char *dir)
-{
-  struct_stat64 buf;
-  return __stat64 (dir, &buf) == 0 && S_ISDIR (buf.st_mode);
-}
+/* Set *R to a random value.
+   Return true if *R is set to high-quality value taken from getrandom.
+   Otherwise return false, falling back to a low-quality *R that might
+   depend on S.
 
-/* Path search algorithm, for tmpnam, tmpfile, etc.  If DIR is
-   non-null and exists, uses it; otherwise uses the first of $TMPDIR,
-   P_tmpdir, /tmp that exists.  Copies into TMPL a template suitable
-   for use with mk[s]temp.  Will fail (-1) if DIR is non-null and
-   doesn't exist, none of the searched dirs exists, or there's not
-   enough space in TMPL. */
-int
-__path_search (char *tmpl, size_t tmpl_len, const char *dir, const char *pfx,
-               int try_tmpdir)
+   This function returns false only when getrandom fails.
+   On GNU systems this should happen only early in the boot process,
+   when the fallback should be good enough for programs using tempname
+   because any attacker likely has root privileges already.  */
+
+static bool
+random_bits (random_value *r, random_value s)
 {
-  const char *d;
-  size_t dlen, plen;
+  /* Without GRND_NONBLOCK it can be blocked for minutes on some systems.  */
+  if (__getrandom (r, sizeof *r, GRND_NONBLOCK) == sizeof *r)
+    return true;
 
-  if (!pfx || !pfx[0])
-    {
-      pfx = "file";
-      plen = 4;
-    }
-  else
-    {
-      plen = strlen (pfx);
-      if (plen > 5)
-        plen = 5;
-    }
+  /* If getrandom did not work, use ersatz entropy based on low-order
+     clock bits.  On GNU systems getrandom should fail only
+     early in booting, when ersatz should be good enough.
+     Do not use ASLR-based entropy, as that would leak ASLR info into
+     the resulting file name which is typically public.
 
-  if (try_tmpdir)
-    {
-      d = __secure_getenv ("TMPDIR");
-      if (d != NULL && direxists (d))
-        dir = d;
-      else if (dir != NULL && direxists (dir))
-        /* nothing */ ;
-      else
-        dir = NULL;
-    }
-  if (dir == NULL)
-    {
-      if (direxists (P_tmpdir))
-        dir = P_tmpdir;
-      else if (strcmp (P_tmpdir, "/tmp") != 0 && direxists ("/tmp"))
-        dir = "/tmp";
-      else
-        {
-          __set_errno (ENOENT);
-          return -1;
-        }
-    }
+     Of course we are in a state of sin here.  */
 
-  dlen = strlen (dir);
-  while (dlen > 1 && dir[dlen - 1] == '/')
-    dlen--;                     /* remove trailing slashes */
+  random_value v = s;
 
-  /* check we have room for "${dir}/${pfx}XXXXXX\0" */
-  if (tmpl_len < dlen + 1 + plen + 6 + 1)
-    {
-      __set_errno (EINVAL);
-      return -1;
-    }
+#if _LIBC || (defined CLOCK_REALTIME && HAVE_CLOCK_GETTIME)
+  struct __timespec64 tv;
+  __clock_gettime64 (CLOCK_REALTIME, &tv);
+  v = mix_random_values (v, tv.tv_sec);
+  v = mix_random_values (v, tv.tv_nsec);
+#endif
 
-  sprintf (tmpl, "%.*s/%.*sXXXXXX", (int) dlen, dir, (int) plen, pfx);
-  return 0;
+  *r = mix_random_values (v, clock ());
+  return false;
 }
-#endif /* _LIBC */
 
 #if _LIBC
 static int try_tempname_len (char *, int, void *, int (*) (char *, void *),
@@ -181,17 +133,17 @@ try_file (char *tmpl, void *flags)
 }
 
 static int
-try_dir (char *tmpl, void *flags _GL_UNUSED)
+try_dir (char *tmpl, _GL_UNUSED void *flags)
 {
   return __mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR);
 }
 
 static int
-try_nocreate (char *tmpl, void *flags _GL_UNUSED)
+try_nocreate (char *tmpl, _GL_UNUSED void *flags)
 {
   struct_stat64 st;
 
-  if (__lstat64 (tmpl, &st) == 0 || errno == EOVERFLOW)
+  if (__lstat64_time64 (tmpl, &st) == 0 || errno == EOVERFLOW)
     __set_errno (EEXIST);
   return errno == ENOENT ? 0 : -1;
 }
@@ -213,7 +165,7 @@ static const char letters[] =
                         and return a read-write fd.  The file is mode 0600.
    __GT_DIR:            create a directory, which will be mode 0700.
 
-   We use a clever algorithm to get hard-to-predict names. */
+   */
 #ifdef _LIBC
 static
 #endif
@@ -261,25 +213,17 @@ try_tempname_len (char *tmpl, int suffixlen, void *args,
   unsigned int attempts = ATTEMPTS_MIN;
 #endif
 
-  /* A random variable.  The initial value is used only the for fallback path
-     on 'random_bits' on 'getrandom' failure.  Its initial value tries to use
-     some entropy from the ASLR and ignore possible bits from the stack
-     alignment.  */
-  random_value v = ((uintptr_t) &v) / alignof (max_align_t);
+  /* A random variable.  */
+  random_value v = 0;
 
-  /* How many random base-62 digits can currently be extracted from V.  */
+  /* A value derived from the random variable, and how many random
+     base-62 digits can currently be extracted from VDIGBUF.  */
+  random_value vdigbuf;
   int vdigits = 0;
 
-  /* Whether to consume entropy when acquiring random bits.  On the
-     first try it's worth the entropy cost with __GT_NOCREATE, which
-     is inherently insecure and can use the entropy to make it a bit
-     less secure.  On the (rare) second and later attempts it might
-     help against DoS attacks.  */
-  bool use_getrandom = tryfunc == try_nocreate;
-
-  /* Least unfair value for V.  If V is less than this, V can generate
-     BASE_62_DIGITS digits fairly.  Otherwise it might be biased.  */
-  random_value const unfair_min
+  /* Least biased value for V.  If V is less than this, V can generate
+     BASE_62_DIGITS unbiased digits.  Otherwise the digits are biased.  */
+  random_value const biased_min
     = RANDOM_VALUE_MAX - RANDOM_VALUE_MAX % BASE_62_POWER;
 
   len = strlen (tmpl);
@@ -299,18 +243,16 @@ try_tempname_len (char *tmpl, int suffixlen, void *args,
         {
           if (vdigits == 0)
             {
-              do
-                {
-                  v = random_bits (v, use_getrandom);
-                  use_getrandom = true;
-                }
-              while (unfair_min <= v);
+              /* Worry about bias only if the bits are high quality.  */
+              while (random_bits (&v, v) && biased_min <= v)
+                continue;
 
+              vdigbuf = v;
               vdigits = BASE_62_DIGITS;
             }
 
-          XXXXXX[i] = letters[v % 62];
-          v /= 62;
+          XXXXXX[i] = letters[vdigbuf % 62];
+          vdigbuf /= 62;
           vdigits--;
         }
 
diff --git a/lib/tempname.h b/lib/tempname.h
index 795bb4976..5e3c5e155 100644
--- a/lib/tempname.h
+++ b/lib/tempname.h
@@ -1,6 +1,6 @@
 /* Create a temporary file or directory.
 
-   Copyright (C) 2006, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2006, 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
@@ -48,7 +48,7 @@ extern "C" {
                         and return a read-write fd.  The file is mode 0600.
    GT_DIR:              create a directory, which will be mode 0700.
 
-   We use a clever algorithm to get hard-to-predict names. */
+   */
 extern int gen_tempname (char *tmpl, int suffixlen, int flags, int kind);
 /* Similar, except X_SUFFIX_LEN gives the number of Xs.  */
 extern int gen_tempname_len (char *tmpl, int suffixlen, int flags, int kind,
diff --git a/lib/time-internal.h b/lib/time-internal.h
index 6bbd0a727..c8a2a8ce6 100644
--- a/lib/time-internal.h
+++ b/lib/time-internal.h
@@ -1,10 +1,10 @@
 /* Time internal interface
 
-   Copyright 2015-2021 Free Software Foundation, Inc.
+   Copyright 2015-2022 Free Software Foundation, Inc.
 
    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 3 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/time.in.h b/lib/time.in.h
index a73fe59cb..6d4c77196 100644
--- a/lib/time.in.h
+++ b/lib/time.in.h
@@ -1,6 +1,6 @@
 /* A more-standard <time.h>.
 
-   Copyright (C) 2007-2021 Free Software Foundation, Inc.
+   Copyright (C) 2007-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
@@ -120,6 +120,17 @@ _GL_CXXALIAS_SYS (timespec_get, int, (struct timespec *ts, int base));
 _GL_CXXALIASWARN (timespec_get);
 # endif
 
+/* Set *TS to the current time resolution, and return BASE.
+   Upon failure, return 0.  */
+# if @GNULIB_TIMESPEC_GETRES@
+#  if ! @HAVE_TIMESPEC_GETRES@
+_GL_FUNCDECL_SYS (timespec_getres, int, (struct timespec *ts, int base)
+                                        _GL_ARG_NONNULL ((1)));
+#  endif
+_GL_CXXALIAS_SYS (timespec_getres, int, (struct timespec *ts, int base));
+_GL_CXXALIASWARN (timespec_getres);
+# endif
+
 /* Sleep for at least RQTP seconds unless interrupted,  If interrupted,
    return -1 and store the remaining time into RMTP.  See
    <https://pubs.opengroup.org/onlinepubs/9699919799/functions/nanosleep.html>.  */
diff --git a/lib/time_r.c b/lib/time_r.c
index 88d3c1c76..d4b227554 100644
--- a/lib/time_r.c
+++ b/lib/time_r.c
@@ -1,6 +1,6 @@
 /* Reentrant time functions like localtime_r.
 
-   Copyright (C) 2003, 2006-2007, 2010-2021 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2006-2007, 2010-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/time_rz.c b/lib/time_rz.c
index e7722447c..1a91d3778 100644
--- a/lib/time_rz.c
+++ b/lib/time_rz.c
@@ -1,10 +1,10 @@
 /* Time zone functions such as tzalloc and localtime_rz
 
-   Copyright 2015-2021 Free Software Foundation, Inc.
+   Copyright 2015-2022 Free Software Foundation, Inc.
 
    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 3 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/timegm.c b/lib/timegm.c
index 7e723e1fb..a1b19efc3 100644
--- a/lib/timegm.c
+++ b/lib/timegm.c
@@ -1,6 +1,6 @@
 /* Convert UTC calendar time to simple time.  Like mktime but assumes UTC.
 
-   Copyright (C) 1994-2021 Free Software Foundation, Inc.
+   Copyright (C) 1994-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
diff --git a/lib/times.c b/lib/times.c
index 72b852e58..68bc8e3c4 100644
--- a/lib/times.c
+++ b/lib/times.c
@@ -1,6 +1,6 @@
 /* Get process times
 
-   Copyright (C) 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2008-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/trunc.c b/lib/trunc.c
index 1c9c420af..be24c8780 100644
--- a/lib/trunc.c
+++ b/lib/trunc.c
@@ -1,9 +1,9 @@
 /* Round towards zero.
-   Copyright (C) 2007, 2010-2021 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2010-2022 Free Software Foundation, Inc.
 
    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 3 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/tzset.c b/lib/tzset.c
index 7fd4936b2..845d34962 100644
--- a/lib/tzset.c
+++ b/lib/tzset.c
@@ -1,10 +1,10 @@
 /* Provide tzset for systems that don't have it or for which it's broken.
 
-   Copyright (C) 2001-2003, 2005-2007, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2001-2003, 2005-2007, 2009-2022 Free Software Foundation, Inc.
 
    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 3 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/unistd.c b/lib/unistd.c
index 076345602..95978e6ad 100644
--- a/lib/unistd.c
+++ b/lib/unistd.c
@@ -1,6 +1,6 @@
 /* Inline functions for <unistd.h>.
 
-   Copyright (C) 2012-2021 Free Software Foundation, Inc.
+   Copyright (C) 2012-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/unistd.in.h b/lib/unistd.in.h
index 73c882f97..57df09ecd 100644
--- a/lib/unistd.in.h
+++ b/lib/unistd.in.h
@@ -1,5 +1,5 @@
 /* Substitute for and wrapper around <unistd.h>.
-   Copyright (C) 2003-2021 Free Software Foundation, Inc.
+   Copyright (C) 2003-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
@@ -415,16 +415,30 @@ _GL_CXXALIASWARN (close);
 
 
 #if @GNULIB_COPY_FILE_RANGE@
-# if !@HAVE_COPY_FILE_RANGE@
+# if @REPLACE_COPY_FILE_RANGE@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef copy_file_range
+#   define copy_file_range rpl_copy_file_range
+#  endif
+_GL_FUNCDECL_RPL (copy_file_range, ssize_t, (int ifd, off_t *ipos,
+                                             int ofd, off_t *opos,
+                                             size_t len, unsigned flags));
+_GL_CXXALIAS_RPL (copy_file_range, ssize_t, (int ifd, off_t *ipos,
+                                             int ofd, off_t *opos,
+                                             size_t len, unsigned flags));
+# else
+#  if !@HAVE_COPY_FILE_RANGE@
 _GL_FUNCDECL_SYS (copy_file_range, ssize_t, (int ifd, off_t *ipos,
                                              int ofd, off_t *opos,
                                              size_t len, unsigned flags));
+#  endif
 _GL_CXXALIAS_SYS (copy_file_range, ssize_t, (int ifd, off_t *ipos,
                                              int ofd, off_t *opos,
                                              size_t len, unsigned flags));
 # endif
 _GL_CXXALIASWARN (copy_file_range);
 #elif defined GNULIB_POSIXCHECK
+# undef copy_file_range
 # if HAVE_RAW_DECL_COPY_FILE_RANGE
 _GL_WARN_ON_USE (copy_file_range,
                  "copy_file_range is unportable - "
@@ -1409,7 +1423,8 @@ _GL_WARN_ON_USE (getpagesize, "getpagesize is unportable - "
      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 (@GNULIB_GETPASS@ && @REPLACE_GETPASS@) \
+     || (@GNULIB_GETPASS_GNU@ && @REPLACE_GETPASS_FOR_GETPASS_GNU@)
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
 #   undef getpass
 #   define getpass rpl_getpass
diff --git a/lib/unsetenv.c b/lib/unsetenv.c
index b2e910e39..07eac6fdd 100644
--- a/lib/unsetenv.c
+++ b/lib/unsetenv.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1995-2002, 2005-2021 Free Software Foundation, Inc.
+/* Copyright (C) 1992, 1995-2002, 2005-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/vasnprintf.c b/lib/vasnprintf.c
index d9b669d15..285c674b9 100644
--- a/lib/vasnprintf.c
+++ b/lib/vasnprintf.c
@@ -1,5 +1,5 @@
 /* vsprintf with automatic memory allocation.
-   Copyright (C) 1999, 2002-2021 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2002-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
@@ -915,8 +915,7 @@ divide (mpn_t a, mpn_t b, mpn_t *q)
       q_ptr[q_len++] = 1;
     }
   keep_q:
-  if (tmp_roomptr != NULL)
-    free (tmp_roomptr);
+  free (tmp_roomptr);
   q->limbs = q_ptr;
   q->nlimbs = q_len;
   return roomptr;
@@ -1873,11 +1872,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
     free (a.arg);
 
   if (PRINTF_FETCHARGS (args, &a) < 0)
-    {
-      CLEANUP ();
-      errno = EINVAL;
-      return NULL;
-    }
+    goto fail_1_with_EINVAL;
 
   {
     size_t buf_neededlength;
@@ -1913,19 +1908,12 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
         buf_malloced = buf;
       }
 
-    if (resultbuf != NULL)
-      {
-        result = resultbuf;
-        allocated = *lengthp;
-      }
-    else
-      {
-        result = NULL;
-        allocated = 0;
-      }
+    result = resultbuf;
+    allocated = (resultbuf != NULL ? *lengthp : 0);
     length = 0;
     /* Invariants:
-       result is either == resultbuf or == NULL or malloc-allocated.
+       result is either == resultbuf or malloc-allocated.
+       If result == NULL, resultbuf is == NULL as well.
        If length > 0, then result != NULL.  */
 
     /* Ensures that allocated >= needed.  Aborts through a jump to
@@ -1942,7 +1930,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
         memory_size = xtimes (allocated, sizeof (DCHAR_T));                  \
         if (size_overflow_p (memory_size))                                   \
           oom_statement                                                      \
-        if (result == resultbuf || result == NULL)                           \
+        if (result == resultbuf)                                             \
           memory = (DCHAR_T *) malloc (memory_size);                         \
         else                                                                 \
           memory = (DCHAR_T *) realloc (result, memory_size);                \
@@ -2112,15 +2100,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                               if (count == 0)
                                 break;
                               if (count < 0)
-                                {
-                                  if (!(result == resultbuf || result == NULL))
-                                    free (result);
-                                  if (buf_malloced != NULL)
-                                    free (buf_malloced);
-                                  CLEANUP ();
-                                  errno = EILSEQ;
-                                  return NULL;
-                                }
+                                goto fail_with_EILSEQ;
                               arg_end += count;
                               characters++;
                             }
@@ -2137,15 +2117,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                               if (count == 0)
                                 break;
                               if (count < 0)
-                                {
-                                  if (!(result == resultbuf || result == NULL))
-                                    free (result);
-                                  if (buf_malloced != NULL)
-                                    free (buf_malloced);
-                                  CLEANUP ();
-                                  errno = EILSEQ;
-                                  return NULL;
-                                }
+                                goto fail_with_EILSEQ;
                               arg_end += count;
                               characters++;
                             }
@@ -2191,14 +2163,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                                        converted, &converted_len);
 #  endif
                         if (converted == NULL)
-                          {
-                            if (!(result == resultbuf || result == NULL))
-                              free (result);
-                            if (buf_malloced != NULL)
-                              free (buf_malloced);
-                            CLEANUP ();
-                            return NULL;
-                          }
+                          goto fail_with_errno;
                         if (converted != result + length)
                           {
                             ENSURE_ALLOCATION_ELSE (xsum (length, converted_len),
@@ -2237,15 +2202,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                               if (count == 0)
                                 break;
                               if (count < 0)
-                                {
-                                  if (!(result == resultbuf || result == NULL))
-                                    free (result);
-                                  if (buf_malloced != NULL)
-                                    free (buf_malloced);
-                                  CLEANUP ();
-                                  errno = EILSEQ;
-                                  return NULL;
-                                }
+                                goto fail_with_EILSEQ;
                               arg_end += count;
                               characters++;
                             }
@@ -2262,15 +2219,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                               if (count == 0)
                                 break;
                               if (count < 0)
-                                {
-                                  if (!(result == resultbuf || result == NULL))
-                                    free (result);
-                                  if (buf_malloced != NULL)
-                                    free (buf_malloced);
-                                  CLEANUP ();
-                                  errno = EILSEQ;
-                                  return NULL;
-                                }
+                                goto fail_with_EILSEQ;
                               arg_end += count;
                               characters++;
                             }
@@ -2316,14 +2265,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                                         converted, &converted_len);
 #  endif
                         if (converted == NULL)
-                          {
-                            if (!(result == resultbuf || result == NULL))
-                              free (result);
-                            if (buf_malloced != NULL)
-                              free (buf_malloced);
-                            CLEANUP ();
-                            return NULL;
-                          }
+                          goto fail_with_errno;
                         if (converted != result + length)
                           {
                             ENSURE_ALLOCATION_ELSE (xsum (length, converted_len),
@@ -2362,15 +2304,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                               if (count == 0)
                                 break;
                               if (count < 0)
-                                {
-                                  if (!(result == resultbuf || result == NULL))
-                                    free (result);
-                                  if (buf_malloced != NULL)
-                                    free (buf_malloced);
-                                  CLEANUP ();
-                                  errno = EILSEQ;
-                                  return NULL;
-                                }
+                                goto fail_with_EILSEQ;
                               arg_end += count;
                               characters++;
                             }
@@ -2387,15 +2321,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                               if (count == 0)
                                 break;
                               if (count < 0)
-                                {
-                                  if (!(result == resultbuf || result == NULL))
-                                    free (result);
-                                  if (buf_malloced != NULL)
-                                    free (buf_malloced);
-                                  CLEANUP ();
-                                  errno = EILSEQ;
-                                  return NULL;
-                                }
+                                goto fail_with_EILSEQ;
                               arg_end += count;
                               characters++;
                             }
@@ -2441,14 +2367,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                                         converted, &converted_len);
 #  endif
                         if (converted == NULL)
-                          {
-                            if (!(result == resultbuf || result == NULL))
-                              free (result);
-                            if (buf_malloced != NULL)
-                              free (buf_malloced);
-                            CLEANUP ();
-                            return NULL;
-                          }
+                          goto fail_with_errno;
                         if (converted != result + length)
                           {
                             ENSURE_ALLOCATION_ELSE (xsum (length, converted_len),
@@ -2590,16 +2509,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                             /* Found the terminating NUL.  */
                             break;
                           if (count < 0)
-                            {
-                              /* Invalid or incomplete multibyte character.  */
-                              if (!(result == resultbuf || result == NULL))
-                                free (result);
-                              if (buf_malloced != NULL)
-                                free (buf_malloced);
-                              CLEANUP ();
-                              errno = EILSEQ;
-                              return NULL;
-                            }
+                            /* Invalid or incomplete multibyte character.  */
+                            goto fail_with_EILSEQ;
                           arg_end += count;
                           characters++;
                         }
@@ -2626,16 +2537,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                             /* Found the terminating NUL.  */
                             break;
                           if (count < 0)
-                            {
-                              /* Invalid or incomplete multibyte character.  */
-                              if (!(result == resultbuf || result == NULL))
-                                free (result);
-                              if (buf_malloced != NULL)
-                                free (buf_malloced);
-                              CLEANUP ();
-                              errno = EILSEQ;
-                              return NULL;
-                            }
+                            /* Invalid or incomplete multibyte character.  */
+                            goto fail_with_EILSEQ;
                           arg_end += count;
                           characters++;
                         }
@@ -2752,16 +2655,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                             break;
                           count = local_wcrtomb (cbuf, *arg_end, &state);
                           if (count < 0)
-                            {
-                              /* Cannot convert.  */
-                              if (!(result == resultbuf || result == NULL))
-                                free (result);
-                              if (buf_malloced != NULL)
-                                free (buf_malloced);
-                              CLEANUP ();
-                              errno = EILSEQ;
-                              return NULL;
-                            }
+                            /* Cannot convert.  */
+                            goto fail_with_EILSEQ;
                           if (precision < (unsigned int) count)
                             break;
                           arg_end++;
@@ -2793,16 +2688,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                             break;
                           count = local_wcrtomb (cbuf, *arg_end, &state);
                           if (count < 0)
-                            {
-                              /* Cannot convert.  */
-                              if (!(result == resultbuf || result == NULL))
-                                free (result);
-                              if (buf_malloced != NULL)
-                                free (buf_malloced);
-                              CLEANUP ();
-                              errno = EILSEQ;
-                              return NULL;
-                            }
+                            /* Cannot convert.  */
+                            goto fail_with_EILSEQ;
                           arg_end++;
                           characters += count;
                         }
@@ -2859,12 +2746,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                   if (tmpdst == NULL)
                     {
                       free (tmpsrc);
-                      if (!(result == resultbuf || result == NULL))
-                        free (result);
-                      if (buf_malloced != NULL)
-                        free (buf_malloced);
-                      CLEANUP ();
-                      return NULL;
+                      goto fail_with_errno;
                     }
                   free (tmpsrc);
 #  endif
@@ -2938,16 +2820,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                             abort ();
                           count = local_wcrtomb (cbuf, *arg, &state);
                           if (count <= 0)
-                            {
-                              /* Cannot convert.  */
-                              if (!(result == resultbuf || result == NULL))
-                                free (result);
-                              if (buf_malloced != NULL)
-                                free (buf_malloced);
-                              CLEANUP ();
-                              errno = EILSEQ;
-                              return NULL;
-                            }
+                            /* Cannot convert.  */
+                            goto fail_with_EILSEQ;
                           ENSURE_ALLOCATION (xsum (length, count));
                           memcpy (result + length, cbuf, count);
                           length += count;
@@ -3083,14 +2957,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                                               NULL,
                                               NULL, &tmpdst_len);
                   if (tmpdst == NULL)
-                    {
-                      if (!(result == resultbuf || result == NULL))
-                        free (result);
-                      if (buf_malloced != NULL)
-                        free (buf_malloced);
-                      CLEANUP ();
-                      return NULL;
-                    }
+                    goto fail_with_errno;
 # endif
 
                   if (has_width)
@@ -5463,13 +5330,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                               errno = EINVAL;
                           }
 
-                        if (!(result == resultbuf || result == NULL))
-                          free (result);
-                        if (buf_malloced != NULL)
-                          free (buf_malloced);
-                        CLEANUP ();
-
-                        return NULL;
+                        goto fail_with_errno;
                       }
 
 #if USE_SNPRINTF
@@ -5603,14 +5464,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
                                                     NULL,
                                                     NULL, &tmpdst_len);
                         if (tmpdst == NULL)
-                          {
-                            if (!(result == resultbuf || result == NULL))
-                              free (result);
-                            if (buf_malloced != NULL)
-                              free (buf_malloced);
-                            CLEANUP ();
-                            return NULL;
-                          }
+                          goto fail_with_errno;
                         ENSURE_ALLOCATION_ELSE (xsum (length, tmpdst_len),
                                                 { free (tmpdst); goto out_of_memory; });
                         DCHAR_CPY (result + length, tmpdst, tmpdst_len);
@@ -5835,25 +5689,40 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
 
 #if USE_SNPRINTF
   overflow:
-    if (!(result == resultbuf || result == NULL))
-      free (result);
-    if (buf_malloced != NULL)
-      free (buf_malloced);
-    CLEANUP ();
     errno = EOVERFLOW;
-    return NULL;
+    goto fail_with_errno;
 #endif
 
   out_of_memory:
-    if (!(result == resultbuf || result == NULL))
+    errno = ENOMEM;
+    goto fail_with_errno;
+
+#if ENABLE_UNISTDIO || ((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL) || ENABLE_WCHAR_FALLBACK) && HAVE_WCHAR_T)
+  fail_with_EILSEQ:
+    errno = EILSEQ;
+    goto fail_with_errno;
+#endif
+
+  fail_with_errno:
+    if (result != resultbuf)
       free (result);
     if (buf_malloced != NULL)
       free (buf_malloced);
-  out_of_memory_1:
     CLEANUP ();
-    errno = ENOMEM;
     return NULL;
   }
+
+ out_of_memory_1:
+  errno = ENOMEM;
+  goto fail_1_with_errno;
+
+ fail_1_with_EINVAL:
+  errno = EINVAL;
+  goto fail_1_with_errno;
+
+ fail_1_with_errno:
+  CLEANUP ();
+  return NULL;
 }
 
 #undef MAX_ROOM_NEEDED
diff --git a/lib/vasnprintf.h b/lib/vasnprintf.h
index 9b02cdf8a..27cf54c50 100644
--- a/lib/vasnprintf.h
+++ b/lib/vasnprintf.h
@@ -1,5 +1,5 @@
 /* vsprintf with automatic memory allocation.
-   Copyright (C) 2002-2004, 2007-2021 Free Software Foundation, Inc.
+   Copyright (C) 2002-2004, 2007-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/verify.h b/lib/verify.h
index a8ca59b09..47b6ee661 100644
--- a/lib/verify.h
+++ b/lib/verify.h
@@ -1,6 +1,6 @@
 /* Compile-time assert-like macros.
 
-   Copyright (C) 2005-2006, 2009-2021 Free Software Foundation, Inc.
+   Copyright (C) 2005-2006, 2009-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
@@ -34,7 +34,7 @@
 #ifndef __cplusplus
 # if (201112L <= __STDC_VERSION__ \
       || (!defined __STRICT_ANSI__ \
-          && (4 < __GNUC__ + (6 <= __GNUC_MINOR__) || 4 <= __clang_major__)))
+          && (4 < __GNUC__ + (6 <= __GNUC_MINOR__) || 5 <= __clang_major__)))
 #  define _GL_HAVE__STATIC_ASSERT 1
 # endif
 # if (202000L <= __STDC_VERSION__ \
@@ -215,6 +215,9 @@ template <int w>
 # define _GL_VERIFY(R, DIAGNOSTIC, ...)                                \
     extern int (*_GL_GENSYM (_gl_verify_function) (void))	       \
       [_GL_VERIFY_TRUE (R, DIAGNOSTIC)]
+# if 4 < __GNUC__ + (6 <= __GNUC_MINOR__)
+#  pragma GCC diagnostic ignored "-Wnested-externs"
+# endif
 #endif
 
 /* _GL_STATIC_ASSERT_H is defined if this code is copied into assert.h.  */
@@ -300,13 +303,16 @@ template <int w>
 # define assume(R) ((R) ? (void) 0 : __builtin_unreachable ())
 #elif 1200 <= _MSC_VER
 # define assume(R) __assume (R)
+#elif 202311L <= __STDC_VERSION__
+# include <stddef.h>
+# define assume(R) ((R) ? (void) 0 : unreachable ())
 #elif (defined GCC_LINT || defined lint) && _GL_HAS_BUILTIN_TRAP
   /* Doing it this way helps various packages when configured with
      --enable-gcc-warnings, which compiles with -Dlint.  It's nicer
-     when 'assume' silences warnings even with older GCCs.  */
+     if 'assume' silences warnings with GCC 3.4 through GCC 4.4.7 (2012).  */
 # define assume(R) ((R) ? (void) 0 : __builtin_trap ())
 #else
-  /* Some tools grok NOTREACHED, e.g., Oracle Studio 12.6.  */
+  /* Some older tools grok NOTREACHED, e.g., Oracle Studio 12.6 (2017).  */
 # define assume(R) ((R) ? (void) 0 : /*NOTREACHED*/ (void) 0)
 #endif
 
diff --git a/lib/vsnprintf.c b/lib/vsnprintf.c
index 4a0a3dc6a..80999e9b4 100644
--- a/lib/vsnprintf.c
+++ b/lib/vsnprintf.c
@@ -1,5 +1,5 @@
 /* Formatted output to strings.
-   Copyright (C) 2004, 2006-2021 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2006-2022 Free Software Foundation, Inc.
    Written by Simon Josefsson and Yoann Vandoorselaere <yoann@prelude-ids.org>.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/w32sock.h b/lib/w32sock.h
index 635a1b228..17db3f12a 100644
--- a/lib/w32sock.h
+++ b/lib/w32sock.h
@@ -1,6 +1,6 @@
 /* w32sock.h --- internal auxiliary functions for Windows socket functions
 
-   Copyright (C) 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2008-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/warn-on-use.h b/lib/warn-on-use.h
index 612937abb..94f5b9201 100644
--- a/lib/warn-on-use.h
+++ b/lib/warn-on-use.h
@@ -1,5 +1,5 @@
 /* A C macro for emitting warnings if a function is used.
-   Copyright (C) 2010-2021 Free Software Foundation, Inc.
+   Copyright (C) 2010-2022 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify it
    under the terms of the GNU Lesser General Public License as published
@@ -84,20 +84,20 @@
 # if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)
 /* A compiler attribute is available in gcc versions 4.3.0 and later.  */
 #  define _GL_WARN_ON_USE(function, message) \
-extern __typeof__ (function) function __attribute__ ((__warning__ (message)))
+_GL_WARN_EXTERN_C __typeof__ (function) function __attribute__ ((__warning__ (message)))
 #  define _GL_WARN_ON_USE_ATTRIBUTE(message) \
   __attribute__ ((__warning__ (message)))
 # elif __clang_major__ >= 4
 /* Another compiler attribute is available in clang.  */
 #  define _GL_WARN_ON_USE(function, message) \
-extern __typeof__ (function) function \
+_GL_WARN_EXTERN_C __typeof__ (function) function \
   __attribute__ ((__diagnose_if__ (1, message, "warning")))
 #  define _GL_WARN_ON_USE_ATTRIBUTE(message) \
   __attribute__ ((__diagnose_if__ (1, message, "warning")))
 # elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
 /* Verify the existence of the function.  */
 #  define _GL_WARN_ON_USE(function, message) \
-extern __typeof__ (function) function
+_GL_WARN_EXTERN_C __typeof__ (function) function
 #  define _GL_WARN_ON_USE_ATTRIBUTE(message)
 # else /* Unsupported.  */
 #  define _GL_WARN_ON_USE(function, message) \
diff --git a/lib/wchar.in.h b/lib/wchar.in.h
index be5d36c8d..835ddbe65 100644
--- a/lib/wchar.in.h
+++ b/lib/wchar.in.h
@@ -1,6 +1,6 @@
 /* A substitute for ISO C99 <wchar.h>, for platforms that have issues.
 
-   Copyright (C) 2007-2021 Free Software Foundation, Inc.
+   Copyright (C) 2007-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
@@ -72,9 +72,6 @@
 # include <stddef.h>
 #endif
 
-/* Get free().  */
-#include <stdlib.h>
-
 /* Include the original <wchar.h> if it exists.
    Some builds of uClibc lack it.  */
 /* The include_next requires a split double-inclusion guard.  */
@@ -87,6 +84,35 @@
 #ifndef _@GUARD_PREFIX@_WCHAR_H
 #define _@GUARD_PREFIX@_WCHAR_H
 
+/* _GL_ATTRIBUTE_DEALLOC (F, I) declares that the function returns pointers
+   that can be freed by passing them as the Ith argument to the
+   function F.  */
+#ifndef _GL_ATTRIBUTE_DEALLOC
+# if __GNUC__ >= 11
+#  define _GL_ATTRIBUTE_DEALLOC(f, i) __attribute__ ((__malloc__ (f, i)))
+# else
+#  define _GL_ATTRIBUTE_DEALLOC(f, i)
+# endif
+#endif
+
+/* _GL_ATTRIBUTE_DEALLOC_FREE declares that the function returns pointers that
+   can be freed via 'free'; it can be used only after declaring 'free'.  */
+/* Applies to: functions.  Cannot be used on inline functions.  */
+#ifndef _GL_ATTRIBUTE_DEALLOC_FREE
+# define _GL_ATTRIBUTE_DEALLOC_FREE _GL_ATTRIBUTE_DEALLOC (free, 1)
+#endif
+
+/* _GL_ATTRIBUTE_MALLOC declares that the function returns a pointer to freshly
+   allocated memory.  */
+/* Applies to: functions.  */
+#ifndef _GL_ATTRIBUTE_MALLOC
+# if __GNUC__ >= 3 || defined __clang__
+#  define _GL_ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
+# else
+#  define _GL_ATTRIBUTE_MALLOC
+# endif
+#endif
+
 /* The __attribute__ feature is available in gcc versions 2.5 and later.
    The attribute __pure__ was added in gcc 2.96.  */
 #ifndef _GL_ATTRIBUTE_PURE
@@ -149,6 +175,45 @@ typedef int rpl_mbstate_t;
 # endif
 #endif
 
+/* Make _GL_ATTRIBUTE_DEALLOC_FREE work, even though <stdlib.h> may not have
+   been included yet.  */
+#if @GNULIB_FREE_POSIX@
+# if (@REPLACE_FREE@ && !defined free \
+      && !(defined __cplusplus && defined GNULIB_NAMESPACE))
+/* We can't do '#define free rpl_free' here.  */
+_GL_EXTERN_C void rpl_free (void *);
+#  undef _GL_ATTRIBUTE_DEALLOC_FREE
+#  define _GL_ATTRIBUTE_DEALLOC_FREE _GL_ATTRIBUTE_DEALLOC (rpl_free, 1)
+# else
+#  if defined _MSC_VER && !defined free
+_GL_EXTERN_C
+#   if defined _DLL
+     __declspec (dllimport)
+#   endif
+     void __cdecl free (void *);
+#  else
+#   if defined __cplusplus && (__GLIBC__ + (__GLIBC_MINOR__ >= 14) > 2)
+_GL_EXTERN_C void free (void *) throw ();
+#   else
+_GL_EXTERN_C void free (void *);
+#   endif
+#  endif
+# endif
+#else
+# if defined _MSC_VER && !defined free
+_GL_EXTERN_C
+#   if defined _DLL
+     __declspec (dllimport)
+#   endif
+     void __cdecl free (void *);
+# else
+#  if defined __cplusplus && (__GLIBC__ + (__GLIBC_MINOR__ >= 14) > 2)
+_GL_EXTERN_C void free (void *) throw ();
+#  else
+_GL_EXTERN_C void free (void *);
+#  endif
+# endif
+#endif
 
 /* Convert a single-byte character to a wide character.  */
 #if @GNULIB_BTOWC@
diff --git a/lib/wcrtomb.c b/lib/wcrtomb.c
index 5c9fd795b..e14d8022a 100644
--- a/lib/wcrtomb.c
+++ b/lib/wcrtomb.c
@@ -1,5 +1,5 @@
 /* Convert wide character to multibyte character.
-   Copyright (C) 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2008-2022 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2008.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/wctype-h.c b/lib/wctype-h.c
index 150221d6d..127814330 100644
--- a/lib/wctype-h.c
+++ b/lib/wctype-h.c
@@ -1,6 +1,6 @@
 /* Inline functions for <wctype.h>.
 
-   Copyright (C) 2012-2021 Free Software Foundation, Inc.
+   Copyright (C) 2012-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/wctype.in.h b/lib/wctype.in.h
index 652d811ea..98cafee77 100644
--- a/lib/wctype.in.h
+++ b/lib/wctype.in.h
@@ -1,6 +1,6 @@
 /* A substitute for ISO C99 <wctype.h>, for platforms that lack it.
 
-   Copyright (C) 2006-2021 Free Software Foundation, Inc.
+   Copyright (C) 2006-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/windows-initguard.h b/lib/windows-initguard.h
index 7999b2339..a29d7e97b 100644
--- a/lib/windows-initguard.h
+++ b/lib/windows-initguard.h
@@ -1,5 +1,5 @@
 /* Init guards, somewhat like spinlocks (native Windows implementation).
-   Copyright (C) 2005-2021 Free Software Foundation, Inc.
+   Copyright (C) 2005-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/windows-spawn.c b/lib/windows-spawn.c
new file mode 100644
index 000000000..a9212d485
--- /dev/null
+++ b/lib/windows-spawn.c
@@ -0,0 +1,727 @@
+/* Auxiliary functions for the creation of subprocesses.  Native Windows API.
+   Copyright (C) 2001, 2003-2022 Free Software Foundation, Inc.
+   Written by Bruno Haible <bruno@clisp.org>, 2003.
+
+   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 2.1 of the
+   License, or (at your option) any later version.
+
+   This file 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include "windows-spawn.h"
+
+/* Get declarations of the native Windows API functions.  */
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+/* Get _get_osfhandle().  */
+#if GNULIB_MSVC_NOTHROW
+# include "msvc-nothrow.h"
+#else
+# include <io.h>
+#endif
+#include <process.h>
+
+#include "findprog.h"
+
+/* Don't assume that UNICODE is not defined.  */
+#undef STARTUPINFO
+#define STARTUPINFO STARTUPINFOA
+#undef CreateProcess
+#define CreateProcess CreateProcessA
+
+#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037*?"
+#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+
+/* Returns the length of a quoted argument string.  */
+static size_t
+quoted_arg_length (const char *string)
+{
+  bool quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL);
+  size_t length;
+  unsigned int backslashes;
+  const char *s;
+
+  length = 0;
+  backslashes = 0;
+  if (quote_around)
+    length++;
+  for (s = string; *s != '\0'; s++)
+    {
+      char c = *s;
+      if (c == '"')
+        length += backslashes + 1;
+      length++;
+      if (c == '\\')
+        backslashes++;
+      else
+        backslashes = 0;
+    }
+  if (quote_around)
+    length += backslashes + 1;
+
+  return length;
+}
+
+/* Produces a quoted argument string.
+   Stores exactly quoted_arg_length (STRING) + 1 bytes, including the final
+   NUL byte, at MEM.
+   Returns a pointer past the stored quoted argument string.  */
+static char *
+quoted_arg_string (const char *string, char *mem)
+{
+  bool quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL);
+  char *p;
+  unsigned int backslashes;
+  const char *s;
+
+  p = mem;
+  backslashes = 0;
+  if (quote_around)
+    *p++ = '"';
+  for (s = string; *s != '\0'; s++)
+    {
+      char c = *s;
+      if (c == '"')
+        {
+          unsigned int j;
+          for (j = backslashes + 1; j > 0; j--)
+            *p++ = '\\';
+        }
+      *p++ = c;
+      if (c == '\\')
+        backslashes++;
+      else
+        backslashes = 0;
+    }
+  if (quote_around)
+    {
+      unsigned int j;
+      for (j = backslashes; j > 0; j--)
+        *p++ = '\\';
+      *p++ = '"';
+    }
+  *p++ = '\0';
+
+  return p;
+}
+
+const char **
+prepare_spawn (const char * const *argv, char **mem_to_free)
+{
+  size_t argc;
+  const char **new_argv;
+  size_t i;
+
+  /* Count number of arguments.  */
+  for (argc = 0; argv[argc] != NULL; argc++)
+    ;
+
+  /* Allocate new argument vector.  */
+  new_argv = (const char **) malloc ((1 + argc + 1) * sizeof (const char *));
+
+  /* Add an element upfront that can be used when argv[0] turns out to be a
+     script, not a program.
+     On Unix, this would be "/bin/sh". On native Windows, "sh" is actually
+     "sh.exe".  We have to omit the directory part and rely on the search in
+     PATH, because the mingw "mount points" are not visible inside Windows
+     CreateProcess().  */
+  new_argv[0] = "sh.exe";
+
+  /* Put quoted arguments into the new argument vector.  */
+  size_t needed_size = 0;
+  for (i = 0; i < argc; i++)
+    {
+      const char *string = argv[i];
+      size_t length;
+
+      if (string[0] == '\0')
+        length = strlen ("\"\"");
+      else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL)
+        length = quoted_arg_length (string);
+      else
+        length = strlen (string);
+      needed_size += length + 1;
+    }
+
+  char *mem;
+  if (needed_size == 0)
+    mem = NULL;
+  else
+    {
+      mem = (char *) malloc (needed_size);
+      if (mem == NULL)
+        {
+          /* Memory allocation failure.  */
+          free (new_argv);
+          errno = ENOMEM;
+          return NULL;
+        }
+    }
+  *mem_to_free = mem;
+
+  for (i = 0; i < argc; i++)
+    {
+      const char *string = argv[i];
+
+      new_argv[1 + i] = mem;
+      if (string[0] == '\0')
+        {
+          size_t length = strlen ("\"\"");
+          memcpy (mem, "\"\"", length + 1);
+          mem += length + 1;
+        }
+      else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL)
+        {
+          mem = quoted_arg_string (string, mem);
+        }
+      else
+        {
+          size_t length = strlen (string);
+          memcpy (mem, string, length + 1);
+          mem += length + 1;
+        }
+    }
+  new_argv[1 + argc] = NULL;
+
+  return new_argv;
+}
+
+char *
+compose_command (const char * const *argv)
+{
+  /* Just concatenate the argv[] strings, separated by spaces.  */
+  char *command;
+
+  /* Determine the size of the needed block of memory.  */
+  size_t total_size = 0;
+  const char * const *ap;
+  const char *p;
+  for (ap = argv; (p = *ap) != NULL; ap++)
+    total_size += strlen (p) + 1;
+  size_t command_size = (total_size > 0 ? total_size : 1);
+
+  /* Allocate the block of memory.  */
+  command = (char *) malloc (command_size);
+  if (command == NULL)
+    {
+      errno = ENOMEM;
+      return NULL;
+    }
+
+  /* Fill it.  */
+  if (total_size > 0)
+    {
+      char *cp = command;
+      for (ap = argv; (p = *ap) != NULL; ap++)
+        {
+          size_t size = strlen (p) + 1;
+          memcpy (cp, p, size - 1);
+          cp += size;
+          cp[-1] = ' ';
+        }
+      cp[-1] = '\0';
+    }
+  else
+    *command = '\0';
+
+  return command;
+}
+
+char *
+compose_envblock (const char * const *envp)
+{
+  /* This is a bit hairy, because we don't have a lock that would prevent other
+     threads from making modifications in ENVP.  So, just make sure we don't
+     crash; but if other threads are making modifications, part of the result
+     may be wrong.  */
+ retry:
+  {
+    /* Guess the size of the needed block of memory.
+       The guess will be exact if other threads don't make modifications.  */
+    size_t total_size = 0;
+    const char * const *ep;
+    const char *p;
+    for (ep = envp; (p = *ep) != NULL; ep++)
+      total_size += strlen (p) + 1;
+    size_t envblock_size = total_size;
+
+    /* Allocate the block of memory.  */
+    char *envblock = (char *) malloc (envblock_size + 1);
+    if (envblock == NULL)
+      {
+        errno = ENOMEM;
+        return NULL;
+      }
+    size_t envblock_used = 0;
+    for (ep = envp; (p = *ep) != NULL; ep++)
+      {
+        size_t size = strlen (p) + 1;
+        if (envblock_used + size > envblock_size)
+          {
+            /* Other threads did modifications.  Need more memory.  */
+            envblock_size += envblock_size / 2;
+            if (envblock_used + size > envblock_size)
+              envblock_size = envblock_used + size;
+
+            char *new_envblock = (char *) realloc (envblock, envblock_size + 1);
+            if (new_envblock == NULL)
+              {
+                free (envblock);
+                errno = ENOMEM;
+                return NULL;
+              }
+            envblock = new_envblock;
+          }
+        memcpy (envblock + envblock_used, p, size);
+        envblock_used += size;
+        if (envblock[envblock_used - 1] != '\0')
+          {
+            /* Other threads did modifications.  Restart.  */
+            free (envblock);
+            goto retry;
+          }
+      }
+    envblock[envblock_used] = '\0';
+    return envblock;
+  }
+}
+
+int
+init_inheritable_handles (struct inheritable_handles *inh_handles,
+                          bool duplicate)
+{
+  /* Determine the minimal count of handles we need to care about.  */
+  size_t handles_count;
+  {
+    /* _getmaxstdio
+       <https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/getmaxstdio>
+       Default value is 512.  */
+    unsigned int fdmax = _getmaxstdio ();
+    if (fdmax < 3)
+      fdmax = 3;
+    for (; fdmax > 3; fdmax--)
+      {
+        unsigned int fd = fdmax - 1;
+        /* _get_osfhandle
+           <https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/get-osfhandle>  */
+        HANDLE handle = (HANDLE) _get_osfhandle (fd);
+        if (handle != INVALID_HANDLE_VALUE)
+          {
+            DWORD hflags;
+            /* GetHandleInformation
+               <https://docs.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-gethandleinformation>  */
+            if (GetHandleInformation (handle, &hflags))
+              {
+                if ((hflags & HANDLE_FLAG_INHERIT) != 0)
+                  /* fd denotes an inheritable descriptor.  */
+                  break;
+              }
+          }
+      }
+    handles_count = fdmax;
+  }
+  /* Note: handles_count >= 3.  */
+
+  /* Allocate the arrays.  */
+  size_t handles_allocated = handles_count;
+  HANDLE *handles_array =
+    (HANDLE *) malloc (handles_allocated * sizeof (HANDLE));
+  if (handles_array == NULL)
+    {
+      errno = ENOMEM;
+      return -1;
+    }
+  unsigned char *flags_array =
+    (unsigned char *) malloc (handles_allocated * sizeof (unsigned char));
+  if (flags_array == NULL)
+    {
+      free (handles_array);
+      errno = ENOMEM;
+      return -1;
+    }
+
+  /* Fill in the two arrays.  */
+  {
+    HANDLE curr_process = (duplicate ? GetCurrentProcess () : INVALID_HANDLE_VALUE);
+    unsigned int fd;
+    for (fd = 0; fd < handles_count; fd++)
+      {
+        handles_array[fd] = INVALID_HANDLE_VALUE;
+        /* _get_osfhandle
+           <https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/get-osfhandle>  */
+        HANDLE handle = (HANDLE) _get_osfhandle (fd);
+        if (handle != INVALID_HANDLE_VALUE)
+          {
+            DWORD hflags;
+            /* GetHandleInformation
+               <https://docs.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-gethandleinformation>  */
+            if (GetHandleInformation (handle, &hflags))
+              {
+                if ((hflags & HANDLE_FLAG_INHERIT) != 0)
+                  {
+                    /* fd denotes an inheritable descriptor.  */
+                    if (duplicate)
+                      {
+                        if (!DuplicateHandle (curr_process, handle,
+                                              curr_process, &handles_array[fd],
+                                              0, TRUE, DUPLICATE_SAME_ACCESS))
+                          {
+                            unsigned int i;
+                            for (i = 0; i < fd; i++)
+                              if (handles_array[i] != INVALID_HANDLE_VALUE)
+                                CloseHandle (handles_array[i]);
+                            free (flags_array);
+                            free (handles_array);
+                            errno = EBADF; /* arbitrary */
+                            return -1;
+                          }
+                      }
+                    else
+                      handles_array[fd] = handle;
+
+                    flags_array[fd] = 0;
+                  }
+              }
+          }
+      }
+  }
+
+  /* Return the result.  */
+  inh_handles->count = handles_count;
+  inh_handles->allocated = handles_allocated;
+  inh_handles->handles = handles_array;
+  inh_handles->flags = flags_array;
+  return 0;
+}
+
+int
+compose_handles_block (const struct inheritable_handles *inh_handles,
+                       STARTUPINFO *sinfo)
+{
+  /* STARTUPINFO
+     <https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/ns-processthreadsapi-startupinfoa>  */
+  sinfo->dwFlags = STARTF_USESTDHANDLES;
+  sinfo->hStdInput  = inh_handles->handles[0];
+  sinfo->hStdOutput = inh_handles->handles[1];
+  sinfo->hStdError  = inh_handles->handles[2];
+
+  /* On newer versions of Windows, more file descriptors / handles than the
+     first three can be passed.
+     The format is as follows: Let N be an exclusive upper bound for the file
+     descriptors to be passed. Two arrays are constructed in memory:
+       - flags[0..N-1], of element type 'unsigned char',
+       - handles[0..N-1], of element type 'HANDLE' or 'intptr_t'.
+     For used entries, handles[i] is the handle, and flags[i] is a set of flags,
+     a combination of:
+        1 for open file descriptors,
+       64 for handles of type FILE_TYPE_CHAR,
+        8 for handles of type FILE_TYPE_PIPE,
+       32 for O_APPEND.
+     For unused entries - this may include any of the first three, since they
+     are already passed above -, handles[i] is INVALID_HANDLE_VALUE and flags[i]
+     is zero.
+     lpReserved2 now is a pointer to the concatenation (without padding) of:
+       - an 'unsigned int' whose value is N,
+       - the contents of the flags[0..N-1] array,
+       - the contents of the handles[0..N-1] array.
+     cbReserved2 is the size (in bytes) of the object at lpReserved2.  */
+
+  size_t handles_count = inh_handles->count;
+
+  sinfo->cbReserved2 =
+    sizeof (unsigned int)
+    + handles_count * sizeof (unsigned char)
+    + handles_count * sizeof (HANDLE);
+  /* Add some padding, so that we can work with a properly aligned HANDLE
+     array.  */
+  char *hblock = (char *) malloc (sinfo->cbReserved2 + (sizeof (HANDLE) - 1));
+  if (hblock == NULL)
+    {
+      errno = ENOMEM;
+      return -1;
+    }
+  unsigned char *flags = (unsigned char *) (hblock + sizeof (unsigned int));
+  char *handles = (char *) (flags + handles_count);
+  HANDLE *handles_aligned =
+    (HANDLE *) (((uintptr_t) handles + (sizeof (HANDLE) - 1))
+                & - (uintptr_t) sizeof (HANDLE));
+
+  * (unsigned int *) hblock = handles_count;
+  {
+    unsigned int fd;
+    for (fd = 0; fd < handles_count; fd++)
+      {
+        handles_aligned[fd] = INVALID_HANDLE_VALUE;
+        flags[fd] = 0;
+
+        HANDLE handle = inh_handles->handles[fd];
+        if (handle != INVALID_HANDLE_VALUE
+            /* The first three are possibly already passed above.
+               But they need to passed here as well, if they have some flags.  */
+            && (fd >= 3 || inh_handles->flags[fd] != 0))
+          {
+            DWORD hflags;
+            /* GetHandleInformation
+               <https://docs.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-gethandleinformation>  */
+            if (GetHandleInformation (handle, &hflags))
+              {
+                if ((hflags & HANDLE_FLAG_INHERIT) != 0)
+                  {
+                    /* fd denotes an inheritable descriptor.  */
+                    handles_aligned[fd] = handle;
+                    /* On Microsoft Windows, it would be sufficient to set
+                       flags[fd] = 1.  But on ReactOS or Wine, adding the bit
+                       that indicates the handle type may be necessary.  So,
+                       just do it everywhere.  */
+                    flags[fd] = 1 | inh_handles->flags[fd];
+                    switch (GetFileType (handle))
+                      {
+                      case FILE_TYPE_CHAR:
+                        flags[fd] |= 64;
+                        break;
+                      case FILE_TYPE_PIPE:
+                        flags[fd] |= 8;
+                        break;
+                      default:
+                        break;
+                      }
+                  }
+                else
+                  /* We shouldn't have any non-inheritable handles in
+                     inh_handles->handles.  */
+                  abort ();
+              }
+          }
+      }
+  }
+  if (handles != (char *) handles_aligned)
+    memmove (handles, (char *) handles_aligned, handles_count * sizeof (HANDLE));
+
+  sinfo->lpReserved2 = (BYTE *) hblock;
+
+  return 0;
+}
+
+void
+free_inheritable_handles (struct inheritable_handles *inh_handles)
+{
+  free (inh_handles->flags);
+  free (inh_handles->handles);
+}
+
+int
+convert_CreateProcess_error (DWORD error)
+{
+  /* Some of these errors probably cannot happen.  But who knows...  */
+  switch (error)
+    {
+    case ERROR_FILE_NOT_FOUND:
+    case ERROR_PATH_NOT_FOUND:
+    case ERROR_BAD_PATHNAME:
+    case ERROR_BAD_NET_NAME:
+    case ERROR_INVALID_NAME:
+    case ERROR_DIRECTORY:
+      return ENOENT;
+      break;
+
+    case ERROR_ACCESS_DENIED:
+    case ERROR_SHARING_VIOLATION:
+      return EACCES;
+      break;
+
+    case ERROR_OUTOFMEMORY:
+      return ENOMEM;
+      break;
+
+    case ERROR_BUFFER_OVERFLOW:
+    case ERROR_FILENAME_EXCED_RANGE:
+      return ENAMETOOLONG;
+      break;
+
+    case ERROR_BAD_FORMAT:
+    case ERROR_BAD_EXE_FORMAT:
+      return ENOEXEC;
+      break;
+
+    default:
+      return EINVAL;
+      break;
+    }
+}
+
+intptr_t
+spawnpvech (int mode,
+            const char *progname, const char * const *argv,
+            const char * const *envp,
+            const char *currdir,
+            HANDLE stdin_handle, HANDLE stdout_handle, HANDLE stderr_handle)
+{
+  /* Validate the arguments.  */
+  if (!(mode == P_WAIT
+        || mode == P_NOWAIT
+        || mode == P_DETACH
+        || mode == P_OVERLAY)
+      || progname == NULL || argv == NULL)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+
+  /* Implement the 'p' letter: search for PROGNAME in getenv ("PATH").  */
+  const char *resolved_progname =
+    find_in_given_path (progname, getenv ("PATH"), NULL, false);
+  if (resolved_progname == NULL)
+    return -1;
+
+  /* Compose the command.  */
+  char *command = compose_command (argv);
+  if (command == NULL)
+    goto out_of_memory_1;
+
+  /* Copy *ENVP into a contiguous block of memory.  */
+  char *envblock;
+  if (envp == NULL)
+    envblock = NULL;
+  else
+    {
+      envblock = compose_envblock (envp);
+      if (envblock == NULL)
+        goto out_of_memory_2;
+    }
+
+  /* Collect the inheritable handles.  */
+  struct inheritable_handles inh_handles;
+  if (init_inheritable_handles (&inh_handles, false) < 0)
+    {
+      int saved_errno = errno;
+      if (envblock != NULL)
+        free (envblock);
+      free (command);
+      if (resolved_progname != progname)
+        free ((char *) resolved_progname);
+      errno = saved_errno;
+      return -1;
+    }
+  inh_handles.handles[0] = stdin_handle;  inh_handles.flags[0] = 0;
+  inh_handles.handles[1] = stdout_handle; inh_handles.flags[1] = 0;
+  inh_handles.handles[2] = stderr_handle; inh_handles.flags[2] = 0;
+
+  /* CreateProcess
+     <https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessa>  */
+  /* <https://docs.microsoft.com/en-us/windows/win32/procthread/process-creation-flags>  */
+  DWORD process_creation_flags = (mode == P_DETACH ? DETACHED_PROCESS : 0);
+  /* STARTUPINFO
+     <https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/ns-processthreadsapi-startupinfoa>  */
+  STARTUPINFO sinfo;
+  sinfo.cb = sizeof (STARTUPINFO);
+  sinfo.lpReserved = NULL;
+  sinfo.lpDesktop = NULL;
+  sinfo.lpTitle = NULL;
+  if (compose_handles_block (&inh_handles, &sinfo) < 0)
+    {
+      int saved_errno = errno;
+      free_inheritable_handles (&inh_handles);
+      if (envblock != NULL)
+        free (envblock);
+      free (command);
+      if (resolved_progname != progname)
+        free ((char *) resolved_progname);
+      errno = saved_errno;
+      return -1;
+    }
+
+  PROCESS_INFORMATION pinfo;
+  if (!CreateProcess (resolved_progname, command, NULL, NULL, TRUE,
+                      process_creation_flags, envblock, currdir, &sinfo,
+                      &pinfo))
+    {
+      DWORD error = GetLastError ();
+
+      free (sinfo.lpReserved2);
+      free_inheritable_handles (&inh_handles);
+      if (envblock != NULL)
+        free (envblock);
+      free (command);
+      if (resolved_progname != progname)
+        free ((char *) resolved_progname);
+
+      errno = convert_CreateProcess_error (error);
+      return -1;
+    }
+
+  if (pinfo.hThread)
+    CloseHandle (pinfo.hThread);
+  free (sinfo.lpReserved2);
+  free_inheritable_handles (&inh_handles);
+  if (envblock != NULL)
+    free (envblock);
+  free (command);
+  if (resolved_progname != progname)
+    free ((char *) resolved_progname);
+
+  switch (mode)
+    {
+    case P_WAIT:
+      {
+        /* Wait until it terminates.  Then get its exit status code.  */
+        switch (WaitForSingleObject (pinfo.hProcess, INFINITE))
+          {
+          case WAIT_OBJECT_0:
+            break;
+          case WAIT_FAILED:
+            errno = ECHILD;
+            return -1;
+          default:
+            abort ();
+          }
+
+        DWORD exit_code;
+        if (!GetExitCodeProcess (pinfo.hProcess, &exit_code))
+          {
+            errno = ECHILD;
+            return -1;
+          }
+        CloseHandle (pinfo.hProcess);
+        return exit_code;
+      }
+
+    case P_NOWAIT:
+      /* Return pinfo.hProcess, not pinfo.dwProcessId.  */
+      return (intptr_t) pinfo.hProcess;
+
+    case P_DETACH:
+    case P_OVERLAY:
+      CloseHandle (pinfo.hProcess);
+      return 0;
+
+    default:
+      /* Already checked above.  */
+      abort ();
+    }
+
+  /*NOTREACHED*/
+ out_of_memory_2:
+  free (command);
+ out_of_memory_1:
+  if (resolved_progname != progname)
+    free ((char *) resolved_progname);
+  errno = ENOMEM;
+  return -1;
+}
diff --git a/lib/windows-spawn.h b/lib/windows-spawn.h
new file mode 100644
index 000000000..0be407bf9
--- /dev/null
+++ b/lib/windows-spawn.h
@@ -0,0 +1,157 @@
+/* Auxiliary functions for the creation of subprocesses.  Native Windows API.
+   Copyright (C) 2001, 2003-2022 Free Software Foundation, Inc.
+   Written by Bruno Haible <bruno@clisp.org>, 2003.
+
+   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 2.1 of the
+   License, or (at your option) any later version.
+
+   This file 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+#ifndef _WINDOWS_SPAWN_H
+#define _WINDOWS_SPAWN_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+/* Get declarations of the native Windows API functions.  */
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+
+/* Prepares an argument vector before calling spawn().
+
+   Note that spawn() does not by itself call the command interpreter
+     (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") :
+      ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+         GetVersionEx(&v);
+         v.dwPlatformId == VER_PLATFORM_WIN32_NT;
+      }) ? "cmd.exe" : "command.com").
+   Instead it simply concatenates the arguments, separated by ' ', and calls
+   CreateProcess().  We must quote the arguments since Windows CreateProcess()
+   interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a
+   special way:
+   - Space and tab are interpreted as delimiters. They are not treated as
+     delimiters if they are surrounded by double quotes: "...".
+   - Unescaped double quotes are removed from the input. Their only effect is
+     that within double quotes, space and tab are treated like normal
+     characters.
+   - Backslashes not followed by double quotes are not special.
+   - But 2*n+1 backslashes followed by a double quote become
+     n backslashes followed by a double quote (n >= 0):
+       \" -> "
+       \\\" -> \"
+       \\\\\" -> \\"
+   - '*', '?' characters may get expanded through wildcard expansion in the
+     callee: By default, in the callee, the initialization code before main()
+     takes the result of GetCommandLine(), wildcard-expands it, and passes it
+     to main(). The exceptions to this rule are:
+       - programs that inspect GetCommandLine() and ignore argv,
+       - mingw programs that have a global variable 'int _CRT_glob = 0;',
+       - Cygwin programs, when invoked from a Cygwin program.
+
+   prepare_spawn creates and returns a new argument vector, where the arguments
+   are appropriately quoted and an additional argument "sh.exe" has been added
+   at the beginning.  The new argument vector is freshly allocated.  The memory
+   for all its elements is allocated within *MEM_TO_FREE, which is freshly
+   allocated as well.  In case of memory allocation failure, NULL is returned,
+   with errno set.
+ */
+extern const char ** prepare_spawn (const char * const *argv,
+                                    char **mem_to_free);
+
+/* Composes the command to be passed to CreateProcess().
+   ARGV must contain appropriately quoted arguments, as returned by
+   prepare_spawn.
+   Returns a freshly allocated string.  In case of memory allocation failure,
+   NULL is returned, with errno set.  */
+extern char * compose_command (const char * const *argv)
+  _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE;
+
+/* Composes the block of memory that contains the environment variables.
+   ENVP must contain an environment (a NULL-terminated array of string of the
+   form VARIABLE=VALUE).
+   Returns a freshly allocated block of memory.  In case of memory allocation
+   failure, NULL is returned, with errno set.  */
+extern char * compose_envblock (const char * const *envp)
+  _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE;
+
+
+/* This struct keeps track of which handles to pass to a subprocess, and with
+   which flags.  All of the handles here are inheritable.
+   Regarding handle inheritance, see
+   <https://docs.microsoft.com/en-us/windows/win32/sysinfo/handle-inheritance>  */
+struct inheritable_handles
+{
+  /* The number of occupied entries in the two arrays below.
+     3 <= count <= allocated.  */
+  size_t count;
+  /* The number of allocated entries in the two arrays below.  */
+  size_t allocated;
+  /* handles[0..count-1] are the occupied entries.
+     handles[fd] is either INVALID_HANDLE_VALUE or an inheritable handle.  */
+  HANDLE *handles;
+  /* flags[0..count-1] are the occupied entries.
+     flags[fd] is only relevant if handles[fd] != INVALID_HANDLE_VALUE.
+     It is a bit mask consisting of:
+       - 32 for O_APPEND.
+   */
+  unsigned char *flags;
+};
+
+/* Initializes a set of inheritable handles, filling in all inheritable handles
+   assigned to file descriptors.
+   If DUPLICATE is true, the handles stored in the set are duplicates.
+   Returns 0 upon success.  In case of failure, -1 is returned, with errno set.
+ */
+extern int init_inheritable_handles (struct inheritable_handles *inh_handles,
+                                     bool duplicate);
+
+/* Fills a set of inheritable handles into a STARTUPINFO for CreateProcess().
+   Returns 0 upon success.  In case of failure, -1 is returned, with errno set.
+ */
+extern int compose_handles_block (const struct inheritable_handles *inh_handles,
+                                  STARTUPINFOA *sinfo);
+
+/* Frees the memory held by a set of inheritable handles.  */
+extern void free_inheritable_handles (struct inheritable_handles *inh_handles);
+
+
+/* Converts a CreateProcess() error code (retrieved through GetLastError()) to
+   an errno value.  */
+extern int convert_CreateProcess_error (DWORD error);
+
+
+/* Creates a subprocess.
+   MODE is either P_WAIT or P_NOWAIT.
+   PROGNAME is the program to invoke.
+   ARGV is the NULL-terminated array of arguments, ARGV[0] being PROGNAME by
+   convention.
+   ENVP is the NULL-terminated set of environment variable assignments, or NULL
+   to inherit the initial environ variable assignments from the caller and
+   ignore all calls to putenv(), setenv(), unsetenv() done in the caller.
+   CURRDIR is the directory in which to start the program, or NULL to inherit
+   the working directory from the caller.
+   STDIN_HANDLE, STDOUT_HANDLE, STDERR_HANDLE are the handles to use for the
+   first three file descriptors in the callee process.
+   Returns
+     - 0 for success (if MODE is P_WAIT), or
+     - a handle that be passed to _cwait (on Windows) or waitpid (on OS/2), or
+     - -1 upon error, with errno set.
+ */
+extern intptr_t spawnpvech (int mode,
+                            const char *progname, const char * const *argv,
+                            const char * const *envp,
+                            const char *currdir,
+                            HANDLE stdin_handle, HANDLE stdout_handle,
+                            HANDLE stderr_handle);
+
+#endif /* _WINDOWS_SPAWN_H */
diff --git a/lib/write.c b/lib/write.c
index 614cdc62f..bcbc97c63 100644
--- a/lib/write.c
+++ b/lib/write.c
@@ -1,5 +1,5 @@
 /* POSIX compatible write() function.
-   Copyright (C) 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2008-2022 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2008.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/xalloc-oversized.h b/lib/xalloc-oversized.h
index 4184f3395..aefa6fd80 100644
--- a/lib/xalloc-oversized.h
+++ b/lib/xalloc-oversized.h
@@ -1,6 +1,6 @@
 /* xalloc-oversized.h -- memory allocation size checking
 
-   Copyright (C) 1990-2000, 2003-2004, 2006-2021 Free Software Foundation, Inc.
+   Copyright (C) 1990-2000, 2003-2004, 2006-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/xsize.c b/lib/xsize.c
index b3d73a2d8..761e3434d 100644
--- a/lib/xsize.c
+++ b/lib/xsize.c
@@ -1,6 +1,6 @@
 /* Checked size_t computations.
 
-   Copyright (C) 2012-2021 Free Software Foundation, Inc.
+   Copyright (C) 2012-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/lib/xsize.h b/lib/xsize.h
index 91fa877ce..0bfa4c889 100644
--- a/lib/xsize.h
+++ b/lib/xsize.h
@@ -1,6 +1,6 @@
 /* xsize.h -- Checked size_t computations.
 
-   Copyright (C) 2003, 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2008-2022 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
diff --git a/m4/00gnulib.m4 b/m4/00gnulib.m4
index 9ba1743e6..dea34e834 100644
--- a/m4/00gnulib.m4
+++ b/m4/00gnulib.m4
@@ -1,5 +1,5 @@
 # 00gnulib.m4 serial 8
-dnl Copyright (C) 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/__inline.m4 b/m4/__inline.m4
index b28cc6abc..fbe2098e8 100644
--- a/m4/__inline.m4
+++ b/m4/__inline.m4
@@ -1,5 +1,5 @@
 # Test for __inline keyword
-dnl Copyright 2017-2021 Free Software Foundation, Inc.
+dnl Copyright 2017-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/absolute-header.m4 b/m4/absolute-header.m4
index 52d80d042..67d6507c3 100644
--- a/m4/absolute-header.m4
+++ b/m4/absolute-header.m4
@@ -1,5 +1,5 @@
 # absolute-header.m4 serial 17
-dnl Copyright (C) 2006-2021 Free Software Foundation, Inc.
+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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/accept4.m4 b/m4/accept4.m4
index c3f4cc00d..c7dff4aeb 100644
--- a/m4/accept4.m4
+++ b/m4/accept4.m4
@@ -1,5 +1,5 @@
 # accept4.m4 serial 3
-dnl Copyright (C) 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/access.m4 b/m4/access.m4
new file mode 100644
index 000000000..7ee801e31
--- /dev/null
+++ b/m4/access.m4
@@ -0,0 +1,16 @@
+# access.m4 serial 1
+dnl Copyright (C) 2019-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,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_ACCESS],
+[
+  AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
+  AC_REQUIRE([AC_CANONICAL_HOST])
+  dnl On native Windows, access (= _access) does not support the X_OK mode.
+  dnl It works by chance on some versions of mingw.
+  case "$host_os" in
+    mingw*) REPLACE_ACCESS=1 ;;
+  esac
+])
diff --git a/m4/alloca.m4 b/m4/alloca.m4
index ba2f679d8..dc6f47e33 100644
--- a/m4/alloca.m4
+++ b/m4/alloca.m4
@@ -1,5 +1,5 @@
-# alloca.m4 serial 20
-dnl Copyright (C) 2002-2004, 2006-2007, 2009-2021 Free Software Foundation,
+# alloca.m4 serial 21
+dnl Copyright (C) 2002-2004, 2006-2007, 2009-2022 Free Software Foundation,
 dnl Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -26,17 +26,15 @@ AC_DEFUN([gl_FUNC_ALLOCA],
       AC_DEFINE([HAVE_ALLOCA], [1],
         [Define to 1 if you have 'alloca' after including <alloca.h>,
          a header that may be supplied by this distribution.])
-      ALLOCA_H=alloca.h
+      GL_GENERATE_ALLOCA_H=true
     else
       dnl alloca exists as a library function, i.e. it is slow and probably
       dnl a memory leak. Don't define HAVE_ALLOCA in this case.
-      ALLOCA_H=
+      GL_GENERATE_ALLOCA_H=false
     fi
   else
-    ALLOCA_H=alloca.h
+    GL_GENERATE_ALLOCA_H=true
   fi
-  AC_SUBST([ALLOCA_H])
-  AM_CONDITIONAL([GL_GENERATE_ALLOCA_H], [test -n "$ALLOCA_H"])
 
   if test $ac_cv_working_alloca_h = yes; then
     HAVE_ALLOCA_H=1
diff --git a/m4/arpa_inet_h.m4 b/m4/arpa_inet_h.m4
index a3ba25624..057e13fc4 100644
--- a/m4/arpa_inet_h.m4
+++ b/m4/arpa_inet_h.m4
@@ -1,5 +1,5 @@
 # arpa_inet_h.m4 serial 17
-dnl Copyright (C) 2006, 2008-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2006, 2008-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/autobuild.m4 b/m4/autobuild.m4
index d931c7d9e..bdb98f90e 100644
--- a/m4/autobuild.m4
+++ b/m4/autobuild.m4
@@ -1,5 +1,5 @@
 # autobuild.m4 serial 8
-dnl Copyright (C) 2004, 2006-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2004, 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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/btowc.m4 b/m4/btowc.m4
index d2b2fe85a..45a61f5ed 100644
--- a/m4/btowc.m4
+++ b/m4/btowc.m4
@@ -1,5 +1,5 @@
 # btowc.m4 serial 12
-dnl Copyright (C) 2008-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2008-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/builtin-expect.m4 b/m4/builtin-expect.m4
index c58411643..b1fb12a3f 100644
--- a/m4/builtin-expect.m4
+++ b/m4/builtin-expect.m4
@@ -1,6 +1,6 @@
 dnl Check for __builtin_expect.
 
-dnl Copyright 2016-2021 Free Software Foundation, Inc.
+dnl Copyright 2016-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/byteswap.m4 b/m4/byteswap.m4
index 1083b4c9e..99aeb6872 100644
--- a/m4/byteswap.m4
+++ b/m4/byteswap.m4
@@ -1,5 +1,5 @@
-# byteswap.m4 serial 4
-dnl Copyright (C) 2005, 2007, 2009-2021 Free Software Foundation, Inc.
+# byteswap.m4 serial 5
+dnl Copyright (C) 2005, 2007, 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
@@ -10,10 +10,8 @@ AC_DEFUN([gl_BYTESWAP],
 [
   dnl Prerequisites of lib/byteswap.in.h.
   AC_CHECK_HEADERS([byteswap.h], [
-    BYTESWAP_H=''
+    GL_GENERATE_BYTESWAP_H=false
   ], [
-    BYTESWAP_H='byteswap.h'
+    GL_GENERATE_BYTESWAP_H=true
   ])
-  AC_SUBST([BYTESWAP_H])
-  AM_CONDITIONAL([GL_GENERATE_BYTESWAP_H], [test -n "$BYTESWAP_H"])
 ])
diff --git a/m4/canonicalize.m4 b/m4/canonicalize.m4
index 0dfb2da9a..b55d5c06e 100644
--- a/m4/canonicalize.m4
+++ b/m4/canonicalize.m4
@@ -1,6 +1,6 @@
 # canonicalize.m4 serial 37
 
-dnl Copyright (C) 2003-2007, 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2003-2007, 2009-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,
diff --git a/m4/ceil.m4 b/m4/ceil.m4
index 8d7b032a0..5aff637d3 100644
--- a/m4/ceil.m4
+++ b/m4/ceil.m4
@@ -1,5 +1,5 @@
 # ceil.m4 serial 15
-dnl Copyright (C) 2007, 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2007, 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/check-math-lib.m4 b/m4/check-math-lib.m4
index 600e23d7f..7eb42aff3 100644
--- a/m4/check-math-lib.m4
+++ b/m4/check-math-lib.m4
@@ -1,5 +1,5 @@
 # check-math-lib.m4 serial 4
-dnl Copyright (C) 2007, 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2007, 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/clock_time.m4 b/m4/clock_time.m4
index 829b224ed..225355331 100644
--- a/m4/clock_time.m4
+++ b/m4/clock_time.m4
@@ -1,10 +1,11 @@
-# clock_time.m4 serial 10
-dnl Copyright (C) 2002-2006, 2009-2021 Free Software Foundation, Inc.
+# clock_time.m4 serial 11
+dnl Copyright (C) 2002-2006, 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
 
-# Check for clock_gettime and clock_settime, and set LIB_CLOCK_GETTIME.
+# Check for clock_getres, clock_gettime and clock_settime,
+# and set LIB_CLOCK_GETTIME.
 # For a program named, say foo, you should add a line like the following
 # in the corresponding Makefile.am file:
 # foo_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME)
@@ -24,15 +25,8 @@ AC_DEFUN([gl_CLOCK_TIME],
   AC_SUBST([LIB_CLOCK_GETTIME])
   gl_saved_libs=$LIBS
     AC_SEARCH_LIBS([clock_gettime], [rt posix4],
-                   [if test "$ac_cv_search_clock_gettime" = "none required"; then
-                      AC_SEARCH_LIBS([clock_getcpuclockid], [rt posix4],
-                                     [test "$ac_cv_search_clock_getcpuclockid" = "none required" \
-                                      || LIB_CLOCK_GETTIME=$ac_cv_search_clock_getcpuclockid],
-                                     [test "$ac_cv_search_clock_gettime" = "none required" \
-                                      || LIB_CLOCK_GETTIME=$ac_cv_search_clock_gettime])
-                    else
-                      LIB_CLOCK_GETTIME=$ac_cv_search_clock_gettime
-                    fi])
-    AC_CHECK_FUNCS([clock_gettime clock_settime clock_getcpuclockid])
+                   [test "$ac_cv_search_clock_gettime" = "none required" ||
+                    LIB_CLOCK_GETTIME=$ac_cv_search_clock_gettime])
+    AC_CHECK_FUNCS([clock_getres clock_gettime clock_settime])
   LIBS=$gl_saved_libs
 ])
diff --git a/m4/close.m4 b/m4/close.m4
index 77a504717..f95dbc9d9 100644
--- a/m4/close.m4
+++ b/m4/close.m4
@@ -1,5 +1,5 @@
 # close.m4 serial 9
-dnl Copyright (C) 2008-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2008-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/codeset.m4 b/m4/codeset.m4
index 629f4ee31..eb7326013 100644
--- a/m4/codeset.m4
+++ b/m4/codeset.m4
@@ -1,5 +1,5 @@
 # codeset.m4 serial 5 (gettext-0.18.2)
-dnl Copyright (C) 2000-2002, 2006, 2008-2014, 2016, 2019-2021 Free Software
+dnl Copyright (C) 2000-2002, 2006, 2008-2014, 2016, 2019-2022 Free Software
 dnl Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
diff --git a/m4/copysign.m4 b/m4/copysign.m4
index d2fc992a3..c66cc7a7f 100644
--- a/m4/copysign.m4
+++ b/m4/copysign.m4
@@ -1,5 +1,5 @@
 # copysign.m4 serial 1
-dnl Copyright (C) 2011-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2011-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/dirent_h.m4 b/m4/dirent_h.m4
index 17e2a20c5..ddaca1680 100644
--- a/m4/dirent_h.m4
+++ b/m4/dirent_h.m4
@@ -1,5 +1,5 @@
 # dirent_h.m4 serial 19
-dnl Copyright (C) 2008-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2008-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/dirfd.m4 b/m4/dirfd.m4
index 3c9ce5dc6..92001700e 100644
--- a/m4/dirfd.m4
+++ b/m4/dirfd.m4
@@ -2,7 +2,7 @@
 
 dnl Find out how to get the file descriptor associated with an open DIR*.
 
-# Copyright (C) 2001-2006, 2008-2021 Free Software Foundation, Inc.
+# Copyright (C) 2001-2006, 2008-2022 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.
diff --git a/m4/double-slash-root.m4 b/m4/double-slash-root.m4
index c9bbcef67..09ff5f0d1 100644
--- a/m4/double-slash-root.m4
+++ b/m4/double-slash-root.m4
@@ -1,5 +1,5 @@
 # double-slash-root.m4 serial 4   -*- Autoconf -*-
-dnl Copyright (C) 2006, 2008-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2006, 2008-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/dup2.m4 b/m4/dup2.m4
index 0753a3249..7e777cdee 100644
--- a/m4/dup2.m4
+++ b/m4/dup2.m4
@@ -1,5 +1,5 @@
 #serial 27
-dnl Copyright (C) 2002, 2005, 2007, 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2002, 2005, 2007, 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/duplocale.m4 b/m4/duplocale.m4
index 8fcd15509..d2c072db0 100644
--- a/m4/duplocale.m4
+++ b/m4/duplocale.m4
@@ -1,5 +1,5 @@
 # duplocale.m4 serial 12
-dnl Copyright (C) 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/eaccess.m4 b/m4/eaccess.m4
new file mode 100644
index 000000000..6ab3d5099
--- /dev/null
+++ b/m4/eaccess.m4
@@ -0,0 +1,12 @@
+# eaccess.m4 serial 2
+dnl Copyright (C) 2003, 2009-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,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_EACCESS],
+[
+  AC_CHECK_FUNC([eaccess], ,
+    [AC_DEFINE([eaccess], [access],
+       [Define as 'access' if you don't have the eaccess() function.])])
+])
diff --git a/m4/eealloc.m4 b/m4/eealloc.m4
index 002f0c867..a6aa2f88d 100644
--- a/m4/eealloc.m4
+++ b/m4/eealloc.m4
@@ -1,5 +1,5 @@
 # eealloc.m4 serial 3
-dnl Copyright (C) 2003, 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2003, 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/environ.m4 b/m4/environ.m4
index ae5329108..583dac393 100644
--- a/m4/environ.m4
+++ b/m4/environ.m4
@@ -1,5 +1,5 @@
 # environ.m4 serial 8
-dnl Copyright (C) 2001-2004, 2006-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2001-2004, 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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/errno_h.m4 b/m4/errno_h.m4
index 51dfe9293..4be9780a7 100644
--- a/m4/errno_h.m4
+++ b/m4/errno_h.m4
@@ -1,5 +1,5 @@
-# errno_h.m4 serial 13
-dnl Copyright (C) 2004, 2006, 2008-2021 Free Software Foundation, Inc.
+# errno_h.m4 serial 14
+dnl Copyright (C) 2004, 2006, 2008-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,
 dnl with or without modifications, as long as this notice is preserved.
@@ -68,13 +68,11 @@ booboo
       [gl_cv_header_errno_h_complete=yes])
   ])
   if test $gl_cv_header_errno_h_complete = yes; then
-    ERRNO_H=''
+    GL_GENERATE_ERRNO_H=false
   else
     gl_NEXT_HEADERS([errno.h])
-    ERRNO_H='errno.h'
+    GL_GENERATE_ERRNO_H=true
   fi
-  AC_SUBST([ERRNO_H])
-  AM_CONDITIONAL([GL_GENERATE_ERRNO_H], [test -n "$ERRNO_H"])
   gl_REPLACE_ERRNO_VALUE([EMULTIHOP])
   gl_REPLACE_ERRNO_VALUE([ENOLINK])
   gl_REPLACE_ERRNO_VALUE([EOVERFLOW])
@@ -88,7 +86,7 @@ booboo
 # Set the variables EOVERFLOW_HIDDEN and EOVERFLOW_VALUE.
 AC_DEFUN([gl_REPLACE_ERRNO_VALUE],
 [
-  if test -n "$ERRNO_H"; then
+  if $GL_GENERATE_ERRNO_H; then
     AC_CACHE_CHECK([for ]$1[ value], [gl_cv_header_errno_h_]$1, [
       AC_EGREP_CPP([yes],[
 #include <errno.h>
diff --git a/m4/exponentd.m4 b/m4/exponentd.m4
index fb136f477..83ac08bf2 100644
--- a/m4/exponentd.m4
+++ b/m4/exponentd.m4
@@ -1,5 +1,5 @@
 # exponentd.m4 serial 3
-dnl Copyright (C) 2007-2008, 2010-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2007-2008, 2010-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/exponentf.m4 b/m4/exponentf.m4
index 308d02387..32fdb6a25 100644
--- a/m4/exponentf.m4
+++ b/m4/exponentf.m4
@@ -1,5 +1,5 @@
 # exponentf.m4 serial 2
-dnl Copyright (C) 2007-2008, 2010-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2007-2008, 2010-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/exponentl.m4 b/m4/exponentl.m4
index 508fe9315..653ad5a94 100644
--- a/m4/exponentl.m4
+++ b/m4/exponentl.m4
@@ -1,5 +1,5 @@
 # exponentl.m4 serial 5
-dnl Copyright (C) 2007-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2007-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/extensions.m4 b/m4/extensions.m4
index 5792a9557..0b3e4b5af 100644
--- a/m4/extensions.m4
+++ b/m4/extensions.m4
@@ -1,7 +1,7 @@
 # serial 22  -*- Autoconf -*-
 # Enable extensions on systems that normally disable them.
 
-# Copyright (C) 2003, 2006-2021 Free Software Foundation, Inc.
+# Copyright (C) 2003, 2006-2022 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.
diff --git a/m4/extern-inline.m4 b/m4/extern-inline.m4
index a2acf126c..8a12bddd5 100644
--- a/m4/extern-inline.m4
+++ b/m4/extern-inline.m4
@@ -1,13 +1,28 @@
 dnl 'extern inline' a la ISO C99.
 
-dnl Copyright 2012-2021 Free Software Foundation, Inc.
+dnl Copyright 2012-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,
 dnl with or without modifications, as long as this notice is preserved.
 
 AC_DEFUN([gl_EXTERN_INLINE],
 [
-  AH_VERBATIM([extern_inline],
+  AC_CACHE_CHECK([whether ctype.h defines __header_inline],
+    [gl_cv_have___header_inline],
+    [AC_PREPROC_IFELSE(
+       [AC_LANG_SOURCE([[#include <ctype.h>
+                         #ifndef __header_inline
+                          #error "<ctype.h> does not define __header_inline"
+                         #endif
+                        ]])],
+       [gl_cv_have___header_inline=yes],
+       [gl_cv_have___header_inline=no])])
+  if test "$gl_cv_have___header_inline" = yes; then
+    AC_DEFINE([HAVE___HEADER_INLINE], [1],
+      [Define to 1 if ctype.h defines __header_inline.])
+  fi
+
+  AH_VERBATIM([HAVE___HEADER_INLINE_1],
 [/* Please see the Gnulib manual for how to use these macros.
 
    Suppress extern inline with HP-UX cc, as it appears to be broken; see
@@ -17,7 +32,8 @@ AC_DEFUN([gl_EXTERN_INLINE],
    mishandles inline functions that call each other.  E.g., for 'inline void f
    (void) { } inline void g (void) { f (); }', c99 incorrectly complains
    'reference to static identifier "f" in extern inline function'.
-   This bug was observed with Sun C 5.12 SunOS_i386 2011/11/16.
+   This bug was observed with Oracle Developer Studio 12.6
+   (Sun C 5.15 SunOS_sparc 2017/05/30).
 
    Suppress extern inline (with or without __attribute__ ((__gnu_inline__)))
    on configurations that mistakenly use 'static inline' to implement
@@ -53,7 +69,7 @@ AC_DEFUN([gl_EXTERN_INLINE],
  */
 #if (((defined __APPLE__ && defined __MACH__) \
       || defined __DragonFly__ || defined __FreeBSD__) \
-     && (defined __header_inline \
+     && (defined HAVE___HEADER_INLINE \
          ? (defined __cplusplus && defined __GNUC_STDC_INLINE__ \
             && ! defined __clang__) \
          : ((! defined _DONT_USE_CTYPE_INLINE_ \
@@ -83,8 +99,8 @@ AC_DEFUN([gl_EXTERN_INLINE],
 # define _GL_EXTERN_INLINE extern
 # define _GL_EXTERN_INLINE_IN_USE
 #else
-# define _GL_INLINE static _GL_UNUSED
-# define _GL_EXTERN_INLINE static _GL_UNUSED
+# define _GL_INLINE _GL_UNUSED static
+# define _GL_EXTERN_INLINE _GL_UNUSED static
 #endif
 
 /* In GCC 4.6 (inclusive) to 5.1 (exclusive),
diff --git a/m4/fcntl-o.m4 b/m4/fcntl-o.m4
index 7c459ad13..4dcde9e06 100644
--- a/m4/fcntl-o.m4
+++ b/m4/fcntl-o.m4
@@ -1,5 +1,5 @@
 # fcntl-o.m4 serial 7
-dnl Copyright (C) 2006, 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2006, 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/fcntl.m4 b/m4/fcntl.m4
index f6264345c..428e5709d 100644
--- a/m4/fcntl.m4
+++ b/m4/fcntl.m4
@@ -1,5 +1,5 @@
 # fcntl.m4 serial 11
-dnl Copyright (C) 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/fcntl_h.m4 b/m4/fcntl_h.m4
index aba44735d..267f98bf5 100644
--- a/m4/fcntl_h.m4
+++ b/m4/fcntl_h.m4
@@ -1,6 +1,6 @@
 # serial 20
 # Configure fcntl.h.
-dnl Copyright (C) 2006-2007, 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2006-2007, 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/findprog-in.m4 b/m4/findprog-in.m4
new file mode 100644
index 000000000..5a295e23d
--- /dev/null
+++ b/m4/findprog-in.m4
@@ -0,0 +1,11 @@
+# findprog-in.m4 serial 1
+dnl Copyright (C) 2003, 2009-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,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FINDPROG_IN],
+[
+  dnl Prerequisites of lib/findprog-in.c.
+  AC_REQUIRE([gl_FUNC_EACCESS])
+])
diff --git a/m4/flexmember.m4 b/m4/flexmember.m4
index 49b1c752d..3b4237e9f 100644
--- a/m4/flexmember.m4
+++ b/m4/flexmember.m4
@@ -1,7 +1,7 @@
 # serial 5
 # Check for flexible array member support.
 
-# Copyright (C) 2006, 2009-2021 Free Software Foundation, Inc.
+# Copyright (C) 2006, 2009-2022 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.
diff --git a/m4/float_h.m4 b/m4/float_h.m4
index ba38a2890..0e8457261 100644
--- a/m4/float_h.m4
+++ b/m4/float_h.m4
@@ -1,5 +1,5 @@
-# float_h.m4 serial 12
-dnl Copyright (C) 2007, 2009-2021 Free Software Foundation, Inc.
+# float_h.m4 serial 13
+dnl Copyright (C) 2007, 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
@@ -8,18 +8,18 @@ AC_DEFUN([gl_FLOAT_H],
 [
   AC_REQUIRE([AC_PROG_CC])
   AC_REQUIRE([AC_CANONICAL_HOST])
-  FLOAT_H=
+  GL_GENERATE_FLOAT_H=false
   REPLACE_FLOAT_LDBL=0
   case "$host_os" in
     aix* | beos* | openbsd* | mirbsd* | irix*)
-      FLOAT_H=float.h
+      GL_GENERATE_FLOAT_H=true
       ;;
     freebsd* | dragonfly*)
       case "$host_cpu" in
 changequote(,)dnl
         i[34567]86 )
 changequote([,])dnl
-          FLOAT_H=float.h
+          GL_GENERATE_FLOAT_H=true
           ;;
         x86_64 )
           # On x86_64 systems, the C compiler may still be generating
@@ -33,21 +33,21 @@ changequote([,])dnl
                  #endif
                ]])],
             [],
-            [FLOAT_H=float.h])
+            [GL_GENERATE_FLOAT_H=true])
           ;;
       esac
       ;;
     linux*)
       case "$host_cpu" in
         powerpc*)
-          FLOAT_H=float.h
+          GL_GENERATE_FLOAT_H=true
           ;;
       esac
       ;;
   esac
   case "$host_os" in
     aix* | freebsd* | dragonfly* | linux*)
-      if test -n "$FLOAT_H"; then
+      if $GL_GENERATE_FLOAT_H; then
         REPLACE_FLOAT_LDBL=1
       fi
       ;;
@@ -95,14 +95,12 @@ int main ()
       REPLACE_ITOLD=1
       dnl We add the workaround to <float.h> but also to <math.h>,
       dnl to increase the chances that the fix function gets pulled in.
-      FLOAT_H=float.h
+      GL_GENERATE_FLOAT_H=true
       ;;
   esac
 
-  if test -n "$FLOAT_H"; then
+  if $GL_GENERATE_FLOAT_H; then
     gl_NEXT_HEADERS([float.h])
   fi
-  AC_SUBST([FLOAT_H])
-  AM_CONDITIONAL([GL_GENERATE_FLOAT_H], [test -n "$FLOAT_H"])
   AC_SUBST([REPLACE_ITOLD])
 ])
diff --git a/m4/flock.m4 b/m4/flock.m4
index e1e5fe030..655395e90 100644
--- a/m4/flock.m4
+++ b/m4/flock.m4
@@ -1,5 +1,5 @@
 # flock.m4 serial 4
-dnl Copyright (C) 2008-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2008-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/floor.m4 b/m4/floor.m4
index e54d2c7f5..727a426c9 100644
--- a/m4/floor.m4
+++ b/m4/floor.m4
@@ -1,5 +1,5 @@
 # floor.m4 serial 14
-dnl Copyright (C) 2007, 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2007, 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/fpieee.m4 b/m4/fpieee.m4
index 3f16957fb..c0c23e956 100644
--- a/m4/fpieee.m4
+++ b/m4/fpieee.m4
@@ -1,5 +1,5 @@
 # fpieee.m4 serial 2  -*- coding: utf-8 -*-
-dnl Copyright (C) 2007, 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2007, 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/free.m4 b/m4/free.m4
index a7923b905..dfeecd2bf 100644
--- a/m4/free.m4
+++ b/m4/free.m4
@@ -1,5 +1,5 @@
 # free.m4 serial 6
-# Copyright (C) 2003-2005, 2009-2021 Free Software Foundation, Inc.
+# Copyright (C) 2003-2005, 2009-2022 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.
diff --git a/m4/frexp.m4 b/m4/frexp.m4
index 04248b04f..d8f3cef44 100644
--- a/m4/frexp.m4
+++ b/m4/frexp.m4
@@ -1,5 +1,5 @@
 # frexp.m4 serial 16
-dnl Copyright (C) 2007-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2007-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/fstat.m4 b/m4/fstat.m4
index cdaca80da..9e61bcce8 100644
--- a/m4/fstat.m4
+++ b/m4/fstat.m4
@@ -1,5 +1,5 @@
 # fstat.m4 serial 8
-dnl Copyright (C) 2011-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2011-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/fsync.m4 b/m4/fsync.m4
index 6dc8cd1c0..cbf35fe31 100644
--- a/m4/fsync.m4
+++ b/m4/fsync.m4
@@ -1,5 +1,5 @@
 # fsync.m4 serial 2
-dnl Copyright (C) 2008-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2008-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/func.m4 b/m4/func.m4
index 63fdd611b..6226deed0 100644
--- a/m4/func.m4
+++ b/m4/func.m4
@@ -1,5 +1,5 @@
 # func.m4 serial 2
-dnl Copyright (C) 2008-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2008-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/getaddrinfo.m4 b/m4/getaddrinfo.m4
index 3f8e04f9b..65a0fd0ec 100644
--- a/m4/getaddrinfo.m4
+++ b/m4/getaddrinfo.m4
@@ -1,5 +1,5 @@
 # getaddrinfo.m4 serial 34
-dnl Copyright (C) 2004-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2004-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/getdtablesize.m4 b/m4/getdtablesize.m4
index 8fbc94189..6134eaace 100644
--- a/m4/getdtablesize.m4
+++ b/m4/getdtablesize.m4
@@ -1,5 +1,5 @@
 # getdtablesize.m4 serial 8
-dnl Copyright (C) 2008-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2008-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/getlogin.m4 b/m4/getlogin.m4
index c5b7f1aae..d51d6cfdc 100644
--- a/m4/getlogin.m4
+++ b/m4/getlogin.m4
@@ -1,5 +1,5 @@
 # getlogin.m4 serial 5
-dnl Copyright (C) 2010-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2010-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/getrandom.m4 b/m4/getrandom.m4
index 5f174dc7e..6ca715005 100644
--- a/m4/getrandom.m4
+++ b/m4/getrandom.m4
@@ -1,5 +1,5 @@
 # getrandom.m4 serial 8
-dnl Copyright 2020-2021 Free Software Foundation, Inc.
+dnl Copyright 2020-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/gettext.m4 b/m4/gettext.m4
new file mode 100644
index 000000000..f84e6a5d7
--- /dev/null
+++ b/m4/gettext.m4
@@ -0,0 +1,383 @@
+# gettext.m4 serial 63 (gettext-0.18)
+dnl Copyright (C) 1995-2010 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
+dnl This file can can be used in projects which are not available under
+dnl the GNU General Public License or the GNU Library General Public
+dnl License but which still want to provide support for the GNU gettext
+dnl functionality.
+dnl Please note that the actual code of the GNU gettext library is covered
+dnl by the GNU Library General Public License, and the rest of the GNU
+dnl gettext package package is covered by the GNU General Public License.
+dnl They are *not* in the public domain.
+
+dnl Authors:
+dnl   Ulrich Drepper <drepper@cygnus.com>, 1995-2000.
+dnl   Bruno Haible <haible@clisp.cons.org>, 2000-2006, 2008-2010.
+
+dnl Macro to add for using GNU gettext.
+
+dnl Usage: AM_GNU_GETTEXT([INTLSYMBOL], [NEEDSYMBOL], [INTLDIR]).
+dnl INTLSYMBOL can be one of 'external', 'no-libtool', 'use-libtool'. The
+dnl    default (if it is not specified or empty) is 'no-libtool'.
+dnl    INTLSYMBOL should be 'external' for packages with no intl directory,
+dnl    and 'no-libtool' or 'use-libtool' for packages with an intl directory.
+dnl    If INTLSYMBOL is 'use-libtool', then a libtool library
+dnl    $(top_builddir)/intl/libintl.la will be created (shared and/or static,
+dnl    depending on --{enable,disable}-{shared,static} and on the presence of
+dnl    AM-DISABLE-SHARED). If INTLSYMBOL is 'no-libtool', a static library
+dnl    $(top_builddir)/intl/libintl.a will be created.
+dnl If NEEDSYMBOL is specified and is 'need-ngettext', then GNU gettext
+dnl    implementations (in libc or libintl) without the ngettext() function
+dnl    will be ignored.  If NEEDSYMBOL is specified and is
+dnl    'need-formatstring-macros', then GNU gettext implementations that don't
+dnl    support the ISO C 99 <inttypes.h> formatstring macros will be ignored.
+dnl INTLDIR is used to find the intl libraries.  If empty,
+dnl    the value `$(top_builddir)/intl/' is used.
+dnl
+dnl The result of the configuration is one of three cases:
+dnl 1) GNU gettext, as included in the intl subdirectory, will be compiled
+dnl    and used.
+dnl    Catalog format: GNU --> install in $(datadir)
+dnl    Catalog extension: .mo after installation, .gmo in source tree
+dnl 2) GNU gettext has been found in the system's C library.
+dnl    Catalog format: GNU --> install in $(datadir)
+dnl    Catalog extension: .mo after installation, .gmo in source tree
+dnl 3) No internationalization, always use English msgid.
+dnl    Catalog format: none
+dnl    Catalog extension: none
+dnl If INTLSYMBOL is 'external', only cases 2 and 3 can occur.
+dnl The use of .gmo is historical (it was needed to avoid overwriting the
+dnl GNU format catalogs when building on a platform with an X/Open gettext),
+dnl but we keep it in order not to force irrelevant filename changes on the
+dnl maintainers.
+dnl
+AC_DEFUN([AM_GNU_GETTEXT],
+[
+  dnl Argument checking.
+  ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [no-libtool], , [ifelse([$1], [use-libtool], ,
+    [errprint([ERROR: invalid first argument to AM_GNU_GETTEXT
+])])])])])
+  ifelse(ifelse([$1], [], [old])[]ifelse([$1], [no-libtool], [old]), [old],
+    [AC_DIAGNOSE([obsolete], [Use of AM_GNU_GETTEXT without [external] argument is deprecated.])])
+  ifelse([$2], [], , [ifelse([$2], [need-ngettext], , [ifelse([$2], [need-formatstring-macros], ,
+    [errprint([ERROR: invalid second argument to AM_GNU_GETTEXT
+])])])])
+  define([gt_included_intl],
+    ifelse([$1], [external],
+      ifdef([AM_GNU_GETTEXT_][INTL_SUBDIR], [yes], [no]),
+      [yes]))
+  define([gt_libtool_suffix_prefix], ifelse([$1], [use-libtool], [l], []))
+  gt_NEEDS_INIT
+  AM_GNU_GETTEXT_NEED([$2])
+
+  AC_REQUIRE([AM_PO_SUBDIRS])dnl
+  ifelse(gt_included_intl, yes, [
+    AC_REQUIRE([AM_INTL_SUBDIR])dnl
+  ])
+
+  dnl Prerequisites of AC_LIB_LINKFLAGS_BODY.
+  AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
+  AC_REQUIRE([AC_LIB_RPATH])
+
+  dnl Sometimes libintl requires libiconv, so first search for libiconv.
+  dnl Ideally we would do this search only after the
+  dnl      if test "$USE_NLS" = "yes"; then
+  dnl        if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then
+  dnl tests. But if configure.in invokes AM_ICONV after AM_GNU_GETTEXT
+  dnl the configure script would need to contain the same shell code
+  dnl again, outside any 'if'. There are two solutions:
+  dnl - Invoke AM_ICONV_LINKFLAGS_BODY here, outside any 'if'.
+  dnl - Control the expansions in more detail using AC_PROVIDE_IFELSE.
+  dnl Since AC_PROVIDE_IFELSE is only in autoconf >= 2.52 and not
+  dnl documented, we avoid it.
+  ifelse(gt_included_intl, yes, , [
+    AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY])
+  ])
+
+  dnl Sometimes, on MacOS X, libintl requires linking with CoreFoundation.
+  gt_INTL_MACOSX
+
+  dnl Set USE_NLS.
+  AC_REQUIRE([AM_NLS])
+
+  ifelse(gt_included_intl, yes, [
+    BUILD_INCLUDED_LIBINTL=no
+    USE_INCLUDED_LIBINTL=no
+  ])
+  LIBINTL=
+  LTLIBINTL=
+  POSUB=
+
+  dnl Add a version number to the cache macros.
+  case " $gt_needs " in
+    *" need-formatstring-macros "*) gt_api_version=3 ;;
+    *" need-ngettext "*) gt_api_version=2 ;;
+    *) gt_api_version=1 ;;
+  esac
+  gt_func_gnugettext_libc="gt_cv_func_gnugettext${gt_api_version}_libc"
+  gt_func_gnugettext_libintl="gt_cv_func_gnugettext${gt_api_version}_libintl"
+
+  dnl If we use NLS figure out what method
+  if test "$USE_NLS" = "yes"; then
+    gt_use_preinstalled_gnugettext=no
+    ifelse(gt_included_intl, yes, [
+      AC_MSG_CHECKING([whether included gettext is requested])
+      AC_ARG_WITH([included-gettext],
+        [  --with-included-gettext use the GNU gettext library included here],
+        nls_cv_force_use_gnu_gettext=$withval,
+        nls_cv_force_use_gnu_gettext=no)
+      AC_MSG_RESULT([$nls_cv_force_use_gnu_gettext])
+
+      nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
+      if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
+    ])
+        dnl User does not insist on using GNU NLS library.  Figure out what
+        dnl to use.  If GNU gettext is available we use this.  Else we have
+        dnl to fall back to GNU NLS library.
+
+        if test $gt_api_version -ge 3; then
+          gt_revision_test_code='
+#ifndef __GNU_GETTEXT_SUPPORTED_REVISION
+#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1)
+#endif
+changequote(,)dnl
+typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1];
+changequote([,])dnl
+'
+        else
+          gt_revision_test_code=
+        fi
+        if test $gt_api_version -ge 2; then
+          gt_expression_test_code=' + * ngettext ("", "", 0)'
+        else
+          gt_expression_test_code=
+        fi
+
+        AC_CACHE_CHECK([for GNU gettext in libc], [$gt_func_gnugettext_libc],
+         [AC_TRY_LINK([#include <libintl.h>
+$gt_revision_test_code
+extern int _nl_msg_cat_cntr;
+extern int *_nl_domain_bindings;],
+            [bindtextdomain ("", "");
+return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_domain_bindings],
+            [eval "$gt_func_gnugettext_libc=yes"],
+            [eval "$gt_func_gnugettext_libc=no"])])
+
+        if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then
+          dnl Sometimes libintl requires libiconv, so first search for libiconv.
+          ifelse(gt_included_intl, yes, , [
+            AM_ICONV_LINK
+          ])
+          dnl Search for libintl and define LIBINTL, LTLIBINTL and INCINTL
+          dnl accordingly. Don't use AC_LIB_LINKFLAGS_BODY([intl],[iconv])
+          dnl because that would add "-liconv" to LIBINTL and LTLIBINTL
+          dnl even if libiconv doesn't exist.
+          AC_LIB_LINKFLAGS_BODY([intl])
+          AC_CACHE_CHECK([for GNU gettext in libintl],
+            [$gt_func_gnugettext_libintl],
+           [gt_save_CPPFLAGS="$CPPFLAGS"
+            CPPFLAGS="$CPPFLAGS $INCINTL"
+            gt_save_LIBS="$LIBS"
+            LIBS="$LIBS $LIBINTL"
+            dnl Now see whether libintl exists and does not depend on libiconv.
+            AC_TRY_LINK([#include <libintl.h>
+$gt_revision_test_code
+extern int _nl_msg_cat_cntr;
+extern
+#ifdef __cplusplus
+"C"
+#endif
+const char *_nl_expand_alias (const char *);],
+              [bindtextdomain ("", "");
+return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")],
+              [eval "$gt_func_gnugettext_libintl=yes"],
+              [eval "$gt_func_gnugettext_libintl=no"])
+            dnl Now see whether libintl exists and depends on libiconv.
+            if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" != yes; } && test -n "$LIBICONV"; then
+              LIBS="$LIBS $LIBICONV"
+              AC_TRY_LINK([#include <libintl.h>
+$gt_revision_test_code
+extern int _nl_msg_cat_cntr;
+extern
+#ifdef __cplusplus
+"C"
+#endif
+const char *_nl_expand_alias (const char *);],
+                [bindtextdomain ("", "");
+return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")],
+               [LIBINTL="$LIBINTL $LIBICONV"
+                LTLIBINTL="$LTLIBINTL $LTLIBICONV"
+                eval "$gt_func_gnugettext_libintl=yes"
+               ])
+            fi
+            CPPFLAGS="$gt_save_CPPFLAGS"
+            LIBS="$gt_save_LIBS"])
+        fi
+
+        dnl If an already present or preinstalled GNU gettext() is found,
+        dnl use it.  But if this macro is used in GNU gettext, and GNU
+        dnl gettext is already preinstalled in libintl, we update this
+        dnl libintl.  (Cf. the install rule in intl/Makefile.in.)
+        if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" = "yes"; } \
+           || { { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; } \
+                && test "$PACKAGE" != gettext-runtime \
+                && test "$PACKAGE" != gettext-tools; }; then
+          gt_use_preinstalled_gnugettext=yes
+        else
+          dnl Reset the values set by searching for libintl.
+          LIBINTL=
+          LTLIBINTL=
+          INCINTL=
+        fi
+
+    ifelse(gt_included_intl, yes, [
+        if test "$gt_use_preinstalled_gnugettext" != "yes"; then
+          dnl GNU gettext is not found in the C library.
+          dnl Fall back on included GNU gettext library.
+          nls_cv_use_gnu_gettext=yes
+        fi
+      fi
+
+      if test "$nls_cv_use_gnu_gettext" = "yes"; then
+        dnl Mark actions used to generate GNU NLS library.
+        BUILD_INCLUDED_LIBINTL=yes
+        USE_INCLUDED_LIBINTL=yes
+        LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LIBICONV $LIBTHREAD"
+        LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LTLIBICONV $LTLIBTHREAD"
+        LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'`
+      fi
+
+      CATOBJEXT=
+      if test "$gt_use_preinstalled_gnugettext" = "yes" \
+         || test "$nls_cv_use_gnu_gettext" = "yes"; then
+        dnl Mark actions to use GNU gettext tools.
+        CATOBJEXT=.gmo
+      fi
+    ])
+
+    if test -n "$INTL_MACOSX_LIBS"; then
+      if test "$gt_use_preinstalled_gnugettext" = "yes" \
+         || test "$nls_cv_use_gnu_gettext" = "yes"; then
+        dnl Some extra flags are needed during linking.
+        LIBINTL="$LIBINTL $INTL_MACOSX_LIBS"
+        LTLIBINTL="$LTLIBINTL $INTL_MACOSX_LIBS"
+      fi
+    fi
+
+    if test "$gt_use_preinstalled_gnugettext" = "yes" \
+       || test "$nls_cv_use_gnu_gettext" = "yes"; then
+      AC_DEFINE([ENABLE_NLS], [1],
+        [Define to 1 if translation of program messages to the user's native language
+   is requested.])
+    else
+      USE_NLS=no
+    fi
+  fi
+
+  AC_MSG_CHECKING([whether to use NLS])
+  AC_MSG_RESULT([$USE_NLS])
+  if test "$USE_NLS" = "yes"; then
+    AC_MSG_CHECKING([where the gettext function comes from])
+    if test "$gt_use_preinstalled_gnugettext" = "yes"; then
+      if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then
+        gt_source="external libintl"
+      else
+        gt_source="libc"
+      fi
+    else
+      gt_source="included intl directory"
+    fi
+    AC_MSG_RESULT([$gt_source])
+  fi
+
+  if test "$USE_NLS" = "yes"; then
+
+    if test "$gt_use_preinstalled_gnugettext" = "yes"; then
+      if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then
+        AC_MSG_CHECKING([how to link with libintl])
+        AC_MSG_RESULT([$LIBINTL])
+        AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCINTL])
+      fi
+
+      dnl For backward compatibility. Some packages may be using this.
+      AC_DEFINE([HAVE_GETTEXT], [1],
+       [Define if the GNU gettext() function is already present or preinstalled.])
+      AC_DEFINE([HAVE_DCGETTEXT], [1],
+       [Define if the GNU dcgettext() function is already present or preinstalled.])
+    fi
+
+    dnl We need to process the po/ directory.
+    POSUB=po
+  fi
+
+  ifelse(gt_included_intl, yes, [
+    dnl If this is used in GNU gettext we have to set BUILD_INCLUDED_LIBINTL
+    dnl to 'yes' because some of the testsuite requires it.
+    if test "$PACKAGE" = gettext-runtime || test "$PACKAGE" = gettext-tools; then
+      BUILD_INCLUDED_LIBINTL=yes
+    fi
+
+    dnl Make all variables we use known to autoconf.
+    AC_SUBST([BUILD_INCLUDED_LIBINTL])
+    AC_SUBST([USE_INCLUDED_LIBINTL])
+    AC_SUBST([CATOBJEXT])
+
+    dnl For backward compatibility. Some configure.ins may be using this.
+    nls_cv_header_intl=
+    nls_cv_header_libgt=
+
+    dnl For backward compatibility. Some Makefiles may be using this.
+    DATADIRNAME=share
+    AC_SUBST([DATADIRNAME])
+
+    dnl For backward compatibility. Some Makefiles may be using this.
+    INSTOBJEXT=.mo
+    AC_SUBST([INSTOBJEXT])
+
+    dnl For backward compatibility. Some Makefiles may be using this.
+    GENCAT=gencat
+    AC_SUBST([GENCAT])
+
+    dnl For backward compatibility. Some Makefiles may be using this.
+    INTLOBJS=
+    if test "$USE_INCLUDED_LIBINTL" = yes; then
+      INTLOBJS="\$(GETTOBJS)"
+    fi
+    AC_SUBST([INTLOBJS])
+
+    dnl Enable libtool support if the surrounding package wishes it.
+    INTL_LIBTOOL_SUFFIX_PREFIX=gt_libtool_suffix_prefix
+    AC_SUBST([INTL_LIBTOOL_SUFFIX_PREFIX])
+  ])
+
+  dnl For backward compatibility. Some Makefiles may be using this.
+  INTLLIBS="$LIBINTL"
+  AC_SUBST([INTLLIBS])
+
+  dnl Make all documented variables known to autoconf.
+  AC_SUBST([LIBINTL])
+  AC_SUBST([LTLIBINTL])
+  AC_SUBST([POSUB])
+])
+
+
+dnl gt_NEEDS_INIT ensures that the gt_needs variable is initialized.
+m4_define([gt_NEEDS_INIT],
+[
+  m4_divert_text([DEFAULTS], [gt_needs=])
+  m4_define([gt_NEEDS_INIT], [])
+])
+
+
+dnl Usage: AM_GNU_GETTEXT_NEED([NEEDSYMBOL])
+AC_DEFUN([AM_GNU_GETTEXT_NEED],
+[
+  m4_divert_text([INIT_PREPARE], [gt_needs="$gt_needs $1"])
+])
+
+
+dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version])
+AC_DEFUN([AM_GNU_GETTEXT_VERSION], [])
diff --git a/m4/glibc2.m4 b/m4/glibc2.m4
new file mode 100644
index 000000000..f148c12c4
--- /dev/null
+++ b/m4/glibc2.m4
@@ -0,0 +1,30 @@
+# glibc2.m4 serial 2
+dnl Copyright (C) 2000-2002, 2004, 2008-2010 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.
+
+# Test for the GNU C Library, version 2.0 or newer.
+# From Bruno Haible.
+
+AC_DEFUN([gt_GLIBC2],
+  [
+    AC_CACHE_CHECK([whether we are using the GNU C Library 2 or newer],
+      [ac_cv_gnu_library_2],
+      [AC_EGREP_CPP([Lucky GNU user],
+        [
+#include <features.h>
+#ifdef __GNU_LIBRARY__
+ #if (__GLIBC__ >= 2)
+  Lucky GNU user
+ #endif
+#endif
+        ],
+        [ac_cv_gnu_library_2=yes],
+        [ac_cv_gnu_library_2=no])
+      ]
+    )
+    AC_SUBST([GLIBC2])
+    GLIBC2="$ac_cv_gnu_library_2"
+  ]
+)
diff --git a/m4/glibc21.m4 b/m4/glibc21.m4
new file mode 100644
index 000000000..68ada9d4d
--- /dev/null
+++ b/m4/glibc21.m4
@@ -0,0 +1,30 @@
+# glibc21.m4 serial 4
+dnl Copyright (C) 2000-2002, 2004, 2008-2010 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.
+
+# Test for the GNU C Library, version 2.1 or newer.
+# From Bruno Haible.
+
+AC_DEFUN([gl_GLIBC21],
+  [
+    AC_CACHE_CHECK([whether we are using the GNU C Library 2.1 or newer],
+      [ac_cv_gnu_library_2_1],
+      [AC_EGREP_CPP([Lucky GNU user],
+        [
+#include <features.h>
+#ifdef __GNU_LIBRARY__
+ #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2)
+  Lucky GNU user
+ #endif
+#endif
+        ],
+        [ac_cv_gnu_library_2_1=yes],
+        [ac_cv_gnu_library_2_1=no])
+      ]
+    )
+    AC_SUBST([GLIBC21])
+    GLIBC21="$ac_cv_gnu_library_2_1"
+  ]
+)
diff --git a/m4/gnulib-cache.m4 b/m4/gnulib-cache.m4
index 9e6b41b4a..7d6f43ab7 100644
--- a/m4/gnulib-cache.m4
+++ b/m4/gnulib-cache.m4
@@ -1,8 +1,8 @@
-# Copyright (C) 2002-2021 Free Software Foundation, Inc.
+# Copyright (C) 2002-2022 Free Software Foundation, Inc.
 #
 # This file 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
+# the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
 #
 # This file is distributed in the hope that it will be useful,
@@ -115,6 +115,7 @@
 #  pipe-posix \
 #  pipe2 \
 #  poll \
+#  posix_spawnp \
 #  putenv \
 #  readlink \
 #  recv \
@@ -214,6 +215,7 @@ gl_MODULES([
   pipe-posix
   pipe2
   poll
+  posix_spawnp
   putenv
   readlink
   recv
@@ -242,7 +244,7 @@ gl_MODULES([
   warnings
   wchar
 ])
-gl_AVOID([ lock unistr/base unistr/u8-mbtouc unistr/u8-mbtouc-unsafe unistr/u8-mbtoucr unistr/u8-prev unistr/u8-uctomb unitypes])
+gl_AVOID([lock unistr/base unistr/u8-mbtouc unistr/u8-mbtouc-unsafe unistr/u8-mbtoucr unistr/u8-prev unistr/u8-uctomb unitypes])
 gl_SOURCE_BASE([lib])
 gl_M4_BASE([m4])
 gl_PO_BASE([])
diff --git a/m4/gnulib-common.m4 b/m4/gnulib-common.m4
index c801b3de9..8a5daa230 100644
--- a/m4/gnulib-common.m4
+++ b/m4/gnulib-common.m4
@@ -1,5 +1,5 @@
-# gnulib-common.m4 serial 67
-dnl Copyright (C) 2007-2021 Free Software Foundation, Inc.
+# gnulib-common.m4 serial 73
+dnl Copyright (C) 2007-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,
 dnl with or without modifications, as long as this notice is preserved.
@@ -69,7 +69,9 @@ AC_DEFUN([gl_COMMON_BODY], [
 [/* Attributes.  */
 #if (defined __has_attribute \
      && (!defined __clang_minor__ \
-         || 3 < __clang_major__ + (5 <= __clang_minor__)))
+         || (defined __apple_build_version__ \
+             ? 6000000 <= __apple_build_version__ \
+             : 3 < __clang_major__ + (5 <= __clang_minor__))))
 # define _GL_HAS_ATTRIBUTE(attr) __has_attribute (__##attr##__)
 #else
 # define _GL_HAS_ATTRIBUTE(attr) _GL_ATTR_##attr
@@ -104,6 +106,10 @@ AC_DEFUN([gl_COMMON_BODY], [
 #endif
 
 #ifdef __has_c_attribute
+# if ((defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) <= 201710 \
+      && _GL_GNUC_PREREQ (4, 6))
+#  pragma GCC diagnostic ignored "-Wpedantic"
+# endif
 # define _GL_HAS_C_ATTRIBUTE(attr) __has_c_attribute (__##attr##__)
 #else
 # define _GL_HAS_C_ATTRIBUTE(attr) 0
@@ -111,24 +117,39 @@ AC_DEFUN([gl_COMMON_BODY], [
 
 ]dnl There is no _GL_ATTRIBUTE_ALIGNED; use stdalign's _Alignas instead.
 [
+/* _GL_ATTRIBUTE_ALLOC_SIZE ((N)) declares that the Nth argument of the function
+   is the size of the returned memory block.
+   _GL_ATTRIBUTE_ALLOC_SIZE ((M, N)) declares that the Mth argument multiplied
+   by the Nth argument of the function is the size of the returned memory block.
+ */
+/* Applies to: function, pointer to function, function types.  */
 #if _GL_HAS_ATTRIBUTE (alloc_size)
 # define _GL_ATTRIBUTE_ALLOC_SIZE(args) __attribute__ ((__alloc_size__ args))
 #else
 # define _GL_ATTRIBUTE_ALLOC_SIZE(args)
 #endif
 
+/* _GL_ATTRIBUTE_ALWAYS_INLINE tells that the compiler should always inline the
+   function and report an error if it cannot do so.  */
+/* Applies to: function.  */
 #if _GL_HAS_ATTRIBUTE (always_inline)
 # define _GL_ATTRIBUTE_ALWAYS_INLINE __attribute__ ((__always_inline__))
 #else
 # define _GL_ATTRIBUTE_ALWAYS_INLINE
 #endif
 
+/* _GL_ATTRIBUTE_ARTIFICIAL declares that the function is not important to show
+    in stack traces when debugging.  The compiler should omit the function from
+    stack traces.  */
+/* Applies to: function.  */
 #if _GL_HAS_ATTRIBUTE (artificial)
 # define _GL_ATTRIBUTE_ARTIFICIAL __attribute__ ((__artificial__))
 #else
 # define _GL_ATTRIBUTE_ARTIFICIAL
 #endif
 
+/* _GL_ATTRIBUTE_COLD declares that the function is rarely executed.  */
+/* Applies to: functions.  */
 /* Avoid __attribute__ ((cold)) on MinGW; see thread starting at
    <https://lists.gnu.org/r/emacs-devel/2019-04/msg01152.html>.
    Also, Oracle Studio 12.6 requires 'cold' not '__cold__'.  */
@@ -142,25 +163,45 @@ AC_DEFUN([gl_COMMON_BODY], [
 # define _GL_ATTRIBUTE_COLD
 #endif
 
+/* _GL_ATTRIBUTE_CONST declares that it is OK for a compiler to omit duplicate
+   calls to the function with the same arguments.
+   This attribute is safe for a function that neither depends on nor affects
+   observable state, and always returns exactly once - e.g., does not loop
+   forever, and does not call longjmp.
+   (This attribute is stricter than _GL_ATTRIBUTE_PURE.)  */
+/* Applies to: functions.  */
 #if _GL_HAS_ATTRIBUTE (const)
 # define _GL_ATTRIBUTE_CONST __attribute__ ((__const__))
 #else
 # define _GL_ATTRIBUTE_CONST
 #endif
 
-/* _GL_ATTRIBUTE_DEALLOC (F, I) is for functions returning pointers
+/* _GL_ATTRIBUTE_DEALLOC (F, I) declares that the function returns pointers
    that can be freed by passing them as the Ith argument to the
-   function F.  _GL_ATTRIBUTE_DEALLOC_FREE is for functions that
-   return pointers that can be freed via 'free'; it can be used
-   only after including stdlib.h.  These macros cannot be used on
-   inline functions.  */
+   function F.
+   _GL_ATTRIBUTE_DEALLOC_FREE declares that the function returns pointers that
+   can be freed via 'free'; it can be used only after declaring 'free'.  */
+/* Applies to: functions.  Cannot be used on inline functions.  */
 #if _GL_GNUC_PREREQ (11, 0)
 # define _GL_ATTRIBUTE_DEALLOC(f, i) __attribute__ ((__malloc__ (f, i)))
 #else
 # define _GL_ATTRIBUTE_DEALLOC(f, i)
 #endif
-#define _GL_ATTRIBUTE_DEALLOC_FREE _GL_ATTRIBUTE_DEALLOC (free, 1)
+/* If gnulib's <string.h> or <wchar.h> has already defined this macro, continue
+   to use this earlier definition, since <stdlib.h> may not have been included
+   yet.  */
+#ifndef _GL_ATTRIBUTE_DEALLOC_FREE
+# define _GL_ATTRIBUTE_DEALLOC_FREE _GL_ATTRIBUTE_DEALLOC (free, 1)
+#endif
 
+/* _GL_ATTRIBUTE_DEPRECATED: Declares that an entity is deprecated.
+   The compiler may warn if the entity is used.  */
+/* Applies to:
+     - function, variable,
+     - struct, union, struct/union member,
+     - enumeration, enumeration item,
+     - typedef,
+   in C++ also: namespace, class, template specialization.  */
 #if _GL_HAS_C_ATTRIBUTE (deprecated)
 # define _GL_ATTRIBUTE_DEPRECATED [[__deprecated__]]
 #elif _GL_HAS_ATTRIBUTE (deprecated)
@@ -169,6 +210,11 @@ AC_DEFUN([gl_COMMON_BODY], [
 # define _GL_ATTRIBUTE_DEPRECATED
 #endif
 
+/* _GL_ATTRIBUTE_ERROR(msg) requests an error if a function is called and
+   the function call is not optimized away.
+   _GL_ATTRIBUTE_WARNING(msg) requests a warning if a function is called and
+   the function call is not optimized away.  */
+/* Applies to: functions.  */
 #if _GL_HAS_ATTRIBUTE (error)
 # define _GL_ATTRIBUTE_ERROR(msg) __attribute__ ((__error__ (msg)))
 # define _GL_ATTRIBUTE_WARNING(msg) __attribute__ ((__warning__ (msg)))
@@ -180,13 +226,20 @@ AC_DEFUN([gl_COMMON_BODY], [
 # define _GL_ATTRIBUTE_WARNING(msg)
 #endif
 
+/* _GL_ATTRIBUTE_EXTERNALLY_VISIBLE declares that the entity should remain
+   visible to debuggers etc., even with '-fwhole-program'.  */
+/* Applies to: functions, variables.  */
 #if _GL_HAS_ATTRIBUTE (externally_visible)
 # define _GL_ATTRIBUTE_EXTERNALLY_VISIBLE __attribute__ ((externally_visible))
 #else
 # define _GL_ATTRIBUTE_EXTERNALLY_VISIBLE
 #endif
 
-/* FALLTHROUGH is special, because it always expands to something.  */
+/* _GL_ATTRIBUTE_FALLTHROUGH declares that it is not a programming mistake if
+   the control flow falls through to the immediately following 'case' or
+   'default' label.  The compiler should not warn in this case.  */
+/* Applies to: Empty statement (;), inside a 'switch' statement.  */
+/* Always expands to something.  */
 #if _GL_HAS_C_ATTRIBUTE (fallthrough)
 # define _GL_ATTRIBUTE_FALLTHROUGH [[__fallthrough__]]
 #elif _GL_HAS_ATTRIBUTE (fallthrough)
@@ -195,24 +248,47 @@ AC_DEFUN([gl_COMMON_BODY], [
 # define _GL_ATTRIBUTE_FALLTHROUGH ((void) 0)
 #endif
 
+/* _GL_ATTRIBUTE_FORMAT ((ARCHETYPE, STRING-INDEX, FIRST-TO-CHECK))
+   declares that the STRING-INDEXth function argument is a format string of
+   style ARCHETYPE, which is one of:
+     printf, gnu_printf
+     scanf, gnu_scanf,
+     strftime, gnu_strftime,
+     strfmon,
+   or the same thing prefixed and suffixed with '__'.
+   If FIRST-TO-CHECK is not 0, arguments starting at FIRST-TO_CHECK
+   are suitable for the format string.  */
+/* Applies to: functions.  */
 #if _GL_HAS_ATTRIBUTE (format)
 # define _GL_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec))
 #else
 # define _GL_ATTRIBUTE_FORMAT(spec)
 #endif
 
+/* _GL_ATTRIBUTE_LEAF declares that if the function is called from some other
+   compilation unit, it executes code from that unit only by return or by
+   exception handling.  This declaration lets the compiler optimize that unit
+   more aggressively.  */
+/* Applies to: functions.  */
 #if _GL_HAS_ATTRIBUTE (leaf)
 # define _GL_ATTRIBUTE_LEAF __attribute__ ((__leaf__))
 #else
 # define _GL_ATTRIBUTE_LEAF
 #endif
 
+/* _GL_ATTRIBUTE_MALLOC declares that the function returns a pointer to freshly
+   allocated memory.  */
+/* Applies to: functions.  */
 #if _GL_HAS_ATTRIBUTE (malloc)
 # define _GL_ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
 #else
 # define _GL_ATTRIBUTE_MALLOC
 #endif
 
+/* _GL_ATTRIBUTE_MAY_ALIAS declares that pointers to the type may point to the
+   same storage as pointers to other types.  Thus this declaration disables
+   strict aliasing optimization.  */
+/* Applies to: types.  */
 /* Oracle Studio 12.6 mishandles may_alias despite __has_attribute OK.  */
 #if _GL_HAS_ATTRIBUTE (may_alias) && !defined __SUNPRO_C
 # define _GL_ATTRIBUTE_MAY_ALIAS __attribute__ ((__may_alias__))
@@ -220,14 +296,33 @@ AC_DEFUN([gl_COMMON_BODY], [
 # define _GL_ATTRIBUTE_MAY_ALIAS
 #endif
 
+/* _GL_ATTRIBUTE_MAYBE_UNUSED declares that it is not a programming mistake if
+   the entity is not used.  The compiler should not warn if the entity is not
+   used.  */
+/* Applies to:
+     - function, variable,
+     - struct, union, struct/union member,
+     - enumeration, enumeration item,
+     - typedef,
+   in C++ also: class.  */
+/* In C++ and C2x, this is spelled [[__maybe_unused__]].
+   GCC's syntax is __attribute__ ((__unused__)).
+   clang supports both syntaxes.  */
 #if _GL_HAS_C_ATTRIBUTE (maybe_unused)
 # define _GL_ATTRIBUTE_MAYBE_UNUSED [[__maybe_unused__]]
 #else
 # define _GL_ATTRIBUTE_MAYBE_UNUSED _GL_ATTRIBUTE_UNUSED
 #endif
+/* Alternative spelling of this macro, for convenience and for
+   compatibility with glibc/include/libc-symbols.h.  */
+#define _GL_UNUSED _GL_ATTRIBUTE_MAYBE_UNUSED
 /* Earlier spellings of this macro.  */
 #define _UNUSED_PARAMETER_ _GL_ATTRIBUTE_MAYBE_UNUSED
 
+/* _GL_ATTRIBUTE_NODISCARD declares that the caller of the function should not
+   discard the return value.  The compiler may warn if the caller does not use
+   the return value, unless the caller uses something like ignore_value.  */
+/* Applies to: function, enumeration, class.  */
 #if _GL_HAS_C_ATTRIBUTE (nodiscard)
 # define _GL_ATTRIBUTE_NODISCARD [[__nodiscard__]]
 #elif _GL_HAS_ATTRIBUTE (warn_unused_result)
@@ -236,18 +331,30 @@ AC_DEFUN([gl_COMMON_BODY], [
 # define _GL_ATTRIBUTE_NODISCARD
 #endif
 
+/* _GL_ATTRIBUTE_NOINLINE tells that the compiler should not inline the
+   function.  */
+/* Applies to: functions.  */
 #if _GL_HAS_ATTRIBUTE (noinline)
 # define _GL_ATTRIBUTE_NOINLINE __attribute__ ((__noinline__))
 #else
 # define _GL_ATTRIBUTE_NOINLINE
 #endif
 
+/* _GL_ATTRIBUTE_NONNULL ((N1, N2,...)) declares that the arguments N1, N2,...
+   must not be NULL.
+   _GL_ATTRIBUTE_NONNULL () declares that all pointer arguments must not be
+   null.  */
+/* Applies to: functions.  */
 #if _GL_HAS_ATTRIBUTE (nonnull)
 # define _GL_ATTRIBUTE_NONNULL(args) __attribute__ ((__nonnull__ args))
 #else
 # define _GL_ATTRIBUTE_NONNULL(args)
 #endif
 
+/* _GL_ATTRIBUTE_NONSTRING declares that the contents of a character array is
+   not meant to be NUL-terminated.  */
+/* Applies to: struct/union members and variables that are arrays of element
+   type '[[un]signed] char'.  */
 #if _GL_HAS_ATTRIBUTE (nonstring)
 # define _GL_ATTRIBUTE_NONSTRING __attribute__ ((__nonstring__))
 #else
@@ -256,48 +363,76 @@ AC_DEFUN([gl_COMMON_BODY], [
 
 /* There is no _GL_ATTRIBUTE_NORETURN; use _Noreturn instead.  */
 
+/* _GL_ATTRIBUTE_NOTHROW declares that the function does not throw exceptions.
+ */
+/* Applies to: functions.  */
 #if _GL_HAS_ATTRIBUTE (nothrow) && !defined __cplusplus
 # define _GL_ATTRIBUTE_NOTHROW __attribute__ ((__nothrow__))
 #else
 # define _GL_ATTRIBUTE_NOTHROW
 #endif
 
+/* _GL_ATTRIBUTE_PACKED declares:
+   For struct members: The member has the smallest possible alignment.
+   For struct, union, class: All members have the smallest possible alignment,
+   minimizing the memory required.  */
+/* Applies to: struct members, struct, union,
+   in C++ also: class.  */
 #if _GL_HAS_ATTRIBUTE (packed)
 # define _GL_ATTRIBUTE_PACKED __attribute__ ((__packed__))
 #else
 # define _GL_ATTRIBUTE_PACKED
 #endif
 
+/* _GL_ATTRIBUTE_PURE declares that It is OK for a compiler to omit duplicate
+   calls to the function with the same arguments if observable state is not
+   changed between calls.
+   This attribute is safe for a function that does not affect
+   observable state, and always returns exactly once.
+   (This attribute is looser than _GL_ATTRIBUTE_CONST.)  */
+/* Applies to: functions.  */
 #if _GL_HAS_ATTRIBUTE (pure)
 # define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__))
 #else
 # define _GL_ATTRIBUTE_PURE
 #endif
 
+/* _GL_ATTRIBUTE_RETURNS_NONNULL declares that the function's return value is
+   a non-NULL pointer.  */
+/* Applies to: functions.  */
 #if _GL_HAS_ATTRIBUTE (returns_nonnull)
 # define _GL_ATTRIBUTE_RETURNS_NONNULL __attribute__ ((__returns_nonnull__))
 #else
 # define _GL_ATTRIBUTE_RETURNS_NONNULL
 #endif
 
+/* _GL_ATTRIBUTE_SENTINEL(pos) declares that the variadic function expects a
+   trailing NULL argument.
+   _GL_ATTRIBUTE_SENTINEL () - The last argument is NULL (requires C99).
+   _GL_ATTRIBUTE_SENTINEL ((N)) - The (N+1)st argument from the end is NULL.  */
+/* Applies to: functions.  */
 #if _GL_HAS_ATTRIBUTE (sentinel)
 # define _GL_ATTRIBUTE_SENTINEL(pos) __attribute__ ((__sentinel__ pos))
 #else
 # define _GL_ATTRIBUTE_SENTINEL(pos)
 #endif
 
+/* A helper macro.  Don't use it directly.  */
 #if _GL_HAS_ATTRIBUTE (unused)
 # define _GL_ATTRIBUTE_UNUSED __attribute__ ((__unused__))
 #else
 # define _GL_ATTRIBUTE_UNUSED
 #endif
-/* Earlier spellings of this macro.  */
-#define _GL_UNUSED _GL_ATTRIBUTE_UNUSED
 
 ]dnl There is no _GL_ATTRIBUTE_VISIBILITY; see m4/visibility.m4 instead.
 [
-/* To support C++ as well as C, use _GL_UNUSED_LABEL with trailing ';'.  */
-#if !defined __cplusplus || _GL_GNUC_PREREQ (4, 5)
+/* _GL_UNUSED_LABEL; declares that it is not a programming mistake if the
+   immediately preceding label is not used.  The compiler should not warn
+   if the label is not used.  */
+/* Applies to: label (both in C and C++).  */
+/* Note that g++ < 4.5 does not support the '__attribute__ ((__unused__)) ;'
+   syntax.  But clang does.  */
+#if !(defined __cplusplus && !_GL_GNUC_PREREQ (4, 5)) || defined __clang__
 # define _GL_UNUSED_LABEL _GL_ATTRIBUTE_UNUSED
 #else
 # define _GL_UNUSED_LABEL
@@ -690,6 +825,24 @@ AC_DEFUN([gl_CACHE_VAL_SILENT],
   ])
 ])
 
+# gl_CONDITIONAL(conditional, condition)
+# is like AM_CONDITIONAL(conditional, condition), except that it does not
+# produce an error
+#   configure: error: conditional "..." was never defined.
+#   Usually this means the macro was only invoked conditionally.
+# when only invoked conditionally. Instead, in that case, both the _TRUE
+# and the _FALSE case are disabled.
+AC_DEFUN([gl_CONDITIONAL],
+[
+  pushdef([AC_CONFIG_COMMANDS_PRE], [:])dnl
+  AM_CONDITIONAL([$1], [$2])
+  popdef([AC_CONFIG_COMMANDS_PRE])dnl
+  if test -z "${[$1]_TRUE}" && test -z "${[$1]_FALSE}"; then
+    [$1]_TRUE='#'
+    [$1]_FALSE='#'
+  fi
+])
+
 # gl_CC_ALLOW_WARNINGS
 # sets and substitutes a variable GL_CFLAG_ALLOW_WARNINGS, to a $(CC) option
 # that reverts a preceding '-Werror' option, if available.
@@ -756,6 +909,102 @@ AC_DEFUN([gl_CXX_ALLOW_WARNINGS],
   AC_SUBST([GL_CXXFLAG_ALLOW_WARNINGS])
 ])
 
+# gl_CC_GNULIB_WARNINGS
+# sets and substitutes a variable GL_CFLAG_GNULIB_WARNINGS, to a $(CC) option
+# set that enables or disables warnings as suitable for the Gnulib coding style.
+AC_DEFUN([gl_CC_GNULIB_WARNINGS],
+[
+  AC_REQUIRE([gl_CC_ALLOW_WARNINGS])
+  dnl Assume that the compiler supports -Wno-* options only if it also supports
+  dnl -Wno-error.
+  GL_CFLAG_GNULIB_WARNINGS=''
+  if test -n "$GL_CFLAG_ALLOW_WARNINGS"; then
+    dnl Enable these warning options:
+    dnl
+    dnl                                       GCC             clang
+    dnl -Wno-cast-qual                        >= 3            >= 3.9
+    dnl -Wno-conversion                       >= 3            >= 3.9
+    dnl -Wno-float-conversion                 >= 4.9          >= 3.9
+    dnl -Wno-float-equal                      >= 3            >= 3.9
+    dnl -Wimplicit-fallthrough                >= 7            >= 3.9
+    dnl -Wno-pedantic                         >= 4.8          >= 3.9
+    dnl -Wno-sign-compare                     >= 3            >= 3.9
+    dnl -Wno-sign-conversion                  >= 4.3          >= 3.9
+    dnl -Wno-type-limits                      >= 4.3          >= 3.9
+    dnl -Wno-undef                            >= 3            >= 3.9
+    dnl -Wno-unsuffixed-float-constants       >= 4.5
+    dnl -Wno-unused-function                  >= 3            >= 3.9
+    dnl -Wno-unused-parameter                 >= 3            >= 3.9
+    dnl
+    cat > conftest.c <<\EOF
+      #if __GNUC__ >= 3 || (__clang_major__ + (__clang_minor__ >= 9) > 3)
+      -Wno-cast-qual
+      -Wno-conversion
+      -Wno-float-equal
+      -Wno-sign-compare
+      -Wno-undef
+      -Wno-unused-function
+      -Wno-unused-parameter
+      #endif
+      #if __GNUC__ + (__GNUC_MINOR__ >= 9) > 4 || (__clang_major__ + (__clang_minor__ >= 9) > 3)
+      -Wno-float-conversion
+      #endif
+      #if __GNUC__ >= 7 || (__clang_major__ + (__clang_minor__ >= 9) > 3)
+      -Wimplicit-fallthrough
+      #endif
+      #if __GNUC__ + (__GNUC_MINOR__ >= 8) > 4 || (__clang_major__ + (__clang_minor__ >= 9) > 3)
+      -Wno-pedantic
+      #endif
+      #if __GNUC__ + (__GNUC_MINOR__ >= 3) > 4 || (__clang_major__ + (__clang_minor__ >= 9) > 3)
+      -Wno-sign-conversion
+      -Wno-type-limits
+      #endif
+      #if __GNUC__ + (__GNUC_MINOR__ >= 5) > 4
+      -Wno-unsuffixed-float-constants
+      #endif
+EOF
+    gl_command="$CC $CFLAGS $CPPFLAGS -E conftest.c > conftest.out"
+    if AC_TRY_EVAL([gl_command]); then
+      gl_options=`grep -v '#' conftest.out`
+      for word in $gl_options; do
+        GL_CFLAG_GNULIB_WARNINGS="$GL_CFLAG_GNULIB_WARNINGS $word"
+      done
+    fi
+    rm -f conftest.c conftest.out
+  fi
+  AC_SUBST([GL_CFLAG_GNULIB_WARNINGS])
+])
+
+dnl gl_CONDITIONAL_HEADER([foo.h])
+dnl takes a shell variable GL_GENERATE_FOO_H (with value true or false) as input
+dnl and produces
+dnl   - an AC_SUBSTed variable FOO_H that is either a file name or empty, based
+dnl     on whether GL_GENERATE_FOO_H is true or false,
+dnl   - an Automake conditional GL_GENERATE_FOO_H that evaluates to the value of
+dnl     the shell variable GL_GENERATE_FOO_H.
+AC_DEFUN([gl_CONDITIONAL_HEADER],
+[
+  m4_pushdef([gl_header_name], AS_TR_SH(m4_toupper($1)))
+  m4_pushdef([gl_generate_var], [GL_GENERATE_]AS_TR_SH(m4_toupper($1)))
+  m4_pushdef([gl_generate_cond], [GL_GENERATE_]AS_TR_SH(m4_toupper($1)))
+  case "$gl_generate_var" in
+    false) gl_header_name='' ;;
+    true)
+      dnl It is OK to use a .h file in lib/ from within tests/, but not vice
+      dnl versa.
+      if test -z "$gl_header_name"; then
+        gl_header_name="${gl_source_base_prefix}$1"
+      fi
+      ;;
+    *) echo "*** gl_generate_var is not set correctly" 1>&2; exit 1 ;;
+  esac
+  AC_SUBST(gl_header_name)
+  gl_CONDITIONAL(gl_generate_cond, [$gl_generate_var])
+  m4_popdef([gl_generate_cond])
+  m4_popdef([gl_generate_var])
+  m4_popdef([gl_header_name])
+])
+
 dnl Expands to some code for use in .c programs that, on native Windows, defines
 dnl the Microsoft deprecated alias function names to the underscore-prefixed
 dnl actual function names. With this macro, these function names are available
diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4
index 0ae96ead7..f286cfc9d 100644
--- a/m4/gnulib-comp.m4
+++ b/m4/gnulib-comp.m4
@@ -1,9 +1,9 @@
 # DO NOT EDIT! GENERATED AUTOMATICALLY!
-# Copyright (C) 2002-2021 Free Software Foundation, Inc.
+# Copyright (C) 2002-2022 Free Software Foundation, Inc.
 #
 # This file 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
+# the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
 #
 # This file is distributed in the hope that it will be useful,
@@ -42,10 +42,10 @@ AC_DEFUN([gl_EARLY],
   AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
   AC_REQUIRE([gl_PROG_AR_RANLIB])
 
-  AC_REQUIRE([AM_PROG_CC_C_O])
   # Code from module absolute-header:
   # Code from module accept:
   # Code from module accept4:
+  # Code from module access:
   # Code from module alignof:
   # Code from module alloca:
   # Code from module alloca-opt:
@@ -71,6 +71,7 @@ AC_DEFUN([gl_EARLY],
   # Code from module clock-time:
   # Code from module cloexec:
   # Code from module close:
+  # Code from module concat-filename:
   # Code from module connect:
   # Code from module copysign:
   # Code from module dirent:
@@ -89,6 +90,7 @@ AC_DEFUN([gl_EARLY],
   # Code from module fcntl-h:
   # Code from module fd-hook:
   # Code from module filename:
+  # Code from module findprog-in:
   # Code from module flexmember:
   # Code from module float:
   # Code from module flock:
@@ -102,6 +104,7 @@ AC_DEFUN([gl_EARLY],
   # Code from module full-read:
   # Code from module full-write:
   # Code from module func:
+  # Code from module gen-header:
   # Code from module gendocs:
   # Code from module getaddrinfo:
   # Code from module getdtablesize:
@@ -187,6 +190,8 @@ AC_DEFUN([gl_EARLY],
   # Code from module pipe2:
   # Code from module poll:
   # Code from module poll-h:
+  # Code from module posix_spawn-internal:
+  # Code from module posix_spawnp:
   # Code from module putenv:
   # Code from module raise:
   # Code from module rawmemchr:
@@ -202,6 +207,7 @@ AC_DEFUN([gl_EARLY],
   # Code from module safe-read:
   # Code from module safe-write:
   # Code from module same-inode:
+  # Code from module sched:
   # Code from module scratch_buffer:
   # Code from module select:
   # Code from module send:
@@ -210,6 +216,7 @@ AC_DEFUN([gl_EARLY],
   # Code from module setenv:
   # Code from module setlocale-null:
   # Code from module setsockopt:
+  # Code from module sh-filename:
   # Code from module shutdown:
   # Code from module signal-h:
   # Code from module signbit:
@@ -223,16 +230,20 @@ AC_DEFUN([gl_EARLY],
   # Code from module socketlib:
   # Code from module sockets:
   # Code from module socklen:
+  # Code from module spawn:
   # Code from module ssize_t:
   # Code from module stat:
   # Code from module stat-time:
   # Code from module std-gnu11:
   # Code from module stdalign:
   # Code from module stdbool:
+  # Code from module stdckdint:
   # Code from module stddef:
   # Code from module stdint:
   # Code from module stdio:
   # Code from module stdlib:
+  # Code from module stpcpy:
+  # Code from module strchrnul:
   # Code from module strdup-posix:
   # Code from module streq:
   # Code from module striconveh:
@@ -257,6 +268,7 @@ AC_DEFUN([gl_EARLY],
   # Code from module unistd:
   # Code from module unsetenv:
   # Code from module useless-if-before-free:
+  # Code from module vararrays:
   # Code from module vasnprintf:
   # Code from module vc-list-files:
   # Code from module verify:
@@ -265,6 +277,7 @@ AC_DEFUN([gl_EARLY],
   # Code from module wchar:
   # Code from module wcrtomb:
   # Code from module wctype-h:
+  # Code from module windows-spawn:
   # Code from module write:
   # Code from module xalloc-oversized:
   # Code from module xsize:
@@ -274,6 +287,7 @@ AC_DEFUN([gl_EARLY],
 # "Check for header files, types and library functions".
 AC_DEFUN([gl_INIT],
 [
+  AC_CONFIG_LIBOBJ_DIR([lib])
   AM_CONDITIONAL([GL_COND_LIBTOOL], [true])
   gl_cond_libtool=true
   gl_m4_base='m4'
@@ -286,97 +300,89 @@ AC_DEFUN([gl_INIT],
   m4_pushdef([GL_MODULE_INDICATOR_PREFIX], [GL])
   gl_COMMON
   gl_source_base='lib'
+  gl_source_base_prefix=
   AC_REQUIRE([gl_SYS_SOCKET_H])
-  if test "$ac_cv_header_winsock2_h" = yes; then
-    AC_LIBOBJ([accept])
-  fi
+  gl_CONDITIONAL([GL_COND_OBJ_ACCEPT], [test "$ac_cv_header_winsock2_h" = yes])
   gl_SYS_SOCKET_MODULE_INDICATOR([accept])
   gl_FUNC_ACCEPT4
   gl_SYS_SOCKET_MODULE_INDICATOR([accept4])
   gl_FUNC_ALLOCA
+  gl_CONDITIONAL_HEADER([alloca.h])
+  AC_PROG_MKDIR_P
   gl_ARPA_INET_H
   gl_ARPA_INET_H_REQUIRE_DEFAULTS
   AC_PROG_MKDIR_P
   AC_REQUIRE([gl_SYS_SOCKET_H])
-  if test "$ac_cv_header_winsock2_h" = yes; then
-    AC_LIBOBJ([bind])
-  fi
+  gl_CONDITIONAL([GL_COND_OBJ_BIND], [test "$ac_cv_header_winsock2_h" = yes])
   gl_SYS_SOCKET_MODULE_INDICATOR([bind])
   gl_BYTESWAP
+  gl_CONDITIONAL_HEADER([byteswap.h])
+  AC_PROG_MKDIR_P
   gl_CANONICALIZE_LGPL
-  if test $HAVE_CANONICALIZE_FILE_NAME = 0 || test $REPLACE_CANONICALIZE_FILE_NAME = 1; then
-    AC_LIBOBJ([canonicalize-lgpl])
-  fi
+  gl_CONDITIONAL([GL_COND_OBJ_CANONICALIZE_LGPL],
+                 [test $HAVE_CANONICALIZE_FILE_NAME = 0 || test $REPLACE_CANONICALIZE_FILE_NAME = 1])
   gl_MODULE_INDICATOR([canonicalize-lgpl])
   gl_STDLIB_MODULE_INDICATOR([canonicalize_file_name])
   gl_STDLIB_MODULE_INDICATOR([realpath])
   gl_FUNC_CEIL
-  if test $REPLACE_CEIL = 1; then
-    AC_LIBOBJ([ceil])
-  fi
+  gl_CONDITIONAL([GL_COND_OBJ_CEIL], [test $REPLACE_CEIL = 1])
   gl_MATH_MODULE_INDICATOR([ceil])
   gl_CLOCK_TIME
   gl_FUNC_CLOSE
-  if test $REPLACE_CLOSE = 1; then
-    AC_LIBOBJ([close])
-  fi
+  gl_CONDITIONAL([GL_COND_OBJ_CLOSE], [test $REPLACE_CLOSE = 1])
   gl_UNISTD_MODULE_INDICATOR([close])
   AC_REQUIRE([gl_SYS_SOCKET_H])
-  if test "$ac_cv_header_winsock2_h" = yes; then
-    AC_LIBOBJ([connect])
-  fi
+  gl_CONDITIONAL([GL_COND_OBJ_CONNECT], [test "$ac_cv_header_winsock2_h" = yes])
   gl_SYS_SOCKET_MODULE_INDICATOR([connect])
   gl_FUNC_COPYSIGN
-  if test $HAVE_COPYSIGN = 0; then
-    AC_LIBOBJ([copysign])
-  fi
+  gl_CONDITIONAL([GL_COND_OBJ_COPYSIGN], [test $HAVE_COPYSIGN = 0])
   gl_MATH_MODULE_INDICATOR([copysign])
   gl_DIRENT_H
   gl_DIRENT_H_REQUIRE_DEFAULTS
+  AC_PROG_MKDIR_P
   gl_FUNC_DIRFD
-  if test $ac_cv_func_dirfd = no && test $gl_cv_func_dirfd_macro = no \
-     || test $REPLACE_DIRFD = 1; then
-    AC_LIBOBJ([dirfd])
+  gl_CONDITIONAL([GL_COND_OBJ_DIRFD],
+                 [test $ac_cv_func_dirfd = no && test $gl_cv_func_dirfd_macro = no || test $REPLACE_DIRFD = 1])
+  AM_COND_IF([GL_COND_OBJ_DIRFD], [
     gl_PREREQ_DIRFD
-  fi
+  ])
   gl_DIRENT_MODULE_INDICATOR([dirfd])
   gl_DOUBLE_SLASH_ROOT
   gl_FUNC_DUPLOCALE
-  if test $REPLACE_DUPLOCALE = 1; then
-    AC_LIBOBJ([duplocale])
+  gl_CONDITIONAL([GL_COND_OBJ_DUPLOCALE], [test $REPLACE_DUPLOCALE = 1])
+  AM_COND_IF([GL_COND_OBJ_DUPLOCALE], [
     gl_PREREQ_DUPLOCALE
-  fi
+  ])
   gl_LOCALE_MODULE_INDICATOR([duplocale])
   gl_ENVIRON
   gl_UNISTD_MODULE_INDICATOR([environ])
   gl_HEADER_ERRNO_H
+  gl_CONDITIONAL_HEADER([errno.h])
+  AC_PROG_MKDIR_P
   AC_REQUIRE([gl_EXTERN_INLINE])
   gl_FCNTL_H
   gl_FCNTL_H_REQUIRE_DEFAULTS
+  AC_PROG_MKDIR_P
   AC_C_FLEXIBLE_ARRAY_MEMBER
   gl_FLOAT_H
-  if test $REPLACE_FLOAT_LDBL = 1; then
-    AC_LIBOBJ([float])
-  fi
-  if test $REPLACE_ITOLD = 1; then
-    AC_LIBOBJ([itold])
-  fi
+  gl_CONDITIONAL_HEADER([float.h])
+  AC_PROG_MKDIR_P
+  gl_CONDITIONAL([GL_COND_OBJ_FLOAT], [test $REPLACE_FLOAT_LDBL = 1])
+  gl_CONDITIONAL([GL_COND_OBJ_ITOLD], [test $REPLACE_ITOLD = 1])
   gl_FUNC_FLOCK
-  if test $HAVE_FLOCK = 0; then
-    AC_LIBOBJ([flock])
+  gl_CONDITIONAL([GL_COND_OBJ_FLOCK], [test $HAVE_FLOCK = 0])
+  AM_COND_IF([GL_COND_OBJ_FLOCK], [
     gl_PREREQ_FLOCK
-  fi
+  ])
   gl_SYS_FILE_MODULE_INDICATOR([flock])
   AC_REQUIRE([gl_FUNC_FLOOR])
-  if test $REPLACE_FLOOR = 1; then
-    AC_LIBOBJ([floor])
-  fi
+  gl_CONDITIONAL([GL_COND_OBJ_FLOOR], [test $REPLACE_FLOOR = 1])
   gl_MATH_MODULE_INDICATOR([floor])
   gl_FUNC_FREE
-  if test $REPLACE_FREE = 1; then
-    AC_LIBOBJ([free])
+  gl_CONDITIONAL([GL_COND_OBJ_FREE], [test $REPLACE_FREE = 1])
+  AM_COND_IF([GL_COND_OBJ_FREE], [
     gl_PREREQ_FREE
-  fi
+  ])
   gl_STDLIB_MODULE_INDICATOR([free-posix])
   AC_REQUIRE([gl_FUNC_FREXP])
   if test $gl_func_frexp != yes; then
@@ -384,51 +390,44 @@ AC_DEFUN([gl_INIT],
   fi
   gl_MATH_MODULE_INDICATOR([frexp])
   gl_FUNC_FSTAT
-  if test $REPLACE_FSTAT = 1; then
-    AC_LIBOBJ([fstat])
+  gl_CONDITIONAL([GL_COND_OBJ_FSTAT], [test $REPLACE_FSTAT = 1])
+  AM_COND_IF([GL_COND_OBJ_FSTAT], [
     case "$host_os" in
       mingw*)
         AC_LIBOBJ([stat-w32])
         ;;
     esac
     gl_PREREQ_FSTAT
-  fi
+  ])
   gl_SYS_STAT_MODULE_INDICATOR([fstat])
   gl_FUNC_FSYNC
-  if test $HAVE_FSYNC = 0; then
-    AC_LIBOBJ([fsync])
+  gl_CONDITIONAL([GL_COND_OBJ_FSYNC], [test $HAVE_FSYNC = 0])
+  AM_COND_IF([GL_COND_OBJ_FSYNC], [
     gl_PREREQ_FSYNC
-  fi
+  ])
   gl_UNISTD_MODULE_INDICATOR([fsync])
   gl_FUNC
   gl_GETADDRINFO
-  if test $HAVE_GETADDRINFO = 0 || test $REPLACE_GETADDRINFO = 1; then
-    AC_LIBOBJ([getaddrinfo])
-  fi
-  if test $HAVE_DECL_GAI_STRERROR = 0 || test $REPLACE_GAI_STRERROR = 1; then
-    AC_LIBOBJ([gai_strerror])
-  fi
+  gl_CONDITIONAL([GL_COND_OBJ_GETADDRINFO],
+                 [test $HAVE_GETADDRINFO = 0 || test $REPLACE_GETADDRINFO = 1])
+  gl_CONDITIONAL([GL_COND_OBJ_GAI_STRERROR],
+                 [test $HAVE_DECL_GAI_STRERROR = 0 || test $REPLACE_GAI_STRERROR = 1])
   gl_NETDB_MODULE_INDICATOR([getaddrinfo])
   gl_FUNC_GETLOGIN
-  if test $HAVE_GETLOGIN = 0; then
-    AC_LIBOBJ([getlogin])
-  fi
+  gl_CONDITIONAL([GL_COND_OBJ_GETLOGIN], [test $HAVE_GETLOGIN = 0])
   gl_UNISTD_MODULE_INDICATOR([getlogin])
   AC_REQUIRE([gl_LIB_GETLOGIN])
   AC_REQUIRE([gl_SYS_SOCKET_H])
-  if test "$ac_cv_header_winsock2_h" = yes; then
-    AC_LIBOBJ([getpeername])
-  fi
+  gl_CONDITIONAL([GL_COND_OBJ_GETPEERNAME],
+                 [test "$ac_cv_header_winsock2_h" = yes])
   gl_SYS_SOCKET_MODULE_INDICATOR([getpeername])
   AC_REQUIRE([gl_SYS_SOCKET_H])
-  if test "$ac_cv_header_winsock2_h" = yes; then
-    AC_LIBOBJ([getsockname])
-  fi
+  gl_CONDITIONAL([GL_COND_OBJ_GETSOCKNAME],
+                 [test "$ac_cv_header_winsock2_h" = yes])
   gl_SYS_SOCKET_MODULE_INDICATOR([getsockname])
   AC_REQUIRE([gl_SYS_SOCKET_H])
-  if test "$ac_cv_header_winsock2_h" = yes; then
-    AC_LIBOBJ([getsockopt])
-  fi
+  gl_CONDITIONAL([GL_COND_OBJ_GETSOCKOPT],
+                 [test "$ac_cv_header_winsock2_h" = yes])
   gl_SYS_SOCKET_MODULE_INDICATOR([getsockopt])
   # Autoconf 2.61a.99 and earlier don't support linking a file only
   # in VPATH builds.  But since GNUmakefile is for maintainer use
@@ -446,38 +445,36 @@ AC_DEFUN([gl_INIT],
     [gl_ICONV_MODULE_INDICATOR([iconv])])
   gl_ICONV_H
   gl_ICONV_H_REQUIRE_DEFAULTS
+  gl_CONDITIONAL_HEADER([iconv.h])
+  AC_PROG_MKDIR_P
   gl_FUNC_ICONV_OPEN
-  if test $REPLACE_ICONV_OPEN = 1; then
-    AC_LIBOBJ([iconv_open])
-  fi
-  if test $REPLACE_ICONV = 1; then
-    AC_LIBOBJ([iconv])
-    AC_LIBOBJ([iconv_close])
-  fi
+  dnl Because of gl_REPLACE_ICONV_H:
+  gl_CONDITIONAL_HEADER([iconv.h])
+  gl_CONDITIONAL([GL_COND_OBJ_ICONV_OPEN], [test $REPLACE_ICONV_OPEN = 1])
+  gl_CONDITIONAL([GL_COND_OBJ_ICONV], [test $REPLACE_ICONV = 1])
   gl_FUNC_ICONV_OPEN_UTF
   gl_FUNC_INET_NTOP
-  if test $HAVE_INET_NTOP = 0 || test $REPLACE_INET_NTOP = 1; then
-    AC_LIBOBJ([inet_ntop])
+  gl_CONDITIONAL([GL_COND_OBJ_INET_NTOP],
+                 [test $HAVE_INET_NTOP = 0 || test $REPLACE_INET_NTOP = 1])
+  AM_COND_IF([GL_COND_OBJ_INET_NTOP], [
     gl_PREREQ_INET_NTOP
-  fi
+  ])
   gl_ARPA_INET_MODULE_INDICATOR([inet_ntop])
   gl_FUNC_INET_PTON
-  if test $HAVE_INET_PTON = 0 || test $REPLACE_INET_PTON = 1; then
-    AC_LIBOBJ([inet_pton])
+  gl_CONDITIONAL([GL_COND_OBJ_INET_PTON],
+                 [test $HAVE_INET_PTON = 0 || test $REPLACE_INET_PTON = 1])
+  AM_COND_IF([GL_COND_OBJ_INET_PTON], [
     gl_PREREQ_INET_PTON
-  fi
+  ])
   gl_ARPA_INET_MODULE_INDICATOR([inet_pton])
   gl_INTTYPES_INCOMPLETE
   gl_INTTYPES_H_REQUIRE_DEFAULTS
+  AC_PROG_MKDIR_P
   gl_ISFINITE
-  if test $REPLACE_ISFINITE = 1; then
-    AC_LIBOBJ([isfinite])
-  fi
+  gl_CONDITIONAL([GL_COND_OBJ_ISFINITE], [test $REPLACE_ISFINITE = 1])
   gl_MATH_MODULE_INDICATOR([isfinite])
   gl_ISINF
-  if test $REPLACE_ISINF = 1; then
-    AC_LIBOBJ([isinf])
-  fi
+  gl_CONDITIONAL([GL_COND_OBJ_ISINF], [test $REPLACE_ISINF = 1])
   gl_MATH_MODULE_INDICATOR([isinf])
   gl_ISNAN
   gl_MATH_MODULE_INDICATOR([isnan])
@@ -510,21 +507,22 @@ AC_DEFUN([gl_INIT],
   gl_MATH_MODULE_INDICATOR([isnanl])
   gl_LANGINFO_H
   gl_LANGINFO_H_REQUIRE_DEFAULTS
+  AC_PROG_MKDIR_P
   AC_REQUIRE([gl_LARGEFILE])
   gl_FUNC_LDEXP
   gl_LD_VERSION_SCRIPT
   gl_VISIBILITY
+  gl___INLINE
   gl_LIBUNISTRING
   gl_LIMITS_H
+  gl_CONDITIONAL_HEADER([limits.h])
+  AC_PROG_MKDIR_P
   gl_FUNC_LINK
-  if test $HAVE_LINK = 0 || test $REPLACE_LINK = 1; then
-    AC_LIBOBJ([link])
-  fi
+  gl_CONDITIONAL([GL_COND_OBJ_LINK],
+                 [test $HAVE_LINK = 0 || test $REPLACE_LINK = 1])
   gl_UNISTD_MODULE_INDICATOR([link])
   AC_REQUIRE([gl_SYS_SOCKET_H])
-  if test "$ac_cv_header_winsock2_h" = yes; then
-    AC_LIBOBJ([listen])
-  fi
+  gl_CONDITIONAL([GL_COND_OBJ_LISTEN], [test "$ac_cv_header_winsock2_h" = yes])
   gl_SYS_SOCKET_MODULE_INDICATOR([listen])
   gl_LOCALCHARSET
   dnl For backward compatibility. Some packages still use this.
@@ -532,173 +530,159 @@ AC_DEFUN([gl_INIT],
   AC_SUBST([LOCALCHARSET_TESTS_ENVIRONMENT])
   gl_LOCALE_H
   gl_LOCALE_H_REQUIRE_DEFAULTS
+  AC_PROG_MKDIR_P
   gl_FUNC_LOG1P
-  if test $HAVE_LOG1P = 0 || test $REPLACE_LOG1P = 1; then
-    AC_LIBOBJ([log1p])
-  fi
+  gl_CONDITIONAL([GL_COND_OBJ_LOG1P],
+                 [test $HAVE_LOG1P = 0 || test $REPLACE_LOG1P = 1])
   gl_MATH_MODULE_INDICATOR([log1p])
   gl_FUNC_LSTAT
-  if test $REPLACE_LSTAT = 1; then
-    AC_LIBOBJ([lstat])
+  gl_CONDITIONAL([GL_COND_OBJ_LSTAT], [test $REPLACE_LSTAT = 1])
+  AM_COND_IF([GL_COND_OBJ_LSTAT], [
     gl_PREREQ_LSTAT
-  fi
+  ])
   gl_SYS_STAT_MODULE_INDICATOR([lstat])
   AC_CONFIG_COMMANDS_PRE([m4_ifdef([AH_HEADER],
     [AC_SUBST([CONFIG_INCLUDE], m4_defn([AH_HEADER]))])])
   AC_REQUIRE([AC_PROG_SED])
   AC_REQUIRE([AC_PROG_GREP])
   gl_FUNC_MALLOC_GNU
-  if test $REPLACE_MALLOC = 1; then
+  if test $REPLACE_MALLOC_FOR_MALLOC_GNU = 1; then
     AC_LIBOBJ([malloc])
   fi
+  gl_STDLIB_MODULE_INDICATOR([malloc-gnu])
   AC_REQUIRE([gl_FUNC_MALLOC_POSIX])
-  if test $REPLACE_MALLOC = 1; then
+  if test $REPLACE_MALLOC_FOR_MALLOC_POSIX = 1; then
     AC_LIBOBJ([malloc])
   fi
   gl_STDLIB_MODULE_INDICATOR([malloc-posix])
   gl_MALLOCA
   gl_MATH_H
   gl_MATH_H_REQUIRE_DEFAULTS
+  AC_PROG_MKDIR_P
   gl_MINMAX
   gl_FUNC_MKDIR
-  if test $REPLACE_MKDIR = 1; then
-    AC_LIBOBJ([mkdir])
-  fi
+  gl_CONDITIONAL([GL_COND_OBJ_MKDIR], [test $REPLACE_MKDIR = 1])
   gl_SYS_STAT_MODULE_INDICATOR([mkdir])
   gl_FUNC_MKOSTEMP
-  if test $HAVE_MKOSTEMP = 0; then
-    AC_LIBOBJ([mkostemp])
+  gl_CONDITIONAL([GL_COND_OBJ_MKOSTEMP], [test $HAVE_MKOSTEMP = 0])
+  AM_COND_IF([GL_COND_OBJ_MKOSTEMP], [
     gl_PREREQ_MKOSTEMP
-  fi
+  ])
   gl_MODULE_INDICATOR([mkostemp])
   gl_STDLIB_MODULE_INDICATOR([mkostemp])
   AC_REQUIRE([gl_MSVC_INVAL])
-  if test $HAVE_MSVC_INVALID_PARAMETER_HANDLER = 1; then
-    AC_LIBOBJ([msvc-inval])
-  fi
+  gl_CONDITIONAL([GL_COND_OBJ_MSVC_INVAL],
+                 [test $HAVE_MSVC_INVALID_PARAMETER_HANDLER = 1])
   AC_REQUIRE([gl_MSVC_NOTHROW])
-  if test $HAVE_MSVC_INVALID_PARAMETER_HANDLER = 1; then
-    AC_LIBOBJ([msvc-nothrow])
-  fi
+  gl_CONDITIONAL([GL_COND_OBJ_MSVC_NOTHROW],
+                 [test $HAVE_MSVC_INVALID_PARAMETER_HANDLER = 1])
   gl_MODULE_INDICATOR([msvc-nothrow])
   gl_MULTIARCH
   gl_NETDB_H
   gl_NETDB_H_REQUIRE_DEFAULTS
-  gl_HEADER_NETINET_IN
   AC_PROG_MKDIR_P
   gl_FUNC_NL_LANGINFO
-  if test $HAVE_NL_LANGINFO = 0 || test $REPLACE_NL_LANGINFO = 1; then
-    AC_LIBOBJ([nl_langinfo])
-  fi
+  gl_CONDITIONAL([GL_COND_OBJ_NL_LANGINFO],
+                 [test $HAVE_NL_LANGINFO = 0 || test $REPLACE_NL_LANGINFO = 1])
+  gl_CONDITIONAL([GL_COND_OBJ_NL_LANGINFO_LOCK],
+                 [test $REPLACE_NL_LANGINFO = 1 && test $NL_LANGINFO_MTSAFE = 0])
   if test $REPLACE_NL_LANGINFO = 1 && test $NL_LANGINFO_MTSAFE = 0; then
-    AC_LIBOBJ([nl_langinfo-lock])
     gl_PREREQ_NL_LANGINFO_LOCK
   fi
   gl_LANGINFO_MODULE_INDICATOR([nl_langinfo])
   gl_NPROC
   gl_FUNC_GNU_STRFTIME
   gl_FUNC_OPEN
-  if test $REPLACE_OPEN = 1; then
-    AC_LIBOBJ([open])
+  gl_CONDITIONAL([GL_COND_OBJ_OPEN], [test $REPLACE_OPEN = 1])
+  AM_COND_IF([GL_COND_OBJ_OPEN], [
     gl_PREREQ_OPEN
-  fi
+  ])
   gl_FCNTL_MODULE_INDICATOR([open])
   gl_FUNC_PIPE
-  if test $HAVE_PIPE = 0; then
-    AC_LIBOBJ([pipe])
-  fi
+  gl_CONDITIONAL([GL_COND_OBJ_PIPE], [test $HAVE_PIPE = 0])
   gl_UNISTD_MODULE_INDICATOR([pipe])
   gl_FUNC_PIPE2
   gl_UNISTD_MODULE_INDICATOR([pipe2])
   gl_FUNC_POLL
-  if test $HAVE_POLL = 0 || test $REPLACE_POLL = 1; then
-    AC_LIBOBJ([poll])
+  gl_CONDITIONAL([GL_COND_OBJ_POLL],
+                 [test $HAVE_POLL = 0 || test $REPLACE_POLL = 1])
+  AM_COND_IF([GL_COND_OBJ_POLL], [
     gl_PREREQ_POLL
-  fi
+  ])
   gl_POLL_MODULE_INDICATOR([poll])
   gl_POLL_H
   gl_POLL_H_REQUIRE_DEFAULTS
+  AC_PROG_MKDIR_P
+  gl_POSIX_SPAWN
+  gl_CONDITIONAL([GL_COND_OBJ_SPAWNP],
+                 [test $HAVE_POSIX_SPAWN = 0 || test $REPLACE_POSIX_SPAWN = 1])
+  gl_SPAWN_MODULE_INDICATOR([posix_spawnp])
   gl_FUNC_PUTENV
-  if test $REPLACE_PUTENV = 1; then
-    AC_LIBOBJ([putenv])
+  gl_CONDITIONAL([GL_COND_OBJ_PUTENV], [test $REPLACE_PUTENV = 1])
+  AM_COND_IF([GL_COND_OBJ_PUTENV], [
     gl_PREREQ_PUTENV
-  fi
+  ])
   gl_STDLIB_MODULE_INDICATOR([putenv])
   gl_FUNC_READ
-  if test $REPLACE_READ = 1; then
-    AC_LIBOBJ([read])
+  gl_CONDITIONAL([GL_COND_OBJ_READ], [test $REPLACE_READ = 1])
+  AM_COND_IF([GL_COND_OBJ_READ], [
     gl_PREREQ_READ
-  fi
+  ])
   gl_UNISTD_MODULE_INDICATOR([read])
   gl_FUNC_READLINK
-  if test $HAVE_READLINK = 0 || test $REPLACE_READLINK = 1; then
-    AC_LIBOBJ([readlink])
+  gl_CONDITIONAL([GL_COND_OBJ_READLINK],
+                 [test $HAVE_READLINK = 0 || test $REPLACE_READLINK = 1])
+  AM_COND_IF([GL_COND_OBJ_READLINK], [
     gl_PREREQ_READLINK
-  fi
+  ])
   gl_UNISTD_MODULE_INDICATOR([readlink])
   AC_REQUIRE([gl_SYS_SOCKET_H])
-  if test "$ac_cv_header_winsock2_h" = yes; then
-    AC_LIBOBJ([recv])
-  fi
+  gl_CONDITIONAL([GL_COND_OBJ_RECV], [test "$ac_cv_header_winsock2_h" = yes])
   gl_SYS_SOCKET_MODULE_INDICATOR([recv])
   AC_REQUIRE([gl_SYS_SOCKET_H])
-  if test "$ac_cv_header_winsock2_h" = yes; then
-    AC_LIBOBJ([recvfrom])
-  fi
+  gl_CONDITIONAL([GL_COND_OBJ_RECVFROM], [test "$ac_cv_header_winsock2_h" = yes])
   gl_SYS_SOCKET_MODULE_INDICATOR([recvfrom])
   gl_REGEX
-  if test $ac_use_included_regex = yes; then
-    AC_LIBOBJ([regex])
+  gl_CONDITIONAL([GL_COND_OBJ_REGEX], [test $ac_use_included_regex = yes])
+  AM_COND_IF([GL_COND_OBJ_REGEX], [
     gl_PREREQ_REGEX
-  fi
+  ])
   gl_FUNC_RENAME
-  if test $REPLACE_RENAME = 1; then
-    AC_LIBOBJ([rename])
-  fi
+  gl_CONDITIONAL([GL_COND_OBJ_RENAME], [test $REPLACE_RENAME = 1])
   gl_STDIO_MODULE_INDICATOR([rename])
   gl_FUNC_RMDIR
-  if test $REPLACE_RMDIR = 1; then
-    AC_LIBOBJ([rmdir])
-  fi
+  gl_CONDITIONAL([GL_COND_OBJ_RMDIR], [test $REPLACE_RMDIR = 1])
   gl_UNISTD_MODULE_INDICATOR([rmdir])
   gl_PREREQ_SAFE_READ
   gl_PREREQ_SAFE_WRITE
+  gl_SCHED_H
+  gl_SCHED_H_REQUIRE_DEFAULTS
+  AC_PROG_MKDIR_P
   gl_FUNC_SELECT
-  if test $REPLACE_SELECT = 1; then
-    AC_LIBOBJ([select])
-  fi
+  gl_CONDITIONAL([GL_COND_OBJ_SELECT], [test $REPLACE_SELECT = 1])
   gl_SYS_SELECT_MODULE_INDICATOR([select])
   AC_REQUIRE([gl_SYS_SOCKET_H])
-  if test "$ac_cv_header_winsock2_h" = yes; then
-    AC_LIBOBJ([send])
-  fi
+  gl_CONDITIONAL([GL_COND_OBJ_SEND], [test "$ac_cv_header_winsock2_h" = yes])
   gl_SYS_SOCKET_MODULE_INDICATOR([send])
   AC_REQUIRE([gl_SYS_SOCKET_H])
-  if test "$ac_cv_header_winsock2_h" = yes; then
-    AC_LIBOBJ([sendto])
-  fi
+  gl_CONDITIONAL([GL_COND_OBJ_SENDTO], [test "$ac_cv_header_winsock2_h" = yes])
   gl_SYS_SOCKET_MODULE_INDICATOR([sendto])
   gl_FUNC_SETENV
-  if test $HAVE_SETENV = 0 || test $REPLACE_SETENV = 1; then
-    AC_LIBOBJ([setenv])
-  fi
+  gl_CONDITIONAL([GL_COND_OBJ_SETENV],
+                 [test $HAVE_SETENV = 0 || test $REPLACE_SETENV = 1])
   gl_STDLIB_MODULE_INDICATOR([setenv])
   AC_REQUIRE([gl_SYS_SOCKET_H])
-  if test "$ac_cv_header_winsock2_h" = yes; then
-    AC_LIBOBJ([setsockopt])
-  fi
+  gl_CONDITIONAL([GL_COND_OBJ_SETSOCKOPT],
+                 [test "$ac_cv_header_winsock2_h" = yes])
   gl_SYS_SOCKET_MODULE_INDICATOR([setsockopt])
   AC_REQUIRE([gl_SYS_SOCKET_H])
-  if test "$ac_cv_header_winsock2_h" = yes; then
-    AC_LIBOBJ([shutdown])
-  fi
+  gl_CONDITIONAL([GL_COND_OBJ_SHUTDOWN], [test "$ac_cv_header_winsock2_h" = yes])
   gl_SYS_SOCKET_MODULE_INDICATOR([shutdown])
   gl_SIGNAL_H
   gl_SIGNAL_H_REQUIRE_DEFAULTS
+  AC_PROG_MKDIR_P
   AC_REQUIRE([gl_SYS_SOCKET_H])
-  if test "$ac_cv_header_winsock2_h" = yes; then
-    AC_LIBOBJ([socket])
-  fi
+  gl_CONDITIONAL([GL_COND_OBJ_SOCKET], [test "$ac_cv_header_winsock2_h" = yes])
   # When this module is used, sockets may actually occur as file descriptors,
   # hence it is worth warning if the modules 'close' and 'ioctl' are not used.
   m4_ifdef([gl_UNISTD_H_DEFAULTS], [gl_UNISTD_H_REQUIRE_DEFAULTS])
@@ -711,16 +695,40 @@ AC_DEFUN([gl_INIT],
   gl_SYS_SOCKET_MODULE_INDICATOR([socket])
   AC_REQUIRE([gl_SOCKETLIB])
   gl_TYPE_SOCKLEN_T
+  gl_SPAWN_H
+  gl_SPAWN_H_REQUIRE_DEFAULTS
+  AC_PROG_MKDIR_P
   gt_TYPE_SSIZE_T
   gl_STAT_TIME
   gl_STAT_BIRTHTIME
   gl_STDALIGN_H
-  AM_STDBOOL_H
+  gl_CONDITIONAL_HEADER([stdalign.h])
+  AC_PROG_MKDIR_P
+  gl_STDBOOL_H
+  gl_CONDITIONAL_HEADER([stdbool.h])
+  AC_PROG_MKDIR_P
+  AC_CHECK_HEADERS_ONCE([stdckdint.h])
+  if test $ac_cv_header_stdckdint_h = yes; then
+    GL_GENERATE_STDCKDINT_H=false
+  else
+    GL_GENERATE_STDCKDINT_H=true
+  fi
+  gl_CONDITIONAL_HEADER([stdckdint.h])
+  AC_PROG_MKDIR_P
   gl_STDDEF_H
   gl_STDDEF_H_REQUIRE_DEFAULTS
+  gl_CONDITIONAL_HEADER([stddef.h])
+  AC_PROG_MKDIR_P
   gl_STDINT_H
+  gl_CONDITIONAL_HEADER([stdint.h])
+  dnl Because of gl_REPLACE_LIMITS_H:
+  gl_CONDITIONAL_HEADER([limits.h])
+  AC_PROG_MKDIR_P
   gl_STDIO_H
   gl_STDIO_H_REQUIRE_DEFAULTS
+  AC_PROG_MKDIR_P
+  gl_CONDITIONAL([GL_COND_OBJ_STDIO_READ], [test $REPLACE_STDIO_READ_FUNCS = 1])
+  gl_CONDITIONAL([GL_COND_OBJ_STDIO_WRITE], [test $REPLACE_STDIO_WRITE_FUNCS = 1])
   dnl No need to create extra modules for these functions. Everyone who uses
   dnl <stdio.h> likely needs them.
   gl_STDIO_MODULE_INDICATOR([fscanf])
@@ -746,12 +754,14 @@ AC_DEFUN([gl_INIT],
   gl_STDIO_MODULE_INDICATOR([fwrite])
   gl_STDLIB_H
   gl_STDLIB_H_REQUIRE_DEFAULTS
+  AC_PROG_MKDIR_P
   if test $gl_cond_libtool = false; then
     gl_ltlibdeps="$gl_ltlibdeps $LTLIBICONV"
     gl_libdeps="$gl_libdeps $LIBICONV"
   fi
   gl_STRING_H
   gl_STRING_H_REQUIRE_DEFAULTS
+  AC_PROG_MKDIR_P
   gl_SYS_FILE_H
   gl_SYS_FILE_H_REQUIRE_DEFAULTS
   AC_PROG_MKDIR_P
@@ -778,44 +788,46 @@ AC_DEFUN([gl_INIT],
   AC_PROG_MKDIR_P
   gl_TIME_H
   gl_TIME_H_REQUIRE_DEFAULTS
+  AC_PROG_MKDIR_P
   gl_TIME_RZ
-  if test $HAVE_TIMEZONE_T = 0; then
-    AC_LIBOBJ([time_rz])
-  fi
+  gl_CONDITIONAL([GL_COND_OBJ_TIME_RZ], [test $HAVE_TIMEZONE_T = 0])
   gl_TIME_MODULE_INDICATOR([time_rz])
   gl_FUNC_TIMES
-  if test $HAVE_TIMES = 0; then
-    AC_LIBOBJ([times])
-  fi
+  gl_CONDITIONAL([GL_COND_OBJ_TIMES], [test $HAVE_TIMES = 0])
   gl_SYS_TIMES_MODULE_INDICATOR([times])
   gl_FUNC_TRUNC
-  if test $HAVE_DECL_TRUNC = 0 || test $REPLACE_TRUNC = 1; then
-    AC_LIBOBJ([trunc])
-  fi
+  gl_CONDITIONAL([GL_COND_OBJ_TRUNC],
+                 [test $HAVE_DECL_TRUNC = 0 || test $REPLACE_TRUNC = 1])
   gl_MATH_MODULE_INDICATOR([trunc])
   gl_UNISTD_H
   gl_UNISTD_H_REQUIRE_DEFAULTS
+  AC_PROG_MKDIR_P
+  AC_C_VARARRAYS
   gl_FUNC_VSNPRINTF
   gl_STDIO_MODULE_INDICATOR([vsnprintf])
   gl_WCHAR_H
   gl_WCHAR_H_REQUIRE_DEFAULTS
+  AC_PROG_MKDIR_P
   gl_FUNC_WRITE
-  if test $REPLACE_WRITE = 1; then
-    AC_LIBOBJ([write])
+  gl_CONDITIONAL([GL_COND_OBJ_WRITE], [test $REPLACE_WRITE = 1])
+  AM_COND_IF([GL_COND_OBJ_WRITE], [
     gl_PREREQ_WRITE
-  fi
+  ])
   gl_UNISTD_MODULE_INDICATOR([write])
+  gl_gnulib_enabled_access=false
   gl_gnulib_enabled_alloca=false
   gl_gnulib_enabled_assure=false
   gl_gnulib_enabled_btowc=false
   gl_gnulib_enabled_37f71b604aa9c54446783d80f42fe547=false
   gl_gnulib_enabled_chdir=false
   gl_gnulib_enabled_cloexec=false
+  gl_gnulib_enabled_6da965dc4d3aa4f87d68116dce96f1a5=false
   gl_gnulib_enabled_dup2=false
   gl_gnulib_enabled_dynarray=false
   gl_gnulib_enabled_925677f0343de64b89a9f0c790b4104c=false
   gl_gnulib_enabled_fcntl=false
   gl_gnulib_enabled_43fe87a341d9b4b93c47c3ad819a5239=false
+  gl_gnulib_enabled_7be38c8cf2027003f573b80556d26ff2=false
   gl_gnulib_enabled_getdtablesize=false
   gl_gnulib_enabled_getrandom=false
   gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36=false
@@ -824,7 +836,6 @@ AC_DEFUN([gl_INIT],
   gl_gnulib_enabled_b1df7117b479d2da59d76deba468ee21=false
   gl_gnulib_enabled_3f0e593033d1fc2c127581960f641b66=false
   gl_gnulib_enabled_dbdf22868a5367f28bf18e0013ac6f8f=false
-  gl_gnulib_enabled_21ee726a3540c09237a8e70c0baf7467=false
   gl_gnulib_enabled_localeconv=false
   gl_gnulib_enabled_log=false
   gl_gnulib_enabled_mbrtowc=false
@@ -834,7 +845,9 @@ AC_DEFUN([gl_INIT],
   gl_gnulib_enabled_mempcpy=false
   gl_gnulib_enabled_mktime=false
   gl_gnulib_enabled_5264294aa0a5557541b53c8c741f7f31=false
+  gl_gnulib_enabled_netinet_in=false
   gl_gnulib_enabled_pathmax=false
+  gl_gnulib_enabled_332607f759618fb73dfc3076748afea7=false
   gl_gnulib_enabled_raise=false
   gl_gnulib_enabled_rawmemchr=false
   gl_gnulib_enabled_61bcaca76b3e6f9ae55d57a1c3193bc4=false
@@ -843,11 +856,14 @@ AC_DEFUN([gl_INIT],
   gl_gnulib_enabled_scratch_buffer=false
   gl_gnulib_enabled_servent=false
   gl_gnulib_enabled_e7e881d32ca02f1c997b13c737c64bbd=false
+  gl_gnulib_enabled_cdeb0f2aaf9d280baa6526bfa1b07f70=false
   gl_gnulib_enabled_signbit=false
   gl_gnulib_enabled_size_max=false
   gl_gnulib_enabled_snprintf=false
   gl_gnulib_enabled_sockets=false
   gl_gnulib_enabled_stat=false
+  gl_gnulib_enabled_stpcpy=false
+  gl_gnulib_enabled_strchrnul=false
   gl_gnulib_enabled_f9850631dca91859e9cddac9359921c0=false
   gl_gnulib_enabled_streq=false
   gl_gnulib_enabled_sys_random=false
@@ -859,7 +875,18 @@ AC_DEFUN([gl_INIT],
   gl_gnulib_enabled_vasnprintf=false
   gl_gnulib_enabled_wcrtomb=false
   gl_gnulib_enabled_3dcce957eadc896e63ab5f137947b410=false
+  gl_gnulib_enabled_fd43d02c899a251eacc999baf40b238e=false
   gl_gnulib_enabled_xsize=false
+  func_gl_gnulib_m4code_access ()
+  {
+    if ! $gl_gnulib_enabled_access; then
+      gl_FUNC_ACCESS
+      gl_CONDITIONAL([GL_COND_OBJ_ACCESS], [test $REPLACE_ACCESS = 1])
+      gl_UNISTD_MODULE_INDICATOR([access])
+      gl_gnulib_enabled_access=true
+      func_gl_gnulib_m4code_fcntl
+    fi
+  }
   func_gl_gnulib_m4code_alloca ()
   {
     if ! $gl_gnulib_enabled_alloca; then
@@ -880,10 +907,11 @@ AC_SUBST([LTALLOCA])
   {
     if ! $gl_gnulib_enabled_btowc; then
       gl_FUNC_BTOWC
-      if test $HAVE_BTOWC = 0 || test $REPLACE_BTOWC = 1; then
-        AC_LIBOBJ([btowc])
+      gl_CONDITIONAL([GL_COND_OBJ_BTOWC],
+                     [test $HAVE_BTOWC = 0 || test $REPLACE_BTOWC = 1])
+      AM_COND_IF([GL_COND_OBJ_BTOWC], [
         gl_PREREQ_BTOWC
-      fi
+      ])
       gl_WCHAR_MODULE_INDICATOR([btowc])
       gl_gnulib_enabled_btowc=true
       if test $HAVE_BTOWC = 0 || test $REPLACE_BTOWC = 1; then
@@ -914,14 +942,21 @@ AC_SUBST([LTALLOCA])
       func_gl_gnulib_m4code_fcntl
     fi
   }
+  func_gl_gnulib_m4code_6da965dc4d3aa4f87d68116dce96f1a5 ()
+  {
+    if ! $gl_gnulib_enabled_6da965dc4d3aa4f87d68116dce96f1a5; then
+      gl_gnulib_enabled_6da965dc4d3aa4f87d68116dce96f1a5=true
+      func_gl_gnulib_m4code_stpcpy
+    fi
+  }
   func_gl_gnulib_m4code_dup2 ()
   {
     if ! $gl_gnulib_enabled_dup2; then
       gl_FUNC_DUP2
-      if test $REPLACE_DUP2 = 1; then
-        AC_LIBOBJ([dup2])
+      gl_CONDITIONAL([GL_COND_OBJ_DUP2], [test $REPLACE_DUP2 = 1])
+      AM_COND_IF([GL_COND_OBJ_DUP2], [
         gl_PREREQ_DUP2
-      fi
+      ])
       gl_UNISTD_MODULE_INDICATOR([dup2])
       gl_gnulib_enabled_dup2=true
     fi
@@ -932,7 +967,6 @@ AC_SUBST([LTALLOCA])
       AC_PROG_MKDIR_P
       gl_gnulib_enabled_dynarray=true
       func_gl_gnulib_m4code_37f71b604aa9c54446783d80f42fe547
-      func_gl_gnulib_m4code_21ee726a3540c09237a8e70c0baf7467
     fi
   }
   func_gl_gnulib_m4code_925677f0343de64b89a9f0c790b4104c ()
@@ -945,9 +979,8 @@ AC_SUBST([LTALLOCA])
   {
     if ! $gl_gnulib_enabled_fcntl; then
       gl_FUNC_FCNTL
-      if test $HAVE_FCNTL = 0 || test $REPLACE_FCNTL = 1; then
-        AC_LIBOBJ([fcntl])
-      fi
+      gl_CONDITIONAL([GL_COND_OBJ_FCNTL],
+                     [test $HAVE_FCNTL = 0 || test $REPLACE_FCNTL = 1])
       gl_FCNTL_MODULE_INDICATOR([fcntl])
       gl_gnulib_enabled_fcntl=true
       if test $HAVE_FCNTL = 0 || test $REPLACE_FCNTL = 1; then
@@ -964,14 +997,26 @@ AC_SUBST([LTALLOCA])
       gl_gnulib_enabled_43fe87a341d9b4b93c47c3ad819a5239=true
     fi
   }
+  func_gl_gnulib_m4code_7be38c8cf2027003f573b80556d26ff2 ()
+  {
+    if ! $gl_gnulib_enabled_7be38c8cf2027003f573b80556d26ff2; then
+      gl_FINDPROG_IN
+      gl_gnulib_enabled_7be38c8cf2027003f573b80556d26ff2=true
+      func_gl_gnulib_m4code_access
+      func_gl_gnulib_m4code_6da965dc4d3aa4f87d68116dce96f1a5
+      func_gl_gnulib_m4code_stat
+      func_gl_gnulib_m4code_f9850631dca91859e9cddac9359921c0
+    fi
+  }
   func_gl_gnulib_m4code_getdtablesize ()
   {
     if ! $gl_gnulib_enabled_getdtablesize; then
       gl_FUNC_GETDTABLESIZE
-      if test $HAVE_GETDTABLESIZE = 0 || test $REPLACE_GETDTABLESIZE = 1; then
-        AC_LIBOBJ([getdtablesize])
+      gl_CONDITIONAL([GL_COND_OBJ_GETDTABLESIZE],
+                     [test $HAVE_GETDTABLESIZE = 0 || test $REPLACE_GETDTABLESIZE = 1])
+      AM_COND_IF([GL_COND_OBJ_GETDTABLESIZE], [
         gl_PREREQ_GETDTABLESIZE
-      fi
+      ])
       gl_UNISTD_MODULE_INDICATOR([getdtablesize])
       gl_gnulib_enabled_getdtablesize=true
     fi
@@ -981,9 +1026,8 @@ AC_SUBST([LTALLOCA])
     if ! $gl_gnulib_enabled_getrandom; then
       AC_REQUIRE([AC_CANONICAL_HOST])
       gl_FUNC_GETRANDOM
-      if test $HAVE_GETRANDOM = 0 || test $REPLACE_GETRANDOM = 1; then
-        AC_LIBOBJ([getrandom])
-      fi
+      gl_CONDITIONAL([GL_COND_OBJ_GETRANDOM],
+                     [test $HAVE_GETRANDOM = 0 || test $REPLACE_GETRANDOM = 1])
       gl_SYS_RANDOM_MODULE_INDICATOR([getrandom])
       gl_gnulib_enabled_getrandom=true
       func_gl_gnulib_m4code_sys_random
@@ -1047,21 +1091,14 @@ AC_SUBST([LTALLOCA])
       gl_gnulib_enabled_dbdf22868a5367f28bf18e0013ac6f8f=true
     fi
   }
-  func_gl_gnulib_m4code_21ee726a3540c09237a8e70c0baf7467 ()
-  {
-    if ! $gl_gnulib_enabled_21ee726a3540c09237a8e70c0baf7467; then
-      gl___INLINE
-      gl_gnulib_enabled_21ee726a3540c09237a8e70c0baf7467=true
-    fi
-  }
   func_gl_gnulib_m4code_localeconv ()
   {
     if ! $gl_gnulib_enabled_localeconv; then
       gl_FUNC_LOCALECONV
-      if test $REPLACE_LOCALECONV = 1; then
-        AC_LIBOBJ([localeconv])
+      gl_CONDITIONAL([GL_COND_OBJ_LOCALECONV], [test $REPLACE_LOCALECONV = 1])
+      AM_COND_IF([GL_COND_OBJ_LOCALECONV], [
         gl_PREREQ_LOCALECONV
-      fi
+      ])
       gl_LOCALE_MODULE_INDICATOR([localeconv])
       gl_gnulib_enabled_localeconv=true
     fi
@@ -1070,9 +1107,7 @@ AC_SUBST([LTALLOCA])
   {
     if ! $gl_gnulib_enabled_log; then
       AC_REQUIRE([gl_FUNC_LOG])
-      if test $REPLACE_LOG = 1; then
-        AC_LIBOBJ([log])
-      fi
+      gl_CONDITIONAL([GL_COND_OBJ_LOG], [test $REPLACE_LOG = 1])
       gl_MATH_MODULE_INDICATOR([log])
       gl_gnulib_enabled_log=true
     fi
@@ -1081,15 +1116,16 @@ AC_SUBST([LTALLOCA])
   {
     if ! $gl_gnulib_enabled_mbrtowc; then
       gl_FUNC_MBRTOWC
-      if test $HAVE_MBRTOWC = 0 || test $REPLACE_MBRTOWC = 1; then
-        AC_LIBOBJ([mbrtowc])
+      gl_CONDITIONAL([GL_COND_OBJ_MBRTOWC],
+                     [test $HAVE_MBRTOWC = 0 || test $REPLACE_MBRTOWC = 1])
+      AM_COND_IF([GL_COND_OBJ_MBRTOWC], [
         if test $REPLACE_MBSTATE_T = 1; then
           AC_LIBOBJ([lc-charset-dispatch])
           AC_LIBOBJ([mbtowc-lock])
           gl_PREREQ_MBTOWC_LOCK
         fi
         gl_PREREQ_MBRTOWC
-      fi
+      ])
       gl_WCHAR_MODULE_INDICATOR([mbrtowc])
       gl_gnulib_enabled_mbrtowc=true
       if { test $HAVE_MBRTOWC = 0 || test $REPLACE_MBRTOWC = 1; } && test $REPLACE_MBSTATE_T = 0; then
@@ -1107,10 +1143,11 @@ AC_SUBST([LTALLOCA])
   {
     if ! $gl_gnulib_enabled_mbsinit; then
       gl_FUNC_MBSINIT
-      if test $HAVE_MBSINIT = 0 || test $REPLACE_MBSINIT = 1; then
-        AC_LIBOBJ([mbsinit])
+      gl_CONDITIONAL([GL_COND_OBJ_MBSINIT],
+                     [test $HAVE_MBSINIT = 0 || test $REPLACE_MBSINIT = 1])
+      AM_COND_IF([GL_COND_OBJ_MBSINIT], [
         gl_PREREQ_MBSINIT
-      fi
+      ])
       gl_WCHAR_MODULE_INDICATOR([mbsinit])
       gl_gnulib_enabled_mbsinit=true
       if test $HAVE_MBSINIT = 0 || test $REPLACE_MBSINIT = 1; then
@@ -1122,10 +1159,11 @@ AC_SUBST([LTALLOCA])
   {
     if ! $gl_gnulib_enabled_mbtowc; then
       gl_FUNC_MBTOWC
-      if test $HAVE_MBTOWC = 0 || test $REPLACE_MBTOWC = 1; then
-        AC_LIBOBJ([mbtowc])
+      gl_CONDITIONAL([GL_COND_OBJ_MBTOWC],
+                     [test $HAVE_MBTOWC = 0 || test $REPLACE_MBTOWC = 1])
+      AM_COND_IF([GL_COND_OBJ_MBTOWC], [
         gl_PREREQ_MBTOWC
-      fi
+      ])
       gl_STDLIB_MODULE_INDICATOR([mbtowc])
       gl_gnulib_enabled_mbtowc=true
       if test $HAVE_MBTOWC = 0 || test $REPLACE_MBTOWC = 1; then
@@ -1137,10 +1175,10 @@ AC_SUBST([LTALLOCA])
   {
     if ! $gl_gnulib_enabled_memchr; then
       gl_FUNC_MEMCHR
-      if test $REPLACE_MEMCHR = 1; then
-        AC_LIBOBJ([memchr])
+      gl_CONDITIONAL([GL_COND_OBJ_MEMCHR], [test $REPLACE_MEMCHR = 1])
+      AM_COND_IF([GL_COND_OBJ_MEMCHR], [
         gl_PREREQ_MEMCHR
-      fi
+      ])
       gl_STRING_MODULE_INDICATOR([memchr])
       gl_gnulib_enabled_memchr=true
     fi
@@ -1149,10 +1187,10 @@ AC_SUBST([LTALLOCA])
   {
     if ! $gl_gnulib_enabled_mempcpy; then
       gl_FUNC_MEMPCPY
-      if test $HAVE_MEMPCPY = 0; then
-        AC_LIBOBJ([mempcpy])
+      gl_CONDITIONAL([GL_COND_OBJ_MEMPCPY], [test $HAVE_MEMPCPY = 0])
+      AM_COND_IF([GL_COND_OBJ_MEMPCPY], [
         gl_PREREQ_MEMPCPY
-      fi
+      ])
       gl_STRING_MODULE_INDICATOR([mempcpy])
       gl_gnulib_enabled_mempcpy=true
     fi
@@ -1167,9 +1205,6 @@ AC_SUBST([LTALLOCA])
       fi
       gl_TIME_MODULE_INDICATOR([mktime])
       gl_gnulib_enabled_mktime=true
-      if test $REPLACE_MKTIME = 1; then
-        func_gl_gnulib_m4code_21ee726a3540c09237a8e70c0baf7467
-      fi
       if test $REPLACE_MKTIME = 1; then
         func_gl_gnulib_m4code_time_r
       fi
@@ -1187,6 +1222,15 @@ AC_SUBST([LTALLOCA])
       func_gl_gnulib_m4code_mktime
     fi
   }
+  func_gl_gnulib_m4code_netinet_in ()
+  {
+    if ! $gl_gnulib_enabled_netinet_in; then
+      gl_HEADER_NETINET_IN
+      gl_CONDITIONAL_HEADER([netinet/in.h])
+      AC_PROG_MKDIR_P
+      gl_gnulib_enabled_netinet_in=true
+    fi
+  }
   func_gl_gnulib_m4code_pathmax ()
   {
     if ! $gl_gnulib_enabled_pathmax; then
@@ -1194,14 +1238,39 @@ AC_SUBST([LTALLOCA])
       gl_gnulib_enabled_pathmax=true
     fi
   }
+  func_gl_gnulib_m4code_332607f759618fb73dfc3076748afea7 ()
+  {
+    if ! $gl_gnulib_enabled_332607f759618fb73dfc3076748afea7; then
+      gl_POSIX_SPAWN
+      gl_CONDITIONAL([GL_COND_OBJ_SPAWNI],
+                     [test $HAVE_POSIX_SPAWN = 0 || test $REPLACE_POSIX_SPAWN = 1])
+      AM_COND_IF([GL_COND_OBJ_SPAWNI], [
+        gl_PREREQ_POSIX_SPAWN_INTERNAL
+      ])
+      gl_gnulib_enabled_332607f759618fb73dfc3076748afea7=true
+      if test $HAVE_POSIX_SPAWN = 0; then
+        func_gl_gnulib_m4code_6da965dc4d3aa4f87d68116dce96f1a5
+      fi
+      func_gl_gnulib_m4code_dup2
+      if test $HAVE_POSIX_SPAWN = 0; then
+        func_gl_gnulib_m4code_7be38c8cf2027003f573b80556d26ff2
+      fi
+      func_gl_gnulib_m4code_cdeb0f2aaf9d280baa6526bfa1b07f70
+      func_gl_gnulib_m4code_strchrnul
+      if test $HAVE_POSIX_SPAWN = 0; then
+        func_gl_gnulib_m4code_fd43d02c899a251eacc999baf40b238e
+      fi
+    fi
+  }
   func_gl_gnulib_m4code_raise ()
   {
     if ! $gl_gnulib_enabled_raise; then
       gl_FUNC_RAISE
-      if test $HAVE_RAISE = 0 || test $REPLACE_RAISE = 1; then
-        AC_LIBOBJ([raise])
+      gl_CONDITIONAL([GL_COND_OBJ_RAISE],
+                     [test $HAVE_RAISE = 0 || test $REPLACE_RAISE = 1])
+      AM_COND_IF([GL_COND_OBJ_RAISE], [
         gl_PREREQ_RAISE
-      fi
+      ])
       gl_SIGNAL_MODULE_INDICATOR([raise])
       gl_gnulib_enabled_raise=true
     fi
@@ -1210,10 +1279,10 @@ AC_SUBST([LTALLOCA])
   {
     if ! $gl_gnulib_enabled_rawmemchr; then
       gl_FUNC_RAWMEMCHR
-      if test $HAVE_RAWMEMCHR = 0; then
-        AC_LIBOBJ([rawmemchr])
+      gl_CONDITIONAL([GL_COND_OBJ_RAWMEMCHR], [test $HAVE_RAWMEMCHR = 0])
+      AM_COND_IF([GL_COND_OBJ_RAWMEMCHR], [
         gl_PREREQ_RAWMEMCHR
-      fi
+      ])
       gl_STRING_MODULE_INDICATOR([rawmemchr])
       gl_gnulib_enabled_rawmemchr=true
     fi
@@ -1222,7 +1291,7 @@ AC_SUBST([LTALLOCA])
   {
     if ! $gl_gnulib_enabled_61bcaca76b3e6f9ae55d57a1c3193bc4; then
       gl_FUNC_REALLOC_POSIX
-      if test $REPLACE_REALLOC = 1; then
+      if test $REPLACE_REALLOC_FOR_REALLOC_POSIX = 1; then
         AC_LIBOBJ([realloc])
       fi
       gl_STDLIB_MODULE_INDICATOR([realloc-posix])
@@ -1233,9 +1302,8 @@ AC_SUBST([LTALLOCA])
   {
     if ! $gl_gnulib_enabled_round; then
       gl_FUNC_ROUND
-      if test $HAVE_ROUND = 0 || test $REPLACE_ROUND = 1; then
-        AC_LIBOBJ([round])
-      fi
+      gl_CONDITIONAL([GL_COND_OBJ_ROUND],
+                     [test $HAVE_ROUND = 0 || test $REPLACE_ROUND = 1])
       gl_MATH_MODULE_INDICATOR([round])
       gl_gnulib_enabled_round=true
     fi
@@ -1252,7 +1320,6 @@ AC_SUBST([LTALLOCA])
       AC_PROG_MKDIR_P
       gl_gnulib_enabled_scratch_buffer=true
       func_gl_gnulib_m4code_37f71b604aa9c54446783d80f42fe547
-      func_gl_gnulib_m4code_21ee726a3540c09237a8e70c0baf7467
       func_gl_gnulib_m4code_61bcaca76b3e6f9ae55d57a1c3193bc4
     fi
   }
@@ -1267,23 +1334,27 @@ AC_SUBST([LTALLOCA])
   {
     if ! $gl_gnulib_enabled_e7e881d32ca02f1c997b13c737c64bbd; then
       gl_FUNC_SETLOCALE_NULL
-      if test $SETLOCALE_NULL_ALL_MTSAFE = 0 || test $SETLOCALE_NULL_ONE_MTSAFE = 0; then
-        AC_LIBOBJ([setlocale-lock])
+      gl_CONDITIONAL([GL_COND_OBJ_SETLOCALE_LOCK],
+                     [test $SETLOCALE_NULL_ALL_MTSAFE = 0 || test $SETLOCALE_NULL_ONE_MTSAFE = 0])
+      AM_COND_IF([GL_COND_OBJ_SETLOCALE_LOCK], [
         gl_PREREQ_SETLOCALE_LOCK
-      fi
+      ])
       gl_LOCALE_MODULE_INDICATOR([setlocale_null])
       gl_gnulib_enabled_e7e881d32ca02f1c997b13c737c64bbd=true
     fi
   }
+  func_gl_gnulib_m4code_cdeb0f2aaf9d280baa6526bfa1b07f70 ()
+  {
+    if ! $gl_gnulib_enabled_cdeb0f2aaf9d280baa6526bfa1b07f70; then
+      gl_SH_FILENAME
+      gl_gnulib_enabled_cdeb0f2aaf9d280baa6526bfa1b07f70=true
+    fi
+  }
   func_gl_gnulib_m4code_signbit ()
   {
     if ! $gl_gnulib_enabled_signbit; then
       gl_SIGNBIT
-      if test $REPLACE_SIGNBIT = 1; then
-        AC_LIBOBJ([signbitf])
-        AC_LIBOBJ([signbitd])
-        AC_LIBOBJ([signbitl])
-      fi
+      gl_CONDITIONAL([GL_COND_OBJ_SIGNBIT3], [test $REPLACE_SIGNBIT = 1])
       gl_MATH_MODULE_INDICATOR([signbit])
       gl_gnulib_enabled_signbit=true
       if test $REPLACE_SIGNBIT = 1; then
@@ -1328,15 +1399,15 @@ AC_SUBST([LTALLOCA])
   {
     if ! $gl_gnulib_enabled_stat; then
       gl_FUNC_STAT
-      if test $REPLACE_STAT = 1; then
-        AC_LIBOBJ([stat])
+      gl_CONDITIONAL([GL_COND_OBJ_STAT], [test $REPLACE_STAT = 1])
+      AM_COND_IF([GL_COND_OBJ_STAT], [
         case "$host_os" in
           mingw*)
             AC_LIBOBJ([stat-w32])
             ;;
         esac
         gl_PREREQ_STAT
-      fi
+      ])
       gl_SYS_STAT_MODULE_INDICATOR([stat])
       gl_gnulib_enabled_stat=true
       if test $REPLACE_STAT = 1; then
@@ -1344,14 +1415,42 @@ AC_SUBST([LTALLOCA])
       fi
     fi
   }
+  func_gl_gnulib_m4code_stpcpy ()
+  {
+    if ! $gl_gnulib_enabled_stpcpy; then
+      gl_FUNC_STPCPY
+      gl_CONDITIONAL([GL_COND_OBJ_STPCPY], [test $HAVE_STPCPY = 0])
+      AM_COND_IF([GL_COND_OBJ_STPCPY], [
+        gl_PREREQ_STPCPY
+      ])
+      gl_STRING_MODULE_INDICATOR([stpcpy])
+      gl_gnulib_enabled_stpcpy=true
+    fi
+  }
+  func_gl_gnulib_m4code_strchrnul ()
+  {
+    if ! $gl_gnulib_enabled_strchrnul; then
+      gl_FUNC_STRCHRNUL
+      gl_CONDITIONAL([GL_COND_OBJ_STRCHRNUL],
+                     [test $HAVE_STRCHRNUL = 0 || test $REPLACE_STRCHRNUL = 1])
+      AM_COND_IF([GL_COND_OBJ_STRCHRNUL], [
+        gl_PREREQ_STRCHRNUL
+      ])
+      gl_STRING_MODULE_INDICATOR([strchrnul])
+      gl_gnulib_enabled_strchrnul=true
+      if test $HAVE_STRCHRNUL = 0 || test $REPLACE_STRCHRNUL = 1; then
+        func_gl_gnulib_m4code_rawmemchr
+      fi
+    fi
+  }
   func_gl_gnulib_m4code_f9850631dca91859e9cddac9359921c0 ()
   {
     if ! $gl_gnulib_enabled_f9850631dca91859e9cddac9359921c0; then
       gl_FUNC_STRDUP_POSIX
-      if test $REPLACE_STRDUP = 1; then
-        AC_LIBOBJ([strdup])
+      gl_CONDITIONAL([GL_COND_OBJ_STRDUP], [test $REPLACE_STRDUP = 1])
+      AM_COND_IF([GL_COND_OBJ_STRDUP], [
         gl_PREREQ_STRDUP
-      fi
+      ])
       gl_STRING_MODULE_INDICATOR([strdup])
       gl_gnulib_enabled_f9850631dca91859e9cddac9359921c0=true
     fi
@@ -1378,17 +1477,17 @@ AC_SUBST([LTALLOCA])
       gl_MODULE_INDICATOR([tempname])
       gl_gnulib_enabled_tempname=true
       func_gl_gnulib_m4code_getrandom
-      func_gl_gnulib_m4code_21ee726a3540c09237a8e70c0baf7467
     fi
   }
   func_gl_gnulib_m4code_time_r ()
   {
     if ! $gl_gnulib_enabled_time_r; then
       gl_TIME_R
-      if test $HAVE_LOCALTIME_R = 0 || test $REPLACE_LOCALTIME_R = 1; then
-        AC_LIBOBJ([time_r])
+      gl_CONDITIONAL([GL_COND_OBJ_TIME_R],
+                     [test $HAVE_LOCALTIME_R = 0 || test $REPLACE_LOCALTIME_R = 1])
+      AM_COND_IF([GL_COND_OBJ_TIME_R], [
         gl_PREREQ_TIME_R
-      fi
+      ])
       gl_TIME_MODULE_INDICATOR([time_r])
       gl_gnulib_enabled_time_r=true
     fi
@@ -1397,10 +1496,11 @@ AC_SUBST([LTALLOCA])
   {
     if ! $gl_gnulib_enabled_timegm; then
       gl_FUNC_TIMEGM
-      if test $HAVE_TIMEGM = 0 || test $REPLACE_TIMEGM = 1; then
-        AC_LIBOBJ([timegm])
+      gl_CONDITIONAL([GL_COND_OBJ_TIMEGM],
+                     [test $HAVE_TIMEGM = 0 || test $REPLACE_TIMEGM = 1])
+      AM_COND_IF([GL_COND_OBJ_TIMEGM], [
         gl_PREREQ_TIMEGM
-      fi
+      ])
       gl_TIME_MODULE_INDICATOR([timegm])
       gl_gnulib_enabled_timegm=true
       if test $HAVE_TIMEGM = 0 || test $REPLACE_TIMEGM = 1; then
@@ -1415,9 +1515,7 @@ AC_SUBST([LTALLOCA])
   {
     if ! $gl_gnulib_enabled_tzset; then
       gl_FUNC_TZSET
-      if test $REPLACE_TZSET = 1; then
-        AC_LIBOBJ([tzset])
-      fi
+      gl_CONDITIONAL([GL_COND_OBJ_TZSET], [test $REPLACE_TZSET = 1])
       gl_TIME_MODULE_INDICATOR([tzset])
       gl_gnulib_enabled_tzset=true
     fi
@@ -1426,10 +1524,11 @@ AC_SUBST([LTALLOCA])
   {
     if ! $gl_gnulib_enabled_unsetenv; then
       gl_FUNC_UNSETENV
-      if test $HAVE_UNSETENV = 0 || test $REPLACE_UNSETENV = 1; then
-        AC_LIBOBJ([unsetenv])
+      gl_CONDITIONAL([GL_COND_OBJ_UNSETENV],
+                     [test $HAVE_UNSETENV = 0 || test $REPLACE_UNSETENV = 1])
+      AM_COND_IF([GL_COND_OBJ_UNSETENV], [
         gl_PREREQ_UNSETENV
-      fi
+      ])
       gl_STDLIB_MODULE_INDICATOR([unsetenv])
       gl_gnulib_enabled_unsetenv=true
     fi
@@ -1448,10 +1547,11 @@ AC_SUBST([LTALLOCA])
   {
     if ! $gl_gnulib_enabled_wcrtomb; then
       gl_FUNC_WCRTOMB
-      if test $HAVE_WCRTOMB = 0 || test $REPLACE_WCRTOMB = 1; then
-        AC_LIBOBJ([wcrtomb])
+      gl_CONDITIONAL([GL_COND_OBJ_WCRTOMB],
+                     [test $HAVE_WCRTOMB = 0 || test $REPLACE_WCRTOMB = 1])
+      AM_COND_IF([GL_COND_OBJ_WCRTOMB], [
         gl_PREREQ_WCRTOMB
-      fi
+      ])
       gl_WCHAR_MODULE_INDICATOR([wcrtomb])
       gl_gnulib_enabled_wcrtomb=true
       if test $HAVE_WCRTOMB = 0 || test $REPLACE_WCRTOMB = 1; then
@@ -1464,9 +1564,20 @@ AC_SUBST([LTALLOCA])
     if ! $gl_gnulib_enabled_3dcce957eadc896e63ab5f137947b410; then
       gl_WCTYPE_H
       gl_WCTYPE_H_REQUIRE_DEFAULTS
+      AC_PROG_MKDIR_P
       gl_gnulib_enabled_3dcce957eadc896e63ab5f137947b410=true
     fi
   }
+  func_gl_gnulib_m4code_fd43d02c899a251eacc999baf40b238e ()
+  {
+    if ! $gl_gnulib_enabled_fd43d02c899a251eacc999baf40b238e; then
+      AC_REQUIRE([AC_CANONICAL_HOST])
+      gl_CONDITIONAL([GL_COND_OBJ_WINDOWS_SPAWN],
+                     [case "$host_os" in mingw*) true;; *) false;; esac])
+      gl_gnulib_enabled_fd43d02c899a251eacc999baf40b238e=true
+      func_gl_gnulib_m4code_7be38c8cf2027003f573b80556d26ff2
+    fi
+  }
   func_gl_gnulib_m4code_xsize ()
   {
     if ! $gl_gnulib_enabled_xsize; then
@@ -1478,9 +1589,6 @@ AC_SUBST([LTALLOCA])
   if test $HAVE_CANONICALIZE_FILE_NAME = 0 || test $REPLACE_CANONICALIZE_FILE_NAME = 1; then
     func_gl_gnulib_m4code_925677f0343de64b89a9f0c790b4104c
   fi
-  if test $HAVE_CANONICALIZE_FILE_NAME = 0 || test $REPLACE_CANONICALIZE_FILE_NAME = 1; then
-    func_gl_gnulib_m4code_21ee726a3540c09237a8e70c0baf7467
-  fi
   if test $HAVE_CANONICALIZE_FILE_NAME = 0 || test $REPLACE_CANONICALIZE_FILE_NAME = 1; then
     func_gl_gnulib_m4code_mempcpy
   fi
@@ -1529,6 +1637,12 @@ AC_SUBST([LTALLOCA])
   if test $HAVE_GETADDRINFO = 0 || test $REPLACE_GETADDRINFO = 1; then
     func_gl_gnulib_m4code_sockets
   fi
+  if test $HAVE_INET_NTOP = 0 || test $REPLACE_INET_NTOP = 1; then
+    func_gl_gnulib_m4code_netinet_in
+  fi
+  if test $HAVE_INET_PTON = 0 || test $REPLACE_INET_PTON = 1; then
+    func_gl_gnulib_m4code_netinet_in
+  fi
   if test $REPLACE_ISFINITE = 1; then
     func_gl_gnulib_m4code_b1df7117b479d2da59d76deba468ee21
   fi
@@ -1580,6 +1694,9 @@ AC_SUBST([LTALLOCA])
   if test $HAVE_POLL = 0 || test $REPLACE_POLL = 1; then
     func_gl_gnulib_m4code_sockets
   fi
+  if test $HAVE_POSIX_SPAWN = 0 || test $REPLACE_POSIX_SPAWN = 1; then
+    func_gl_gnulib_m4code_332607f759618fb73dfc3076748afea7
+  fi
   if test $HAVE_READLINK = 0 || test $REPLACE_READLINK = 1; then
     func_gl_gnulib_m4code_stat
   fi
@@ -1592,9 +1709,6 @@ AC_SUBST([LTALLOCA])
   if test $ac_use_included_regex = yes; then
     func_gl_gnulib_m4code_dynarray
   fi
-  if test $ac_use_included_regex = yes; then
-    func_gl_gnulib_m4code_21ee726a3540c09237a8e70c0baf7467
-  fi
   if test $ac_use_included_regex = yes; then
     func_gl_gnulib_m4code_mbrtowc
   fi
@@ -1647,17 +1761,20 @@ AC_SUBST([LTALLOCA])
     func_gl_gnulib_m4code_raise
   fi
   m4_pattern_allow([^gl_GNULIB_ENABLED_])
+  AM_CONDITIONAL([gl_GNULIB_ENABLED_access], [$gl_gnulib_enabled_access])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_alloca], [$gl_gnulib_enabled_alloca])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_assure], [$gl_gnulib_enabled_assure])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_btowc], [$gl_gnulib_enabled_btowc])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_37f71b604aa9c54446783d80f42fe547], [$gl_gnulib_enabled_37f71b604aa9c54446783d80f42fe547])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_chdir], [$gl_gnulib_enabled_chdir])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_cloexec], [$gl_gnulib_enabled_cloexec])
+  AM_CONDITIONAL([gl_GNULIB_ENABLED_6da965dc4d3aa4f87d68116dce96f1a5], [$gl_gnulib_enabled_6da965dc4d3aa4f87d68116dce96f1a5])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_dup2], [$gl_gnulib_enabled_dup2])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_dynarray], [$gl_gnulib_enabled_dynarray])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_925677f0343de64b89a9f0c790b4104c], [$gl_gnulib_enabled_925677f0343de64b89a9f0c790b4104c])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_fcntl], [$gl_gnulib_enabled_fcntl])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_43fe87a341d9b4b93c47c3ad819a5239], [$gl_gnulib_enabled_43fe87a341d9b4b93c47c3ad819a5239])
+  AM_CONDITIONAL([gl_GNULIB_ENABLED_7be38c8cf2027003f573b80556d26ff2], [$gl_gnulib_enabled_7be38c8cf2027003f573b80556d26ff2])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_getdtablesize], [$gl_gnulib_enabled_getdtablesize])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_getrandom], [$gl_gnulib_enabled_getrandom])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36], [$gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36])
@@ -1666,7 +1783,6 @@ AC_SUBST([LTALLOCA])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_b1df7117b479d2da59d76deba468ee21], [$gl_gnulib_enabled_b1df7117b479d2da59d76deba468ee21])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_3f0e593033d1fc2c127581960f641b66], [$gl_gnulib_enabled_3f0e593033d1fc2c127581960f641b66])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_dbdf22868a5367f28bf18e0013ac6f8f], [$gl_gnulib_enabled_dbdf22868a5367f28bf18e0013ac6f8f])
-  AM_CONDITIONAL([gl_GNULIB_ENABLED_21ee726a3540c09237a8e70c0baf7467], [$gl_gnulib_enabled_21ee726a3540c09237a8e70c0baf7467])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_localeconv], [$gl_gnulib_enabled_localeconv])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_log], [$gl_gnulib_enabled_log])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_mbrtowc], [$gl_gnulib_enabled_mbrtowc])
@@ -1676,7 +1792,9 @@ AC_SUBST([LTALLOCA])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_mempcpy], [$gl_gnulib_enabled_mempcpy])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_mktime], [$gl_gnulib_enabled_mktime])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_5264294aa0a5557541b53c8c741f7f31], [$gl_gnulib_enabled_5264294aa0a5557541b53c8c741f7f31])
+  AM_CONDITIONAL([gl_GNULIB_ENABLED_netinet_in], [$gl_gnulib_enabled_netinet_in])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_pathmax], [$gl_gnulib_enabled_pathmax])
+  AM_CONDITIONAL([gl_GNULIB_ENABLED_332607f759618fb73dfc3076748afea7], [$gl_gnulib_enabled_332607f759618fb73dfc3076748afea7])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_raise], [$gl_gnulib_enabled_raise])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_rawmemchr], [$gl_gnulib_enabled_rawmemchr])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_61bcaca76b3e6f9ae55d57a1c3193bc4], [$gl_gnulib_enabled_61bcaca76b3e6f9ae55d57a1c3193bc4])
@@ -1685,11 +1803,14 @@ AC_SUBST([LTALLOCA])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_scratch_buffer], [$gl_gnulib_enabled_scratch_buffer])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_servent], [$gl_gnulib_enabled_servent])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_e7e881d32ca02f1c997b13c737c64bbd], [$gl_gnulib_enabled_e7e881d32ca02f1c997b13c737c64bbd])
+  AM_CONDITIONAL([gl_GNULIB_ENABLED_cdeb0f2aaf9d280baa6526bfa1b07f70], [$gl_gnulib_enabled_cdeb0f2aaf9d280baa6526bfa1b07f70])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_signbit], [$gl_gnulib_enabled_signbit])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_size_max], [$gl_gnulib_enabled_size_max])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_snprintf], [$gl_gnulib_enabled_snprintf])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_sockets], [$gl_gnulib_enabled_sockets])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_stat], [$gl_gnulib_enabled_stat])
+  AM_CONDITIONAL([gl_GNULIB_ENABLED_stpcpy], [$gl_gnulib_enabled_stpcpy])
+  AM_CONDITIONAL([gl_GNULIB_ENABLED_strchrnul], [$gl_gnulib_enabled_strchrnul])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_f9850631dca91859e9cddac9359921c0], [$gl_gnulib_enabled_f9850631dca91859e9cddac9359921c0])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_streq], [$gl_gnulib_enabled_streq])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_sys_random], [$gl_gnulib_enabled_sys_random])
@@ -1701,6 +1822,7 @@ AC_SUBST([LTALLOCA])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_vasnprintf], [$gl_gnulib_enabled_vasnprintf])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_wcrtomb], [$gl_gnulib_enabled_wcrtomb])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_3dcce957eadc896e63ab5f137947b410], [$gl_gnulib_enabled_3dcce957eadc896e63ab5f137947b410])
+  AM_CONDITIONAL([gl_GNULIB_ENABLED_fd43d02c899a251eacc999baf40b238e], [$gl_gnulib_enabled_fd43d02c899a251eacc999baf40b238e])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_xsize], [$gl_gnulib_enabled_xsize])
   # End of code from modules
   m4_ifval(gl_LIBSOURCES_LIST, [
@@ -1724,16 +1846,28 @@ AC_SUBST([LTALLOCA])
   AC_CONFIG_COMMANDS_PRE([
     gl_libobjs=
     gl_ltlibobjs=
+    gl_libobjdeps=
     if test -n "$gl_LIBOBJS"; then
       # Remove the extension.
+changequote(,)dnl
       sed_drop_objext='s/\.o$//;s/\.obj$//'
+      sed_dirname1='s,//*,/,g'
+      sed_dirname2='s,\(.\)/$,\1,'
+      sed_dirname3='s,^[^/]*$,.,'
+      sed_dirname4='s,\(.\)/[^/]*$,\1,'
+      sed_basename1='s,.*/,,'
+changequote([, ])dnl
       for i in `for i in $gl_LIBOBJS; do echo "$i"; done | sed -e "$sed_drop_objext" | sort | uniq`; do
         gl_libobjs="$gl_libobjs $i.$ac_objext"
         gl_ltlibobjs="$gl_ltlibobjs $i.lo"
+        i_dir=`echo "$i" | sed -e "$sed_dirname1" -e "$sed_dirname2" -e "$sed_dirname3" -e "$sed_dirname4"`
+        i_base=`echo "$i" | sed -e "$sed_basename1"`
+        gl_libobjdeps="$gl_libobjdeps $i_dir/\$(DEPDIR)/$i_base.Plo"
       done
     fi
     AC_SUBST([gl_LIBOBJS], [$gl_libobjs])
     AC_SUBST([gl_LTLIBOBJS], [$gl_ltlibobjs])
+    AC_SUBST([gl_LIBOBJDEPS], [$gl_libobjdeps])
   ])
   gltests_libdeps=
   gltests_ltlibdeps=
@@ -1746,6 +1880,7 @@ AC_SUBST([LTALLOCA])
   m4_pushdef([GL_MODULE_INDICATOR_PREFIX], [GL])
   gl_COMMON
   gl_source_base='tests'
+  gl_source_base_prefix=
 changequote(,)dnl
   gltests_WITNESS=IN_`echo "${PACKAGE-$PACKAGE_TARNAME}" | LC_ALL=C tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ | LC_ALL=C sed -e 's/[^A-Z0-9_]/_/g'`_GNULIB_TESTS
 changequote([, ])dnl
@@ -1775,17 +1910,30 @@ changequote([, ])dnl
   AC_CONFIG_COMMANDS_PRE([
     gltests_libobjs=
     gltests_ltlibobjs=
+    gltests_libobjdeps=
     if test -n "$gltests_LIBOBJS"; then
       # Remove the extension.
+changequote(,)dnl
       sed_drop_objext='s/\.o$//;s/\.obj$//'
+      sed_dirname1='s,//*,/,g'
+      sed_dirname2='s,\(.\)/$,\1,'
+      sed_dirname3='s,^[^/]*$,.,'
+      sed_dirname4='s,\(.\)/[^/]*$,\1,'
+      sed_basename1='s,.*/,,'
+changequote([, ])dnl
       for i in `for i in $gltests_LIBOBJS; do echo "$i"; done | sed -e "$sed_drop_objext" | sort | uniq`; do
         gltests_libobjs="$gltests_libobjs $i.$ac_objext"
         gltests_ltlibobjs="$gltests_ltlibobjs $i.lo"
+        i_dir=`echo "$i" | sed -e "$sed_dirname1" -e "$sed_dirname2" -e "$sed_dirname3" -e "$sed_dirname4"`
+        i_base=`echo "$i" | sed -e "$sed_basename1"`
+        gltests_libobjdeps="$gltests_libobjdeps $i_dir/\$(DEPDIR)/$i_base.Plo"
       done
     fi
     AC_SUBST([gltests_LIBOBJS], [$gltests_libobjs])
     AC_SUBST([gltests_LTLIBOBJS], [$gltests_ltlibobjs])
+    AC_SUBST([gltests_LIBOBJDEPS], [$gltests_libobjdeps])
   ])
+  AC_REQUIRE([gl_CC_GNULIB_WARNINGS])
 ])
 
 # Like AC_LIBOBJ, except that the module name goes
@@ -1859,6 +2007,7 @@ AC_DEFUN([gl_FILE_LIST], [
   lib/_Noreturn.h
   lib/accept.c
   lib/accept4.c
+  lib/access.c
   lib/alignof.h
   lib/alloca.c
   lib/alloca.in.h
@@ -1887,6 +2036,8 @@ AC_DEFUN([gl_FILE_LIST], [
   lib/cloexec.c
   lib/cloexec.h
   lib/close.c
+  lib/concat-filename.c
+  lib/concat-filename.h
   lib/connect.c
   lib/copysign.c
   lib/dirent.in.h
@@ -1903,6 +2054,8 @@ AC_DEFUN([gl_FILE_LIST], [
   lib/fd-hook.c
   lib/fd-hook.h
   lib/filename.h
+  lib/findprog-in.c
+  lib/findprog.h
   lib/flexmember.h
   lib/float+.h
   lib/float.c
@@ -1942,6 +2095,7 @@ AC_DEFUN([gl_FILE_LIST], [
   lib/idx.h
   lib/inet_ntop.c
   lib/inet_pton.c
+  lib/intprops-internal.h
   lib/intprops.h
   lib/inttypes.in.h
   lib/isfinite.c
@@ -2046,6 +2200,7 @@ AC_DEFUN([gl_FILE_LIST], [
   lib/safe-write.c
   lib/safe-write.h
   lib/same-inode.h
+  lib/sched.in.h
   lib/scratch_buffer.h
   lib/select.c
   lib/send.c
@@ -2065,6 +2220,10 @@ AC_DEFUN([gl_FILE_LIST], [
   lib/socket.c
   lib/sockets.c
   lib/sockets.h
+  lib/spawn.in.h
+  lib/spawn_int.h
+  lib/spawni.c
+  lib/spawnp.c
   lib/stat-time.c
   lib/stat-time.h
   lib/stat-w32.c
@@ -2072,10 +2231,16 @@ AC_DEFUN([gl_FILE_LIST], [
   lib/stat.c
   lib/stdalign.in.h
   lib/stdbool.in.h
+  lib/stdckdint.in.h
   lib/stddef.in.h
   lib/stdint.in.h
+  lib/stdio-read.c
+  lib/stdio-write.c
   lib/stdio.in.h
   lib/stdlib.in.h
+  lib/stpcpy.c
+  lib/strchrnul.c
+  lib/strchrnul.valgrind
   lib/strdup.c
   lib/streq.h
   lib/strftime.h
@@ -2118,6 +2283,8 @@ AC_DEFUN([gl_FILE_LIST], [
   lib/wctype-h.c
   lib/wctype.in.h
   lib/windows-initguard.h
+  lib/windows-spawn.c
+  lib/windows-spawn.h
   lib/write.c
   lib/xalloc-oversized.h
   lib/xsize.c
@@ -2126,6 +2293,7 @@ AC_DEFUN([gl_FILE_LIST], [
   m4/__inline.m4
   m4/absolute-header.m4
   m4/accept4.m4
+  m4/access.m4
   m4/alloca.m4
   m4/arpa_inet_h.m4
   m4/autobuild.m4
@@ -2144,6 +2312,7 @@ AC_DEFUN([gl_FILE_LIST], [
   m4/double-slash-root.m4
   m4/dup2.m4
   m4/duplocale.m4
+  m4/eaccess.m4
   m4/eealloc.m4
   m4/environ.m4
   m4/errno_h.m4
@@ -2155,6 +2324,7 @@ AC_DEFUN([gl_FILE_LIST], [
   m4/fcntl-o.m4
   m4/fcntl.m4
   m4/fcntl_h.m4
+  m4/findprog-in.m4
   m4/flexmember.m4
   m4/float_h.m4
   m4/flock.m4
@@ -2242,6 +2412,7 @@ AC_DEFUN([gl_FILE_LIST], [
   m4/pipe2.m4
   m4/poll.m4
   m4/poll_h.m4
+  m4/posix_spawn.m4
   m4/printf.m4
   m4/putenv.m4
   m4/raise.m4
@@ -2255,10 +2426,12 @@ AC_DEFUN([gl_FILE_LIST], [
   m4/round.m4
   m4/safe-read.m4
   m4/safe-write.m4
+  m4/sched_h.m4
   m4/select.m4
   m4/servent.m4
   m4/setenv.m4
   m4/setlocale_null.m4
+  m4/sh-filename.m4
   m4/signal_h.m4
   m4/signbit.m4
   m4/size_max.m4
@@ -2267,6 +2440,7 @@ AC_DEFUN([gl_FILE_LIST], [
   m4/sockets.m4
   m4/socklen.m4
   m4/sockpfaf.m4
+  m4/spawn_h.m4
   m4/ssize_t.m4
   m4/stat-time.m4
   m4/stat.m4
@@ -2278,6 +2452,8 @@ AC_DEFUN([gl_FILE_LIST], [
   m4/stdint_h.m4
   m4/stdio_h.m4
   m4/stdlib_h.m4
+  m4/stpcpy.m4
+  m4/strchrnul.m4
   m4/strdup.m4
   m4/string_h.m4
   m4/sys_file_h.m4
@@ -2300,6 +2476,7 @@ AC_DEFUN([gl_FILE_LIST], [
   m4/trunc.m4
   m4/tzset.m4
   m4/unistd_h.m4
+  m4/vararrays.m4
   m4/vasnprintf.m4
   m4/visibility.m4
   m4/vsnprintf.m4
diff --git a/m4/gnulib-tool.m4 b/m4/gnulib-tool.m4
index 3d56d83f1..8428901c3 100644
--- a/m4/gnulib-tool.m4
+++ b/m4/gnulib-tool.m4
@@ -1,5 +1,5 @@
-# gnulib-tool.m4 serial 2
-dnl Copyright (C) 2004-2005, 2009-2021 Free Software Foundation, Inc.
+# gnulib-tool.m4 serial 4
+dnl Copyright (C) 2004-2005, 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
@@ -44,6 +44,12 @@ AC_DEFUN([gl_LGPL], [])
 dnl Usage: gl_MAKEFILE_NAME([FILENAME])
 AC_DEFUN([gl_MAKEFILE_NAME], [])
 
+dnl Usage: gl_TESTS_MAKEFILE_NAME([FILENAME])
+AC_DEFUN([gl_TESTS_MAKEFILE_NAME], [])
+
+dnl Usage: gl_AUTOMAKE_SUBDIR
+AC_DEFUN([gl_AUTOMAKE_SUBDIR], [])
+
 dnl Usage: gl_LIBTOOL
 AC_DEFUN([gl_LIBTOOL], [])
 
diff --git a/m4/host-cpu-c-abi.m4 b/m4/host-cpu-c-abi.m4
index 64e28b1d3..b9223241b 100644
--- a/m4/host-cpu-c-abi.m4
+++ b/m4/host-cpu-c-abi.m4
@@ -1,5 +1,5 @@
-# host-cpu-c-abi.m4 serial 14
-dnl Copyright (C) 2002-2021 Free Software Foundation, Inc.
+# host-cpu-c-abi.m4 serial 15
+dnl Copyright (C) 2002-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,
 dnl with or without modifications, as long as this notice is preserved.
@@ -382,6 +382,9 @@ EOF
 #ifndef __ia64__
 #undef __ia64__
 #endif
+#ifndef __loongarch64__
+#undef __loongarch64__
+#endif
 #ifndef __m68k__
 #undef __m68k__
 #endif
diff --git a/m4/hostent.m4 b/m4/hostent.m4
index f1390a32e..69fc5ac1a 100644
--- a/m4/hostent.m4
+++ b/m4/hostent.m4
@@ -1,5 +1,5 @@
 # hostent.m4 serial 4
-dnl Copyright (C) 2008, 2010-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2008, 2010-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/iconv.m4 b/m4/iconv.m4
index d0e61de26..2065c9772 100644
--- a/m4/iconv.m4
+++ b/m4/iconv.m4
@@ -1,5 +1,5 @@
-# iconv.m4 serial 24
-dnl Copyright (C) 2000-2002, 2007-2014, 2016-2021 Free Software Foundation,
+# iconv.m4 serial 26
+dnl Copyright (C) 2000-2002, 2007-2014, 2016-2022 Free Software Foundation,
 dnl Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -234,12 +234,6 @@ AC_DEFUN([AM_ICONV_LINK],
 
 dnl Define AM_ICONV using AC_DEFUN_ONCE, in order to avoid warnings like
 dnl "warning: AC_REQUIRE: `AM_ICONV' was expanded before it was required".
-dnl This is tricky because of the way 'aclocal' is implemented:
-dnl - It requires defining an auxiliary macro whose name ends in AC_DEFUN.
-dnl   Otherwise aclocal's initial scan pass would miss the macro definition.
-dnl - It requires a line break inside the AC_DEFUN_ONCE and AC_DEFUN expansions.
-dnl   Otherwise aclocal would emit many "Use of uninitialized value $1"
-dnl   warnings.
 AC_DEFUN_ONCE([AM_ICONV],
 [
   AM_ICONV_LINK
@@ -280,4 +274,20 @@ size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, si
        ICONV_CONST="const"
      fi
     ])
+
+  dnl A summary result, for those packages which want to print a summary at the
+  dnl end of the configuration.
+  if test "$am_func_iconv" = yes; then
+    if test -n "$LIBICONV"; then
+      am_cv_func_iconv_summary='yes, in libiconv'
+    else
+      am_cv_func_iconv_summary='yes, in libc'
+    fi
+  else
+    if test "$am_cv_func_iconv" = yes; then
+      am_cv_func_iconv_summary='not working, consider installing GNU libiconv'
+    else
+      am_cv_func_iconv_summary='no, consider installing GNU libiconv'
+    fi
+  fi
 ])
diff --git a/m4/iconv_h.m4 b/m4/iconv_h.m4
index 294098829..584656628 100644
--- a/m4/iconv_h.m4
+++ b/m4/iconv_h.m4
@@ -1,5 +1,5 @@
-# iconv_h.m4 serial 15
-dnl Copyright (C) 2007-2021 Free Software Foundation, Inc.
+# iconv_h.m4 serial 16
+dnl Copyright (C) 2007-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,
 dnl with or without modifications, as long as this notice is preserved.
@@ -8,8 +8,8 @@ AC_DEFUN_ONCE([gl_ICONV_H],
 [
   AC_REQUIRE([gl_ICONV_H_DEFAULTS])
 
-  dnl Execute this unconditionally, because ICONV_H may be set by other
-  dnl modules, after this code is executed.
+  dnl Execute this unconditionally, because GL_GENERATE_ICONV_H may be set to
+  dnl true by other modules, after this code is executed.
   gl_CHECK_NEXT_HEADERS([iconv.h])
 
   dnl Check for declarations of anything we want to poison if the
@@ -25,8 +25,7 @@ dnl Unconditionally enables the replacement of <iconv.h>.
 AC_DEFUN([gl_REPLACE_ICONV_H],
 [
   gl_ICONV_H_REQUIRE_DEFAULTS
-  ICONV_H='iconv.h'
-  AM_CONDITIONAL([GL_GENERATE_ICONV_H], [test -n "$ICONV_H"])
+  GL_GENERATE_ICONV_H=true
 ])
 
 # gl_ICONV_MODULE_INDICATOR([modulename])
@@ -60,13 +59,12 @@ AC_DEFUN([gl_ICONV_H_DEFAULTS],
   REPLACE_ICONV=0;      AC_SUBST([REPLACE_ICONV])
   REPLACE_ICONV_OPEN=0; AC_SUBST([REPLACE_ICONV_OPEN])
   REPLACE_ICONV_UTF=0;  AC_SUBST([REPLACE_ICONV_UTF])
-  ICONV_H='';           AC_SUBST([ICONV_H])
+  GL_GENERATE_ICONV_H=false
   m4_ifdef([gl_POSIXCHECK],
-    [ICONV_H='iconv.h'],
+    [GL_GENERATE_ICONV_H=true],
     [if m4_ifdef([gl_ANSI_CXX], [test "$CXX" != no], [false]); then
        dnl Override <fnmatch.h> always, to support the C++ GNULIB_NAMESPACE.
-       ICONV_H='iconv.h'
+       GL_GENERATE_ICONV_H=true
      fi
     ])
-  AM_CONDITIONAL([GL_GENERATE_ICONV_H], [test -n "$ICONV_H"])
 ])
diff --git a/m4/iconv_open-utf.m4 b/m4/iconv_open-utf.m4
index 68efaf9da..282c2b7e7 100644
--- a/m4/iconv_open-utf.m4
+++ b/m4/iconv_open-utf.m4
@@ -1,5 +1,5 @@
 # iconv_open-utf.m4 serial 4
-dnl Copyright (C) 2007-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2007-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/iconv_open.m4 b/m4/iconv_open.m4
index 61b6af487..1ed26cd82 100644
--- a/m4/iconv_open.m4
+++ b/m4/iconv_open.m4
@@ -1,5 +1,5 @@
 # iconv_open.m4 serial 16
-dnl Copyright (C) 2007-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2007-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/include_next.m4 b/m4/include_next.m4
index bdd542bc6..a9247f6f1 100644
--- a/m4/include_next.m4
+++ b/m4/include_next.m4
@@ -1,5 +1,5 @@
 # include_next.m4 serial 26
-dnl Copyright (C) 2006-2021 Free Software Foundation, Inc.
+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,
 dnl with or without modifications, as long as this notice is preserved.
@@ -193,9 +193,9 @@ AC_DEFUN([gl_NEXT_HEADERS_INTERNAL],
              if test AS_VAR_GET([gl_header_exists]) = yes; then
              AS_VAR_POPDEF([gl_header_exists])
             ])
-           gl_ABSOLUTE_HEADER_ONE(gl_HEADER_NAME)
-           AS_VAR_COPY([gl_header], [gl_cv_absolute_]AS_TR_SH(gl_HEADER_NAME))
-           AS_VAR_SET([gl_next_header], ['"'$gl_header'"'])
+          gl_ABSOLUTE_HEADER_ONE(gl_HEADER_NAME)
+          AS_VAR_COPY([gl_header], [gl_cv_absolute_]AS_TR_SH(gl_HEADER_NAME))
+          AS_VAR_SET([gl_next_header], ['"'$gl_header'"'])
           m4_if([$2], [check],
             [else
                AS_VAR_SET([gl_next_header], ['<'gl_HEADER_NAME'>'])
diff --git a/m4/inet_ntop.m4 b/m4/inet_ntop.m4
index 171f53ee7..c335cae7e 100644
--- a/m4/inet_ntop.m4
+++ b/m4/inet_ntop.m4
@@ -1,5 +1,5 @@
 # inet_ntop.m4 serial 21
-dnl Copyright (C) 2005-2006, 2008-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2005-2006, 2008-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/inet_pton.m4 b/m4/inet_pton.m4
index 197917910..9507296d3 100644
--- a/m4/inet_pton.m4
+++ b/m4/inet_pton.m4
@@ -1,5 +1,5 @@
 # inet_pton.m4 serial 19
-dnl Copyright (C) 2006, 2008-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2006, 2008-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/intdiv0.m4 b/m4/intdiv0.m4
new file mode 100644
index 000000000..289c4df5e
--- /dev/null
+++ b/m4/intdiv0.m4
@@ -0,0 +1,84 @@
+# intdiv0.m4 serial 3 (gettext-0.18)
+dnl Copyright (C) 2002, 2007-2010 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 From Bruno Haible.
+
+AC_DEFUN([gt_INTDIV0],
+[
+  AC_REQUIRE([AC_PROG_CC])dnl
+  AC_REQUIRE([AC_CANONICAL_HOST])dnl
+
+  AC_CACHE_CHECK([whether integer division by zero raises SIGFPE],
+    gt_cv_int_divbyzero_sigfpe,
+    [
+      gt_cv_int_divbyzero_sigfpe=
+changequote(,)dnl
+      case "$host_os" in
+        macos* | darwin[6-9]* | darwin[1-9][0-9]*)
+          # On MacOS X 10.2 or newer, just assume the same as when cross-
+          # compiling. If we were to perform the real test, 1 Crash Report
+          # dialog window would pop up.
+          case "$host_cpu" in
+            i[34567]86 | x86_64)
+              gt_cv_int_divbyzero_sigfpe="guessing yes" ;;
+          esac
+          ;;
+      esac
+changequote([,])dnl
+      if test -z "$gt_cv_int_divbyzero_sigfpe"; then
+        AC_TRY_RUN([
+#include <stdlib.h>
+#include <signal.h>
+
+static void
+sigfpe_handler (int sig)
+{
+  /* Exit with code 0 if SIGFPE, with code 1 if any other signal.  */
+  exit (sig != SIGFPE);
+}
+
+int x = 1;
+int y = 0;
+int z;
+int nan;
+
+int main ()
+{
+  signal (SIGFPE, sigfpe_handler);
+/* IRIX and AIX (when "xlc -qcheck" is used) yield signal SIGTRAP.  */
+#if (defined (__sgi) || defined (_AIX)) && defined (SIGTRAP)
+  signal (SIGTRAP, sigfpe_handler);
+#endif
+/* Linux/SPARC yields signal SIGILL.  */
+#if defined (__sparc__) && defined (__linux__)
+  signal (SIGILL, sigfpe_handler);
+#endif
+
+  z = x / y;
+  nan = y / y;
+  exit (1);
+}
+], [gt_cv_int_divbyzero_sigfpe=yes], [gt_cv_int_divbyzero_sigfpe=no],
+          [
+            # Guess based on the CPU.
+changequote(,)dnl
+            case "$host_cpu" in
+              alpha* | i[34567]86 | x86_64 | m68k | s390*)
+                gt_cv_int_divbyzero_sigfpe="guessing yes";;
+              *)
+                gt_cv_int_divbyzero_sigfpe="guessing no";;
+            esac
+changequote([,])dnl
+          ])
+      fi
+    ])
+  case "$gt_cv_int_divbyzero_sigfpe" in
+    *yes) value=1;;
+    *) value=0;;
+  esac
+  AC_DEFINE_UNQUOTED([INTDIV0_RAISES_SIGFPE], [$value],
+    [Define if integer division by zero raises signal SIGFPE.])
+])
diff --git a/m4/intl.m4 b/m4/intl.m4
new file mode 100644
index 000000000..335b23c20
--- /dev/null
+++ b/m4/intl.m4
@@ -0,0 +1,294 @@
+# intl.m4 serial 17 (gettext-0.18)
+dnl Copyright (C) 1995-2009 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
+dnl This file can can be used in projects which are not available under
+dnl the GNU General Public License or the GNU Library General Public
+dnl License but which still want to provide support for the GNU gettext
+dnl functionality.
+dnl Please note that the actual code of the GNU gettext library is covered
+dnl by the GNU Library General Public License, and the rest of the GNU
+dnl gettext package package is covered by the GNU General Public License.
+dnl They are *not* in the public domain.
+
+dnl Authors:
+dnl   Ulrich Drepper <drepper@cygnus.com>, 1995-2000.
+dnl   Bruno Haible <haible@clisp.cons.org>, 2000-2009.
+
+AC_PREREQ([2.52])
+
+dnl Checks for all prerequisites of the intl subdirectory,
+dnl except for INTL_LIBTOOL_SUFFIX_PREFIX (and possibly LIBTOOL), INTLOBJS,
+dnl            USE_INCLUDED_LIBINTL, BUILD_INCLUDED_LIBINTL.
+AC_DEFUN([AM_INTL_SUBDIR],
+[
+  AC_REQUIRE([AC_PROG_INSTALL])dnl
+  AC_REQUIRE([AM_PROG_MKDIR_P])dnl defined by automake
+  AC_REQUIRE([AC_PROG_CC])dnl
+  AC_REQUIRE([AC_CANONICAL_HOST])dnl
+  AC_REQUIRE([gt_GLIBC2])dnl
+  AC_REQUIRE([AC_PROG_RANLIB])dnl
+  AC_REQUIRE([gl_VISIBILITY])dnl
+  AC_REQUIRE([gt_INTL_SUBDIR_CORE])dnl
+  AC_REQUIRE([AC_TYPE_LONG_LONG_INT])dnl
+  AC_REQUIRE([gt_TYPE_WCHAR_T])dnl
+  AC_REQUIRE([gt_TYPE_WINT_T])dnl
+  AC_REQUIRE([gl_AC_HEADER_INTTYPES_H])
+  AC_REQUIRE([gt_TYPE_INTMAX_T])
+  AC_REQUIRE([gt_PRINTF_POSIX])
+  AC_REQUIRE([gl_GLIBC21])dnl
+  AC_REQUIRE([gl_XSIZE])dnl
+  AC_REQUIRE([gl_FCNTL_O_FLAGS])dnl
+  AC_REQUIRE([gt_INTL_MACOSX])dnl
+
+  dnl Support for automake's --enable-silent-rules.
+  case "$enable_silent_rules" in
+    yes) INTL_DEFAULT_VERBOSITY=0;;
+    no)  INTL_DEFAULT_VERBOSITY=1;;
+    *)   INTL_DEFAULT_VERBOSITY=1;;
+  esac
+  AC_SUBST([INTL_DEFAULT_VERBOSITY])
+
+  AC_CHECK_TYPE([ptrdiff_t], ,
+    [AC_DEFINE([ptrdiff_t], [long],
+       [Define as the type of the result of subtracting two pointers, if the system doesn't define it.])
+    ])
+  AC_CHECK_HEADERS([stddef.h stdlib.h string.h])
+  AC_CHECK_FUNCS([asprintf fwprintf newlocale putenv setenv setlocale \
+    snprintf strnlen wcslen wcsnlen mbrtowc wcrtomb])
+
+  dnl Use the _snprintf function only if it is declared (because on NetBSD it
+  dnl is defined as a weak alias of snprintf; we prefer to use the latter).
+  gt_CHECK_DECL(_snprintf, [#include <stdio.h>])
+  gt_CHECK_DECL(_snwprintf, [#include <stdio.h>])
+
+  dnl Use the *_unlocked functions only if they are declared.
+  dnl (because some of them were defined without being declared in Solaris
+  dnl 2.5.1 but were removed in Solaris 2.6, whereas we want binaries built
+  dnl on Solaris 2.5.1 to run on Solaris 2.6).
+  dnl Don't use AC_CHECK_DECLS because it isn't supported in autoconf-2.13.
+  gt_CHECK_DECL(getc_unlocked, [#include <stdio.h>])
+
+  case $gt_cv_func_printf_posix in
+    *yes) HAVE_POSIX_PRINTF=1 ;;
+    *) HAVE_POSIX_PRINTF=0 ;;
+  esac
+  AC_SUBST([HAVE_POSIX_PRINTF])
+  if test "$ac_cv_func_asprintf" = yes; then
+    HAVE_ASPRINTF=1
+  else
+    HAVE_ASPRINTF=0
+  fi
+  AC_SUBST([HAVE_ASPRINTF])
+  if test "$ac_cv_func_snprintf" = yes; then
+    HAVE_SNPRINTF=1
+  else
+    HAVE_SNPRINTF=0
+  fi
+  AC_SUBST([HAVE_SNPRINTF])
+  if test "$ac_cv_func_newlocale" = yes; then
+    HAVE_NEWLOCALE=1
+  else
+    HAVE_NEWLOCALE=0
+  fi
+  AC_SUBST([HAVE_NEWLOCALE])
+  if test "$ac_cv_func_wprintf" = yes; then
+    HAVE_WPRINTF=1
+  else
+    HAVE_WPRINTF=0
+  fi
+  AC_SUBST([HAVE_WPRINTF])
+
+  AM_LANGINFO_CODESET
+  gt_LC_MESSAGES
+
+  dnl Compilation on mingw and Cygwin needs special Makefile rules, because
+  dnl 1. when we install a shared library, we must arrange to export
+  dnl    auxiliary pointer variables for every exported variable,
+  dnl 2. when we install a shared library and a static library simultaneously,
+  dnl    the include file specifies __declspec(dllimport) and therefore we
+  dnl    must arrange to define the auxiliary pointer variables for the
+  dnl    exported variables _also_ in the static library.
+  if test "$enable_shared" = yes; then
+    case "$host_os" in
+      mingw* | cygwin*) is_woe32dll=yes ;;
+      *) is_woe32dll=no ;;
+    esac
+  else
+    is_woe32dll=no
+  fi
+  WOE32DLL=$is_woe32dll
+  AC_SUBST([WOE32DLL])
+
+  dnl On mingw and Cygwin, we can activate special Makefile rules which add
+  dnl version information to the shared libraries and executables.
+  case "$host_os" in
+    mingw* | cygwin*) is_woe32=yes ;;
+    *) is_woe32=no ;;
+  esac
+  WOE32=$is_woe32
+  AC_SUBST([WOE32])
+  if test $WOE32 = yes; then
+    dnl Check for a program that compiles Windows resource files.
+    AC_CHECK_TOOL([WINDRES], [windres])
+  fi
+
+  dnl Determine whether when creating a library, "-lc" should be passed to
+  dnl libtool or not. On many platforms, it is required for the libtool option
+  dnl -no-undefined to work. On HP-UX, however, the -lc - stored by libtool
+  dnl in the *.la files - makes it impossible to create multithreaded programs,
+  dnl because libtool also reorders the -lc to come before the -pthread, and
+  dnl this disables pthread_create() <http://docs.hp.com/en/1896/pthreads.html>.
+  case "$host_os" in
+    hpux*) LTLIBC="" ;;
+    *)     LTLIBC="-lc" ;;
+  esac
+  AC_SUBST([LTLIBC])
+
+  dnl Rename some macros and functions used for locking.
+  AH_BOTTOM([
+#define __libc_lock_t                   gl_lock_t
+#define __libc_lock_define              gl_lock_define
+#define __libc_lock_define_initialized  gl_lock_define_initialized
+#define __libc_lock_init                gl_lock_init
+#define __libc_lock_lock                gl_lock_lock
+#define __libc_lock_unlock              gl_lock_unlock
+#define __libc_lock_recursive_t                   gl_recursive_lock_t
+#define __libc_lock_define_recursive              gl_recursive_lock_define
+#define __libc_lock_define_initialized_recursive  gl_recursive_lock_define_initialized
+#define __libc_lock_init_recursive                gl_recursive_lock_init
+#define __libc_lock_lock_recursive                gl_recursive_lock_lock
+#define __libc_lock_unlock_recursive              gl_recursive_lock_unlock
+#define glthread_in_use  libintl_thread_in_use
+#define glthread_lock_init_func     libintl_lock_init_func
+#define glthread_lock_lock_func     libintl_lock_lock_func
+#define glthread_lock_unlock_func   libintl_lock_unlock_func
+#define glthread_lock_destroy_func  libintl_lock_destroy_func
+#define glthread_rwlock_init_multithreaded     libintl_rwlock_init_multithreaded
+#define glthread_rwlock_init_func              libintl_rwlock_init_func
+#define glthread_rwlock_rdlock_multithreaded   libintl_rwlock_rdlock_multithreaded
+#define glthread_rwlock_rdlock_func            libintl_rwlock_rdlock_func
+#define glthread_rwlock_wrlock_multithreaded   libintl_rwlock_wrlock_multithreaded
+#define glthread_rwlock_wrlock_func            libintl_rwlock_wrlock_func
+#define glthread_rwlock_unlock_multithreaded   libintl_rwlock_unlock_multithreaded
+#define glthread_rwlock_unlock_func            libintl_rwlock_unlock_func
+#define glthread_rwlock_destroy_multithreaded  libintl_rwlock_destroy_multithreaded
+#define glthread_rwlock_destroy_func           libintl_rwlock_destroy_func
+#define glthread_recursive_lock_init_multithreaded     libintl_recursive_lock_init_multithreaded
+#define glthread_recursive_lock_init_func              libintl_recursive_lock_init_func
+#define glthread_recursive_lock_lock_multithreaded     libintl_recursive_lock_lock_multithreaded
+#define glthread_recursive_lock_lock_func              libintl_recursive_lock_lock_func
+#define glthread_recursive_lock_unlock_multithreaded   libintl_recursive_lock_unlock_multithreaded
+#define glthread_recursive_lock_unlock_func            libintl_recursive_lock_unlock_func
+#define glthread_recursive_lock_destroy_multithreaded  libintl_recursive_lock_destroy_multithreaded
+#define glthread_recursive_lock_destroy_func           libintl_recursive_lock_destroy_func
+#define glthread_once_func            libintl_once_func
+#define glthread_once_singlethreaded  libintl_once_singlethreaded
+#define glthread_once_multithreaded   libintl_once_multithreaded
+])
+])
+
+
+dnl Checks for the core files of the intl subdirectory:
+dnl   dcigettext.c
+dnl   eval-plural.h
+dnl   explodename.c
+dnl   finddomain.c
+dnl   gettextP.h
+dnl   gmo.h
+dnl   hash-string.h hash-string.c
+dnl   l10nflist.c
+dnl   libgnuintl.h.in (except the *printf stuff)
+dnl   loadinfo.h
+dnl   loadmsgcat.c
+dnl   localealias.c
+dnl   log.c
+dnl   plural-exp.h plural-exp.c
+dnl   plural.y
+dnl Used by libglocale.
+AC_DEFUN([gt_INTL_SUBDIR_CORE],
+[
+  AC_REQUIRE([AC_C_INLINE])dnl
+  AC_REQUIRE([AC_TYPE_SIZE_T])dnl
+  AC_REQUIRE([gl_AC_HEADER_STDINT_H])
+  AC_REQUIRE([AC_FUNC_ALLOCA])dnl
+  AC_REQUIRE([AC_FUNC_MMAP])dnl
+  AC_REQUIRE([gt_INTDIV0])dnl
+  AC_REQUIRE([gl_AC_TYPE_UINTMAX_T])dnl
+  AC_REQUIRE([gt_INTTYPES_PRI])dnl
+  AC_REQUIRE([gl_LOCK])dnl
+
+  AC_TRY_LINK(
+    [int foo (int a) { a = __builtin_expect (a, 10); return a == 10 ? 0 : 1; }],
+    [],
+    [AC_DEFINE([HAVE_BUILTIN_EXPECT], [1],
+       [Define to 1 if the compiler understands __builtin_expect.])])
+
+  AC_CHECK_HEADERS([argz.h inttypes.h limits.h unistd.h sys/param.h])
+  AC_CHECK_FUNCS([getcwd getegid geteuid getgid getuid mempcpy munmap \
+    stpcpy strcasecmp strdup strtoul tsearch uselocale argz_count \
+    argz_stringify argz_next __fsetlocking])
+
+  dnl Use the *_unlocked functions only if they are declared.
+  dnl (because some of them were defined without being declared in Solaris
+  dnl 2.5.1 but were removed in Solaris 2.6, whereas we want binaries built
+  dnl on Solaris 2.5.1 to run on Solaris 2.6).
+  dnl Don't use AC_CHECK_DECLS because it isn't supported in autoconf-2.13.
+  gt_CHECK_DECL([feof_unlocked], [#include <stdio.h>])
+  gt_CHECK_DECL([fgets_unlocked], [#include <stdio.h>])
+
+  AM_ICONV
+
+  dnl intl/plural.c is generated from intl/plural.y. It requires bison,
+  dnl because plural.y uses bison specific features. It requires at least
+  dnl bison-1.26 because earlier versions generate a plural.c that doesn't
+  dnl compile.
+  dnl bison is only needed for the maintainer (who touches plural.y). But in
+  dnl order to avoid separate Makefiles or --enable-maintainer-mode, we put
+  dnl the rule in general Makefile. Now, some people carelessly touch the
+  dnl files or have a broken "make" program, hence the plural.c rule will
+  dnl sometimes fire. To avoid an error, defines BISON to ":" if it is not
+  dnl present or too old.
+  AC_CHECK_PROGS([INTLBISON], [bison])
+  if test -z "$INTLBISON"; then
+    ac_verc_fail=yes
+  else
+    dnl Found it, now check the version.
+    AC_MSG_CHECKING([version of bison])
+changequote(<<,>>)dnl
+    ac_prog_version=`$INTLBISON --version 2>&1 | sed -n 's/^.*GNU Bison.* \([0-9]*\.[0-9.]*\).*$/\1/p'`
+    case $ac_prog_version in
+      '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;;
+      1.2[6-9]* | 1.[3-9][0-9]* | [2-9].*)
+changequote([,])dnl
+         ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;;
+      *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;;
+    esac
+    AC_MSG_RESULT([$ac_prog_version])
+  fi
+  if test $ac_verc_fail = yes; then
+    INTLBISON=:
+  fi
+])
+
+
+dnl gt_CHECK_DECL(FUNC, INCLUDES)
+dnl Check whether a function is declared.
+AC_DEFUN([gt_CHECK_DECL],
+[
+  AC_CACHE_CHECK([whether $1 is declared], [ac_cv_have_decl_$1],
+    [AC_TRY_COMPILE([$2], [
+#ifndef $1
+  char *p = (char *) $1;
+#endif
+], ac_cv_have_decl_$1=yes, ac_cv_have_decl_$1=no)])
+  if test $ac_cv_have_decl_$1 = yes; then
+    gt_value=1
+  else
+    gt_value=0
+  fi
+  AC_DEFINE_UNQUOTED([HAVE_DECL_]translit($1, [a-z], [A-Z]), [$gt_value],
+    [Define to 1 if you have the declaration of `$1', and to 0 if you don't.])
+])
diff --git a/m4/intldir.m4 b/m4/intldir.m4
new file mode 100644
index 000000000..ebae76d36
--- /dev/null
+++ b/m4/intldir.m4
@@ -0,0 +1,19 @@
+# intldir.m4 serial 2 (gettext-0.18)
+dnl Copyright (C) 2006, 2009-2010 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
+dnl This file can can be used in projects which are not available under
+dnl the GNU General Public License or the GNU Library General Public
+dnl License but which still want to provide support for the GNU gettext
+dnl functionality.
+dnl Please note that the actual code of the GNU gettext library is covered
+dnl by the GNU Library General Public License, and the rest of the GNU
+dnl gettext package package is covered by the GNU General Public License.
+dnl They are *not* in the public domain.
+
+AC_PREREQ([2.52])
+
+dnl Tells the AM_GNU_GETTEXT macro to consider an intl/ directory.
+AC_DEFUN([AM_GNU_GETTEXT_INTL_SUBDIR], [])
diff --git a/m4/intlmacosx.m4 b/m4/intlmacosx.m4
new file mode 100644
index 000000000..dd9102596
--- /dev/null
+++ b/m4/intlmacosx.m4
@@ -0,0 +1,51 @@
+# intlmacosx.m4 serial 3 (gettext-0.18)
+dnl Copyright (C) 2004-2010 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
+dnl This file can can be used in projects which are not available under
+dnl the GNU General Public License or the GNU Library General Public
+dnl License but which still want to provide support for the GNU gettext
+dnl functionality.
+dnl Please note that the actual code of the GNU gettext library is covered
+dnl by the GNU Library General Public License, and the rest of the GNU
+dnl gettext package package is covered by the GNU General Public License.
+dnl They are *not* in the public domain.
+
+dnl Checks for special options needed on MacOS X.
+dnl Defines INTL_MACOSX_LIBS.
+AC_DEFUN([gt_INTL_MACOSX],
+[
+  dnl Check for API introduced in MacOS X 10.2.
+  AC_CACHE_CHECK([for CFPreferencesCopyAppValue],
+    [gt_cv_func_CFPreferencesCopyAppValue],
+    [gt_save_LIBS="$LIBS"
+     LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation"
+     AC_TRY_LINK([#include <CoreFoundation/CFPreferences.h>],
+       [CFPreferencesCopyAppValue(NULL, NULL)],
+       [gt_cv_func_CFPreferencesCopyAppValue=yes],
+       [gt_cv_func_CFPreferencesCopyAppValue=no])
+     LIBS="$gt_save_LIBS"])
+  if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then
+    AC_DEFINE([HAVE_CFPREFERENCESCOPYAPPVALUE], [1],
+      [Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in the CoreFoundation framework.])
+  fi
+  dnl Check for API introduced in MacOS X 10.3.
+  AC_CACHE_CHECK([for CFLocaleCopyCurrent], [gt_cv_func_CFLocaleCopyCurrent],
+    [gt_save_LIBS="$LIBS"
+     LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation"
+     AC_TRY_LINK([#include <CoreFoundation/CFLocale.h>], [CFLocaleCopyCurrent();],
+       [gt_cv_func_CFLocaleCopyCurrent=yes],
+       [gt_cv_func_CFLocaleCopyCurrent=no])
+     LIBS="$gt_save_LIBS"])
+  if test $gt_cv_func_CFLocaleCopyCurrent = yes; then
+    AC_DEFINE([HAVE_CFLOCALECOPYCURRENT], [1],
+      [Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the CoreFoundation framework.])
+  fi
+  INTL_MACOSX_LIBS=
+  if test $gt_cv_func_CFPreferencesCopyAppValue = yes || test $gt_cv_func_CFLocaleCopyCurrent = yes; then
+    INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation"
+  fi
+  AC_SUBST([INTL_MACOSX_LIBS])
+])
diff --git a/m4/intmax.m4 b/m4/intmax.m4
new file mode 100644
index 000000000..74aaaf5ed
--- /dev/null
+++ b/m4/intmax.m4
@@ -0,0 +1,33 @@
+# intmax.m4 serial 5 (gettext-0.18)
+dnl Copyright (C) 2002-2005, 2008-2010 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 From Bruno Haible.
+dnl Test whether the system has the 'intmax_t' type, but don't attempt to
+dnl find a replacement if it is lacking.
+
+AC_DEFUN([gt_TYPE_INTMAX_T],
+[
+  AC_REQUIRE([gl_AC_HEADER_INTTYPES_H])
+  AC_REQUIRE([gl_AC_HEADER_STDINT_H])
+  AC_CACHE_CHECK([for intmax_t], [gt_cv_c_intmax_t],
+    [AC_TRY_COMPILE([
+#include <stddef.h>
+#include <stdlib.h>
+#if HAVE_STDINT_H_WITH_UINTMAX
+#include <stdint.h>
+#endif
+#if HAVE_INTTYPES_H_WITH_UINTMAX
+#include <inttypes.h>
+#endif
+],     [intmax_t x = -1;
+        return !x;],
+       [gt_cv_c_intmax_t=yes],
+       [gt_cv_c_intmax_t=no])])
+  if test $gt_cv_c_intmax_t = yes; then
+    AC_DEFINE([HAVE_INTMAX_T], [1],
+      [Define if you have the 'intmax_t' type in <stdint.h> or <inttypes.h>.])
+  fi
+])
diff --git a/m4/intmax_t.m4 b/m4/intmax_t.m4
index 63c4b415d..8a15dabdf 100644
--- a/m4/intmax_t.m4
+++ b/m4/intmax_t.m4
@@ -1,5 +1,5 @@
 # intmax_t.m4 serial 9
-dnl Copyright (C) 1997-2004, 2006-2007, 2009-2021 Free Software Foundation,
+dnl Copyright (C) 1997-2004, 2006-2007, 2009-2022 Free Software Foundation,
 dnl Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
diff --git a/m4/inttypes-pri.m4 b/m4/inttypes-pri.m4
new file mode 100644
index 000000000..718a4f4e1
--- /dev/null
+++ b/m4/inttypes-pri.m4
@@ -0,0 +1,36 @@
+# inttypes-pri.m4 serial 6 (gettext-0.18)
+dnl Copyright (C) 1997-2002, 2006, 2008-2010 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 From Bruno Haible.
+
+AC_PREREQ([2.52])
+
+# Define PRI_MACROS_BROKEN if <inttypes.h> exists and defines the PRI*
+# macros to non-string values.  This is the case on AIX 4.3.3.
+
+AC_DEFUN([gt_INTTYPES_PRI],
+[
+  AC_CHECK_HEADERS([inttypes.h])
+  if test $ac_cv_header_inttypes_h = yes; then
+    AC_CACHE_CHECK([whether the inttypes.h PRIxNN macros are broken],
+      [gt_cv_inttypes_pri_broken],
+      [
+        AC_TRY_COMPILE([#include <inttypes.h>
+#ifdef PRId32
+char *p = PRId32;
+#endif
+], [], [gt_cv_inttypes_pri_broken=no], [gt_cv_inttypes_pri_broken=yes])
+      ])
+  fi
+  if test "$gt_cv_inttypes_pri_broken" = yes; then
+    AC_DEFINE_UNQUOTED([PRI_MACROS_BROKEN], [1],
+      [Define if <inttypes.h> exists and defines unusable PRI* macros.])
+    PRI_MACROS_BROKEN=1
+  else
+    PRI_MACROS_BROKEN=0
+  fi
+  AC_SUBST([PRI_MACROS_BROKEN])
+])
diff --git a/m4/inttypes.m4 b/m4/inttypes.m4
index 64b1de5c4..df25a21eb 100644
--- a/m4/inttypes.m4
+++ b/m4/inttypes.m4
@@ -1,5 +1,5 @@
-# inttypes.m4 serial 35
-dnl Copyright (C) 2006-2021 Free Software Foundation, Inc.
+# inttypes.m4 serial 36
+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,
 dnl with or without modifications, as long as this notice is preserved.
@@ -36,7 +36,7 @@ AC_DEFUN_ONCE([gl_INTTYPES_INCOMPLETE],
 AC_DEFUN([gl_INTTYPES_PRI_SCN],
 [
   PRIPTR_PREFIX=
-  if test -n "$STDINT_H"; then
+  if $GL_GENERATE_STDINT_H; then
     dnl Using the gnulib <stdint.h>. It defines intptr_t to 'long' or
     dnl 'long long', depending on _WIN64.
     AC_COMPILE_IFELSE(
diff --git a/m4/inttypes_h.m4 b/m4/inttypes_h.m4
index 672a93e09..6e9eebf1b 100644
--- a/m4/inttypes_h.m4
+++ b/m4/inttypes_h.m4
@@ -1,5 +1,5 @@
 # inttypes_h.m4 serial 10
-dnl Copyright (C) 1997-2004, 2006, 2008-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 1997-2004, 2006, 2008-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/isfinite.m4 b/m4/isfinite.m4
index 2b8902d4a..e6325f952 100644
--- a/m4/isfinite.m4
+++ b/m4/isfinite.m4
@@ -1,5 +1,5 @@
 # isfinite.m4 serial 17
-dnl Copyright (C) 2007-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2007-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/isinf.m4 b/m4/isinf.m4
index ad6ef47ce..6f0029324 100644
--- a/m4/isinf.m4
+++ b/m4/isinf.m4
@@ -1,5 +1,5 @@
 # isinf.m4 serial 13
-dnl Copyright (C) 2007-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2007-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/isnan.m4 b/m4/isnan.m4
index e0bc03f98..4ae6ed711 100644
--- a/m4/isnan.m4
+++ b/m4/isnan.m4
@@ -1,5 +1,5 @@
 # isnan.m4 serial 5
-dnl Copyright (C) 2007-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2007-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/isnand.m4 b/m4/isnand.m4
index fc79f0b0c..4eadde7cb 100644
--- a/m4/isnand.m4
+++ b/m4/isnand.m4
@@ -1,5 +1,5 @@
 # isnand.m4 serial 12
-dnl Copyright (C) 2007-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2007-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/isnanf.m4 b/m4/isnanf.m4
index d0f6a5623..44c825a1f 100644
--- a/m4/isnanf.m4
+++ b/m4/isnanf.m4
@@ -1,5 +1,5 @@
 # isnanf.m4 serial 18
-dnl Copyright (C) 2007-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2007-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/isnanl.m4 b/m4/isnanl.m4
index 1ef16f5e3..fa49a644f 100644
--- a/m4/isnanl.m4
+++ b/m4/isnanl.m4
@@ -1,5 +1,5 @@
 # isnanl.m4 serial 22
-dnl Copyright (C) 2007-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2007-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/langinfo_h.m4 b/m4/langinfo_h.m4
index 87959f77a..563c8c431 100644
--- a/m4/langinfo_h.m4
+++ b/m4/langinfo_h.m4
@@ -1,5 +1,5 @@
 # langinfo_h.m4 serial 12
-dnl Copyright (C) 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/largefile.m4 b/m4/largefile.m4
index fbde5e664..ec9677c46 100644
--- a/m4/largefile.m4
+++ b/m4/largefile.m4
@@ -1,7 +1,7 @@
 # Enable large files on systems where this is not the default.
 # Enable support for files on Linux file systems with 64-bit inode numbers.
 
-# Copyright 1992-1996, 1998-2021 Free Software Foundation, Inc.
+# Copyright 1992-1996, 1998-2022 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.
@@ -10,8 +10,10 @@
 # It does not set _LARGEFILE_SOURCE=1 on HP-UX/ia64 32-bit, although this
 # setting of _LARGEFILE_SOURCE is needed so that <stdio.h> declares fseeko
 # and ftello in C++ mode as well.
+# Fixed in Autoconf 2.72, which has AC_SYS_YEAR2038.
 AC_DEFUN([gl_SET_LARGEFILE_SOURCE],
 [
+ m4_ifndef([AC_SYS_YEAR2038], [
   AC_REQUIRE([AC_CANONICAL_HOST])
   AC_FUNC_FSEEKO
   case "$host_os" in
@@ -20,9 +22,10 @@ AC_DEFUN([gl_SET_LARGEFILE_SOURCE],
         [Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2).])
       ;;
   esac
+ ])
 ])
 
-# Work around a problem in Autoconf through at least 2.71 on glibc 2.34+
+# Work around a problem in Autoconf through 2.71 on glibc 2.34+
 # with _TIME_BITS.  Also, work around a problem in autoconf <= 2.69:
 # AC_SYS_LARGEFILE does not configure for large inodes on Mac OS X 10.5,
 # or configures them incorrectly in some cases.
@@ -43,6 +46,7 @@ m4_define([_AC_SYS_LARGEFILE_TEST_INCLUDES],
 ])
 ])# m4_version_prereq 2.70
 
+m4_ifndef([AC_SYS_YEAR2038], [
 
 # _AC_SYS_LARGEFILE_MACRO_VALUE(C-MACRO, VALUE,
 #                               CACHE-VAR,
@@ -118,6 +122,7 @@ AS_IF([test "$enable_largefile" != no],
     [64],
       [gl_YEAR2038_BODY([])])])
 ])# AC_SYS_LARGEFILE
+])# m4_ifndef AC_SYS_YEAR2038
 
 # Enable large files on systems where this is implemented by Gnulib, not by the
 # system headers.
diff --git a/m4/lcmessage.m4 b/m4/lcmessage.m4
new file mode 100644
index 000000000..1a705431a
--- /dev/null
+++ b/m4/lcmessage.m4
@@ -0,0 +1,31 @@
+# lcmessage.m4 serial 6 (gettext-0.18)
+dnl Copyright (C) 1995-2002, 2004-2005, 2008-2010 Free Software Foundation,
+dnl 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
+dnl This file can can be used in projects which are not available under
+dnl the GNU General Public License or the GNU Library General Public
+dnl License but which still want to provide support for the GNU gettext
+dnl functionality.
+dnl Please note that the actual code of the GNU gettext library is covered
+dnl by the GNU Library General Public License, and the rest of the GNU
+dnl gettext package package is covered by the GNU General Public License.
+dnl They are *not* in the public domain.
+
+dnl Authors:
+dnl   Ulrich Drepper <drepper@cygnus.com>, 1995.
+
+# Check whether LC_MESSAGES is available in <locale.h>.
+
+AC_DEFUN([gt_LC_MESSAGES],
+[
+  AC_CACHE_CHECK([for LC_MESSAGES], [gt_cv_val_LC_MESSAGES],
+    [AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES],
+       [gt_cv_val_LC_MESSAGES=yes], [gt_cv_val_LC_MESSAGES=no])])
+  if test $gt_cv_val_LC_MESSAGES = yes; then
+    AC_DEFINE([HAVE_LC_MESSAGES], [1],
+      [Define if your <locale.h> file defines LC_MESSAGES.])
+  fi
+])
diff --git a/m4/ld-version-script.m4 b/m4/ld-version-script.m4
index 98126d9af..bf81b496d 100644
--- a/m4/ld-version-script.m4
+++ b/m4/ld-version-script.m4
@@ -1,5 +1,5 @@
 # ld-version-script.m4 serial 5
-dnl Copyright (C) 2008-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2008-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/ldexp.m4 b/m4/ldexp.m4
index cb7ce6422..b07dc0550 100644
--- a/m4/ldexp.m4
+++ b/m4/ldexp.m4
@@ -1,5 +1,5 @@
 # ldexp.m4 serial 1
-dnl Copyright (C) 2010-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2010-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/lib-ld.m4 b/m4/lib-ld.m4
index 076358d5d..934207a76 100644
--- a/m4/lib-ld.m4
+++ b/m4/lib-ld.m4
@@ -1,5 +1,5 @@
 # lib-ld.m4 serial 10
-dnl Copyright (C) 1996-2003, 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 1996-2003, 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/lib-link.m4 b/m4/lib-link.m4
index 787efab2d..3b75bcd0d 100644
--- a/m4/lib-link.m4
+++ b/m4/lib-link.m4
@@ -1,5 +1,5 @@
-# lib-link.m4 serial 32
-dnl Copyright (C) 2001-2021 Free Software Foundation, Inc.
+# lib-link.m4 serial 33
+dnl Copyright (C) 2001-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,
 dnl with or without modifications, as long as this notice is preserved.
@@ -196,8 +196,8 @@ AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
     eval additional_libdir3=\"$exec_prefix/$acl_libdirstem3\"
   ])
   AC_ARG_WITH(PACK[-prefix],
-[[  --with-]]PACK[[-prefix[=DIR]  search for ]PACKLIBS[ in DIR/include and DIR/lib
-  --without-]]PACK[[-prefix     don't search for ]PACKLIBS[ in includedir and libdir]],
+[[  --with-]]PACK[[-prefix[=DIR]  search for ]]PACKLIBS[[ in DIR/include and DIR/lib
+  --without-]]PACK[[-prefix     don't search for ]]PACKLIBS[[ in includedir and libdir]],
 [
     if test "X$withval" = "Xno"; then
       use_additional=no
diff --git a/m4/lib-prefix.m4 b/m4/lib-prefix.m4
index 3c94db0ac..999f712f5 100644
--- a/m4/lib-prefix.m4
+++ b/m4/lib-prefix.m4
@@ -1,5 +1,5 @@
-# lib-prefix.m4 serial 19
-dnl Copyright (C) 2001-2005, 2008-2021 Free Software Foundation, Inc.
+# lib-prefix.m4 serial 20
+dnl Copyright (C) 2001-2005, 2008-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,
 dnl with or without modifications, as long as this notice is preserved.
@@ -174,7 +174,7 @@ AC_DEFUN([AC_LIB_PREPARE_MULTILIB],
 
   AC_CACHE_CHECK([for ELF binary format], [gl_cv_elf],
     [AC_EGREP_CPP([Extensible Linking Format],
-       [#ifdef __ELF__
+       [#if defined __ELF__ || (defined __linux__ && defined __EDG__)
         Extensible Linking Format
         #endif
        ],
diff --git a/m4/libunistring.m4 b/m4/libunistring.m4
index e3d944793..3c18edbb7 100644
--- a/m4/libunistring.m4
+++ b/m4/libunistring.m4
@@ -1,5 +1,5 @@
 # libunistring.m4 serial 12
-dnl Copyright (C) 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/limits-h.m4 b/m4/limits-h.m4
index 00c9fe9e5..5d5a5bf58 100644
--- a/m4/limits-h.m4
+++ b/m4/limits-h.m4
@@ -1,6 +1,6 @@
 dnl Check whether limits.h has needed features.
 
-dnl Copyright 2016-2021 Free Software Foundation, Inc.
+dnl Copyright 2016-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,
 dnl with or without modifications, as long as this notice is preserved.
@@ -27,18 +27,15 @@ AC_DEFUN_ONCE([gl_LIMITS_H],
        [gl_cv_header_limits_width=yes],
        [gl_cv_header_limits_width=no])])
   if test "$gl_cv_header_limits_width" = yes; then
-    LIMITS_H=
+    GL_GENERATE_LIMITS_H=false
   else
-    LIMITS_H=limits.h
+    GL_GENERATE_LIMITS_H=true
   fi
-  AC_SUBST([LIMITS_H])
-  AM_CONDITIONAL([GL_GENERATE_LIMITS_H], [test -n "$LIMITS_H"])
 ])
 
 dnl Unconditionally enables the replacement of <limits.h>.
 AC_DEFUN([gl_REPLACE_LIMITS_H],
 [
   AC_REQUIRE([gl_LIMITS_H])
-  LIMITS_H='limits.h'
-  AM_CONDITIONAL([GL_GENERATE_LIMITS_H], [test -n "$LIMITS_H"])
+  GL_GENERATE_LIMITS_H=true
 ])
diff --git a/m4/link.m4 b/m4/link.m4
index 55a8a8d13..154b9d02b 100644
--- a/m4/link.m4
+++ b/m4/link.m4
@@ -1,5 +1,5 @@
 # link.m4 serial 11
-dnl Copyright (C) 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/localcharset.m4 b/m4/localcharset.m4
index 04389fcbd..f5dbbd4f3 100644
--- a/m4/localcharset.m4
+++ b/m4/localcharset.m4
@@ -1,5 +1,5 @@
 # localcharset.m4 serial 8
-dnl Copyright (C) 2002, 2004, 2006, 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2002, 2004, 2006, 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/locale-fr.m4 b/m4/locale-fr.m4
index b61df7ec9..3753891f3 100644
--- a/m4/locale-fr.m4
+++ b/m4/locale-fr.m4
@@ -1,5 +1,5 @@
 # locale-fr.m4 serial 20
-dnl Copyright (C) 2003, 2005-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2003, 2005-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/locale-ja.m4 b/m4/locale-ja.m4
index cd94288cc..73a5d1aeb 100644
--- a/m4/locale-ja.m4
+++ b/m4/locale-ja.m4
@@ -1,5 +1,5 @@
 # locale-ja.m4 serial 15
-dnl Copyright (C) 2003, 2005-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2003, 2005-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/locale-zh.m4 b/m4/locale-zh.m4
index 1228be828..c997971fa 100644
--- a/m4/locale-zh.m4
+++ b/m4/locale-zh.m4
@@ -1,5 +1,5 @@
 # locale-zh.m4 serial 15
-dnl Copyright (C) 2003, 2005-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2003, 2005-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/locale_h.m4 b/m4/locale_h.m4
index 444a38178..ca5d0d0fd 100644
--- a/m4/locale_h.m4
+++ b/m4/locale_h.m4
@@ -1,5 +1,5 @@
 # locale_h.m4 serial 28
-dnl Copyright (C) 2007, 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2007, 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/localeconv.m4 b/m4/localeconv.m4
index e29c7c329..09c1a1ac4 100644
--- a/m4/localeconv.m4
+++ b/m4/localeconv.m4
@@ -1,5 +1,5 @@
 # localeconv.m4 serial 1
-dnl Copyright (C) 2012-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2012-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/lock.m4 b/m4/lock.m4
new file mode 100644
index 000000000..9da8465eb
--- /dev/null
+++ b/m4/lock.m4
@@ -0,0 +1,37 @@
+# lock.m4 serial 10 (gettext-0.18)
+dnl Copyright (C) 2005-2010 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 From Bruno Haible.
+
+AC_DEFUN([gl_LOCK],
+[
+  AC_REQUIRE([gl_THREADLIB])
+  if test "$gl_threads_api" = posix; then
+    # OSF/1 4.0 and MacOS X 10.1 lack the pthread_rwlock_t type and the
+    # pthread_rwlock_* functions.
+    AC_CHECK_TYPE([pthread_rwlock_t],
+      [AC_DEFINE([HAVE_PTHREAD_RWLOCK], [1],
+         [Define if the POSIX multithreading library has read/write locks.])],
+      [],
+      [#include <pthread.h>])
+    # glibc defines PTHREAD_MUTEX_RECURSIVE as enum, not as a macro.
+    AC_TRY_COMPILE([#include <pthread.h>],
+      [#if __FreeBSD__ == 4
+error "No, in FreeBSD 4.0 recursive mutexes actually don't work."
+#else
+int x = (int)PTHREAD_MUTEX_RECURSIVE;
+return !x;
+#endif],
+      [AC_DEFINE([HAVE_PTHREAD_MUTEX_RECURSIVE], [1],
+         [Define if the <pthread.h> defines PTHREAD_MUTEX_RECURSIVE.])])
+  fi
+  gl_PREREQ_LOCK
+])
+
+# Prerequisites of lib/lock.c.
+AC_DEFUN([gl_PREREQ_LOCK], [
+  AC_REQUIRE([AC_C_INLINE])
+])
diff --git a/m4/log.m4 b/m4/log.m4
index 2c1683c9a..eedb871cb 100644
--- a/m4/log.m4
+++ b/m4/log.m4
@@ -1,5 +1,5 @@
 # log.m4 serial 11
-dnl Copyright (C) 2011-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2011-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/log1p.m4 b/m4/log1p.m4
index a1cf0f0de..7536eaf4c 100644
--- a/m4/log1p.m4
+++ b/m4/log1p.m4
@@ -1,5 +1,5 @@
 # log1p.m4 serial 8
-dnl Copyright (C) 2012-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2012-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/longlong.m4 b/m4/longlong.m4
new file mode 100644
index 000000000..cca3c1a90
--- /dev/null
+++ b/m4/longlong.m4
@@ -0,0 +1,106 @@
+# longlong.m4 serial 14
+dnl Copyright (C) 1999-2007, 2009-2010 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 From Paul Eggert.
+
+# Define HAVE_LONG_LONG_INT if 'long long int' works.
+# This fixes a bug in Autoconf 2.61, but can be removed once we
+# assume 2.62 everywhere.
+
+# Note: If the type 'long long int' exists but is only 32 bits large
+# (as on some very old compilers), HAVE_LONG_LONG_INT will not be
+# defined. In this case you can treat 'long long int' like 'long int'.
+
+AC_DEFUN([AC_TYPE_LONG_LONG_INT],
+[
+  AC_CACHE_CHECK([for long long int], [ac_cv_type_long_long_int],
+    [AC_LINK_IFELSE(
+       [_AC_TYPE_LONG_LONG_SNIPPET],
+       [dnl This catches a bug in Tandem NonStop Kernel (OSS) cc -O circa 2004.
+        dnl If cross compiling, assume the bug isn't important, since
+        dnl nobody cross compiles for this platform as far as we know.
+        AC_RUN_IFELSE(
+          [AC_LANG_PROGRAM(
+             [[@%:@include <limits.h>
+               @%:@ifndef LLONG_MAX
+               @%:@ define HALF \
+                        (1LL << (sizeof (long long int) * CHAR_BIT - 2))
+               @%:@ define LLONG_MAX (HALF - 1 + HALF)
+               @%:@endif]],
+             [[long long int n = 1;
+               int i;
+               for (i = 0; ; i++)
+                 {
+                   long long int m = n << i;
+                   if (m >> i != n)
+                     return 1;
+                   if (LLONG_MAX / 2 < m)
+                     break;
+                 }
+               return 0;]])],
+          [ac_cv_type_long_long_int=yes],
+          [ac_cv_type_long_long_int=no],
+          [ac_cv_type_long_long_int=yes])],
+       [ac_cv_type_long_long_int=no])])
+  if test $ac_cv_type_long_long_int = yes; then
+    AC_DEFINE([HAVE_LONG_LONG_INT], [1],
+      [Define to 1 if the system has the type `long long int'.])
+  fi
+])
+
+# Define HAVE_UNSIGNED_LONG_LONG_INT if 'unsigned long long int' works.
+# This fixes a bug in Autoconf 2.61, but can be removed once we
+# assume 2.62 everywhere.
+
+# Note: If the type 'unsigned long long int' exists but is only 32 bits
+# large (as on some very old compilers), AC_TYPE_UNSIGNED_LONG_LONG_INT
+# will not be defined. In this case you can treat 'unsigned long long int'
+# like 'unsigned long int'.
+
+AC_DEFUN([AC_TYPE_UNSIGNED_LONG_LONG_INT],
+[
+  AC_CACHE_CHECK([for unsigned long long int],
+    [ac_cv_type_unsigned_long_long_int],
+    [AC_LINK_IFELSE(
+       [_AC_TYPE_LONG_LONG_SNIPPET],
+       [ac_cv_type_unsigned_long_long_int=yes],
+       [ac_cv_type_unsigned_long_long_int=no])])
+  if test $ac_cv_type_unsigned_long_long_int = yes; then
+    AC_DEFINE([HAVE_UNSIGNED_LONG_LONG_INT], [1],
+      [Define to 1 if the system has the type `unsigned long long int'.])
+  fi
+])
+
+# Expands to a C program that can be used to test for simultaneous support
+# of 'long long' and 'unsigned long long'. We don't want to say that
+# 'long long' is available if 'unsigned long long' is not, or vice versa,
+# because too many programs rely on the symmetry between signed and unsigned
+# integer types (excluding 'bool').
+AC_DEFUN([_AC_TYPE_LONG_LONG_SNIPPET],
+[
+  AC_LANG_PROGRAM(
+    [[/* For now, do not test the preprocessor; as of 2007 there are too many
+         implementations with broken preprocessors.  Perhaps this can
+         be revisited in 2012.  In the meantime, code should not expect
+         #if to work with literals wider than 32 bits.  */
+      /* Test literals.  */
+      long long int ll = 9223372036854775807ll;
+      long long int nll = -9223372036854775807LL;
+      unsigned long long int ull = 18446744073709551615ULL;
+      /* Test constant expressions.   */
+      typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll)
+                     ? 1 : -1)];
+      typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1
+                     ? 1 : -1)];
+      int i = 63;]],
+    [[/* Test availability of runtime routines for shift and division.  */
+      long long int llmax = 9223372036854775807ll;
+      unsigned long long int ullmax = 18446744073709551615ull;
+      return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i)
+              | (llmax / ll) | (llmax % ll)
+              | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i)
+              | (ullmax / ull) | (ullmax % ull));]])
+])
diff --git a/m4/lstat.m4 b/m4/lstat.m4
index 62e9db29a..d987060bd 100644
--- a/m4/lstat.m4
+++ b/m4/lstat.m4
@@ -1,6 +1,6 @@
 # serial 33
 
-# Copyright (C) 1997-2001, 2003-2021 Free Software Foundation, Inc.
+# Copyright (C) 1997-2001, 2003-2022 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
diff --git a/m4/malloc.m4 b/m4/malloc.m4
index 972e808ab..6b76c1e64 100644
--- a/m4/malloc.m4
+++ b/m4/malloc.m4
@@ -1,5 +1,5 @@
-# malloc.m4 serial 27
-dnl Copyright (C) 2007, 2009-2021 Free Software Foundation, Inc.
+# malloc.m4 serial 28
+dnl Copyright (C) 2007, 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
@@ -43,8 +43,9 @@ AC_DEFUN([gl_FUNC_MALLOC_GNU],
 [
   AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
   AC_REQUIRE([gl_FUNC_MALLOC_POSIX])
-  if test $REPLACE_MALLOC = 0; then
-    _AC_FUNC_MALLOC_IF([], [REPLACE_MALLOC=1])
+  REPLACE_MALLOC_FOR_MALLOC_GNU="$REPLACE_MALLOC_FOR_MALLOC_POSIX"
+  if test $REPLACE_MALLOC_FOR_MALLOC_GNU = 0; then
+    _AC_FUNC_MALLOC_IF([], [REPLACE_MALLOC_FOR_MALLOC_GNU=1])
   fi
 ])
 
@@ -56,7 +57,7 @@ AC_DEFUN([gl_FUNC_MALLOC_PTRDIFF],
 [
   AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
   AC_REQUIRE([gl_CHECK_MALLOC_PTRDIFF])
-  test "$gl_cv_malloc_ptrdiff" = yes || REPLACE_MALLOC=1
+  test "$gl_cv_malloc_ptrdiff" = yes || REPLACE_MALLOC_FOR_MALLOC_POSIX=1
 ])
 
 # Test whether malloc, realloc, calloc refuse to create objects
@@ -109,7 +110,7 @@ AC_DEFUN([gl_FUNC_MALLOC_POSIX],
     AC_DEFINE([HAVE_MALLOC_POSIX], [1],
       [Define if malloc, realloc, and calloc set errno on allocation failure.])
   else
-    REPLACE_MALLOC=1
+    REPLACE_MALLOC_FOR_MALLOC_POSIX=1
   fi
 ])
 
diff --git a/m4/malloca.m4 b/m4/malloca.m4
index 06ed2c6b7..77eb96a09 100644
--- a/m4/malloca.m4
+++ b/m4/malloca.m4
@@ -1,5 +1,5 @@
 # malloca.m4 serial 2
-dnl Copyright (C) 2003-2004, 2006-2007, 2009-2021 Free Software Foundation,
+dnl Copyright (C) 2003-2004, 2006-2007, 2009-2022 Free Software Foundation,
 dnl Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
diff --git a/m4/math_h.m4 b/m4/math_h.m4
index b3a10c3fb..a08526a7a 100644
--- a/m4/math_h.m4
+++ b/m4/math_h.m4
@@ -1,5 +1,5 @@
 # math_h.m4 serial 125
-dnl Copyright (C) 2007-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2007-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/mathfunc.m4 b/m4/mathfunc.m4
index 92b374baa..34f5e76c4 100644
--- a/m4/mathfunc.m4
+++ b/m4/mathfunc.m4
@@ -1,5 +1,5 @@
 # mathfunc.m4 serial 12
-dnl Copyright (C) 2010-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2010-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/mbrtowc.m4 b/m4/mbrtowc.m4
index 1d4e73d72..ec8716b59 100644
--- a/m4/mbrtowc.m4
+++ b/m4/mbrtowc.m4
@@ -1,5 +1,5 @@
 # mbrtowc.m4 serial 38  -*- coding: utf-8 -*-
-dnl Copyright (C) 2001-2002, 2004-2005, 2008-2021 Free Software Foundation,
+dnl Copyright (C) 2001-2002, 2004-2005, 2008-2022 Free Software Foundation,
 dnl Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
diff --git a/m4/mbsinit.m4 b/m4/mbsinit.m4
index dc6e10d7f..ebd2d4ffb 100644
--- a/m4/mbsinit.m4
+++ b/m4/mbsinit.m4
@@ -1,5 +1,5 @@
 # mbsinit.m4 serial 9
-dnl Copyright (C) 2008, 2010-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2008, 2010-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/mbstate_t.m4 b/m4/mbstate_t.m4
index e7fe3580d..a6eba1bc1 100644
--- a/m4/mbstate_t.m4
+++ b/m4/mbstate_t.m4
@@ -1,5 +1,5 @@
 # mbstate_t.m4 serial 14
-dnl Copyright (C) 2000-2002, 2008-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2000-2002, 2008-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/mbtowc.m4 b/m4/mbtowc.m4
index 7fc74c945..2827e8335 100644
--- a/m4/mbtowc.m4
+++ b/m4/mbtowc.m4
@@ -1,5 +1,5 @@
 # mbtowc.m4 serial 3
-dnl Copyright (C) 2011-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2011-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/memchr.m4 b/m4/memchr.m4
index ca08192a6..c7489d871 100644
--- a/m4/memchr.m4
+++ b/m4/memchr.m4
@@ -1,5 +1,5 @@
 # memchr.m4 serial 18
-dnl Copyright (C) 2002-2004, 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2002-2004, 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/mempcpy.m4 b/m4/mempcpy.m4
index f9d9ec8f3..1107eb4a4 100644
--- a/m4/mempcpy.m4
+++ b/m4/mempcpy.m4
@@ -1,5 +1,5 @@
 # mempcpy.m4 serial 12
-dnl Copyright (C) 2003-2004, 2006-2007, 2009-2021 Free Software Foundation,
+dnl Copyright (C) 2003-2004, 2006-2007, 2009-2022 Free Software Foundation,
 dnl Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
diff --git a/m4/minmax.m4 b/m4/minmax.m4
index e21a6879a..b97673979 100644
--- a/m4/minmax.m4
+++ b/m4/minmax.m4
@@ -1,5 +1,5 @@
 # minmax.m4 serial 4
-dnl Copyright (C) 2005, 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2005, 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/mkdir.m4 b/m4/mkdir.m4
index 031fd291b..8b78ce960 100644
--- a/m4/mkdir.m4
+++ b/m4/mkdir.m4
@@ -1,6 +1,6 @@
 # serial 17
 
-# Copyright (C) 2001, 2003-2004, 2006, 2008-2021 Free Software Foundation, Inc.
+# Copyright (C) 2001, 2003-2004, 2006, 2008-2022 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.
diff --git a/m4/mkostemp.m4 b/m4/mkostemp.m4
index 46534d48e..2176f3729 100644
--- a/m4/mkostemp.m4
+++ b/m4/mkostemp.m4
@@ -1,5 +1,5 @@
 # mkostemp.m4 serial 2
-dnl Copyright (C) 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/mktime.m4 b/m4/mktime.m4
index 721189af5..431b17dcb 100644
--- a/m4/mktime.m4
+++ b/m4/mktime.m4
@@ -1,5 +1,5 @@
-# serial 36
-dnl Copyright (C) 2002-2003, 2005-2007, 2009-2021 Free Software Foundation,
+# serial 37
+dnl Copyright (C) 2002-2003, 2005-2007, 2009-2022 Free Software Foundation,
 dnl Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -82,7 +82,8 @@ spring_forward_gap ()
      instead of "TZ=America/Vancouver" in order to detect the bug even
      on systems that don't support the Olson extension, or don't have the
      full zoneinfo tables installed.  */
-  putenv ("TZ=PST8PDT,M4.1.0,M10.5.0");
+  if (putenv ("TZ=PST8PDT,M4.1.0,M10.5.0") != 0)
+    return -1;
 
   tm.tm_year = 98;
   tm.tm_mon = 3;
@@ -170,7 +171,8 @@ year_2050_test ()
      instead of "TZ=America/Vancouver" in order to detect the bug even
      on systems that don't support the Olson extension, or don't have the
      full zoneinfo tables installed.  */
-  putenv ("TZ=PST8PDT,M4.1.0,M10.5.0");
+  if (putenv ("TZ=PST8PDT,M4.1.0,M10.5.0") != 0)
+    return -1;
 
   t = mktime (&tm);
 
@@ -181,6 +183,25 @@ year_2050_test ()
           || (0 < t && answer - 120 <= t && t <= answer + 120));
 }
 
+static int
+indiana_test ()
+{
+  if (putenv ("TZ=America/Indiana/Indianapolis") != 0)
+    return -1;
+  struct tm tm;
+  tm.tm_year = 1986 - 1900; tm.tm_mon = 4 - 1; tm.tm_mday = 28;
+  tm.tm_hour = 16; tm.tm_min = 24; tm.tm_sec = 50; tm.tm_isdst = 0;
+  time_t std = mktime (&tm);
+  if (! (std == 515107490 || std == 515107503))
+    return 1;
+
+  /* This platform supports TZDB, either without or with leap seconds.
+     Return true if GNU Bug#48085 is absent.  */
+  tm.tm_isdst = 1;
+  time_t dst = mktime (&tm);
+  return std - dst == 60 * 60;
+}
+
 int
 main ()
 {
@@ -236,7 +257,7 @@ main ()
     result |= 16;
   if (! spring_forward_gap ())
     result |= 32;
-  if (! year_2050_test ())
+  if (! year_2050_test () || ! indiana_test ())
     result |= 64;
   return result;
 }]])],
diff --git a/m4/mmap-anon.m4 b/m4/mmap-anon.m4
index e47aa2d2f..a4580ff94 100644
--- a/m4/mmap-anon.m4
+++ b/m4/mmap-anon.m4
@@ -1,5 +1,5 @@
 # mmap-anon.m4 serial 12
-dnl Copyright (C) 2005, 2007, 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2005, 2007, 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/mode_t.m4 b/m4/mode_t.m4
index 3bd4b89fe..e08d27a74 100644
--- a/m4/mode_t.m4
+++ b/m4/mode_t.m4
@@ -1,5 +1,5 @@
 # mode_t.m4 serial 2
-dnl Copyright (C) 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/msvc-inval.m4 b/m4/msvc-inval.m4
index 3ba5b4e98..b32cf6eba 100644
--- a/m4/msvc-inval.m4
+++ b/m4/msvc-inval.m4
@@ -1,5 +1,5 @@
 # msvc-inval.m4 serial 1
-dnl Copyright (C) 2011-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2011-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/msvc-nothrow.m4 b/m4/msvc-nothrow.m4
index aae25ce7c..16ceb1f15 100644
--- a/m4/msvc-nothrow.m4
+++ b/m4/msvc-nothrow.m4
@@ -1,5 +1,5 @@
 # msvc-nothrow.m4 serial 1
-dnl Copyright (C) 2011-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2011-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/multiarch.m4 b/m4/multiarch.m4
index f1678d9f6..5d942765d 100644
--- a/m4/multiarch.m4
+++ b/m4/multiarch.m4
@@ -1,5 +1,5 @@
 # multiarch.m4 serial 9
-dnl Copyright (C) 2008-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2008-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/netdb_h.m4 b/m4/netdb_h.m4
index eb7c3b8b5..d6a9d709c 100644
--- a/m4/netdb_h.m4
+++ b/m4/netdb_h.m4
@@ -1,5 +1,5 @@
 # netdb_h.m4 serial 15
-dnl Copyright (C) 2008-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2008-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/netinet_in_h.m4 b/m4/netinet_in_h.m4
index c55559643..de26fe859 100644
--- a/m4/netinet_in_h.m4
+++ b/m4/netinet_in_h.m4
@@ -1,5 +1,5 @@
-# netinet_in_h.m4 serial 5
-dnl Copyright (C) 2006-2021 Free Software Foundation, Inc.
+# netinet_in_h.m4 serial 6
+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,
 dnl with or without modifications, as long as this notice is preserved.
@@ -14,9 +14,9 @@ AC_DEFUN([gl_HEADER_NETINET_IN],
         [gl_cv_header_netinet_in_h_selfcontained=no])
     ])
   if test $gl_cv_header_netinet_in_h_selfcontained = yes; then
-    NETINET_IN_H=''
+    GL_GENERATE_NETINET_IN_H=false
   else
-    NETINET_IN_H='netinet/in.h'
+    GL_GENERATE_NETINET_IN_H=true
     AC_CHECK_HEADERS([netinet/in.h])
     gl_CHECK_NEXT_HEADERS([netinet/in.h])
     if test $ac_cv_header_netinet_in_h = yes; then
@@ -26,6 +26,4 @@ AC_DEFUN([gl_HEADER_NETINET_IN],
     fi
     AC_SUBST([HAVE_NETINET_IN_H])
   fi
-  AC_SUBST([NETINET_IN_H])
-  AM_CONDITIONAL([GL_GENERATE_NETINET_IN_H], [test -n "$NETINET_IN_H"])
 ])
diff --git a/m4/nl_langinfo.m4 b/m4/nl_langinfo.m4
index 6ad32c807..d20a09cf8 100644
--- a/m4/nl_langinfo.m4
+++ b/m4/nl_langinfo.m4
@@ -1,5 +1,5 @@
 # nl_langinfo.m4 serial 8
-dnl Copyright (C) 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/nls.m4 b/m4/nls.m4
new file mode 100644
index 000000000..003704c4b
--- /dev/null
+++ b/m4/nls.m4
@@ -0,0 +1,32 @@
+# nls.m4 serial 5 (gettext-0.18)
+dnl Copyright (C) 1995-2003, 2005-2006, 2008-2010 Free Software Foundation,
+dnl 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
+dnl This file can can be used in projects which are not available under
+dnl the GNU General Public License or the GNU Library General Public
+dnl License but which still want to provide support for the GNU gettext
+dnl functionality.
+dnl Please note that the actual code of the GNU gettext library is covered
+dnl by the GNU Library General Public License, and the rest of the GNU
+dnl gettext package package is covered by the GNU General Public License.
+dnl They are *not* in the public domain.
+
+dnl Authors:
+dnl   Ulrich Drepper <drepper@cygnus.com>, 1995-2000.
+dnl   Bruno Haible <haible@clisp.cons.org>, 2000-2003.
+
+AC_PREREQ([2.50])
+
+AC_DEFUN([AM_NLS],
+[
+  AC_MSG_CHECKING([whether NLS is requested])
+  dnl Default is enabled NLS
+  AC_ARG_ENABLE([nls],
+    [  --disable-nls           do not use Native Language Support],
+    USE_NLS=$enableval, USE_NLS=yes)
+  AC_MSG_RESULT([$USE_NLS])
+  AC_SUBST([USE_NLS])
+])
diff --git a/m4/nocrash.m4 b/m4/nocrash.m4
index 27412cd2e..91f00c1bc 100644
--- a/m4/nocrash.m4
+++ b/m4/nocrash.m4
@@ -1,5 +1,5 @@
 # nocrash.m4 serial 5
-dnl Copyright (C) 2005, 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2005, 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/nproc.m4 b/m4/nproc.m4
index 887c66bee..5c220ae2c 100644
--- a/m4/nproc.m4
+++ b/m4/nproc.m4
@@ -1,5 +1,5 @@
 # nproc.m4 serial 5
-dnl Copyright (C) 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/nstrftime.m4 b/m4/nstrftime.m4
index b510554b9..0f613048e 100644
--- a/m4/nstrftime.m4
+++ b/m4/nstrftime.m4
@@ -1,6 +1,6 @@
 # serial 37
 
-# Copyright (C) 1996-1997, 1999-2007, 2009-2021 Free Software Foundation, Inc.
+# Copyright (C) 1996-1997, 1999-2007, 2009-2022 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
diff --git a/m4/off_t.m4 b/m4/off_t.m4
index bdec43c80..0890adafc 100644
--- a/m4/off_t.m4
+++ b/m4/off_t.m4
@@ -1,5 +1,5 @@
 # off_t.m4 serial 1
-dnl Copyright (C) 2012-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2012-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/open-cloexec.m4 b/m4/open-cloexec.m4
index 542a90f42..16cd5ec4c 100644
--- a/m4/open-cloexec.m4
+++ b/m4/open-cloexec.m4
@@ -1,6 +1,6 @@
 # Test whether O_CLOEXEC is defined.
 
-dnl Copyright 2017-2021 Free Software Foundation, Inc.
+dnl Copyright 2017-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/open-slash.m4 b/m4/open-slash.m4
index e619039e8..4fbf491a7 100644
--- a/m4/open-slash.m4
+++ b/m4/open-slash.m4
@@ -1,5 +1,5 @@
 # open-slash.m4 serial 2
-dnl Copyright (C) 2007-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2007-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/open.m4 b/m4/open.m4
index c63438650..f82fd6cac 100644
--- a/m4/open.m4
+++ b/m4/open.m4
@@ -1,5 +1,5 @@
 # open.m4 serial 15
-dnl Copyright (C) 2007-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2007-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/pathmax.m4 b/m4/pathmax.m4
index e67c65665..44add9905 100644
--- a/m4/pathmax.m4
+++ b/m4/pathmax.m4
@@ -1,5 +1,5 @@
 # pathmax.m4 serial 11
-dnl Copyright (C) 2002-2003, 2005-2006, 2009-2021 Free Software Foundation,
+dnl Copyright (C) 2002-2003, 2005-2006, 2009-2022 Free Software Foundation,
 dnl Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
diff --git a/m4/pid_t.m4 b/m4/pid_t.m4
index b7650a10f..cb26f3612 100644
--- a/m4/pid_t.m4
+++ b/m4/pid_t.m4
@@ -1,5 +1,5 @@
 # pid_t.m4 serial 4
-dnl Copyright (C) 2020-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2020-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/pipe.m4 b/m4/pipe.m4
index 89d666d2a..62871c6d3 100644
--- a/m4/pipe.m4
+++ b/m4/pipe.m4
@@ -1,5 +1,5 @@
 # pipe.m4 serial 2
-dnl Copyright (C) 2010-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2010-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/pipe2.m4 b/m4/pipe2.m4
index 43d547cb4..b75224782 100644
--- a/m4/pipe2.m4
+++ b/m4/pipe2.m4
@@ -1,5 +1,5 @@
 # pipe2.m4 serial 2
-dnl Copyright (C) 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/po.m4 b/m4/po.m4
new file mode 100644
index 000000000..47f36a41a
--- /dev/null
+++ b/m4/po.m4
@@ -0,0 +1,449 @@
+# po.m4 serial 17 (gettext-0.18)
+dnl Copyright (C) 1995-2010 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
+dnl This file can can be used in projects which are not available under
+dnl the GNU General Public License or the GNU Library General Public
+dnl License but which still want to provide support for the GNU gettext
+dnl functionality.
+dnl Please note that the actual code of the GNU gettext library is covered
+dnl by the GNU Library General Public License, and the rest of the GNU
+dnl gettext package package is covered by the GNU General Public License.
+dnl They are *not* in the public domain.
+
+dnl Authors:
+dnl   Ulrich Drepper <drepper@cygnus.com>, 1995-2000.
+dnl   Bruno Haible <haible@clisp.cons.org>, 2000-2003.
+
+AC_PREREQ([2.50])
+
+dnl Checks for all prerequisites of the po subdirectory.
+AC_DEFUN([AM_PO_SUBDIRS],
+[
+  AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+  AC_REQUIRE([AC_PROG_INSTALL])dnl
+  AC_REQUIRE([AM_PROG_MKDIR_P])dnl defined by automake
+  AC_REQUIRE([AM_NLS])dnl
+
+  dnl Release version of the gettext macros. This is used to ensure that
+  dnl the gettext macros and po/Makefile.in.in are in sync.
+  AC_SUBST([GETTEXT_MACRO_VERSION], [0.18])
+
+  dnl Perform the following tests also if --disable-nls has been given,
+  dnl because they are needed for "make dist" to work.
+
+  dnl Search for GNU msgfmt in the PATH.
+  dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions.
+  dnl The second test excludes FreeBSD msgfmt.
+  AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
+    [$ac_dir/$ac_word --statistics /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 &&
+     (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)],
+    :)
+  AC_PATH_PROG([GMSGFMT], [gmsgfmt], [$MSGFMT])
+
+  dnl Test whether it is GNU msgfmt >= 0.15.
+changequote(,)dnl
+  case `$MSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
+    '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) MSGFMT_015=: ;;
+    *) MSGFMT_015=$MSGFMT ;;
+  esac
+changequote([,])dnl
+  AC_SUBST([MSGFMT_015])
+changequote(,)dnl
+  case `$GMSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
+    '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) GMSGFMT_015=: ;;
+    *) GMSGFMT_015=$GMSGFMT ;;
+  esac
+changequote([,])dnl
+  AC_SUBST([GMSGFMT_015])
+
+  dnl Search for GNU xgettext 0.12 or newer in the PATH.
+  dnl The first test excludes Solaris xgettext and early GNU xgettext versions.
+  dnl The second test excludes FreeBSD xgettext.
+  AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+    [$ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 &&
+     (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)],
+    :)
+  dnl Remove leftover from FreeBSD xgettext call.
+  rm -f messages.po
+
+  dnl Test whether it is GNU xgettext >= 0.15.
+changequote(,)dnl
+  case `$XGETTEXT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
+    '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) XGETTEXT_015=: ;;
+    *) XGETTEXT_015=$XGETTEXT ;;
+  esac
+changequote([,])dnl
+  AC_SUBST([XGETTEXT_015])
+
+  dnl Search for GNU msgmerge 0.11 or newer in the PATH.
+  AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge,
+    [$ac_dir/$ac_word --update -q /dev/null /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1], :)
+
+  dnl Installation directories.
+  dnl Autoconf >= 2.60 defines localedir. For older versions of autoconf, we
+  dnl have to define it here, so that it can be used in po/Makefile.
+  test -n "$localedir" || localedir='${datadir}/locale'
+  AC_SUBST([localedir])
+
+  dnl Support for AM_XGETTEXT_OPTION.
+  test -n "${XGETTEXT_EXTRA_OPTIONS+set}" || XGETTEXT_EXTRA_OPTIONS=
+  AC_SUBST([XGETTEXT_EXTRA_OPTIONS])
+
+  AC_CONFIG_COMMANDS([po-directories], [[
+    for ac_file in $CONFIG_FILES; do
+      # Support "outfile[:infile[:infile...]]"
+      case "$ac_file" in
+        *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+      esac
+      # PO directories have a Makefile.in generated from Makefile.in.in.
+      case "$ac_file" in */Makefile.in)
+        # Adjust a relative srcdir.
+        ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'`
+        ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`"
+        ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'`
+        # In autoconf-2.13 it is called $ac_given_srcdir.
+        # In autoconf-2.50 it is called $srcdir.
+        test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir"
+        case "$ac_given_srcdir" in
+          .)  top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;;
+          /*) top_srcdir="$ac_given_srcdir" ;;
+          *)  top_srcdir="$ac_dots$ac_given_srcdir" ;;
+        esac
+        # Treat a directory as a PO directory if and only if it has a
+        # POTFILES.in file. This allows packages to have multiple PO
+        # directories under different names or in different locations.
+        if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then
+          rm -f "$ac_dir/POTFILES"
+          test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES"
+          cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ 	]*\$/d" -e "s,.*,     $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES"
+          POMAKEFILEDEPS="POTFILES.in"
+          # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend
+          # on $ac_dir but don't depend on user-specified configuration
+          # parameters.
+          if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then
+            # The LINGUAS file contains the set of available languages.
+            if test -n "$OBSOLETE_ALL_LINGUAS"; then
+              test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete"
+            fi
+            ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"`
+            # Hide the ALL_LINGUAS assigment from automake < 1.5.
+            eval 'ALL_LINGUAS''=$ALL_LINGUAS_'
+            POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS"
+          else
+            # The set of available languages was given in configure.in.
+            # Hide the ALL_LINGUAS assigment from automake < 1.5.
+            eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS'
+          fi
+          # Compute POFILES
+          # as      $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po)
+          # Compute UPDATEPOFILES
+          # as      $(foreach lang, $(ALL_LINGUAS), $(lang).po-update)
+          # Compute DUMMYPOFILES
+          # as      $(foreach lang, $(ALL_LINGUAS), $(lang).nop)
+          # Compute GMOFILES
+          # as      $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo)
+          case "$ac_given_srcdir" in
+            .) srcdirpre= ;;
+            *) srcdirpre='$(srcdir)/' ;;
+          esac
+          POFILES=
+          UPDATEPOFILES=
+          DUMMYPOFILES=
+          GMOFILES=
+          for lang in $ALL_LINGUAS; do
+            POFILES="$POFILES $srcdirpre$lang.po"
+            UPDATEPOFILES="$UPDATEPOFILES $lang.po-update"
+            DUMMYPOFILES="$DUMMYPOFILES $lang.nop"
+            GMOFILES="$GMOFILES $srcdirpre$lang.gmo"
+          done
+          # CATALOGS depends on both $ac_dir and the user's LINGUAS
+          # environment variable.
+          INST_LINGUAS=
+          if test -n "$ALL_LINGUAS"; then
+            for presentlang in $ALL_LINGUAS; do
+              useit=no
+              if test "%UNSET%" != "$LINGUAS"; then
+                desiredlanguages="$LINGUAS"
+              else
+                desiredlanguages="$ALL_LINGUAS"
+              fi
+              for desiredlang in $desiredlanguages; do
+                # Use the presentlang catalog if desiredlang is
+                #   a. equal to presentlang, or
+                #   b. a variant of presentlang (because in this case,
+                #      presentlang can be used as a fallback for messages
+                #      which are not translated in the desiredlang catalog).
+                case "$desiredlang" in
+                  "$presentlang"*) useit=yes;;
+                esac
+              done
+              if test $useit = yes; then
+                INST_LINGUAS="$INST_LINGUAS $presentlang"
+              fi
+            done
+          fi
+          CATALOGS=
+          if test -n "$INST_LINGUAS"; then
+            for lang in $INST_LINGUAS; do
+              CATALOGS="$CATALOGS $lang.gmo"
+            done
+          fi
+          test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile"
+          sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile"
+          for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do
+            if test -f "$f"; then
+              case "$f" in
+                *.orig | *.bak | *~) ;;
+                *) cat "$f" >> "$ac_dir/Makefile" ;;
+              esac
+            fi
+          done
+        fi
+        ;;
+      esac
+    done]],
+   [# Capture the value of obsolete ALL_LINGUAS because we need it to compute
+    # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. But hide it
+    # from automake < 1.5.
+    eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"'
+    # Capture the value of LINGUAS because we need it to compute CATALOGS.
+    LINGUAS="${LINGUAS-%UNSET%}"
+   ])
+])
+
+dnl Postprocesses a Makefile in a directory containing PO files.
+AC_DEFUN([AM_POSTPROCESS_PO_MAKEFILE],
+[
+  # When this code is run, in config.status, two variables have already been
+  # set:
+  # - OBSOLETE_ALL_LINGUAS is the value of LINGUAS set in configure.in,
+  # - LINGUAS is the value of the environment variable LINGUAS at configure
+  #   time.
+
+changequote(,)dnl
+  # Adjust a relative srcdir.
+  ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'`
+  ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`"
+  ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'`
+  # In autoconf-2.13 it is called $ac_given_srcdir.
+  # In autoconf-2.50 it is called $srcdir.
+  test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir"
+  case "$ac_given_srcdir" in
+    .)  top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;;
+    /*) top_srcdir="$ac_given_srcdir" ;;
+    *)  top_srcdir="$ac_dots$ac_given_srcdir" ;;
+  esac
+
+  # Find a way to echo strings without interpreting backslash.
+  if test "X`(echo '\t') 2>/dev/null`" = 'X\t'; then
+    gt_echo='echo'
+  else
+    if test "X`(printf '%s\n' '\t') 2>/dev/null`" = 'X\t'; then
+      gt_echo='printf %s\n'
+    else
+      echo_func () {
+        cat <<EOT
+$*
+EOT
+      }
+      gt_echo='echo_func'
+    fi
+  fi
+
+  # A sed script that extracts the value of VARIABLE from a Makefile.
+  sed_x_variable='
+# Test if the hold space is empty.
+x
+s/P/P/
+x
+ta
+# Yes it was empty. Look if we have the expected variable definition.
+/^[	 ]*VARIABLE[	 ]*=/{
+  # Seen the first line of the variable definition.
+  s/^[	 ]*VARIABLE[	 ]*=//
+  ba
+}
+bd
+:a
+# Here we are processing a line from the variable definition.
+# Remove comment, more precisely replace it with a space.
+s/#.*$/ /
+# See if the line ends in a backslash.
+tb
+:b
+s/\\$//
+# Print the line, without the trailing backslash.
+p
+tc
+# There was no trailing backslash. The end of the variable definition is
+# reached. Clear the hold space.
+s/^.*$//
+x
+bd
+:c
+# A trailing backslash means that the variable definition continues in the
+# next line. Put a nonempty string into the hold space to indicate this.
+s/^.*$/P/
+x
+:d
+'
+changequote([,])dnl
+
+  # Set POTFILES to the value of the Makefile variable POTFILES.
+  sed_x_POTFILES=`$gt_echo "$sed_x_variable" | sed -e '/^ *#/d' -e 's/VARIABLE/POTFILES/g'`
+  POTFILES=`sed -n -e "$sed_x_POTFILES" < "$ac_file"`
+  # Compute POTFILES_DEPS as
+  #   $(foreach file, $(POTFILES), $(top_srcdir)/$(file))
+  POTFILES_DEPS=
+  for file in $POTFILES; do
+    POTFILES_DEPS="$POTFILES_DEPS "'$(top_srcdir)/'"$file"
+  done
+  POMAKEFILEDEPS=""
+
+  if test -n "$OBSOLETE_ALL_LINGUAS"; then
+    test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete"
+  fi
+  if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then
+    # The LINGUAS file contains the set of available languages.
+    ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"`
+    POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS"
+  else
+    # Set ALL_LINGUAS to the value of the Makefile variable LINGUAS.
+    sed_x_LINGUAS=`$gt_echo "$sed_x_variable" | sed -e '/^ *#/d' -e 's/VARIABLE/LINGUAS/g'`
+    ALL_LINGUAS_=`sed -n -e "$sed_x_LINGUAS" < "$ac_file"`
+  fi
+  # Hide the ALL_LINGUAS assigment from automake < 1.5.
+  eval 'ALL_LINGUAS''=$ALL_LINGUAS_'
+  # Compute POFILES
+  # as      $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po)
+  # Compute UPDATEPOFILES
+  # as      $(foreach lang, $(ALL_LINGUAS), $(lang).po-update)
+  # Compute DUMMYPOFILES
+  # as      $(foreach lang, $(ALL_LINGUAS), $(lang).nop)
+  # Compute GMOFILES
+  # as      $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo)
+  # Compute PROPERTIESFILES
+  # as      $(foreach lang, $(ALL_LINGUAS), $(top_srcdir)/$(DOMAIN)_$(lang).properties)
+  # Compute CLASSFILES
+  # as      $(foreach lang, $(ALL_LINGUAS), $(top_srcdir)/$(DOMAIN)_$(lang).class)
+  # Compute QMFILES
+  # as      $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).qm)
+  # Compute MSGFILES
+  # as      $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(frob $(lang)).msg)
+  # Compute RESOURCESDLLFILES
+  # as      $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(frob $(lang))/$(DOMAIN).resources.dll)
+  case "$ac_given_srcdir" in
+    .) srcdirpre= ;;
+    *) srcdirpre='$(srcdir)/' ;;
+  esac
+  POFILES=
+  UPDATEPOFILES=
+  DUMMYPOFILES=
+  GMOFILES=
+  PROPERTIESFILES=
+  CLASSFILES=
+  QMFILES=
+  MSGFILES=
+  RESOURCESDLLFILES=
+  for lang in $ALL_LINGUAS; do
+    POFILES="$POFILES $srcdirpre$lang.po"
+    UPDATEPOFILES="$UPDATEPOFILES $lang.po-update"
+    DUMMYPOFILES="$DUMMYPOFILES $lang.nop"
+    GMOFILES="$GMOFILES $srcdirpre$lang.gmo"
+    PROPERTIESFILES="$PROPERTIESFILES \$(top_srcdir)/\$(DOMAIN)_$lang.properties"
+    CLASSFILES="$CLASSFILES \$(top_srcdir)/\$(DOMAIN)_$lang.class"
+    QMFILES="$QMFILES $srcdirpre$lang.qm"
+    frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
+    MSGFILES="$MSGFILES $srcdirpre$frobbedlang.msg"
+    frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'`
+    RESOURCESDLLFILES="$RESOURCESDLLFILES $srcdirpre$frobbedlang/\$(DOMAIN).resources.dll"
+  done
+  # CATALOGS depends on both $ac_dir and the user's LINGUAS
+  # environment variable.
+  INST_LINGUAS=
+  if test -n "$ALL_LINGUAS"; then
+    for presentlang in $ALL_LINGUAS; do
+      useit=no
+      if test "%UNSET%" != "$LINGUAS"; then
+        desiredlanguages="$LINGUAS"
+      else
+        desiredlanguages="$ALL_LINGUAS"
+      fi
+      for desiredlang in $desiredlanguages; do
+        # Use the presentlang catalog if desiredlang is
+        #   a. equal to presentlang, or
+        #   b. a variant of presentlang (because in this case,
+        #      presentlang can be used as a fallback for messages
+        #      which are not translated in the desiredlang catalog).
+        case "$desiredlang" in
+          "$presentlang"*) useit=yes;;
+        esac
+      done
+      if test $useit = yes; then
+        INST_LINGUAS="$INST_LINGUAS $presentlang"
+      fi
+    done
+  fi
+  CATALOGS=
+  JAVACATALOGS=
+  QTCATALOGS=
+  TCLCATALOGS=
+  CSHARPCATALOGS=
+  if test -n "$INST_LINGUAS"; then
+    for lang in $INST_LINGUAS; do
+      CATALOGS="$CATALOGS $lang.gmo"
+      JAVACATALOGS="$JAVACATALOGS \$(DOMAIN)_$lang.properties"
+      QTCATALOGS="$QTCATALOGS $lang.qm"
+      frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
+      TCLCATALOGS="$TCLCATALOGS $frobbedlang.msg"
+      frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'`
+      CSHARPCATALOGS="$CSHARPCATALOGS $frobbedlang/\$(DOMAIN).resources.dll"
+    done
+  fi
+
+  sed -e "s|@POTFILES_DEPS@|$POTFILES_DEPS|g" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@PROPERTIESFILES@|$PROPERTIESFILES|g" -e "s|@CLASSFILES@|$CLASSFILES|g" -e "s|@QMFILES@|$QMFILES|g" -e "s|@MSGFILES@|$MSGFILES|g" -e "s|@RESOURCESDLLFILES@|$RESOURCESDLLFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@JAVACATALOGS@|$JAVACATALOGS|g" -e "s|@QTCATALOGS@|$QTCATALOGS|g" -e "s|@TCLCATALOGS@|$TCLCATALOGS|g" -e "s|@CSHARPCATALOGS@|$CSHARPCATALOGS|g" -e 's,^#distdir:,distdir:,' < "$ac_file" > "$ac_file.tmp"
+  if grep -l '@TCLCATALOGS@' "$ac_file" > /dev/null; then
+    # Add dependencies that cannot be formulated as a simple suffix rule.
+    for lang in $ALL_LINGUAS; do
+      frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
+      cat >> "$ac_file.tmp" <<EOF
+$frobbedlang.msg: $lang.po
+	@echo "\$(MSGFMT) -c --tcl -d \$(srcdir) -l $lang $srcdirpre$lang.po"; \
+	\$(MSGFMT) -c --tcl -d "\$(srcdir)" -l $lang $srcdirpre$lang.po || { rm -f "\$(srcdir)/$frobbedlang.msg"; exit 1; }
+EOF
+    done
+  fi
+  if grep -l '@CSHARPCATALOGS@' "$ac_file" > /dev/null; then
+    # Add dependencies that cannot be formulated as a simple suffix rule.
+    for lang in $ALL_LINGUAS; do
+      frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'`
+      cat >> "$ac_file.tmp" <<EOF
+$frobbedlang/\$(DOMAIN).resources.dll: $lang.po
+	@echo "\$(MSGFMT) -c --csharp -d \$(srcdir) -l $lang $srcdirpre$lang.po -r \$(DOMAIN)"; \
+	\$(MSGFMT) -c --csharp -d "\$(srcdir)" -l $lang $srcdirpre$lang.po -r "\$(DOMAIN)" || { rm -f "\$(srcdir)/$frobbedlang.msg"; exit 1; }
+EOF
+    done
+  fi
+  if test -n "$POMAKEFILEDEPS"; then
+    cat >> "$ac_file.tmp" <<EOF
+Makefile: $POMAKEFILEDEPS
+EOF
+  fi
+  mv "$ac_file.tmp" "$ac_file"
+])
+
+dnl Initializes the accumulator used by AM_XGETTEXT_OPTION.
+AC_DEFUN([AM_XGETTEXT_OPTION_INIT],
+[
+  XGETTEXT_EXTRA_OPTIONS=
+])
+
+dnl Registers an option to be passed to xgettext in the po subdirectory.
+AC_DEFUN([AM_XGETTEXT_OPTION],
+[
+  AC_REQUIRE([AM_XGETTEXT_OPTION_INIT])
+  XGETTEXT_EXTRA_OPTIONS="$XGETTEXT_EXTRA_OPTIONS $1"
+])
diff --git a/m4/poll.m4 b/m4/poll.m4
index 80e991142..eb3b78617 100644
--- a/m4/poll.m4
+++ b/m4/poll.m4
@@ -1,5 +1,5 @@
 # poll.m4 serial 20
-dnl Copyright (c) 2003, 2005-2007, 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (c) 2003, 2005-2007, 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/poll_h.m4 b/m4/poll_h.m4
index 1f0d7964a..8fc437bf9 100644
--- a/m4/poll_h.m4
+++ b/m4/poll_h.m4
@@ -1,5 +1,5 @@
 # poll_h.m4 serial 6
-dnl Copyright (C) 2010-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2010-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/posix_spawn.m4 b/m4/posix_spawn.m4
new file mode 100644
index 000000000..86143b678
--- /dev/null
+++ b/m4/posix_spawn.m4
@@ -0,0 +1,691 @@
+# posix_spawn.m4 serial 22
+dnl Copyright (C) 2008-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,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl Tests whether the entire posix_spawn facility is available.
+AC_DEFUN([gl_POSIX_SPAWN],
+[
+  AC_REQUIRE([gl_POSIX_SPAWN_BODY])
+])
+
+AC_DEFUN([gl_POSIX_SPAWN_BODY],
+[
+  AC_REQUIRE([gl_SPAWN_H_DEFAULTS])
+  AC_REQUIRE([gl_HAVE_POSIX_SPAWN])
+  dnl Assume that when the main function exists, all the others,
+  dnl except posix_spawnattr_{get,set}sched*, are available as well.
+  dnl AC_CHECK_FUNCS_ONCE([posix_spawnp])
+  dnl AC_CHECK_FUNCS_ONCE([posix_spawn_file_actions_init])
+  dnl AC_CHECK_FUNCS_ONCE([posix_spawn_file_actions_addclose])
+  dnl AC_CHECK_FUNCS_ONCE([posix_spawn_file_actions_adddup2])
+  dnl AC_CHECK_FUNCS_ONCE([posix_spawn_file_actions_addopen])
+  dnl AC_CHECK_FUNCS_ONCE([posix_spawn_file_actions_destroy])
+  dnl AC_CHECK_FUNCS_ONCE([posix_spawnattr_init])
+  dnl AC_CHECK_FUNCS_ONCE([posix_spawnattr_getflags])
+  dnl AC_CHECK_FUNCS_ONCE([posix_spawnattr_setflags])
+  dnl AC_CHECK_FUNCS_ONCE([posix_spawnattr_getpgroup])
+  dnl AC_CHECK_FUNCS_ONCE([posix_spawnattr_setpgroup])
+  dnl AC_CHECK_FUNCS_ONCE([posix_spawnattr_getsigdefault])
+  dnl AC_CHECK_FUNCS_ONCE([posix_spawnattr_setsigdefault])
+  dnl AC_CHECK_FUNCS_ONCE([posix_spawnattr_getsigmask])
+  dnl AC_CHECK_FUNCS_ONCE([posix_spawnattr_setsigmask])
+  dnl AC_CHECK_FUNCS_ONCE([posix_spawnattr_destroy])
+  AC_CHECK_DECLS([posix_spawn], , , [[#include <spawn.h>]])
+  if test $ac_cv_func_posix_spawn = yes; then
+    m4_ifdef([gl_FUNC_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR],
+      [dnl Module 'posix_spawn_file_actions_addchdir' is present.
+       AC_CHECK_FUNCS_ONCE([posix_spawn_file_actions_addchdir_np])
+       if test $ac_cv_func_posix_spawn_file_actions_addchdir_np = no; then
+         dnl In order to implement the posix_spawn_file_actions_addchdir
+         dnl function, we need to replace the entire posix_spawn facility.
+         REPLACE_POSIX_SPAWN=1
+       fi
+      ])
+    m4_ifdef([gl_FUNC_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR],
+      [dnl Module 'posix_spawn_file_actions_addfchdir' is present.
+       AC_CHECK_FUNCS_ONCE([posix_spawn_file_actions_addfchdir_np])
+       if test $ac_cv_func_posix_spawn_file_actions_addfchdir_np = no; then
+         dnl In order to implement the posix_spawn_file_actions_addfchdir
+         dnl function, we need to replace the entire posix_spawn facility.
+         REPLACE_POSIX_SPAWN=1
+       fi
+      ])
+    if test $REPLACE_POSIX_SPAWN = 0; then
+      gl_POSIX_SPAWN_WORKS
+      case "$gl_cv_func_posix_spawn_works" in
+        *yes) ;;
+        *) REPLACE_POSIX_SPAWN=1 ;;
+      esac
+    fi
+    if test $REPLACE_POSIX_SPAWN = 0; then
+      gl_POSIX_SPAWN_SECURE
+      case "$gl_cv_func_posix_spawn_secure_exec" in
+        *yes) ;;
+        *) REPLACE_POSIX_SPAWN=1 ;;
+      esac
+      case "$gl_cv_func_posix_spawnp_secure_exec" in
+        *yes) ;;
+        *) REPLACE_POSIX_SPAWN=1 ;;
+      esac
+    fi
+    if test $REPLACE_POSIX_SPAWN = 0; then
+      dnl Assume that these functions are available if POSIX_SPAWN_SETSCHEDULER
+      dnl evaluates to nonzero.
+      dnl AC_CHECK_FUNCS_ONCE([posix_spawnattr_getschedpolicy])
+      dnl AC_CHECK_FUNCS_ONCE([posix_spawnattr_setschedpolicy])
+      AC_CACHE_CHECK([whether posix_spawnattr_setschedpolicy is supported],
+        [gl_cv_func_spawnattr_setschedpolicy],
+        [AC_EGREP_CPP([POSIX scheduling supported], [
+#include <spawn.h>
+#if POSIX_SPAWN_SETSCHEDULER
+ POSIX scheduling supported
+#endif
+],
+           [gl_cv_func_spawnattr_setschedpolicy=yes],
+           [gl_cv_func_spawnattr_setschedpolicy=no])
+        ])
+      dnl Assume that these functions are available if POSIX_SPAWN_SETSCHEDPARAM
+      dnl evaluates to nonzero.
+      dnl AC_CHECK_FUNCS_ONCE([posix_spawnattr_getschedparam])
+      dnl AC_CHECK_FUNCS_ONCE([posix_spawnattr_setschedparam])
+      AC_CACHE_CHECK([whether posix_spawnattr_setschedparam is supported],
+        [gl_cv_func_spawnattr_setschedparam],
+        [AC_EGREP_CPP([POSIX scheduling supported], [
+#include <spawn.h>
+#if POSIX_SPAWN_SETSCHEDPARAM
+ POSIX scheduling supported
+#endif
+],
+           [gl_cv_func_spawnattr_setschedparam=yes],
+           [gl_cv_func_spawnattr_setschedparam=no])
+        ])
+    fi
+  else
+    dnl The system does not have the main function. Therefore we have to
+    dnl provide our own implementation. This implies to define our own
+    dnl posix_spawn_file_actions_t and posix_spawnattr_t types.
+    if test $ac_cv_have_decl_posix_spawn = yes; then
+      dnl The system declares posix_spawn() already. This declaration uses
+      dnl the original posix_spawn_file_actions_t and posix_spawnattr_t types.
+      dnl But we need a declaration with our own posix_spawn_file_actions_t and
+      dnl posix_spawnattr_t types.
+      REPLACE_POSIX_SPAWN=1
+    fi
+  fi
+  if test $ac_cv_func_posix_spawn != yes || test $REPLACE_POSIX_SPAWN = 1; then
+    AC_DEFINE([REPLACE_POSIX_SPAWN], [1],
+      [Define if gnulib uses its own posix_spawn and posix_spawnp functions.])
+  fi
+])
+
+dnl Test whether posix_spawn actually works.
+dnl posix_spawn on AIX 5.3..6.1 has two bugs:
+dnl 1) When it fails to execute the program, the child process exits with
+dnl    exit() rather than _exit(), which causes the stdio buffers to be
+dnl    flushed. Reported by Rainer Tammer.
+dnl 2) The posix_spawn_file_actions_addopen function does not support file
+dnl    names that contain a '*'.
+dnl posix_spawn on AIX 5.3..6.1 has also a third bug: It does not work
+dnl when POSIX threads are used. But we don't test against this bug here.
+AC_DEFUN([gl_POSIX_SPAWN_WORKS],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_CACHE_CHECK([whether posix_spawn works], [gl_cv_func_posix_spawn_works],
+    [if test $cross_compiling = no; then
+       AC_LINK_IFELSE([AC_LANG_SOURCE([[
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <spawn.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+]GL_MDA_DEFINES[
+
+extern char **environ;
+
+#ifndef STDIN_FILENO
+# define STDIN_FILENO 0
+#endif
+#ifndef STDOUT_FILENO
+# define STDOUT_FILENO 1
+#endif
+#ifndef STDERR_FILENO
+# define STDERR_FILENO 2
+#endif
+
+#ifndef WTERMSIG
+# define WTERMSIG(x) ((x) & 0x7f)
+#endif
+#ifndef WIFEXITED
+# define WIFEXITED(x) (WTERMSIG (x) == 0)
+#endif
+#ifndef WEXITSTATUS
+# define WEXITSTATUS(x) (((x) >> 8) & 0xff)
+#endif
+
+#define CHILD_PROGRAM_FILENAME "/non/exist/ent"
+
+static int
+fd_safer (int fd)
+{
+  if (0 <= fd && fd <= 2)
+    {
+      int f = fd_safer (dup (fd));
+      int e = errno;
+      close (fd);
+      errno = e;
+      fd = f;
+    }
+
+  return fd;
+}
+
+int
+main ()
+{
+  char *argv[2] = { CHILD_PROGRAM_FILENAME, NULL };
+  int ofd[2];
+  sigset_t blocked_signals;
+  sigset_t fatal_signal_set;
+  posix_spawn_file_actions_t actions;
+  bool actions_allocated;
+  posix_spawnattr_t attrs;
+  bool attrs_allocated;
+  int err;
+  pid_t child;
+  int status;
+  int exitstatus;
+
+  setvbuf (stdout, NULL, _IOFBF, 0);
+  puts ("This should be seen only once.");
+  if (pipe (ofd) < 0 || (ofd[1] = fd_safer (ofd[1])) < 0)
+    {
+      perror ("cannot create pipe");
+      exit (1);
+    }
+  sigprocmask (SIG_SETMASK, NULL, &blocked_signals);
+  sigemptyset (&fatal_signal_set);
+  sigaddset (&fatal_signal_set, SIGINT);
+  sigaddset (&fatal_signal_set, SIGTERM);
+  sigaddset (&fatal_signal_set, SIGHUP);
+  sigaddset (&fatal_signal_set, SIGPIPE);
+  sigprocmask (SIG_BLOCK, &fatal_signal_set, NULL);
+  actions_allocated = false;
+  attrs_allocated = false;
+  if ((err = posix_spawn_file_actions_init (&actions)) != 0
+      || (actions_allocated = true,
+          (err = posix_spawn_file_actions_adddup2 (&actions, ofd[0], STDIN_FILENO)) != 0
+          || (err = posix_spawn_file_actions_addclose (&actions, ofd[0])) != 0
+          || (err = posix_spawn_file_actions_addclose (&actions, ofd[1])) != 0
+          || (err = posix_spawnattr_init (&attrs)) != 0
+          || (attrs_allocated = true,
+              (err = posix_spawnattr_setsigmask (&attrs, &blocked_signals)) != 0
+              || (err = posix_spawnattr_setflags (&attrs, POSIX_SPAWN_SETSIGMASK)) != 0)
+          || (err = posix_spawnp (&child, CHILD_PROGRAM_FILENAME, &actions, &attrs, argv, environ)) != 0))
+    {
+      if (actions_allocated)
+        posix_spawn_file_actions_destroy (&actions);
+      if (attrs_allocated)
+        posix_spawnattr_destroy (&attrs);
+      sigprocmask (SIG_UNBLOCK, &fatal_signal_set, NULL);
+      if (err == ENOENT)
+        return 0;
+      else
+        {
+          errno = err;
+          perror ("subprocess failed");
+          exit (1);
+        }
+    }
+  posix_spawn_file_actions_destroy (&actions);
+  posix_spawnattr_destroy (&attrs);
+  sigprocmask (SIG_UNBLOCK, &fatal_signal_set, NULL);
+  close (ofd[0]);
+  close (ofd[1]);
+  status = 0;
+  while (waitpid (child, &status, 0) != child)
+    ;
+  if (!WIFEXITED (status))
+    {
+      fprintf (stderr, "subprocess terminated with unexpected wait status %d\n", status);
+      exit (1);
+    }
+  exitstatus = WEXITSTATUS (status);
+  if (exitstatus != 127)
+    {
+      fprintf (stderr, "subprocess terminated with unexpected exit status %d\n", exitstatus);
+      exit (1);
+    }
+  return 0;
+}
+]])],
+         [if test -s conftest$ac_exeext \
+             && ./conftest$ac_exeext > conftest.out \
+             && echo 'This should be seen only once.' > conftest.ok \
+             && cmp conftest.out conftest.ok >/dev/null 2>&1; then
+            gl_cv_func_posix_spawn_works=yes
+          else
+            gl_cv_func_posix_spawn_works=no
+          fi],
+         [gl_cv_func_posix_spawn_works=no])
+       if test $gl_cv_func_posix_spawn_works = yes; then
+         AC_RUN_IFELSE([AC_LANG_SOURCE([[
+/* Test whether posix_spawn_file_actions_addopen supports filename arguments
+   that contain special characters such as '*'.  */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <spawn.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+]GL_MDA_DEFINES[
+
+extern char **environ;
+
+#ifndef STDIN_FILENO
+# define STDIN_FILENO 0
+#endif
+#ifndef STDOUT_FILENO
+# define STDOUT_FILENO 1
+#endif
+#ifndef STDERR_FILENO
+# define STDERR_FILENO 2
+#endif
+
+#ifndef WTERMSIG
+# define WTERMSIG(x) ((x) & 0x7f)
+#endif
+#ifndef WIFEXITED
+# define WIFEXITED(x) (WTERMSIG (x) == 0)
+#endif
+#ifndef WEXITSTATUS
+# define WEXITSTATUS(x) (((x) >> 8) & 0xff)
+#endif
+
+#define CHILD_PROGRAM_FILENAME "conftest"
+#define DATA_FILENAME "conftest%=*#?"
+
+static int
+parent_main (void)
+{
+  FILE *fp;
+  char *argv[3] = { CHILD_PROGRAM_FILENAME, "-child", NULL };
+  posix_spawn_file_actions_t actions;
+  bool actions_allocated;
+  int err;
+  pid_t child;
+  int status;
+  int exitstatus;
+
+  /* Create a data file with specific contents.  */
+  fp = fopen (DATA_FILENAME, "wb");
+  if (fp == NULL)
+    {
+      perror ("cannot create data file");
+      return 1;
+    }
+  fwrite ("Halle Potta", 1, 11, fp);
+  if (fflush (fp) || fclose (fp))
+    {
+      perror ("cannot prepare data file");
+      return 2;
+    }
+
+  /* Avoid reading from our stdin, as it could block.  */
+  freopen ("/dev/null", "rb", stdin);
+
+  /* Test whether posix_spawn_file_actions_addopen with this file name
+     actually works, but spawning a child that reads from this file.  */
+  actions_allocated = false;
+  if ((err = posix_spawn_file_actions_init (&actions)) != 0
+      || (actions_allocated = true,
+          (err = posix_spawn_file_actions_addopen (&actions, STDIN_FILENO, DATA_FILENAME, O_RDONLY, 0600)) != 0
+          || (err = posix_spawn (&child, CHILD_PROGRAM_FILENAME, &actions, NULL, argv, environ)) != 0))
+    {
+      if (actions_allocated)
+        posix_spawn_file_actions_destroy (&actions);
+      errno = err;
+      perror ("subprocess failed");
+      return 3;
+    }
+  posix_spawn_file_actions_destroy (&actions);
+  status = 0;
+  while (waitpid (child, &status, 0) != child)
+    ;
+  if (!WIFEXITED (status))
+    {
+      fprintf (stderr, "subprocess terminated with unexpected wait status %d\n", status);
+      return 4;
+    }
+  exitstatus = WEXITSTATUS (status);
+  if (exitstatus != 0)
+    {
+      fprintf (stderr, "subprocess terminated with unexpected exit status %d\n", exitstatus);
+      return 5;
+    }
+  return 0;
+}
+
+static int
+child_main (void)
+{
+  char buf[1024];
+
+  /* See if reading from STDIN_FILENO yields the expected contents.  */
+  if (fread (buf, 1, sizeof (buf), stdin) == 11
+      && memcmp (buf, "Halle Potta", 11) == 0)
+    return 0;
+  else
+    return 8;
+}
+
+static void
+cleanup_then_die (int sig)
+{
+  /* Clean up data file.  */
+  unlink (DATA_FILENAME);
+
+  /* Re-raise the signal and die from it.  */
+  signal (sig, SIG_DFL);
+  raise (sig);
+}
+
+int
+main (int argc, char *argv[])
+{
+  int exitstatus;
+
+  if (!(argc > 1 && strcmp (argv[1], "-child") == 0))
+    {
+      /* This is the parent process.  */
+      signal (SIGINT, cleanup_then_die);
+      signal (SIGTERM, cleanup_then_die);
+      #ifdef SIGHUP
+      signal (SIGHUP, cleanup_then_die);
+      #endif
+
+      exitstatus = parent_main ();
+    }
+  else
+    {
+      /* This is the child process.  */
+
+      exitstatus = child_main ();
+    }
+  unlink (DATA_FILENAME);
+  return exitstatus;
+}
+]])],
+           [],
+           [gl_cv_func_posix_spawn_works=no])
+       fi
+     else
+       case "$host_os" in
+         aix*) gl_cv_func_posix_spawn_works="guessing no";;
+         *)    gl_cv_func_posix_spawn_works="guessing yes";;
+       esac
+     fi
+    ])
+])
+
+dnl Test whether posix_spawn and posix_spawnp are secure.
+AC_DEFUN([gl_POSIX_SPAWN_SECURE],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  dnl On many platforms, posix_spawn or posix_spawnp allow executing a
+  dnl script without a '#!' marker as a shell script. This is unsecure.
+  AC_CACHE_CHECK([whether posix_spawn rejects scripts without shebang],
+    [gl_cv_func_posix_spawn_secure_exec],
+    [echo ':' > conftest.scr
+     chmod a+x conftest.scr
+     AC_RUN_IFELSE([AC_LANG_SOURCE([[
+       #include <errno.h>
+       #include <spawn.h>
+       #include <stddef.h>
+       #include <sys/types.h>
+       #include <sys/wait.h>
+       int
+       main ()
+       {
+         const char *prog_path = "./conftest.scr";
+         const char *prog_argv[2] = { prog_path, NULL };
+         const char *environment[2] = { "PATH=.", NULL };
+         pid_t child;
+         int status;
+         int err = posix_spawn (&child, prog_path, NULL, NULL,
+                                (char **) prog_argv, (char **) environment);
+         if (err == ENOEXEC)
+           return 0;
+         if (err != 0)
+           return 1;
+         status = 0;
+         while (waitpid (child, &status, 0) != child)
+           ;
+         if (!WIFEXITED (status))
+           return 2;
+         if (WEXITSTATUS (status) != 127)
+           return 3;
+         return 0;
+       }
+       ]])],
+       [gl_cv_func_posix_spawn_secure_exec=yes],
+       [gl_cv_func_posix_spawn_secure_exec=no],
+       [case "$host_os" in
+          # Guess no on GNU/Hurd.
+          gnu*)
+            gl_cv_func_posix_spawn_secure_exec="guessing no" ;;
+          # Guess yes on all other platforms.
+          *)
+            gl_cv_func_posix_spawn_secure_exec="guessing yes" ;;
+        esac
+       ])
+     rm -f conftest.scr
+    ])
+  AC_CACHE_CHECK([whether posix_spawnp rejects scripts without shebang],
+    [gl_cv_func_posix_spawnp_secure_exec],
+    [echo ':' > conftest.scr
+     chmod a+x conftest.scr
+     AC_RUN_IFELSE([AC_LANG_SOURCE([[
+       #include <errno.h>
+       #include <spawn.h>
+       #include <stddef.h>
+       #include <sys/types.h>
+       #include <sys/wait.h>
+       int
+       main ()
+       {
+         const char *prog_path = "./conftest.scr";
+         const char *prog_argv[2] = { prog_path, NULL };
+         const char *environment[2] = { "PATH=.", NULL };
+         pid_t child;
+         int status;
+         int err = posix_spawnp (&child, prog_path, NULL, NULL,
+                                 (char **) prog_argv, (char **) environment);
+         if (err == ENOEXEC)
+           return 0;
+         if (err != 0)
+           return 1;
+         status = 0;
+         while (waitpid (child, &status, 0) != child)
+           ;
+         if (!WIFEXITED (status))
+           return 2;
+         if (WEXITSTATUS (status) != 127)
+           return 3;
+         return 0;
+       }
+       ]])],
+       [gl_cv_func_posix_spawnp_secure_exec=yes],
+       [gl_cv_func_posix_spawnp_secure_exec=no],
+       [case "$host_os" in
+          # Guess yes on glibc systems (glibc >= 2.15 actually) except GNU/Hurd,
+          # musl libc, NetBSD.
+          *-gnu* | *-musl* | netbsd*)
+            gl_cv_func_posix_spawnp_secure_exec="guessing yes" ;;
+          # Guess no on GNU/Hurd, macOS, FreeBSD, OpenBSD, AIX, Solaris, Cygwin.
+          gnu* | darwin* | freebsd* | dragonfly* | midnightbsd* | openbsd* | \
+          aix* | solaris* | cygwin*)
+            gl_cv_func_posix_spawnp_secure_exec="guessing no" ;;
+          # If we don't know, obey --enable-cross-guesses.
+          *)
+            gl_cv_func_posix_spawnp_secure_exec="$gl_cross_guess_normal" ;;
+        esac
+       ])
+     rm -f conftest.scr
+    ])
+])
+
+# Prerequisites of lib/spawni.c.
+AC_DEFUN([gl_PREREQ_POSIX_SPAWN_INTERNAL],
+[
+  AC_CHECK_HEADERS([paths.h])
+  AC_CHECK_FUNCS([confstr sched_setparam sched_setscheduler setegid seteuid vfork])
+])
+
+AC_DEFUN([gl_FUNC_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE],
+[
+  AC_REQUIRE([gl_SPAWN_H_DEFAULTS])
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  gl_POSIX_SPAWN
+  if test $REPLACE_POSIX_SPAWN = 1; then
+    REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE=1
+  else
+    dnl On musl libc, posix_spawn_file_actions_addclose succeeds even if the fd
+    dnl argument is negative.
+    AC_CACHE_CHECK([whether posix_spawn_file_actions_addclose works],
+      [gl_cv_func_posix_spawn_file_actions_addclose_works],
+      [AC_RUN_IFELSE(
+         [AC_LANG_SOURCE([[
+#include <spawn.h>
+int main ()
+{
+  posix_spawn_file_actions_t actions;
+  if (posix_spawn_file_actions_init (&actions) != 0)
+    return 1;
+  if (posix_spawn_file_actions_addclose (&actions, -5) == 0)
+    return 2;
+  return 0;
+}]])],
+         [gl_cv_func_posix_spawn_file_actions_addclose_works=yes],
+         [gl_cv_func_posix_spawn_file_actions_addclose_works=no],
+         [# Guess no on musl libc and Solaris, yes otherwise.
+          case "$host_os" in
+            *-musl*)  gl_cv_func_posix_spawn_file_actions_addclose_works="guessing no" ;;
+            solaris*) gl_cv_func_posix_spawn_file_actions_addclose_works="guessing no" ;;
+                      # Guess no on native Windows.
+            mingw*)   gl_cv_func_posix_spawn_file_actions_addclose_works="guessing no" ;;
+            *)        gl_cv_func_posix_spawn_file_actions_addclose_works="guessing yes" ;;
+          esac
+         ])
+      ])
+    case "$gl_cv_func_posix_spawn_file_actions_addclose_works" in
+      *yes) ;;
+      *) REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE=1 ;;
+    esac
+  fi
+])
+
+AC_DEFUN([gl_FUNC_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2],
+[
+  AC_REQUIRE([gl_SPAWN_H_DEFAULTS])
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  gl_POSIX_SPAWN
+  if test $REPLACE_POSIX_SPAWN = 1; then
+    REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2=1
+  else
+    dnl On musl libc and Solaris 11.0, posix_spawn_file_actions_adddup2
+    dnl succeeds even if the fd argument is out of range.
+    AC_CACHE_CHECK([whether posix_spawn_file_actions_adddup2 works],
+      [gl_cv_func_posix_spawn_file_actions_adddup2_works],
+      [AC_RUN_IFELSE(
+         [AC_LANG_SOURCE([[
+#include <spawn.h>
+int main ()
+{
+  posix_spawn_file_actions_t actions;
+  if (posix_spawn_file_actions_init (&actions) != 0)
+    return 1;
+  if (posix_spawn_file_actions_adddup2 (&actions, 10000000, 2) == 0)
+    return 2;
+  return 0;
+}]])],
+         [gl_cv_func_posix_spawn_file_actions_adddup2_works=yes],
+         [gl_cv_func_posix_spawn_file_actions_adddup2_works=no],
+         [# Guess no on musl libc and Solaris, yes otherwise.
+          case "$host_os" in
+            *-musl*)  gl_cv_func_posix_spawn_file_actions_adddup2_works="guessing no";;
+            solaris*) gl_cv_func_posix_spawn_file_actions_adddup2_works="guessing no";;
+                      # Guess no on native Windows.
+            mingw*)   gl_cv_func_posix_spawn_file_actions_adddup2_works="guessing no" ;;
+            *)        gl_cv_func_posix_spawn_file_actions_adddup2_works="guessing yes";;
+          esac
+         ])
+      ])
+    case "$gl_cv_func_posix_spawn_file_actions_adddup2_works" in
+      *yes) ;;
+      *) REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2=1 ;;
+    esac
+  fi
+])
+
+AC_DEFUN([gl_FUNC_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN],
+[
+  AC_REQUIRE([gl_SPAWN_H_DEFAULTS])
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  gl_POSIX_SPAWN
+  if test $REPLACE_POSIX_SPAWN = 1; then
+    REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN=1
+  else
+    dnl On musl libc and Solaris 11.0, posix_spawn_file_actions_addopen
+    dnl succeeds even if the fd argument is out of range.
+    AC_CACHE_CHECK([whether posix_spawn_file_actions_addopen works],
+      [gl_cv_func_posix_spawn_file_actions_addopen_works],
+      [AC_RUN_IFELSE(
+         [AC_LANG_SOURCE([[
+#include <spawn.h>
+#include <fcntl.h>
+int main ()
+{
+  posix_spawn_file_actions_t actions;
+  if (posix_spawn_file_actions_init (&actions) != 0)
+    return 1;
+  if (posix_spawn_file_actions_addopen (&actions, 10000000, "foo", 0, O_RDONLY)
+      == 0)
+    return 2;
+  return 0;
+}]])],
+         [gl_cv_func_posix_spawn_file_actions_addopen_works=yes],
+         [gl_cv_func_posix_spawn_file_actions_addopen_works=no],
+         [# Guess no on musl libc and Solaris, yes otherwise.
+          case "$host_os" in
+            *-musl*)  gl_cv_func_posix_spawn_file_actions_addopen_works="guessing no";;
+            solaris*) gl_cv_func_posix_spawn_file_actions_addopen_works="guessing no";;
+                      # Guess no on native Windows.
+            mingw*)   gl_cv_func_posix_spawn_file_actions_addopen_works="guessing no" ;;
+            *)        gl_cv_func_posix_spawn_file_actions_addopen_works="guessing yes";;
+          esac
+         ])
+      ])
+    case "$gl_cv_func_posix_spawn_file_actions_addopen_works" in
+      *yes) ;;
+      *) REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN=1 ;;
+    esac
+  fi
+])
diff --git a/m4/printf-posix.m4 b/m4/printf-posix.m4
new file mode 100644
index 000000000..1eacf95ac
--- /dev/null
+++ b/m4/printf-posix.m4
@@ -0,0 +1,45 @@
+# printf-posix.m4 serial 5 (gettext-0.18)
+dnl Copyright (C) 2003, 2007, 2009-2010 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 From Bruno Haible.
+dnl Test whether the printf() function supports POSIX/XSI format strings with
+dnl positions.
+
+AC_DEFUN([gt_PRINTF_POSIX],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_CACHE_CHECK([whether printf() supports POSIX/XSI format strings],
+    gt_cv_func_printf_posix,
+    [
+      AC_TRY_RUN([
+#include <stdio.h>
+#include <string.h>
+/* The string "%2$d %1$d", with dollar characters protected from the shell's
+   dollar expansion (possibly an autoconf bug).  */
+static char format[] = { '%', '2', '$', 'd', ' ', '%', '1', '$', 'd', '\0' };
+static char buf[100];
+int main ()
+{
+  sprintf (buf, format, 33, 55);
+  return (strcmp (buf, "55 33") != 0);
+}], gt_cv_func_printf_posix=yes, gt_cv_func_printf_posix=no,
+      [
+        AC_EGREP_CPP([notposix], [
+#if defined __NetBSD__ || defined __BEOS__ || defined _MSC_VER || defined __MINGW32__ || defined __CYGWIN__
+  notposix
+#endif
+          ],
+          [gt_cv_func_printf_posix="guessing no"],
+          [gt_cv_func_printf_posix="guessing yes"])
+      ])
+    ])
+  case $gt_cv_func_printf_posix in
+    *yes)
+      AC_DEFINE([HAVE_POSIX_PRINTF], [1],
+        [Define if your printf() function supports format strings with positions.])
+      ;;
+  esac
+])
diff --git a/m4/printf.m4 b/m4/printf.m4
index 284c7c5d3..667452e34 100644
--- a/m4/printf.m4
+++ b/m4/printf.m4
@@ -1,5 +1,5 @@
 # printf.m4 serial 73
-dnl Copyright (C) 2003, 2007-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2003, 2007-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/progtest.m4 b/m4/progtest.m4
new file mode 100644
index 000000000..2d804ac99
--- /dev/null
+++ b/m4/progtest.m4
@@ -0,0 +1,92 @@
+# progtest.m4 serial 6 (gettext-0.18)
+dnl Copyright (C) 1996-2003, 2005, 2008-2010 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
+dnl This file can can be used in projects which are not available under
+dnl the GNU General Public License or the GNU Library General Public
+dnl License but which still want to provide support for the GNU gettext
+dnl functionality.
+dnl Please note that the actual code of the GNU gettext library is covered
+dnl by the GNU Library General Public License, and the rest of the GNU
+dnl gettext package package is covered by the GNU General Public License.
+dnl They are *not* in the public domain.
+
+dnl Authors:
+dnl   Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+AC_PREREQ([2.50])
+
+# Search path for a program which passes the given test.
+
+dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR,
+dnl   TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
+AC_DEFUN([AM_PATH_PROG_WITH_TEST],
+[
+# Prepare PATH_SEPARATOR.
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+# Find out how to test for executable files. Don't use a zero-byte file,
+# as systems may use methods other than mode bits to determine executability.
+cat >conf$$.file <<_ASEOF
+#! /bin/sh
+exit 0
+_ASEOF
+chmod +x conf$$.file
+if test -x conf$$.file >/dev/null 2>&1; then
+  ac_executable_p="test -x"
+else
+  ac_executable_p="test -f"
+fi
+rm -f conf$$.file
+
+# Extract the first word of "$2", so it can be a program name with args.
+set dummy $2; ac_word=[$]2
+AC_MSG_CHECKING([for $ac_word])
+AC_CACHE_VAL([ac_cv_path_$1],
+[case "[$]$1" in
+  [[\\/]]* | ?:[[\\/]]*)
+    ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
+    ;;
+  *)
+    ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR
+    for ac_dir in ifelse([$5], , $PATH, [$5]); do
+      IFS="$ac_save_IFS"
+      test -z "$ac_dir" && ac_dir=.
+      for ac_exec_ext in '' $ac_executable_extensions; do
+        if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then
+          echo "$as_me: trying $ac_dir/$ac_word..." >&AS_MESSAGE_LOG_FD
+          if [$3]; then
+            ac_cv_path_$1="$ac_dir/$ac_word$ac_exec_ext"
+            break 2
+          fi
+        fi
+      done
+    done
+    IFS="$ac_save_IFS"
+dnl If no 4th arg is given, leave the cache variable unset,
+dnl so AC_PATH_PROGS will keep looking.
+ifelse([$4], , , [  test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
+])dnl
+    ;;
+esac])dnl
+$1="$ac_cv_path_$1"
+if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then
+  AC_MSG_RESULT([$][$1])
+else
+  AC_MSG_RESULT([no])
+fi
+AC_SUBST([$1])dnl
+])
diff --git a/m4/putenv.m4 b/m4/putenv.m4
index 919984d91..c7b45034e 100644
--- a/m4/putenv.m4
+++ b/m4/putenv.m4
@@ -1,5 +1,5 @@
 # putenv.m4 serial 25
-dnl Copyright (C) 2002-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2002-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/raise.m4 b/m4/raise.m4
index 4bf0ca9c1..0c78d0950 100644
--- a/m4/raise.m4
+++ b/m4/raise.m4
@@ -1,5 +1,5 @@
 # raise.m4 serial 4
-dnl Copyright (C) 2011-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2011-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/rawmemchr.m4 b/m4/rawmemchr.m4
index 452fab18f..dae419355 100644
--- a/m4/rawmemchr.m4
+++ b/m4/rawmemchr.m4
@@ -1,5 +1,5 @@
 # rawmemchr.m4 serial 3
-dnl Copyright (C) 2003, 2007-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2003, 2007-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/read.m4 b/m4/read.m4
index c162b7cda..1c199eabb 100644
--- a/m4/read.m4
+++ b/m4/read.m4
@@ -1,5 +1,5 @@
 # read.m4 serial 5
-dnl Copyright (C) 2011-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2011-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/readlink.m4 b/m4/readlink.m4
index 352788c65..d1dd52122 100644
--- a/m4/readlink.m4
+++ b/m4/readlink.m4
@@ -1,5 +1,5 @@
 # readlink.m4 serial 16
-dnl Copyright (C) 2003, 2007, 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2003, 2007, 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/realloc.m4 b/m4/realloc.m4
index 0abc4185e..86e57c259 100644
--- a/m4/realloc.m4
+++ b/m4/realloc.m4
@@ -1,5 +1,5 @@
-# realloc.m4 serial 24
-dnl Copyright (C) 2007, 2009-2021 Free Software Foundation, Inc.
+# realloc.m4 serial 26
+dnl Copyright (C) 2007, 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
@@ -43,8 +43,8 @@ AC_DEFUN([gl_FUNC_REALLOC_GNU],
 [
   AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
   AC_REQUIRE([gl_FUNC_REALLOC_POSIX])
-  if test $REPLACE_REALLOC = 0; then
-    _AC_FUNC_REALLOC_IF([], [REPLACE_REALLOC=1])
+  if test $REPLACE_REALLOC_FOR_REALLOC_GNU = 0; then
+    _AC_FUNC_REALLOC_IF([], [REPLACE_REALLOC_FOR_REALLOC_GNU=1])
   fi
 ])# gl_FUNC_REALLOC_GNU
 
@@ -57,7 +57,7 @@ AC_DEFUN([gl_FUNC_REALLOC_POSIX],
 [
   AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
   AC_REQUIRE([gl_FUNC_MALLOC_POSIX])
-  if test $REPLACE_MALLOC = 1; then
-    REPLACE_REALLOC=1
+  if test $REPLACE_MALLOC_FOR_MALLOC_POSIX = 1; then
+    REPLACE_REALLOC_FOR_REALLOC_POSIX=1
   fi
 ])
diff --git a/m4/regex.m4 b/m4/regex.m4
index 1c7e562f6..47342986d 100644
--- a/m4/regex.m4
+++ b/m4/regex.m4
@@ -1,6 +1,6 @@
 # serial 73
 
-# Copyright (C) 1996-2001, 2003-2021 Free Software Foundation, Inc.
+# Copyright (C) 1996-2001, 2003-2022 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
diff --git a/m4/rename.m4 b/m4/rename.m4
index 8a95b8aee..9f1a56543 100644
--- a/m4/rename.m4
+++ b/m4/rename.m4
@@ -1,6 +1,6 @@
 # serial 33
 
-# Copyright (C) 2001, 2003, 2005-2006, 2009-2021 Free Software Foundation, Inc.
+# Copyright (C) 2001, 2003, 2005-2006, 2009-2022 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.
diff --git a/m4/rmdir.m4 b/m4/rmdir.m4
index 82b9cccf2..54880278d 100644
--- a/m4/rmdir.m4
+++ b/m4/rmdir.m4
@@ -1,5 +1,5 @@
 # rmdir.m4 serial 18
-dnl Copyright (C) 2002, 2005, 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2002, 2005, 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/round.m4 b/m4/round.m4
index 68399d363..177bfdf62 100644
--- a/m4/round.m4
+++ b/m4/round.m4
@@ -1,5 +1,5 @@
 # round.m4 serial 23
-dnl Copyright (C) 2007, 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2007, 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/safe-read.m4 b/m4/safe-read.m4
index 3cba2888d..54d47699c 100644
--- a/m4/safe-read.m4
+++ b/m4/safe-read.m4
@@ -1,5 +1,5 @@
 # safe-read.m4 serial 6
-dnl Copyright (C) 2002-2003, 2005-2006, 2009-2021 Free Software Foundation,
+dnl Copyright (C) 2002-2003, 2005-2006, 2009-2022 Free Software Foundation,
 dnl Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
diff --git a/m4/safe-write.m4 b/m4/safe-write.m4
index ef10d961b..65c791193 100644
--- a/m4/safe-write.m4
+++ b/m4/safe-write.m4
@@ -1,5 +1,5 @@
 # safe-write.m4 serial 4
-dnl Copyright (C) 2002, 2005-2006, 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2002, 2005-2006, 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/sched_h.m4 b/m4/sched_h.m4
new file mode 100644
index 000000000..ce44f7b36
--- /dev/null
+++ b/m4/sched_h.m4
@@ -0,0 +1,106 @@
+# sched_h.m4 serial 15
+dnl Copyright (C) 2008-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,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl Written by Bruno Haible.
+
+AC_DEFUN_ONCE([gl_SCHED_H],
+[
+  dnl Ensure to expand the default settings once only, before all statements
+  dnl that occur in other macros.
+  AC_REQUIRE([gl_SCHED_H_DEFAULTS])
+
+  AC_REQUIRE([AC_CANONICAL_HOST])
+
+  AC_CHECK_HEADERS_ONCE([sys/cdefs.h])
+  AC_CHECK_HEADERS([sched.h], [], [],
+    [[#if HAVE_SYS_CDEFS_H
+       #include <sys/cdefs.h>
+      #endif
+    ]])
+  gl_NEXT_HEADERS([sched.h])
+
+  if test "$ac_cv_header_sched_h" = yes; then
+    HAVE_SCHED_H=1
+  else
+    HAVE_SCHED_H=0
+  fi
+  AC_SUBST([HAVE_SCHED_H])
+
+  if test "$HAVE_SCHED_H" = 1; then
+    AC_CHECK_TYPE([struct sched_param],
+      [HAVE_STRUCT_SCHED_PARAM=1], [HAVE_STRUCT_SCHED_PARAM=0],
+      [[#if HAVE_SYS_CDEFS_H
+         #include <sys/cdefs.h>
+        #endif
+        #include <sched.h>
+      ]])
+  else
+    HAVE_STRUCT_SCHED_PARAM=0
+    case "$host_os" in
+      os2*)
+        dnl On OS/2 kLIBC, struct sched_param is in spawn.h.
+        AC_CHECK_TYPE([struct sched_param],
+          [HAVE_STRUCT_SCHED_PARAM=1], [],
+          [#include <spawn.h>])
+        ;;
+      vms)
+        dnl On OpenVMS 7.2 or newer, struct sched_param is in pthread.h.
+        AC_CHECK_TYPE([struct sched_param],
+          [HAVE_STRUCT_SCHED_PARAM=1], [],
+          [#include <pthread.h>])
+        ;;
+    esac
+  fi
+  AC_SUBST([HAVE_STRUCT_SCHED_PARAM])
+
+  if test "$ac_cv_header_sys_cdefs_h" = yes; then
+    HAVE_SYS_CDEFS_H=1
+  else
+    HAVE_SYS_CDEFS_H=0
+  fi
+  AC_SUBST([HAVE_SYS_CDEFS_H])
+
+  dnl Ensure the type pid_t gets defined.
+  AC_REQUIRE([AC_TYPE_PID_T])
+
+  dnl Check for declarations of anything we want to poison if the
+  dnl corresponding gnulib module is not in use, if it is not common
+  dnl enough to be declared everywhere.
+  gl_WARN_ON_USE_PREPARE([[#include <sched.h>
+    ]], [sched_yield])
+])
+
+# gl_SCHED_MODULE_INDICATOR([modulename])
+# sets the shell variable that indicates the presence of the given module
+# to a C preprocessor expression that will evaluate to 1.
+# This macro invocation must not occur in macros that are AC_REQUIREd.
+AC_DEFUN([gl_SCHED_MODULE_INDICATOR],
+[
+  dnl Ensure to expand the default settings once only.
+  gl_SCHED_H_REQUIRE_DEFAULTS
+  gl_MODULE_INDICATOR_SET_VARIABLE([$1])
+  dnl Define it also as a C macro, for the benefit of the unit tests.
+  gl_MODULE_INDICATOR_FOR_TESTS([$1])
+])
+
+# Initializes the default values for AC_SUBSTed shell variables.
+# This macro must not be AC_REQUIREd.  It must only be invoked, and only
+# outside of macros or in macros that are not AC_REQUIREd.
+AC_DEFUN([gl_SCHED_H_REQUIRE_DEFAULTS],
+[
+  m4_defun(GL_MODULE_INDICATOR_PREFIX[_SCHED_H_MODULE_INDICATOR_DEFAULTS], [
+    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SCHED_YIELD])
+  ])
+  m4_require(GL_MODULE_INDICATOR_PREFIX[_SCHED_H_MODULE_INDICATOR_DEFAULTS])
+  AC_REQUIRE([gl_SCHED_H_DEFAULTS])
+])
+
+AC_DEFUN([gl_SCHED_H_DEFAULTS],
+[
+  dnl Assume proper GNU behavior unless another module says otherwise.
+  HAVE_SCHED_YIELD=1;    AC_SUBST([HAVE_SCHED_YIELD])
+  REPLACE_SCHED_YIELD=0; AC_SUBST([REPLACE_SCHED_YIELD])
+])
diff --git a/m4/select.m4 b/m4/select.m4
index 72c068fa4..163f8fbf7 100644
--- a/m4/select.m4
+++ b/m4/select.m4
@@ -1,5 +1,5 @@
 # select.m4 serial 13
-dnl Copyright (C) 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/servent.m4 b/m4/servent.m4
index 9bc3bcd4f..c1b7d1546 100644
--- a/m4/servent.m4
+++ b/m4/servent.m4
@@ -1,5 +1,5 @@
 # servent.m4 serial 4
-dnl Copyright (C) 2008, 2010-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2008, 2010-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/setenv.m4 b/m4/setenv.m4
index f79a27850..2000039ab 100644
--- a/m4/setenv.m4
+++ b/m4/setenv.m4
@@ -1,5 +1,5 @@
 # setenv.m4 serial 30
-dnl Copyright (C) 2001-2004, 2006-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2001-2004, 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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/setlocale_null.m4 b/m4/setlocale_null.m4
index 2c958ed77..09ea50eaf 100644
--- a/m4/setlocale_null.m4
+++ b/m4/setlocale_null.m4
@@ -1,5 +1,5 @@
 # setlocale_null.m4 serial 5
-dnl Copyright (C) 2019-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2019-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/sh-filename.m4 b/m4/sh-filename.m4
new file mode 100644
index 000000000..f5b11eaf4
--- /dev/null
+++ b/m4/sh-filename.m4
@@ -0,0 +1,24 @@
+# sh-filename.m4 serial 3
+dnl Copyright (C) 2018-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,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+
+AC_DEFUN([gl_SH_FILENAME],
+[
+  AH_VERBATIM([SH_FILENAME],
+[/* File name of the Bourne shell.  */
+#if (defined _WIN32 && !defined __CYGWIN__) || defined __CYGWIN__ || defined __ANDROID__
+/* Omit the directory part because
+   - For native Windows programs in a Cygwin environment, the Cygwin mounts
+     are not visible.
+   - For 32-bit Cygwin programs in a 64-bit Cygwin environment, the Cygwin
+     mounts are not visible.
+   - On Android, /bin/sh does not exist. It's /system/bin/sh instead.  */
+# define BOURNE_SHELL "sh"
+#else
+# define BOURNE_SHELL "/bin/sh"
+#endif])
+])
diff --git a/m4/signal_h.m4 b/m4/signal_h.m4
index 8b938809b..4c05c6274 100644
--- a/m4/signal_h.m4
+++ b/m4/signal_h.m4
@@ -1,5 +1,5 @@
 # signal_h.m4 serial 22
-dnl Copyright (C) 2007-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2007-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/signbit.m4 b/m4/signbit.m4
index 6ec70ec44..8a4114db6 100644
--- a/m4/signbit.m4
+++ b/m4/signbit.m4
@@ -1,5 +1,5 @@
 # signbit.m4 serial 20
-dnl Copyright (C) 2007-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2007-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/size_max.m4 b/m4/size_max.m4
index 1d41ce9ab..1d6abaeaa 100644
--- a/m4/size_max.m4
+++ b/m4/size_max.m4
@@ -1,5 +1,5 @@
 # size_max.m4 serial 12
-dnl Copyright (C) 2003, 2005-2006, 2008-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2003, 2005-2006, 2008-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/snprintf.m4 b/m4/snprintf.m4
index 852099408..7420591c9 100644
--- a/m4/snprintf.m4
+++ b/m4/snprintf.m4
@@ -1,5 +1,5 @@
 # snprintf.m4 serial 7
-dnl Copyright (C) 2002-2004, 2007-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2002-2004, 2007-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/socketlib.m4 b/m4/socketlib.m4
index 0f8a0829c..b8bd0afa5 100644
--- a/m4/socketlib.m4
+++ b/m4/socketlib.m4
@@ -1,5 +1,5 @@
 # socketlib.m4 serial 3
-dnl Copyright (C) 2008-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2008-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/sockets.m4 b/m4/sockets.m4
index 02b43b6e7..aa04acc3e 100644
--- a/m4/sockets.m4
+++ b/m4/sockets.m4
@@ -1,5 +1,5 @@
 # sockets.m4 serial 7
-dnl Copyright (C) 2008-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2008-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/socklen.m4 b/m4/socklen.m4
index eca1d1b94..1390ac41b 100644
--- a/m4/socklen.m4
+++ b/m4/socklen.m4
@@ -1,5 +1,5 @@
 # socklen.m4 serial 11
-dnl Copyright (C) 2005-2007, 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2005-2007, 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/sockpfaf.m4 b/m4/sockpfaf.m4
index 17e14c7a6..b1c4068ac 100644
--- a/m4/sockpfaf.m4
+++ b/m4/sockpfaf.m4
@@ -1,5 +1,5 @@
 # sockpfaf.m4 serial 10
-dnl Copyright (C) 2004, 2006, 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2004, 2006, 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/spawn_h.m4 b/m4/spawn_h.m4
new file mode 100644
index 000000000..1b28d8036
--- /dev/null
+++ b/m4/spawn_h.m4
@@ -0,0 +1,151 @@
+# spawn_h.m4 serial 21
+dnl Copyright (C) 2008-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,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl Written by Bruno Haible.
+
+AC_DEFUN_ONCE([gl_SPAWN_H],
+[
+  dnl Ensure to expand the default settings once only, before all statements
+  dnl that occur in other macros.
+  AC_REQUIRE([gl_SPAWN_H_DEFAULTS])
+
+  dnl <spawn.h> is always overridden, because of GNULIB_POSIXCHECK.
+  gl_CHECK_NEXT_HEADERS([spawn.h])
+
+  if test $ac_cv_header_spawn_h = yes; then
+    HAVE_SPAWN_H=1
+    AC_CHECK_TYPES([posix_spawnattr_t], [], [HAVE_POSIX_SPAWNATTR_T=0], [[
+#include <spawn.h>
+      ]])
+    AC_CHECK_TYPES([posix_spawn_file_actions_t], [],
+      [HAVE_POSIX_SPAWN_FILE_ACTIONS_T=0], [[
+#include <spawn.h>
+      ]])
+  else
+    HAVE_SPAWN_H=0
+    HAVE_POSIX_SPAWNATTR_T=0
+    HAVE_POSIX_SPAWN_FILE_ACTIONS_T=0
+  fi
+  AC_SUBST([HAVE_SPAWN_H])
+
+  dnl Ensure the type pid_t gets defined.
+  AC_REQUIRE([AC_TYPE_PID_T])
+
+  dnl Ensure the type mode_t gets defined.
+  AC_REQUIRE([AC_TYPE_MODE_T])
+
+  AC_REQUIRE([gl_HAVE_POSIX_SPAWN])
+
+  AC_REQUIRE([AC_C_RESTRICT])
+
+  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 <spawn.h>
+    ]], [posix_spawn posix_spawnp posix_spawnattr_init posix_spawnattr_destroy
+    posix_spawnattr_getsigdefault posix_spawnattr_setsigdefault
+    posix_spawnattr_getsigmask posix_spawnattr_setsigmask
+    posix_spawnattr_getflags posix_spawnattr_setflags
+    posix_spawnattr_getpgroup posix_spawnattr_setpgroup
+    posix_spawnattr_getschedpolicy posix_spawnattr_setschedpolicy
+    posix_spawnattr_getschedparam posix_spawnattr_setschedparam
+    posix_spawn_file_actions_init posix_spawn_file_actions_destroy
+    posix_spawn_file_actions_addopen posix_spawn_file_actions_addclose
+    posix_spawn_file_actions_adddup2 posix_spawn_file_actions_addchdir
+    posix_spawn_file_actions_addfchdir])
+])
+
+dnl Checks whether the system has the functions posix_spawn.
+dnl Sets ac_cv_func_posix_spawn and HAVE_POSIX_SPAWN.
+AC_DEFUN([gl_HAVE_POSIX_SPAWN],
+[
+  dnl Ensure to expand the default settings once only, before all statements
+  dnl that occur in other macros.
+  AC_REQUIRE([gl_SPAWN_H_DEFAULTS])
+
+  LIB_POSIX_SPAWN=
+  AC_SUBST([LIB_POSIX_SPAWN])
+  gl_saved_libs=$LIBS
+    AC_SEARCH_LIBS([posix_spawn], [rt],
+                   [test "$ac_cv_search_posix_spawn" = "none required" ||
+                    LIB_POSIX_SPAWN=$ac_cv_search_posix_spawn])
+    AC_CHECK_FUNCS([posix_spawn])
+  LIBS=$gl_saved_libs
+
+  if test $ac_cv_func_posix_spawn != yes; then
+    HAVE_POSIX_SPAWN=0
+  fi
+])
+
+# gl_SPAWN_MODULE_INDICATOR([modulename])
+# sets the shell variable that indicates the presence of the given module
+# to a C preprocessor expression that will evaluate to 1.
+# This macro invocation must not occur in macros that are AC_REQUIREd.
+AC_DEFUN([gl_SPAWN_MODULE_INDICATOR],
+[
+  dnl Ensure to expand the default settings once only.
+  gl_SPAWN_H_REQUIRE_DEFAULTS
+  gl_MODULE_INDICATOR_SET_VARIABLE([$1])
+  dnl Define it also as a C macro, for the benefit of the unit tests.
+  gl_MODULE_INDICATOR_FOR_TESTS([$1])
+])
+
+# Initializes the default values for AC_SUBSTed shell variables.
+# This macro must not be AC_REQUIREd.  It must only be invoked, and only
+# outside of macros or in macros that are not AC_REQUIREd.
+AC_DEFUN([gl_SPAWN_H_REQUIRE_DEFAULTS],
+[
+  m4_defun(GL_MODULE_INDICATOR_PREFIX[_SPAWN_H_MODULE_INDICATOR_DEFAULTS], [
+    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_POSIX_SPAWN])
+    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_POSIX_SPAWNP])
+    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_POSIX_SPAWN_FILE_ACTIONS_INIT])
+    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR])
+    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE])
+    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2])
+    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR])
+    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN])
+    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_POSIX_SPAWN_FILE_ACTIONS_DESTROY])
+    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_POSIX_SPAWNATTR_INIT])
+    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_POSIX_SPAWNATTR_GETFLAGS])
+    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_POSIX_SPAWNATTR_SETFLAGS])
+    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_POSIX_SPAWNATTR_GETPGROUP])
+    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_POSIX_SPAWNATTR_SETPGROUP])
+    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_POSIX_SPAWNATTR_GETSCHEDPARAM])
+    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_POSIX_SPAWNATTR_SETSCHEDPARAM])
+    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_POSIX_SPAWNATTR_GETSCHEDPOLICY])
+    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_POSIX_SPAWNATTR_SETSCHEDPOLICY])
+    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_POSIX_SPAWNATTR_GETSIGDEFAULT])
+    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_POSIX_SPAWNATTR_SETSIGDEFAULT])
+    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_POSIX_SPAWNATTR_GETSIGMASK])
+    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_POSIX_SPAWNATTR_SETSIGMASK])
+    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_POSIX_SPAWNATTR_DESTROY])
+  ])
+  m4_require(GL_MODULE_INDICATOR_PREFIX[_SPAWN_H_MODULE_INDICATOR_DEFAULTS])
+  AC_REQUIRE([gl_SPAWN_H_DEFAULTS])
+])
+
+AC_DEFUN([gl_SPAWN_H_DEFAULTS],
+[
+  dnl Assume proper GNU behavior unless another module says otherwise.
+  HAVE_POSIX_SPAWN=1;        AC_SUBST([HAVE_POSIX_SPAWN])
+  HAVE_POSIX_SPAWNATTR_T=1;  AC_SUBST([HAVE_POSIX_SPAWNATTR_T])
+  HAVE_POSIX_SPAWN_FILE_ACTIONS_T=1;
+                             AC_SUBST([HAVE_POSIX_SPAWN_FILE_ACTIONS_T])
+  HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR=1;
+                             AC_SUBST([HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR])
+  HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR=1;
+                             AC_SUBST([HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR])
+  REPLACE_POSIX_SPAWN=0;     AC_SUBST([REPLACE_POSIX_SPAWN])
+  REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR=0;
+                             AC_SUBST([REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR])
+  REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE=0;
+                             AC_SUBST([REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE])
+  REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2=0;
+                             AC_SUBST([REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2])
+  REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR=0;
+                             AC_SUBST([REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR])
+  REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN=0;
+                             AC_SUBST([REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN])
+])
diff --git a/m4/ssize_t.m4 b/m4/ssize_t.m4
index f0ed509fc..03b2b895b 100644
--- a/m4/ssize_t.m4
+++ b/m4/ssize_t.m4
@@ -1,5 +1,5 @@
 # ssize_t.m4 serial 5 (gettext-0.18.2)
-dnl Copyright (C) 2001-2003, 2006, 2010-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2001-2003, 2006, 2010-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/stat-time.m4 b/m4/stat-time.m4
index df1c2a745..342857d39 100644
--- a/m4/stat-time.m4
+++ b/m4/stat-time.m4
@@ -1,6 +1,6 @@
 # Checks for stat-related time functions.
 
-# Copyright (C) 1998-1999, 2001, 2003, 2005-2007, 2009-2021 Free Software
+# Copyright (C) 1998-1999, 2001, 2003, 2005-2007, 2009-2022 Free Software
 # Foundation, Inc.
 
 # This file is free software; the Free Software Foundation
diff --git a/m4/stat.m4 b/m4/stat.m4
index 9bcdb72d6..916eb8861 100644
--- a/m4/stat.m4
+++ b/m4/stat.m4
@@ -1,6 +1,6 @@
 # serial 18
 
-# Copyright (C) 2009-2021 Free Software Foundation, Inc.
+# Copyright (C) 2009-2022 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
diff --git a/m4/std-gnu11.m4 b/m4/std-gnu11.m4
index 7b1a042af..5ca18607f 100644
--- a/m4/std-gnu11.m4
+++ b/m4/std-gnu11.m4
@@ -9,7 +9,7 @@
 m4_version_prereq([2.70], [], [
 
 
-# Copyright (C) 2001-2021 Free Software Foundation, Inc.
+# Copyright (C) 2001-2022 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
diff --git a/m4/stdalign.m4 b/m4/stdalign.m4
index e22d7f78c..78577cb2a 100644
--- a/m4/stdalign.m4
+++ b/m4/stdalign.m4
@@ -1,6 +1,6 @@
 # Check for stdalign.h that conforms to C11.
 
-dnl Copyright 2011-2021 Free Software Foundation, Inc.
+dnl Copyright 2011-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,
 dnl with or without modifications, as long as this notice is preserved.
@@ -49,11 +49,8 @@ AC_DEFUN([gl_STDALIGN_H],
        [gl_cv_header_working_stdalign_h=no])])
 
   if test $gl_cv_header_working_stdalign_h = yes; then
-    STDALIGN_H=''
+    GL_GENERATE_STDALIGN_H=false
   else
-    STDALIGN_H='stdalign.h'
+    GL_GENERATE_STDALIGN_H=true
   fi
-
-  AC_SUBST([STDALIGN_H])
-  AM_CONDITIONAL([GL_GENERATE_STDALIGN_H], [test -n "$STDALIGN_H"])
 ])
diff --git a/m4/stdbool.m4 b/m4/stdbool.m4
index 3169779d4..c67908aa8 100644
--- a/m4/stdbool.m4
+++ b/m4/stdbool.m4
@@ -1,15 +1,15 @@
 # Check for stdbool.h that conforms to C99.
 
-dnl Copyright (C) 2002-2006, 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2002-2006, 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
 
-#serial 8
+#serial 9
 
 # Prepare for substituting <stdbool.h> if it is not supported.
 
-AC_DEFUN([AM_STDBOOL_H],
+AC_DEFUN([gl_STDBOOL_H],
 [
   AC_REQUIRE([AC_CHECK_HEADER_STDBOOL])
   AC_REQUIRE([AC_CANONICAL_HOST])
@@ -22,20 +22,18 @@ AC_DEFUN([AM_STDBOOL_H],
     case "$host_os" in
       solaris*)
         if test -z "$GCC"; then
-          STDBOOL_H='stdbool.h'
+          GL_GENERATE_STDBOOL_H=true
         else
-          STDBOOL_H=''
+          GL_GENERATE_STDBOOL_H=false
         fi
         ;;
       *)
-        STDBOOL_H=''
+        GL_GENERATE_STDBOOL_H=false
         ;;
     esac
   else
-    STDBOOL_H='stdbool.h'
+    GL_GENERATE_STDBOOL_H=true
   fi
-  AC_SUBST([STDBOOL_H])
-  AM_CONDITIONAL([GL_GENERATE_STDBOOL_H], [test -n "$STDBOOL_H"])
 
   if test "$ac_cv_type__Bool" = yes; then
     HAVE__BOOL=1
@@ -45,78 +43,76 @@ AC_DEFUN([AM_STDBOOL_H],
   AC_SUBST([HAVE__BOOL])
 ])
 
-# AM_STDBOOL_H will be renamed to gl_STDBOOL_H in the future.
-AC_DEFUN([gl_STDBOOL_H], [AM_STDBOOL_H])
-
-# This version of the macro is needed in autoconf <= 2.68.
+m4_version_prereq([2.72], [], [
 
 AC_DEFUN([AC_CHECK_HEADER_STDBOOL],
-  [AC_CACHE_CHECK([for stdbool.h that conforms to C99],
+  [AC_CHECK_TYPES([_Bool])
+   AC_CACHE_CHECK([for stdbool.h that conforms to C99 or later],
      [ac_cv_header_stdbool_h],
      [AC_COMPILE_IFELSE(
         [AC_LANG_PROGRAM(
-           [[
-             #include <stdbool.h>
-
-             #ifdef __cplusplus
-              typedef bool Bool;
-             #else
-              typedef _Bool Bool;
-              #ifndef bool
-               "error: bool is not defined"
-              #endif
-              #ifndef false
-               "error: false is not defined"
-              #endif
-              #if false
-               "error: false is not 0"
-              #endif
-              #ifndef true
-               "error: true is not defined"
-              #endif
-              #if true != 1
-               "error: true is not 1"
-              #endif
+           [[#include <stdbool.h>
+
+             /* "true" and "false" should be usable in #if expressions and
+                integer constant expressions, and "bool" should be a valid
+                type name.
+
+                Although C 1999 requires bool, true, and false to be macros,
+                C 2023 and C++ 2011 overrule that, so do not test for that.
+                Although C 1999 requires __bool_true_false_are_defined and
+                _Bool, C 2023 says they are obsolescent, so do not require
+                them.  */
+
+             #if !true
+               #error "'true' is not true"
+             #endif
+             #if true != 1
+               #error "'true' is not equal to 1"
              #endif
+             char b[true == 1 ? 1 : -1];
+             char c[true];
 
-             #ifndef __bool_true_false_are_defined
-              "error: __bool_true_false_are_defined is not defined"
+             #if false
+               #error "'false' is not false"
+             #endif
+             #if false != 0
+               #error "'false' is not equal to 0"
              #endif
+             char d[false == 0 ? 1 : -1];
+
+             enum { e = false, f = true, g = false * true, h = true * 256 };
+
+             char i[(bool) 0.5 == true ? 1 : -1];
+             char j[(bool) 0.0 == false ? 1 : -1];
+             char k[sizeof (bool) > 0 ? 1 : -1];
+
+             struct sb { bool s: 1; bool t; } s;
+             char l[sizeof s.t > 0 ? 1 : -1];
 
-             struct s { Bool s: 1; Bool t; bool u: 1; bool v; } s;
-
-             char a[true == 1 ? 1 : -1];
-             char b[false == 0 ? 1 : -1];
-             char c[__bool_true_false_are_defined == 1 ? 1 : -1];
-             char d[(bool) 0.5 == true ? 1 : -1];
-             /* See body of main program for 'e'.  */
-             char f[(Bool) 0.0 == false ? 1 : -1];
-             char g[true];
-             char h[sizeof (Bool)];
-             char i[sizeof s.t];
-             enum { j = false, k = true, l = false * true, m = true * 256 };
              /* The following fails for
                 HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */
-             Bool n[m];
-             char o[sizeof n == m * sizeof n[0] ? 1 : -1];
-             char p[-1 - (Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1];
+             bool m[h];
+             char n[sizeof m == h * sizeof m[0] ? 1 : -1];
+             char o[-1 - (bool) 0 < 0 ? 1 : -1];
              /* Catch a bug in an HP-UX C compiler.  See
                 https://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html
                 https://lists.gnu.org/r/bug-coreutils/2005-11/msg00161.html
               */
-             Bool q = true;
-             Bool *pq = &q;
-             bool *qq = &q;
+             bool p = true;
+             bool *pp = &p;
            ]],
            [[
-             bool e = &s;
-             *pq |= q; *pq |= ! q;
-             *qq |= q; *qq |= ! q;
-             /* Refer to every declared value, to avoid compiler optimizations.  */
-             return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l
-                     + !m + !n + !o + !p + !q + !pq + !qq);
+             bool ps = &s;
+             *pp |= p;
+             *pp |= ! p;
+
+             /* Refer to every declared value, so they cannot be
+                discarded as unused.  */
+             return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !j + !k
+                     + !l + !m + !n + !o + !p + !pp + !ps);
            ]])],
         [ac_cv_header_stdbool_h=yes],
         [ac_cv_header_stdbool_h=no])])
-   AC_CHECK_TYPES([_Bool])
-])
+])# AC_CHECK_HEADER_STDBOOL
+
+]) # m4_version_prereq 2.72
diff --git a/m4/stddef_h.m4 b/m4/stddef_h.m4
index 1303d2e06..abfd20303 100644
--- a/m4/stddef_h.m4
+++ b/m4/stddef_h.m4
@@ -1,5 +1,5 @@
-# stddef_h.m4 serial 11
-dnl Copyright (C) 2009-2021 Free Software Foundation, Inc.
+# stddef_h.m4 serial 12
+dnl Copyright (C) 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
@@ -14,7 +14,7 @@ AC_DEFUN_ONCE([gl_STDDEF_H],
   dnl Persuade OpenBSD <stddef.h> to declare max_align_t.
   AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
 
-  STDDEF_H=
+  GL_GENERATE_STDDEF_H=false
 
   dnl Test whether the type max_align_t exists and whether its alignment
   dnl "is as great as is supported by the implementation in all contexts".
@@ -41,12 +41,12 @@ AC_DEFUN_ONCE([gl_STDDEF_H],
     ])
   if test $gl_cv_type_max_align_t = no; then
     HAVE_MAX_ALIGN_T=0
-    STDDEF_H=stddef.h
+    GL_GENERATE_STDDEF_H=true
   fi
 
   if test $gt_cv_c_wchar_t = no; then
     HAVE_WCHAR_T=0
-    STDDEF_H=stddef.h
+    GL_GENERATE_STDDEF_H=true
   fi
 
   AC_CACHE_CHECK([whether NULL can be used in arbitrary expressions],
@@ -58,12 +58,10 @@ AC_DEFUN_ONCE([gl_STDDEF_H],
       [gl_cv_decl_null_works=no])])
   if test $gl_cv_decl_null_works = no; then
     REPLACE_NULL=1
-    STDDEF_H=stddef.h
+    GL_GENERATE_STDDEF_H=true
   fi
 
-  AC_SUBST([STDDEF_H])
-  AM_CONDITIONAL([GL_GENERATE_STDDEF_H], [test -n "$STDDEF_H"])
-  if test -n "$STDDEF_H"; then
+  if $GL_GENERATE_STDDEF_H; then
     gl_NEXT_HEADERS([stddef.h])
   fi
 ])
diff --git a/m4/stdint.m4 b/m4/stdint.m4
index 2eb1652d8..c3f089427 100644
--- a/m4/stdint.m4
+++ b/m4/stdint.m4
@@ -1,5 +1,5 @@
-# stdint.m4 serial 60
-dnl Copyright (C) 2001-2021 Free Software Foundation, Inc.
+# stdint.m4 serial 61
+dnl Copyright (C) 2001-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,
 dnl with or without modifications, as long as this notice is preserved.
@@ -296,7 +296,7 @@ static const char *macro_values[] =
   HAVE_C99_STDINT_H=0
   HAVE_SYS_BITYPES_H=0
   HAVE_SYS_INTTYPES_H=0
-  STDINT_H=stdint.h
+  GL_GENERATE_STDINT_H=true
   case "$gl_cv_header_working_stdint_h" in
     *yes)
       HAVE_C99_STDINT_H=1
@@ -341,7 +341,7 @@ int32_t i32 = INT32_C (0x7fffffff);
               ]])],
            [gl_cv_header_stdint_width=yes])])
       if test "$gl_cv_header_stdint_width" = yes; then
-        STDINT_H=
+        GL_GENERATE_STDINT_H=false
       fi
       ;;
     *)
@@ -364,8 +364,6 @@ int32_t i32 = INT32_C (0x7fffffff);
   AC_SUBST([HAVE_C99_STDINT_H])
   AC_SUBST([HAVE_SYS_BITYPES_H])
   AC_SUBST([HAVE_SYS_INTTYPES_H])
-  AC_SUBST([STDINT_H])
-  AM_CONDITIONAL([GL_GENERATE_STDINT_H], [test -n "$STDINT_H"])
 ])
 
 dnl gl_STDINT_BITSIZEOF(TYPES, INCLUDES)
diff --git a/m4/stdint_h.m4 b/m4/stdint_h.m4
index 18aa50a4a..b8684b61a 100644
--- a/m4/stdint_h.m4
+++ b/m4/stdint_h.m4
@@ -1,5 +1,5 @@
 # stdint_h.m4 serial 9
-dnl Copyright (C) 1997-2004, 2006, 2008-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 1997-2004, 2006, 2008-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/stdio_h.m4 b/m4/stdio_h.m4
index e70438386..42e96071f 100644
--- a/m4/stdio_h.m4
+++ b/m4/stdio_h.m4
@@ -1,5 +1,5 @@
-# stdio_h.m4 serial 56
-dnl Copyright (C) 2007-2021 Free Software Foundation, Inc.
+# stdio_h.m4 serial 59
+dnl Copyright (C) 2007-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,
 dnl with or without modifications, as long as this notice is preserved.
@@ -40,41 +40,32 @@ AC_DEFUN_ONCE([gl_STDIO_H],
        attribute "__gnu_printf__" instead of "__printf__"])
   fi
 
-  dnl This ifdef is necessary to avoid an error "missing file lib/stdio-read.c"
-  dnl "expected source file, required through AC_LIBSOURCES, not found". It is
-  dnl also an optimization, to avoid performing a configure check whose result
-  dnl is not used. But it does not make the test of GNULIB_STDIO_H_NONBLOCKING
-  dnl or GNULIB_NONBLOCKING redundant.
+  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.
   m4_ifdef([gl_NONBLOCKING_IO], [
     gl_NONBLOCKING_IO
     if test $gl_cv_have_nonblocking != yes; then
       REPLACE_STDIO_READ_FUNCS=1
-      AC_LIBOBJ([stdio-read])
     fi
   ])
 
-  dnl This ifdef is necessary to avoid an error "missing file lib/stdio-write.c"
-  dnl "expected source file, required through AC_LIBSOURCES, not found". It is
-  dnl also an optimization, to avoid performing a configure check whose result
-  dnl is not used. But it does not make the test of GNULIB_STDIO_H_SIGPIPE or
-  dnl GNULIB_SIGPIPE redundant.
+  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_SIGPIPE or GNULIB_SIGPIPE redundant.
   m4_ifdef([gl_SIGNAL_SIGPIPE], [
     gl_SIGNAL_SIGPIPE
     if test $gl_cv_header_signal_h_SIGPIPE != yes; then
       REPLACE_STDIO_WRITE_FUNCS=1
-      AC_LIBOBJ([stdio-write])
     fi
   ])
-  dnl This ifdef is necessary to avoid an error "missing file lib/stdio-write.c"
-  dnl "expected source file, required through AC_LIBSOURCES, not found". It is
-  dnl also an optimization, to avoid performing a configure check whose result
-  dnl is not used. But it does not make the test of GNULIB_STDIO_H_NONBLOCKING
-  dnl or GNULIB_NONBLOCKING redundant.
+  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.
   m4_ifdef([gl_NONBLOCKING_IO], [
     gl_NONBLOCKING_IO
     if test $gl_cv_have_nonblocking != yes; then
       REPLACE_STDIO_WRITE_FUNCS=1
-      AC_LIBOBJ([stdio-write])
     fi
   ])
 
@@ -119,6 +110,7 @@ AC_DEFUN([gl_STDIO_H_REQUIRE_DEFAULTS],
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FGETC])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FGETS])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FOPEN])
+    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FOPEN_GNU])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FPRINTF])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FPRINTF_POSIX])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FPURGE])
@@ -202,6 +194,7 @@ AC_DEFUN([gl_STDIO_H_DEFAULTS],
   REPLACE_FDOPEN=0;              AC_SUBST([REPLACE_FDOPEN])
   REPLACE_FFLUSH=0;              AC_SUBST([REPLACE_FFLUSH])
   REPLACE_FOPEN=0;               AC_SUBST([REPLACE_FOPEN])
+  REPLACE_FOPEN_FOR_FOPEN_GNU=0; AC_SUBST([REPLACE_FOPEN_FOR_FOPEN_GNU])
   REPLACE_FPRINTF=0;             AC_SUBST([REPLACE_FPRINTF])
   REPLACE_FPURGE=0;              AC_SUBST([REPLACE_FPURGE])
   REPLACE_FREOPEN=0;             AC_SUBST([REPLACE_FREOPEN])
diff --git a/m4/stdlib_h.m4 b/m4/stdlib_h.m4
index 9c1d1c76c..9e2096976 100644
--- a/m4/stdlib_h.m4
+++ b/m4/stdlib_h.m4
@@ -1,5 +1,5 @@
-# stdlib_h.m4 serial 63
-dnl Copyright (C) 2007-2021 Free Software Foundation, Inc.
+# stdlib_h.m4 serial 66
+dnl Copyright (C) 2007-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,
 dnl with or without modifications, as long as this notice is preserved.
@@ -68,12 +68,14 @@ AC_DEFUN([gl_STDLIB_H_REQUIRE_DEFAULTS],
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB__EXIT])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ALIGNED_ALLOC])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ATOLL])
+    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CALLOC_GNU])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CALLOC_POSIX])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CANONICALIZE_FILE_NAME])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FREE_POSIX])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETLOADAVG])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETSUBOPT])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GRANTPT])
+    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MALLOC_GNU])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MALLOC_POSIX])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBTOWC])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MKDTEMP])
@@ -90,6 +92,7 @@ AC_DEFUN([gl_STDLIB_H_REQUIRE_DEFAULTS],
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RANDOM])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RANDOM_R])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_REALLOCARRAY])
+    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_REALLOC_GNU])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_REALLOC_POSIX])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_REALPATH])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RPMATCH])
@@ -164,11 +167,13 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS],
   HAVE_UNLOCKPT=1;           AC_SUBST([HAVE_UNLOCKPT])
   HAVE_DECL_UNSETENV=1;      AC_SUBST([HAVE_DECL_UNSETENV])
   REPLACE_ALIGNED_ALLOC=0;   AC_SUBST([REPLACE_ALIGNED_ALLOC])
-  REPLACE_CALLOC=0;          AC_SUBST([REPLACE_CALLOC])
+  REPLACE_CALLOC_FOR_CALLOC_GNU=0;    AC_SUBST([REPLACE_CALLOC_FOR_CALLOC_GNU])
+  REPLACE_CALLOC_FOR_CALLOC_POSIX=0;  AC_SUBST([REPLACE_CALLOC_FOR_CALLOC_POSIX])
   REPLACE_CANONICALIZE_FILE_NAME=0;  AC_SUBST([REPLACE_CANONICALIZE_FILE_NAME])
   REPLACE_FREE=0;            AC_SUBST([REPLACE_FREE])
   REPLACE_INITSTATE=0;       AC_SUBST([REPLACE_INITSTATE])
-  REPLACE_MALLOC=0;          AC_SUBST([REPLACE_MALLOC])
+  REPLACE_MALLOC_FOR_MALLOC_GNU=0;    AC_SUBST([REPLACE_MALLOC_FOR_MALLOC_GNU])
+  REPLACE_MALLOC_FOR_MALLOC_POSIX=0;  AC_SUBST([REPLACE_MALLOC_FOR_MALLOC_POSIX])
   REPLACE_MBTOWC=0;          AC_SUBST([REPLACE_MBTOWC])
   REPLACE_MKSTEMP=0;         AC_SUBST([REPLACE_MKSTEMP])
   REPLACE_POSIX_MEMALIGN=0;  AC_SUBST([REPLACE_POSIX_MEMALIGN])
@@ -178,7 +183,8 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS],
   REPLACE_QSORT_R=0;         AC_SUBST([REPLACE_QSORT_R])
   REPLACE_RANDOM=0;          AC_SUBST([REPLACE_RANDOM])
   REPLACE_RANDOM_R=0;        AC_SUBST([REPLACE_RANDOM_R])
-  REPLACE_REALLOC=0;         AC_SUBST([REPLACE_REALLOC])
+  REPLACE_REALLOC_FOR_REALLOC_GNU=0;    AC_SUBST([REPLACE_REALLOC_FOR_REALLOC_GNU])
+  REPLACE_REALLOC_FOR_REALLOC_POSIX=0;  AC_SUBST([REPLACE_REALLOC_FOR_REALLOC_POSIX])
   REPLACE_REALLOCARRAY=0;    AC_SUBST([REPLACE_REALLOCARRAY])
   REPLACE_REALPATH=0;        AC_SUBST([REPLACE_REALPATH])
   REPLACE_SETENV=0;          AC_SUBST([REPLACE_SETENV])
diff --git a/m4/stpcpy.m4 b/m4/stpcpy.m4
new file mode 100644
index 000000000..241e68c8c
--- /dev/null
+++ b/m4/stpcpy.m4
@@ -0,0 +1,25 @@
+# stpcpy.m4 serial 9
+dnl Copyright (C) 2002, 2007, 2009-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,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_STPCPY],
+[
+  dnl Persuade glibc <string.h> to declare stpcpy().
+  AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+
+  dnl The stpcpy() declaration in lib/string.in.h uses 'restrict'.
+  AC_REQUIRE([AC_C_RESTRICT])
+
+  AC_REQUIRE([gl_STRING_H_DEFAULTS])
+  AC_CHECK_FUNCS([stpcpy])
+  if test $ac_cv_func_stpcpy = no; then
+    HAVE_STPCPY=0
+  fi
+])
+
+# Prerequisites of lib/stpcpy.c.
+AC_DEFUN([gl_PREREQ_STPCPY], [
+  :
+])
diff --git a/m4/strchrnul.m4 b/m4/strchrnul.m4
new file mode 100644
index 000000000..630699b8f
--- /dev/null
+++ b/m4/strchrnul.m4
@@ -0,0 +1,50 @@
+# strchrnul.m4 serial 10
+dnl Copyright (C) 2003, 2007, 2009-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,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_STRCHRNUL],
+[
+  dnl Persuade glibc <string.h> to declare strchrnul().
+  AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+
+  AC_REQUIRE([gl_STRING_H_DEFAULTS])
+  AC_CHECK_FUNCS([strchrnul])
+  if test $ac_cv_func_strchrnul = no; then
+    HAVE_STRCHRNUL=0
+  else
+    AC_CACHE_CHECK([whether strchrnul works],
+      [gl_cv_func_strchrnul_works],
+      [AC_RUN_IFELSE([AC_LANG_PROGRAM([[
+#include <string.h> /* for strchrnul */
+]], [[const char *buf = "a";
+      return strchrnul (buf, 'b') != buf + 1;
+    ]])],
+        [gl_cv_func_strchrnul_works=yes],
+        [gl_cv_func_strchrnul_works=no],
+        [dnl Cygwin 1.7.9 introduced strchrnul, but it was broken until 1.7.10
+         AC_EGREP_CPP([Lucky user],
+           [
+#if defined __CYGWIN__
+ #include <cygwin/version.h>
+ #if CYGWIN_VERSION_DLL_COMBINED > CYGWIN_VERSION_DLL_MAKE_COMBINED (1007, 9)
+  Lucky user
+ #endif
+#else
+  Lucky user
+#endif
+           ],
+           [gl_cv_func_strchrnul_works="guessing yes"],
+           [gl_cv_func_strchrnul_works="guessing no"])
+        ])
+      ])
+    case "$gl_cv_func_strchrnul_works" in
+      *yes) ;;
+      *) REPLACE_STRCHRNUL=1 ;;
+    esac
+  fi
+])
+
+# Prerequisites of lib/strchrnul.c.
+AC_DEFUN([gl_PREREQ_STRCHRNUL], [:])
diff --git a/m4/strdup.m4 b/m4/strdup.m4
index 5b6018ff2..da8899d16 100644
--- a/m4/strdup.m4
+++ b/m4/strdup.m4
@@ -1,6 +1,6 @@
 # strdup.m4 serial 15
 
-dnl Copyright (C) 2002-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2002-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,
diff --git a/m4/string_h.m4 b/m4/string_h.m4
index 80d1e5875..9e09b96e1 100644
--- a/m4/string_h.m4
+++ b/m4/string_h.m4
@@ -1,11 +1,11 @@
 # Configure a GNU-like replacement for <string.h>.
 
-# Copyright (C) 2007-2021 Free Software Foundation, Inc.
+# Copyright (C) 2007-2022 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.
 
-# serial 32
+# serial 34
 
 # Written by Paul Eggert.
 
@@ -93,6 +93,8 @@ AC_DEFUN([gl_STRING_H_REQUIRE_DEFAULTS],
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_STRDUP], [1])
   ])
   m4_require(GL_MODULE_INDICATOR_PREFIX[_STRING_H_MODULE_INDICATOR_DEFAULTS])
+  dnl Make sure the shell variable for GNULIB_FREE_POSIX is initialized.
+  gl_STDLIB_H_REQUIRE_DEFAULTS
   AC_REQUIRE([gl_STRING_H_DEFAULTS])
 ])
 
diff --git a/m4/sys_file_h.m4 b/m4/sys_file_h.m4
index bcde4d70b..61bd733ee 100644
--- a/m4/sys_file_h.m4
+++ b/m4/sys_file_h.m4
@@ -1,7 +1,7 @@
 # Configure a replacement for <sys/file.h>.
 # serial 9
 
-# Copyright (C) 2008-2021 Free Software Foundation, Inc.
+# Copyright (C) 2008-2022 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.
diff --git a/m4/sys_random_h.m4 b/m4/sys_random_h.m4
index 37bc31606..a5ba85c67 100644
--- a/m4/sys_random_h.m4
+++ b/m4/sys_random_h.m4
@@ -1,5 +1,5 @@
 # sys_random_h.m4 serial 8
-dnl Copyright (C) 2020-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2020-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/sys_select_h.m4 b/m4/sys_select_h.m4
index 2e7d140de..2743cd179 100644
--- a/m4/sys_select_h.m4
+++ b/m4/sys_select_h.m4
@@ -1,5 +1,5 @@
 # sys_select_h.m4 serial 23
-dnl Copyright (C) 2006-2021 Free Software Foundation, Inc.
+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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/sys_socket_h.m4 b/m4/sys_socket_h.m4
index 5676a0d21..ba3ae68e6 100644
--- a/m4/sys_socket_h.m4
+++ b/m4/sys_socket_h.m4
@@ -1,5 +1,5 @@
-# sys_socket_h.m4 serial 28
-dnl Copyright (C) 2005-2021 Free Software Foundation, Inc.
+# sys_socket_h.m4 serial 29
+dnl Copyright (C) 2005-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,
 dnl with or without modifications, as long as this notice is preserved.
@@ -22,6 +22,7 @@ AC_DEFUN_ONCE([gl_SYS_SOCKET_H],
       ;;
   esac
 
+  GL_GENERATE_SYS_SOCKET_H=false
   AC_CACHE_CHECK([whether <sys/socket.h> is self-contained],
     [gl_cv_header_sys_socket_h_selfcontained],
     [
@@ -44,7 +45,7 @@ AC_DEFUN_ONCE([gl_SYS_SOCKET_H],
             [gl_cv_header_sys_socket_h_shut=no])
         ])
       if test $gl_cv_header_sys_socket_h_shut = no; then
-        SYS_SOCKET_H='sys/socket.h'
+        GL_GENERATE_SYS_SOCKET_H=true
       fi
     fi
   fi
@@ -83,7 +84,7 @@ AC_DEFUN_ONCE([gl_SYS_SOCKET_H],
   fi
   if test $HAVE_STRUCT_SOCKADDR_STORAGE = 0 || test $HAVE_SA_FAMILY_T = 0 \
      || test $HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY = 0; then
-    SYS_SOCKET_H='sys/socket.h'
+    GL_GENERATE_SYS_SOCKET_H=true
   fi
   gl_PREREQ_SYS_H_WINSOCK2
 
diff --git a/m4/sys_stat_h.m4 b/m4/sys_stat_h.m4
index ac91d425b..2adbfdeef 100644
--- a/m4/sys_stat_h.m4
+++ b/m4/sys_stat_h.m4
@@ -1,5 +1,5 @@
-# sys_stat_h.m4 serial 41   -*- Autoconf -*-
-dnl Copyright (C) 2006-2021 Free Software Foundation, Inc.
+# 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,
 dnl with or without modifications, as long as this notice is preserved.
@@ -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 <sys/stat.h>
-    ]], [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/m4/sys_time_h.m4 b/m4/sys_time_h.m4
index c425a9639..bc5e2b136 100644
--- a/m4/sys_time_h.m4
+++ b/m4/sys_time_h.m4
@@ -1,7 +1,7 @@
 # Configure a replacement for <sys/time.h>.
 # serial 12
 
-# Copyright (C) 2007, 2009-2021 Free Software Foundation, Inc.
+# Copyright (C) 2007, 2009-2022 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.
diff --git a/m4/sys_times_h.m4 b/m4/sys_times_h.m4
index 577ead66f..5d26954e9 100644
--- a/m4/sys_times_h.m4
+++ b/m4/sys_times_h.m4
@@ -1,7 +1,7 @@
 # Configure a replacement for <sys/times.h>.
 # serial 11
 
-# Copyright (C) 2008-2021 Free Software Foundation, Inc.
+# Copyright (C) 2008-2022 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.
diff --git a/m4/sys_types_h.m4 b/m4/sys_types_h.m4
index 6dd6fee10..a5bef220c 100644
--- a/m4/sys_types_h.m4
+++ b/m4/sys_types_h.m4
@@ -1,5 +1,5 @@
 # sys_types_h.m4 serial 13
-dnl Copyright (C) 2011-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2011-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/sys_uio_h.m4 b/m4/sys_uio_h.m4
index fa176e0b6..36f55eadc 100644
--- a/m4/sys_uio_h.m4
+++ b/m4/sys_uio_h.m4
@@ -1,5 +1,5 @@
 # sys_uio_h.m4 serial 3
-dnl Copyright (C) 2011-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2011-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/tempname.m4 b/m4/tempname.m4
index 14c796d3e..22ccec1f8 100644
--- a/m4/tempname.m4
+++ b/m4/tempname.m4
@@ -1,6 +1,6 @@
 #serial 5
 
-# Copyright (C) 2006-2007, 2009-2021 Free Software Foundation, Inc.
+# Copyright (C) 2006-2007, 2009-2022 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.
diff --git a/m4/threadlib.m4 b/m4/threadlib.m4
index 37b797c18..ecb4970af 100644
--- a/m4/threadlib.m4
+++ b/m4/threadlib.m4
@@ -1,5 +1,5 @@
-# threadlib.m4 serial 31
-dnl Copyright (C) 2005-2021 Free Software Foundation, Inc.
+# threadlib.m4 serial 32
+dnl Copyright (C) 2005-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,
 dnl with or without modifications, as long as this notice is preserved.
@@ -84,38 +84,48 @@ AC_DEFUN([gl_WEAK_SYMBOLS],
   AC_REQUIRE([AC_CANONICAL_HOST])
   AC_CACHE_CHECK([whether imported symbols can be declared weak],
     [gl_cv_have_weak],
-    [gl_cv_have_weak=no
-     dnl First, test whether the compiler accepts it syntactically.
-     AC_LINK_IFELSE(
-       [AC_LANG_PROGRAM(
-          [[extern void xyzzy ();
+    [case "$host_os" in
+       cygwin*)
+         dnl On Cygwin 3.2.0 with gcc 10.2, the test below would succeed, but
+         dnl programs that use pthread_in_use() with weak symbol references
+         dnl crash miserably at runtime.
+         gl_cv_have_weak="guessing no"
+         ;;
+       *)
+         gl_cv_have_weak=no
+         dnl First, test whether the compiler accepts it syntactically.
+         AC_LINK_IFELSE(
+           [AC_LANG_PROGRAM(
+              [[extern void xyzzy ();
 #pragma weak xyzzy]],
-          [[xyzzy();]])],
-       [gl_cv_have_weak=maybe])
-     if test $gl_cv_have_weak = maybe; then
-       dnl Second, test whether it actually works. On Cygwin 1.7.2, with
-       dnl gcc 4.3, symbols declared weak always evaluate to the address 0.
-       AC_RUN_IFELSE(
-         [AC_LANG_SOURCE([[
+              [[xyzzy();]])],
+           [gl_cv_have_weak=maybe])
+         if test $gl_cv_have_weak = maybe; then
+           dnl Second, test whether it actually works. On Cygwin 1.7.2, with
+           dnl gcc 4.3, symbols declared weak always evaluate to the address 0.
+           AC_RUN_IFELSE(
+             [AC_LANG_SOURCE([[
 #include <stdio.h>
 #pragma weak fputs
 int main ()
 {
   return (fputs == NULL);
 }]])],
-         [gl_cv_have_weak=yes],
-         [gl_cv_have_weak=no],
-         [dnl When cross-compiling, assume that only ELF platforms support
-          dnl weak symbols.
-          AC_EGREP_CPP([Extensible Linking Format],
-            [#ifdef __ELF__
-             Extensible Linking Format
-             #endif
-            ],
-            [gl_cv_have_weak="guessing yes"],
-            [gl_cv_have_weak="guessing no"])
-         ])
-     fi
+             [gl_cv_have_weak=yes],
+             [gl_cv_have_weak=no],
+             [dnl When cross-compiling, assume that only ELF platforms support
+              dnl weak symbols.
+              AC_EGREP_CPP([Extensible Linking Format],
+                [#ifdef __ELF__
+                 Extensible Linking Format
+                 #endif
+                ],
+                [gl_cv_have_weak="guessing yes"],
+                [gl_cv_have_weak="guessing no"])
+             ])
+         fi
+         ;;
+     esac
      dnl But when linking statically, weak symbols don't work.
      case " $LDFLAGS " in
        *" -static "*) gl_cv_have_weak=no ;;
diff --git a/m4/time_h.m4 b/m4/time_h.m4
index b57474b48..98d7b6e01 100644
--- a/m4/time_h.m4
+++ b/m4/time_h.m4
@@ -1,8 +1,8 @@
 # Configure a more-standard replacement for <time.h>.
 
-# Copyright (C) 2000-2001, 2003-2007, 2009-2021 Free Software Foundation, Inc.
+# Copyright (C) 2000-2001, 2003-2007, 2009-2022 Free Software Foundation, Inc.
 
-# serial 18
+# serial 19
 
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -133,6 +133,7 @@ AC_DEFUN([gl_TIME_H_REQUIRE_DEFAULTS],
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRPTIME])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TIMEGM])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TIMESPEC_GET])
+    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TIMESPEC_GETRES])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TIME_R])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TIME_RZ])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TZSET])
@@ -151,6 +152,7 @@ AC_DEFUN([gl_TIME_H_DEFAULTS],
   HAVE_STRPTIME=1;                       AC_SUBST([HAVE_STRPTIME])
   HAVE_TIMEGM=1;                         AC_SUBST([HAVE_TIMEGM])
   HAVE_TIMESPEC_GET=1;                   AC_SUBST([HAVE_TIMESPEC_GET])
+  HAVE_TIMESPEC_GETRES=1;                AC_SUBST([HAVE_TIMESPEC_GETRES])
   dnl Even GNU libc does not have timezone_t yet.
   HAVE_TIMEZONE_T=0;                     AC_SUBST([HAVE_TIMEZONE_T])
   dnl If another module says to replace or to not replace, do that.
diff --git a/m4/time_r.m4 b/m4/time_r.m4
index 2d49b64f1..8a1ad9dad 100644
--- a/m4/time_r.m4
+++ b/m4/time_r.m4
@@ -1,6 +1,6 @@
 dnl Reentrant time functions: localtime_r, gmtime_r.
 
-dnl Copyright (C) 2003, 2006-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2003, 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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/time_rz.m4 b/m4/time_rz.m4
index c5e85dc62..4cb6a0648 100644
--- a/m4/time_rz.m4
+++ b/m4/time_rz.m4
@@ -1,6 +1,6 @@
 dnl Time zone functions: tzalloc, localtime_rz, etc.
 
-dnl Copyright (C) 2015-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2015-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/timegm.m4 b/m4/timegm.m4
index 58123beb0..f1893941f 100644
--- a/m4/timegm.m4
+++ b/m4/timegm.m4
@@ -1,5 +1,5 @@
 # timegm.m4 serial 13
-dnl Copyright (C) 2003, 2007, 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2003, 2007, 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/times.m4 b/m4/times.m4
index fe75c31bf..cd828c6d4 100644
--- a/m4/times.m4
+++ b/m4/times.m4
@@ -1,5 +1,5 @@
 # times.m4 serial 2
-dnl Copyright (C) 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/tm_gmtoff.m4 b/m4/tm_gmtoff.m4
index 2743999fb..9275bed67 100644
--- a/m4/tm_gmtoff.m4
+++ b/m4/tm_gmtoff.m4
@@ -1,5 +1,5 @@
 # tm_gmtoff.m4 serial 3
-dnl Copyright (C) 2002, 2009-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2002, 2009-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/trunc.m4 b/m4/trunc.m4
index b80b91926..811256ce5 100644
--- a/m4/trunc.m4
+++ b/m4/trunc.m4
@@ -1,5 +1,5 @@
 # trunc.m4 serial 15
-dnl Copyright (C) 2007, 2010-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2007, 2010-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/tzset.m4 b/m4/tzset.m4
index 8a4f28557..2c7e17e28 100644
--- a/m4/tzset.m4
+++ b/m4/tzset.m4
@@ -1,6 +1,6 @@
 # serial 16
 
-# Copyright (C) 2003, 2007, 2009-2021 Free Software Foundation, Inc.
+# Copyright (C) 2003, 2007, 2009-2022 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.
diff --git a/m4/uintmax_t.m4 b/m4/uintmax_t.m4
new file mode 100644
index 000000000..03b51bcfe
--- /dev/null
+++ b/m4/uintmax_t.m4
@@ -0,0 +1,30 @@
+# uintmax_t.m4 serial 12
+dnl Copyright (C) 1997-2004, 2007-2010 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 From Paul Eggert.
+
+AC_PREREQ([2.13])
+
+# Define uintmax_t to 'unsigned long' or 'unsigned long long'
+# if it is not already defined in <stdint.h> or <inttypes.h>.
+
+AC_DEFUN([gl_AC_TYPE_UINTMAX_T],
+[
+  AC_REQUIRE([gl_AC_HEADER_INTTYPES_H])
+  AC_REQUIRE([gl_AC_HEADER_STDINT_H])
+  if test $gl_cv_header_inttypes_h = no && test $gl_cv_header_stdint_h = no; then
+    AC_REQUIRE([AC_TYPE_UNSIGNED_LONG_LONG_INT])
+    test $ac_cv_type_unsigned_long_long_int = yes \
+      && ac_type='unsigned long long' \
+      || ac_type='unsigned long'
+    AC_DEFINE_UNQUOTED([uintmax_t], [$ac_type],
+      [Define to unsigned long or unsigned long long
+       if <stdint.h> and <inttypes.h> don't define.])
+  else
+    AC_DEFINE([HAVE_UINTMAX_T], [1],
+      [Define if you have the 'uintmax_t' type in <stdint.h> or <inttypes.h>.])
+  fi
+])
diff --git a/m4/unistd_h.m4 b/m4/unistd_h.m4
index 0ce4ea451..4c66ccc0a 100644
--- a/m4/unistd_h.m4
+++ b/m4/unistd_h.m4
@@ -1,5 +1,5 @@
-# unistd_h.m4 serial 89
-dnl Copyright (C) 2006-2021 Free Software Foundation, Inc.
+# unistd_h.m4 serial 90
+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,
 dnl with or without modifications, as long as this notice is preserved.
@@ -112,6 +112,7 @@ AC_DEFUN([gl_UNISTD_H_REQUIRE_DEFAULTS],
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETOPT_POSIX])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETPAGESIZE])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETPASS])
+    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETPASS_GNU])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETUSERSHELL])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GROUP_MEMBER])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ISATTY])
@@ -170,98 +171,100 @@ AC_DEFUN([gl_UNISTD_H_REQUIRE_DEFAULTS],
 AC_DEFUN([gl_UNISTD_H_DEFAULTS],
 [
   dnl Assume proper GNU behavior unless another module says otherwise.
-  HAVE_CHOWN=1;           AC_SUBST([HAVE_CHOWN])
-  HAVE_COPY_FILE_RANGE=1; AC_SUBST([HAVE_COPY_FILE_RANGE])
-  HAVE_DUP3=1;            AC_SUBST([HAVE_DUP3])
-  HAVE_EUIDACCESS=1;      AC_SUBST([HAVE_EUIDACCESS])
-  HAVE_EXECVPE=1;         AC_SUBST([HAVE_EXECVPE])
-  HAVE_FACCESSAT=1;       AC_SUBST([HAVE_FACCESSAT])
-  HAVE_FCHDIR=1;          AC_SUBST([HAVE_FCHDIR])
-  HAVE_FCHOWNAT=1;        AC_SUBST([HAVE_FCHOWNAT])
-  HAVE_FDATASYNC=1;       AC_SUBST([HAVE_FDATASYNC])
-  HAVE_FSYNC=1;           AC_SUBST([HAVE_FSYNC])
-  HAVE_FTRUNCATE=1;       AC_SUBST([HAVE_FTRUNCATE])
-  HAVE_GETDTABLESIZE=1;   AC_SUBST([HAVE_GETDTABLESIZE])
-  HAVE_GETENTROPY=1;      AC_SUBST([HAVE_GETENTROPY])
-  HAVE_GETGROUPS=1;       AC_SUBST([HAVE_GETGROUPS])
-  HAVE_GETHOSTNAME=1;     AC_SUBST([HAVE_GETHOSTNAME])
-  HAVE_GETLOGIN=1;        AC_SUBST([HAVE_GETLOGIN])
-  HAVE_GETPAGESIZE=1;     AC_SUBST([HAVE_GETPAGESIZE])
-  HAVE_GETPASS=1;         AC_SUBST([HAVE_GETPASS])
-  HAVE_GROUP_MEMBER=1;    AC_SUBST([HAVE_GROUP_MEMBER])
-  HAVE_LCHOWN=1;          AC_SUBST([HAVE_LCHOWN])
-  HAVE_LINK=1;            AC_SUBST([HAVE_LINK])
-  HAVE_LINKAT=1;          AC_SUBST([HAVE_LINKAT])
-  HAVE_PIPE=1;            AC_SUBST([HAVE_PIPE])
-  HAVE_PIPE2=1;           AC_SUBST([HAVE_PIPE2])
-  HAVE_PREAD=1;           AC_SUBST([HAVE_PREAD])
-  HAVE_PWRITE=1;          AC_SUBST([HAVE_PWRITE])
-  HAVE_READLINK=1;        AC_SUBST([HAVE_READLINK])
-  HAVE_READLINKAT=1;      AC_SUBST([HAVE_READLINKAT])
-  HAVE_SETHOSTNAME=1;     AC_SUBST([HAVE_SETHOSTNAME])
-  HAVE_SLEEP=1;           AC_SUBST([HAVE_SLEEP])
-  HAVE_SYMLINK=1;         AC_SUBST([HAVE_SYMLINK])
-  HAVE_SYMLINKAT=1;       AC_SUBST([HAVE_SYMLINKAT])
-  HAVE_UNLINKAT=1;        AC_SUBST([HAVE_UNLINKAT])
-  HAVE_USLEEP=1;          AC_SUBST([HAVE_USLEEP])
-  HAVE_DECL_ENVIRON=1;    AC_SUBST([HAVE_DECL_ENVIRON])
-  HAVE_DECL_EXECVPE=1;    AC_SUBST([HAVE_DECL_EXECVPE])
-  HAVE_DECL_FCHDIR=1;     AC_SUBST([HAVE_DECL_FCHDIR])
-  HAVE_DECL_FDATASYNC=1;  AC_SUBST([HAVE_DECL_FDATASYNC])
-  HAVE_DECL_GETDOMAINNAME=1; AC_SUBST([HAVE_DECL_GETDOMAINNAME])
-  HAVE_DECL_GETLOGIN=1;   AC_SUBST([HAVE_DECL_GETLOGIN])
-  HAVE_DECL_GETLOGIN_R=1; AC_SUBST([HAVE_DECL_GETLOGIN_R])
-  HAVE_DECL_GETPAGESIZE=1; AC_SUBST([HAVE_DECL_GETPAGESIZE])
-  HAVE_DECL_GETUSERSHELL=1; AC_SUBST([HAVE_DECL_GETUSERSHELL])
-  HAVE_DECL_SETHOSTNAME=1; AC_SUBST([HAVE_DECL_SETHOSTNAME])
-  HAVE_DECL_TRUNCATE=1;   AC_SUBST([HAVE_DECL_TRUNCATE])
-  HAVE_DECL_TTYNAME_R=1;  AC_SUBST([HAVE_DECL_TTYNAME_R])
-  HAVE_OS_H=0;            AC_SUBST([HAVE_OS_H])
-  HAVE_SYS_PARAM_H=0;     AC_SUBST([HAVE_SYS_PARAM_H])
-  REPLACE_ACCESS=0;       AC_SUBST([REPLACE_ACCESS])
-  REPLACE_CHOWN=0;        AC_SUBST([REPLACE_CHOWN])
-  REPLACE_CLOSE=0;        AC_SUBST([REPLACE_CLOSE])
-  REPLACE_DUP=0;          AC_SUBST([REPLACE_DUP])
-  REPLACE_DUP2=0;         AC_SUBST([REPLACE_DUP2])
-  REPLACE_EXECL=0;        AC_SUBST([REPLACE_EXECL])
-  REPLACE_EXECLE=0;       AC_SUBST([REPLACE_EXECLE])
-  REPLACE_EXECLP=0;       AC_SUBST([REPLACE_EXECLP])
-  REPLACE_EXECV=0;        AC_SUBST([REPLACE_EXECV])
-  REPLACE_EXECVE=0;       AC_SUBST([REPLACE_EXECVE])
-  REPLACE_EXECVP=0;       AC_SUBST([REPLACE_EXECVP])
-  REPLACE_EXECVPE=0;      AC_SUBST([REPLACE_EXECVPE])
-  REPLACE_FACCESSAT=0;    AC_SUBST([REPLACE_FACCESSAT])
-  REPLACE_FCHOWNAT=0;     AC_SUBST([REPLACE_FCHOWNAT])
-  REPLACE_FTRUNCATE=0;    AC_SUBST([REPLACE_FTRUNCATE])
-  REPLACE_GETCWD=0;       AC_SUBST([REPLACE_GETCWD])
-  REPLACE_GETDOMAINNAME=0; AC_SUBST([REPLACE_GETDOMAINNAME])
-  REPLACE_GETDTABLESIZE=0; AC_SUBST([REPLACE_GETDTABLESIZE])
-  REPLACE_GETLOGIN_R=0;   AC_SUBST([REPLACE_GETLOGIN_R])
-  REPLACE_GETGROUPS=0;    AC_SUBST([REPLACE_GETGROUPS])
-  REPLACE_GETPAGESIZE=0;  AC_SUBST([REPLACE_GETPAGESIZE])
-  REPLACE_GETPASS=0;      AC_SUBST([REPLACE_GETPASS])
-  REPLACE_ISATTY=0;       AC_SUBST([REPLACE_ISATTY])
-  REPLACE_LCHOWN=0;       AC_SUBST([REPLACE_LCHOWN])
-  REPLACE_LINK=0;         AC_SUBST([REPLACE_LINK])
-  REPLACE_LINKAT=0;       AC_SUBST([REPLACE_LINKAT])
-  REPLACE_LSEEK=0;        AC_SUBST([REPLACE_LSEEK])
-  REPLACE_PREAD=0;        AC_SUBST([REPLACE_PREAD])
-  REPLACE_PWRITE=0;       AC_SUBST([REPLACE_PWRITE])
-  REPLACE_READ=0;         AC_SUBST([REPLACE_READ])
-  REPLACE_READLINK=0;     AC_SUBST([REPLACE_READLINK])
-  REPLACE_READLINKAT=0;   AC_SUBST([REPLACE_READLINKAT])
-  REPLACE_RMDIR=0;        AC_SUBST([REPLACE_RMDIR])
-  REPLACE_SLEEP=0;        AC_SUBST([REPLACE_SLEEP])
-  REPLACE_SYMLINK=0;      AC_SUBST([REPLACE_SYMLINK])
-  REPLACE_SYMLINKAT=0;    AC_SUBST([REPLACE_SYMLINKAT])
-  REPLACE_TRUNCATE=0;     AC_SUBST([REPLACE_TRUNCATE])
-  REPLACE_TTYNAME_R=0;    AC_SUBST([REPLACE_TTYNAME_R])
-  REPLACE_UNLINK=0;       AC_SUBST([REPLACE_UNLINK])
-  REPLACE_UNLINKAT=0;     AC_SUBST([REPLACE_UNLINKAT])
-  REPLACE_USLEEP=0;       AC_SUBST([REPLACE_USLEEP])
-  REPLACE_WRITE=0;        AC_SUBST([REPLACE_WRITE])
-  UNISTD_H_HAVE_SYS_RANDOM_H=0; AC_SUBST([UNISTD_H_HAVE_SYS_RANDOM_H])
-  UNISTD_H_HAVE_WINSOCK2_H=0; AC_SUBST([UNISTD_H_HAVE_WINSOCK2_H])
+  HAVE_CHOWN=1;                      AC_SUBST([HAVE_CHOWN])
+  HAVE_COPY_FILE_RANGE=1;            AC_SUBST([HAVE_COPY_FILE_RANGE])
+  HAVE_DUP3=1;                       AC_SUBST([HAVE_DUP3])
+  HAVE_EUIDACCESS=1;                 AC_SUBST([HAVE_EUIDACCESS])
+  HAVE_EXECVPE=1;                    AC_SUBST([HAVE_EXECVPE])
+  HAVE_FACCESSAT=1;                  AC_SUBST([HAVE_FACCESSAT])
+  HAVE_FCHDIR=1;                     AC_SUBST([HAVE_FCHDIR])
+  HAVE_FCHOWNAT=1;                   AC_SUBST([HAVE_FCHOWNAT])
+  HAVE_FDATASYNC=1;                  AC_SUBST([HAVE_FDATASYNC])
+  HAVE_FSYNC=1;                      AC_SUBST([HAVE_FSYNC])
+  HAVE_FTRUNCATE=1;                  AC_SUBST([HAVE_FTRUNCATE])
+  HAVE_GETDTABLESIZE=1;              AC_SUBST([HAVE_GETDTABLESIZE])
+  HAVE_GETENTROPY=1;                 AC_SUBST([HAVE_GETENTROPY])
+  HAVE_GETGROUPS=1;                  AC_SUBST([HAVE_GETGROUPS])
+  HAVE_GETHOSTNAME=1;                AC_SUBST([HAVE_GETHOSTNAME])
+  HAVE_GETLOGIN=1;                   AC_SUBST([HAVE_GETLOGIN])
+  HAVE_GETPAGESIZE=1;                AC_SUBST([HAVE_GETPAGESIZE])
+  HAVE_GETPASS=1;                    AC_SUBST([HAVE_GETPASS])
+  HAVE_GROUP_MEMBER=1;               AC_SUBST([HAVE_GROUP_MEMBER])
+  HAVE_LCHOWN=1;                     AC_SUBST([HAVE_LCHOWN])
+  HAVE_LINK=1;                       AC_SUBST([HAVE_LINK])
+  HAVE_LINKAT=1;                     AC_SUBST([HAVE_LINKAT])
+  HAVE_PIPE=1;                       AC_SUBST([HAVE_PIPE])
+  HAVE_PIPE2=1;                      AC_SUBST([HAVE_PIPE2])
+  HAVE_PREAD=1;                      AC_SUBST([HAVE_PREAD])
+  HAVE_PWRITE=1;                     AC_SUBST([HAVE_PWRITE])
+  HAVE_READLINK=1;                   AC_SUBST([HAVE_READLINK])
+  HAVE_READLINKAT=1;                 AC_SUBST([HAVE_READLINKAT])
+  HAVE_SETHOSTNAME=1;                AC_SUBST([HAVE_SETHOSTNAME])
+  HAVE_SLEEP=1;                      AC_SUBST([HAVE_SLEEP])
+  HAVE_SYMLINK=1;                    AC_SUBST([HAVE_SYMLINK])
+  HAVE_SYMLINKAT=1;                  AC_SUBST([HAVE_SYMLINKAT])
+  HAVE_UNLINKAT=1;                   AC_SUBST([HAVE_UNLINKAT])
+  HAVE_USLEEP=1;                     AC_SUBST([HAVE_USLEEP])
+  HAVE_DECL_ENVIRON=1;               AC_SUBST([HAVE_DECL_ENVIRON])
+  HAVE_DECL_EXECVPE=1;               AC_SUBST([HAVE_DECL_EXECVPE])
+  HAVE_DECL_FCHDIR=1;                AC_SUBST([HAVE_DECL_FCHDIR])
+  HAVE_DECL_FDATASYNC=1;             AC_SUBST([HAVE_DECL_FDATASYNC])
+  HAVE_DECL_GETDOMAINNAME=1;         AC_SUBST([HAVE_DECL_GETDOMAINNAME])
+  HAVE_DECL_GETLOGIN=1;              AC_SUBST([HAVE_DECL_GETLOGIN])
+  HAVE_DECL_GETLOGIN_R=1;            AC_SUBST([HAVE_DECL_GETLOGIN_R])
+  HAVE_DECL_GETPAGESIZE=1;           AC_SUBST([HAVE_DECL_GETPAGESIZE])
+  HAVE_DECL_GETUSERSHELL=1;          AC_SUBST([HAVE_DECL_GETUSERSHELL])
+  HAVE_DECL_SETHOSTNAME=1;           AC_SUBST([HAVE_DECL_SETHOSTNAME])
+  HAVE_DECL_TRUNCATE=1;              AC_SUBST([HAVE_DECL_TRUNCATE])
+  HAVE_DECL_TTYNAME_R=1;             AC_SUBST([HAVE_DECL_TTYNAME_R])
+  HAVE_OS_H=0;                       AC_SUBST([HAVE_OS_H])
+  HAVE_SYS_PARAM_H=0;                AC_SUBST([HAVE_SYS_PARAM_H])
+  REPLACE_ACCESS=0;                  AC_SUBST([REPLACE_ACCESS])
+  REPLACE_CHOWN=0;                   AC_SUBST([REPLACE_CHOWN])
+  REPLACE_CLOSE=0;                   AC_SUBST([REPLACE_CLOSE])
+  REPLACE_COPY_FILE_RANGE=0;         AC_SUBST([REPLACE_COPY_FILE_RANGE])
+  REPLACE_DUP=0;                     AC_SUBST([REPLACE_DUP])
+  REPLACE_DUP2=0;                    AC_SUBST([REPLACE_DUP2])
+  REPLACE_EXECL=0;                   AC_SUBST([REPLACE_EXECL])
+  REPLACE_EXECLE=0;                  AC_SUBST([REPLACE_EXECLE])
+  REPLACE_EXECLP=0;                  AC_SUBST([REPLACE_EXECLP])
+  REPLACE_EXECV=0;                   AC_SUBST([REPLACE_EXECV])
+  REPLACE_EXECVE=0;                  AC_SUBST([REPLACE_EXECVE])
+  REPLACE_EXECVP=0;                  AC_SUBST([REPLACE_EXECVP])
+  REPLACE_EXECVPE=0;                 AC_SUBST([REPLACE_EXECVPE])
+  REPLACE_FACCESSAT=0;               AC_SUBST([REPLACE_FACCESSAT])
+  REPLACE_FCHOWNAT=0;                AC_SUBST([REPLACE_FCHOWNAT])
+  REPLACE_FTRUNCATE=0;               AC_SUBST([REPLACE_FTRUNCATE])
+  REPLACE_GETCWD=0;                  AC_SUBST([REPLACE_GETCWD])
+  REPLACE_GETDOMAINNAME=0;           AC_SUBST([REPLACE_GETDOMAINNAME])
+  REPLACE_GETDTABLESIZE=0;           AC_SUBST([REPLACE_GETDTABLESIZE])
+  REPLACE_GETLOGIN_R=0;              AC_SUBST([REPLACE_GETLOGIN_R])
+  REPLACE_GETGROUPS=0;               AC_SUBST([REPLACE_GETGROUPS])
+  REPLACE_GETPAGESIZE=0;             AC_SUBST([REPLACE_GETPAGESIZE])
+  REPLACE_GETPASS=0;                 AC_SUBST([REPLACE_GETPASS])
+  REPLACE_GETPASS_FOR_GETPASS_GNU=0; AC_SUBST([REPLACE_GETPASS_FOR_GETPASS_GNU])
+  REPLACE_ISATTY=0;                  AC_SUBST([REPLACE_ISATTY])
+  REPLACE_LCHOWN=0;                  AC_SUBST([REPLACE_LCHOWN])
+  REPLACE_LINK=0;                    AC_SUBST([REPLACE_LINK])
+  REPLACE_LINKAT=0;                  AC_SUBST([REPLACE_LINKAT])
+  REPLACE_LSEEK=0;                   AC_SUBST([REPLACE_LSEEK])
+  REPLACE_PREAD=0;                   AC_SUBST([REPLACE_PREAD])
+  REPLACE_PWRITE=0;                  AC_SUBST([REPLACE_PWRITE])
+  REPLACE_READ=0;                    AC_SUBST([REPLACE_READ])
+  REPLACE_READLINK=0;                AC_SUBST([REPLACE_READLINK])
+  REPLACE_READLINKAT=0;              AC_SUBST([REPLACE_READLINKAT])
+  REPLACE_RMDIR=0;                   AC_SUBST([REPLACE_RMDIR])
+  REPLACE_SLEEP=0;                   AC_SUBST([REPLACE_SLEEP])
+  REPLACE_SYMLINK=0;                 AC_SUBST([REPLACE_SYMLINK])
+  REPLACE_SYMLINKAT=0;               AC_SUBST([REPLACE_SYMLINKAT])
+  REPLACE_TRUNCATE=0;                AC_SUBST([REPLACE_TRUNCATE])
+  REPLACE_TTYNAME_R=0;               AC_SUBST([REPLACE_TTYNAME_R])
+  REPLACE_UNLINK=0;                  AC_SUBST([REPLACE_UNLINK])
+  REPLACE_UNLINKAT=0;                AC_SUBST([REPLACE_UNLINKAT])
+  REPLACE_USLEEP=0;                  AC_SUBST([REPLACE_USLEEP])
+  REPLACE_WRITE=0;                   AC_SUBST([REPLACE_WRITE])
+  UNISTD_H_HAVE_SYS_RANDOM_H=0;      AC_SUBST([UNISTD_H_HAVE_SYS_RANDOM_H])
+  UNISTD_H_HAVE_WINSOCK2_H=0;        AC_SUBST([UNISTD_H_HAVE_WINSOCK2_H])
   UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS=0;
                            AC_SUBST([UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS])
 ])
diff --git a/m4/vararrays.m4 b/m4/vararrays.m4
new file mode 100644
index 000000000..28e22a49d
--- /dev/null
+++ b/m4/vararrays.m4
@@ -0,0 +1,72 @@
+# Check for variable-length arrays.
+
+# serial 6
+
+# From Paul Eggert
+
+# Copyright (C) 2001, 2009-2022 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.
+
+m4_version_prereq([2.70], [], [
+
+# AC_C_VARARRAYS
+# --------------
+# Check whether the C compiler supports variable-length arrays.
+AC_DEFUN([AC_C_VARARRAYS],
+[
+  AC_CACHE_CHECK([for variable-length arrays],
+    ac_cv_c_vararrays,
+    [AC_EGREP_CPP([defined],
+       [#ifdef __STDC_NO_VLA__
+        defined
+        #endif
+       ],
+       [ac_cv_c_vararrays='no: __STDC_NO_VLA__ is defined'],
+       [AC_COMPILE_IFELSE(
+          [AC_LANG_PROGRAM(
+             [[/* Test for VLA support.  This test is partly inspired
+                  from examples in the C standard.  Use at least two VLA
+                  functions to detect the GCC 3.4.3 bug described in:
+                  https://lists.gnu.org/archive/html/bug-gnulib/2014-08/msg00014.html
+                  */
+               #ifdef __STDC_NO_VLA__
+                syntax error;
+               #else
+                 extern int n;
+                 int B[100];
+                 int fvla (int m, int C[m][m]);
+
+                 int
+                 simple (int count, int all[static count])
+                 {
+                   return all[count - 1];
+                 }
+
+                 int
+                 fvla (int m, int C[m][m])
+                 {
+                   typedef int VLA[m][m];
+                   VLA x;
+                   int D[m];
+                   static int (*q)[m] = &B;
+                   int (*s)[n] = q;
+                   return C && &x[0][0] == &D[0] && &D[0] == s[0];
+                 }
+               #endif
+               ]])],
+          [ac_cv_c_vararrays=yes],
+          [ac_cv_c_vararrays=no])])])
+  if test "$ac_cv_c_vararrays" = yes; then
+    dnl This is for compatibility with Autoconf 2.61-2.69.
+    AC_DEFINE([HAVE_C_VARARRAYS], 1,
+      [Define to 1 if C supports variable-length arrays.])
+  elif test "$ac_cv_c_vararrays" = no; then
+    AC_DEFINE([__STDC_NO_VLA__], 1,
+      [Define to 1 if C does not support variable-length arrays, and
+       if the compiler does not already define this.])
+  fi
+])
+
+])
diff --git a/m4/vasnprintf.m4 b/m4/vasnprintf.m4
index 483bba969..afdece71c 100644
--- a/m4/vasnprintf.m4
+++ b/m4/vasnprintf.m4
@@ -1,5 +1,5 @@
 # vasnprintf.m4 serial 38
-dnl Copyright (C) 2002-2004, 2006-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2002-2004, 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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/visibility.m4 b/m4/visibility.m4
index d161bd7f7..4a212a4e5 100644
--- a/m4/visibility.m4
+++ b/m4/visibility.m4
@@ -1,5 +1,5 @@
 # visibility.m4 serial 8
-dnl Copyright (C) 2005, 2008, 2010-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2005, 2008, 2010-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/vsnprintf.m4 b/m4/vsnprintf.m4
index 5f5375e63..02b448f3b 100644
--- a/m4/vsnprintf.m4
+++ b/m4/vsnprintf.m4
@@ -1,5 +1,5 @@
 # vsnprintf.m4 serial 7
-dnl Copyright (C) 2002-2004, 2007-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2002-2004, 2007-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/warn-on-use.m4 b/m4/warn-on-use.m4
index 04edfe85d..d43355ab1 100644
--- a/m4/warn-on-use.m4
+++ b/m4/warn-on-use.m4
@@ -1,5 +1,5 @@
 # warn-on-use.m4 serial 9
-dnl Copyright (C) 2010-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2010-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/warnings.m4 b/m4/warnings.m4
index 9e24d898e..60088f93e 100644
--- a/m4/warnings.m4
+++ b/m4/warnings.m4
@@ -1,5 +1,5 @@
 # warnings.m4 serial 16
-dnl Copyright (C) 2008-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2008-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/wchar_h.m4 b/m4/wchar_h.m4
index 818b3192e..4baba1af0 100644
--- a/m4/wchar_h.m4
+++ b/m4/wchar_h.m4
@@ -1,13 +1,13 @@
 dnl A placeholder for ISO C99 <wchar.h>, for platforms that have issues.
 
-dnl Copyright (C) 2007-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2007-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,
 dnl with or without modifications, as long as this notice is preserved.
 
 dnl Written by Eric Blake.
 
-# wchar_h.m4 serial 53
+# wchar_h.m4 serial 55
 
 AC_DEFUN_ONCE([gl_WCHAR_H],
 [
@@ -189,6 +189,8 @@ AC_DEFUN([gl_WCHAR_H_REQUIRE_DEFAULTS],
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_WCSDUP], [1])
   ])
   m4_require(GL_MODULE_INDICATOR_PREFIX[_WCHAR_H_MODULE_INDICATOR_DEFAULTS])
+  dnl Make sure the shell variable for GNULIB_FREE_POSIX is initialized.
+  gl_STDLIB_H_REQUIRE_DEFAULTS
   AC_REQUIRE([gl_WCHAR_H_DEFAULTS])
 ])
 
diff --git a/m4/wchar_t.m4 b/m4/wchar_t.m4
index 34db10e5c..268e3e515 100644
--- a/m4/wchar_t.m4
+++ b/m4/wchar_t.m4
@@ -1,5 +1,5 @@
 # wchar_t.m4 serial 4 (gettext-0.18.2)
-dnl Copyright (C) 2002-2003, 2008-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2002-2003, 2008-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/wcrtomb.m4 b/m4/wcrtomb.m4
index cd96f1161..fee21d7ef 100644
--- a/m4/wcrtomb.m4
+++ b/m4/wcrtomb.m4
@@ -1,5 +1,5 @@
 # wcrtomb.m4 serial 17
-dnl Copyright (C) 2008-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2008-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/wctype_h.m4 b/m4/wctype_h.m4
index 7d7421277..702cb39cd 100644
--- a/m4/wctype_h.m4
+++ b/m4/wctype_h.m4
@@ -2,7 +2,7 @@
 
 dnl A placeholder for ISO C99 <wctype.h>, for platforms that lack it.
 
-dnl Copyright (C) 2006-2021 Free Software Foundation, Inc.
+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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/wint_t.m4 b/m4/wint_t.m4
index a49c50813..adc586614 100644
--- a/m4/wint_t.m4
+++ b/m4/wint_t.m4
@@ -1,5 +1,5 @@
 # wint_t.m4 serial 11
-dnl Copyright (C) 2003, 2007-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2003, 2007-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/write.m4 b/m4/write.m4
index 84400c5f0..33b5dce60 100644
--- a/m4/write.m4
+++ b/m4/write.m4
@@ -1,5 +1,5 @@
 # write.m4 serial 6
-dnl Copyright (C) 2008-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2008-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/xsize.m4 b/m4/xsize.m4
index 64e8a4f45..0109049e0 100644
--- a/m4/xsize.m4
+++ b/m4/xsize.m4
@@ -1,5 +1,5 @@
 # xsize.m4 serial 5
-dnl Copyright (C) 2003-2004, 2008-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2003-2004, 2008-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/year2038.m4 b/m4/year2038.m4
index da0f8d730..2e4427e6f 100644
--- a/m4/year2038.m4
+++ b/m4/year2038.m4
@@ -1,5 +1,5 @@
-# year2038.m4 serial 7
-dnl Copyright (C) 2017-2021 Free Software Foundation, Inc.
+# year2038.m4 serial 8
+dnl Copyright (C) 2017-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,
 dnl with or without modifications, as long as this notice is preserved.
@@ -7,6 +7,12 @@ dnl with or without modifications, as long as this notice is preserved.
 dnl Attempt to ensure that 'time_t' can go past the year 2038 and that
 dnl the functions 'time', 'stat', etc. work with post-2038 timestamps.
 
+m4_ifdef([AC_SYS_YEAR2038], [
+  AC_DEFUN([gl_YEAR2038_EARLY])
+  AC_DEFUN([gl_YEAR2038], [AC_SYS_YEAR2038])
+  AC_DEFUN([gl_YEAR2038_BODY], [_AC_SYS_YEAR2038])
+], [
+
 AC_DEFUN([gl_YEAR2038_EARLY],
 [
   AC_REQUIRE([AC_CANONICAL_HOST])
@@ -122,3 +128,5 @@ AC_DEFUN([gl_YEAR2038],
 [
   gl_YEAR2038_BODY([require-year2038-safe])
 ])
+
+]) # m4_ifndef AC_SYS_YEAR2038
diff --git a/m4/zzgnulib.m4 b/m4/zzgnulib.m4
index b9533847c..fd73a201f 100644
--- a/m4/zzgnulib.m4
+++ b/m4/zzgnulib.m4
@@ -1,5 +1,5 @@
 # zzgnulib.m4 serial 1
-dnl Copyright (C) 2020-2021 Free Software Foundation, Inc.
+dnl Copyright (C) 2020-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,
 dnl with or without modifications, as long as this notice is preserved.
diff --git a/maint.mk b/maint.mk
index 6a3ea9606..5745d5831 100644
--- a/maint.mk
+++ b/maint.mk
@@ -2,7 +2,7 @@
 # This Makefile fragment tries to be general-purpose enough to be
 # used by many projects via the gnulib maintainer-makefile module.
 
-## Copyright (C) 2001-2021 Free Software Foundation, Inc.
+## Copyright (C) 2001-2022 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
@@ -64,7 +64,7 @@ VC_LIST = $(srcdir)/$(_build-aux)/vc-list-files -C $(srcdir)
 
 # You can override this variable in cfg.mk if your gnulib submodule lives
 # in a different location.
-gnulib_dir ?= $(shell if test -d $(srcdir)/gnulib; then \
+gnulib_dir ?= $(shell if test -f $(srcdir)/gnulib/gnulib-tool; then \
 			echo $(srcdir)/gnulib; \
 		else \
 			echo ${GNULIB_SRCDIR}; \
@@ -473,7 +473,7 @@ sc_error_message_uppercase:
 	@$(VC_LIST_EXCEPT)						\
 	  | xargs $(GREP) -nEA2 '[^rp]error *\(' /dev/null		\
 	  | $(GREP) -E '"[A-Z]'						\
-	  | $(GREP) -vE '"FATAL|"WARNING|"Java|"C#|PRIuMAX'		\
+	  | $(GREP) -vE '"FATAL|"WARNING|"Java|"C#|"PRI'		\
 	  && { echo '$(ME): found capitalized error message' 1>&2;	\
 	       exit 1; }						\
 	  || :
@@ -622,9 +622,9 @@ sc_prohibit_xalloc_without_use:
 	  $(_sc_header_without_use)
 
 # Extract function names:
-# perl -lne '/^(?:extern )?(?:void|char) \*?(\w+) *\(/ and print $1' lib/hash.h
+# perl -lne '/^(?:extern )?(?:void|char|Hash_table) \*?(\w+) *\(/ and print $1' lib/hash.h
 _hash_re = \
-clear|delete|free|get_(first|next)|insert|lookup|print_statistics|reset_tuning
+hash_(re(set_tuning|move)|xin(itialize|sert)|in(itialize|sert)|get_(firs|nex)t|print_statistics|(delet|fre)e|lookup|clear)
 _hash_fn = \<($(_hash_re)) *\(
 _hash_struct = (struct )?\<[Hh]ash_(table|tuning)\>
 sc_prohibit_hash_without_use:
@@ -823,7 +823,7 @@ sc_trailing_blank:
 # Match lines like the following, but where there is only one space
 # between the options and the description:
 #   -D, --all-repeated[=delimit-method]  print all duplicate lines\n
-longopt_re = --[a-z][0-9A-Za-z-]*(\[?=[0-9A-Za-z-]*\]?)?
+longopt_re = --[a-z][0-9A-Za-z-]*(\[?=[0-9A-Za-z-]*]?)?
 sc_two_space_separator_in_usage:
 	@prohibit='^   *(-[A-Za-z],)? $(longopt_re) [^ ].*\\$$'		\
 	halt='help2man requires at least two spaces between an option and its description'\
@@ -1031,7 +1031,7 @@ perl_filename_lineno_text_ =						\
     -e '  }'
 
 prohibit_doubled_words_ = \
-    the then in an on if is it but for or at and do to
+    the then in an on if is it but for or at and do to can
 # expand the regex before running the check to avoid using expensive captures
 prohibit_doubled_word_expanded_ = \
     $(join $(prohibit_doubled_words_),$(addprefix \s+,$(prohibit_doubled_words_)))
@@ -1256,6 +1256,12 @@ sc_makefile_path_separator_check:
 	halt=$(msg)							\
 	  $(_sc_search_regexp)
 
+sc_makefile_DISTCHECK_CONFIGURE_FLAGS:
+	@prohibit='^DISTCHECK_CONFIGURE_FLAGS'				\
+	in_vc_files='akefile|\.mk$$'					\
+	halt="use AM_DISTCHECK_CONFIGURE_FLAGS"				\
+	  $(_sc_search_regexp)
+
 # Check that 'make alpha' will not fail at the end of the process,
 # i.e., when pkg-M.N.tar.xz already exists (either in "." or in ../release)
 # and is read-only.
@@ -1390,7 +1396,12 @@ gpg_key_ID ?=								\
   $$(cd $(srcdir)							\
      && git cat-file tag v$(VERSION)					\
         | $(gpgv) --status-fd 1 --keyring /dev/null - - 2>/dev/null	\
-        | $(AWK) '/^\[GNUPG:\] ERRSIG / {print $$3; exit}')
+        | $(AWK) '/^\[GNUPG:] ERRSIG / {print $$3; exit}')
+gpg_key_email ?=							\
+  $$(gpg --list-key --with-colons $(gpg_key_ID) 2>/dev/null		\
+	| $(AWK) -F: '/^uid/ {print $$10; exit}'			\
+	| $(SED) -n 's/.*<\(.*\)>/\1/p')
+gpg_keyring_url ?= https://savannah.gnu.org/project/release-gpgkeys.php?group=$(PACKAGE)&download=1
 
 translation_project_ ?= coordinator@translationproject.org
 
@@ -1421,6 +1432,10 @@ announcement: NEWS ChangeLog $(rel-files)
 	    --prev=$(PREV_VERSION)					\
 	    --curr=$(VERSION)						\
 	    --gpg-key-id=$(gpg_key_ID)					\
+	    $$(test -n "$(gpg_key_email)" &&				\
+	       echo --gpg-key-email="$(gpg_key_email)")			\
+	    $$(test -n "$(gpg_keyring_url)" &&				\
+	       echo --gpg-keyring-url="$(gpg_keyring_url)")		\
 	    --srcdir=$(srcdir)						\
 	    --news=$(srcdir)/NEWS					\
 	    --bootstrap-tools=$(bootstrap-tools)			\
@@ -1522,7 +1537,7 @@ alpha beta stable: $(local-check) writable-files $(submodule-checks)
 
 release:
 	$(AM_V_GEN)$(MAKE) _version
-	$(AM_V_GEN)$(MAKE) $(release-type)
+	$(AM_V_at)$(MAKE) $(release-type)
 
 # Override this in cfg.mk if you follow different procedures.
 release-prep-hook ?= release-prep
@@ -1631,12 +1646,32 @@ refresh-po:
 	ls $(PODIR)/*.po | $(SED) 's/\.po//;s,$(PODIR)/,,' | \
 	  sort >> $(PODIR)/LINGUAS
 
- # Running indent once is not idempotent, but running it twice is.
+# Indentation
+
+indent_args ?= -ppi 1
+C_SOURCES ?= $$($(VC_LIST_EXCEPT) | grep '\.[ch]\(.in\)\?$$')
 INDENT_SOURCES ?= $(C_SOURCES)
+exclude_file_name_regexp--indent ?= $(exclude_file_name_regexp--sc_indent)
+
 .PHONY: indent
-indent:
-	indent $(INDENT_SOURCES)
-	indent $(INDENT_SOURCES)
+indent: # Running indent once is not idempotent, but running it twice is.
+	$(AM_V_GEN)indent $(indent_args) $(INDENT_SOURCES) && \
+	indent $(indent_args) $(INDENT_SOURCES)
+
+sc_indent:
+	@if ! command -v indent > /dev/null; then			\
+	    echo 1>&2 '$(ME): sc_indent: indent is missing';		\
+	else								\
+	  fail=0; files="$(INDENT_SOURCES)";				\
+	  for f in $$files; do						\
+	    indent $(indent_args) -st $$f				\
+		| indent $(indent_args) -st -				\
+		| diff -u $$f - || fail=1;				\
+	  done;								\
+	  test $$fail = 1 &&						\
+	    { echo 1>&2 '$(ME): code format error, try "make indent"';	\
+	      exit 1; } || :;						\
+	fi
 
 # If you want to set UPDATE_COPYRIGHT_* environment variables,
 # put the assignments in this variable.
@@ -1682,9 +1717,8 @@ sc_tight_scope: tight-scope.mk
 	exit $$fail
 
 tight-scope.mk: $(ME)
-	@rm -f $@ $@-t
 	@perl -ne '/^# TS-start/.../^# TS-end/ and print' $(srcdir)/$(ME) > $@-t
-	@chmod a=r $@-t && mv $@-t $@
+	@mv $@-t $@
 
 ifeq (a,b)
 # TS-start
@@ -1715,8 +1749,8 @@ _gl_TS_unmarked_extern_vars ?=
 # a macro like this: GLOBAL(type, var_name, initializer), then you
 # can override this definition to automatically extract those names:
 # export _gl_TS_var_match = \
-#   /^(?:$(_gl_TS_extern)) .*?\**(\w+)(\[.*?\])?;/ || /\bGLOBAL\(.*?,\s*(.*?),/
-_gl_TS_var_match ?= /^(?:$(_gl_TS_extern)) .*?(\w+)(\[.*?\])?;/
+#   /^(?:$(_gl_TS_extern)) .*?\**(\w+)(\[.*?])?;/ || /\bGLOBAL\(.*?,\s*(.*?),/
+_gl_TS_var_match ?= /^(?:$(_gl_TS_extern)) .*?(\w+)(\[.*?])?;/
 
 # The names of object files in (or relative to) $(_gl_TS_dir).
 _gl_TS_obj_files ?= *.$(OBJEXT)
-- 
2.37.2






^ permalink raw reply related	[flat|nested] 36+ messages in thread

* bug#52835: [PATCH v5 2/3] Add spawn*.
  2022-09-05  6:48         ` bug#52835: [PATCH v5 0/3] Move spawning procedures to posix_spawn Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2022-09-05  6:48           ` bug#52835: [PATCH v5 1/3] Update gnulib to 0.1.5414-8204d and add posix_spawn, posix_spawnp Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
@ 2022-09-05  6:48           ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2022-09-05  6:48           ` bug#52835: [PATCH v5 3/3] Move popen and posix procedures to spawn* Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2 siblings, 0 replies; 36+ messages in thread
From: Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language @ 2022-09-05  6:48 UTC (permalink / raw)
  To: 52835; +Cc: Timothy Sample, Josselin Poiret

* libguile/posix.c: Include spawn.h from Gnulib.
(scm_spawn_process): New function.
(scm_init_popen): Define spawn*.
---
 libguile/posix.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 71 insertions(+)

diff --git a/libguile/posix.c b/libguile/posix.c
index f4ca72d3e..5d287ff2a 100644
--- a/libguile/posix.c
+++ b/libguile/posix.c
@@ -32,6 +32,7 @@
 #include <sys/types.h>
 #include <uniconv.h>
 #include <unistd.h>
+#include <spawn.h>
 
 #ifdef HAVE_SCHED_H
 # include <sched.h>
@@ -1472,6 +1473,75 @@ scm_piped_process (SCM prog, SCM args, SCM from, SCM to)
 }
 #undef FUNC_NAME
 
+static SCM
+scm_spawn_process (SCM prog, SCM args, SCM scm_in, SCM scm_out, SCM scm_err)
+#define FUNC_NAME "spawn*"
+{
+  int in, out, err;
+  int pid;
+  char *exec_file;
+  char **exec_argv;
+  char **exec_env = NULL;
+
+  posix_spawn_file_actions_t actions;
+  posix_spawnattr_t *attrp = NULL;
+
+  exec_file = scm_to_locale_string (prog);
+  exec_argv = scm_i_allocate_string_pointers (args);
+
+  in = scm_to_int (scm_in);
+  out = scm_to_int (scm_out);
+  err = scm_to_int (scm_err);
+
+  int max_fd = 1024;
+
+#if defined (HAVE_GETRLIMIT) && defined (RLIMIT_NOFILE)
+  {
+    struct rlimit lim = { 0, 0 };
+    if (getrlimit (RLIMIT_NOFILE, &lim) == 0)
+      max_fd = lim.rlim_cur;
+  }
+#endif
+
+  posix_spawn_file_actions_init (&actions);
+
+  int free_fd_slots = 0;
+  int fd_slot[3];
+
+  for (int fdnum = 3;free_fd_slots < 3 && fdnum < max_fd;fdnum++)
+    {
+      if (fdnum != in && fdnum != out && fdnum != err)
+        {
+          fd_slot[free_fd_slots] = fdnum;
+          free_fd_slots++;
+        }
+    }
+
+  /* Move the fds out of the way, so that duplicate fds or fds equal
+     to 0, 1, 2 don't trample each other */
+
+  posix_spawn_file_actions_adddup2 (&actions, in, fd_slot[0]);
+  posix_spawn_file_actions_adddup2 (&actions, out, fd_slot[1]);
+  posix_spawn_file_actions_adddup2 (&actions, err, fd_slot[2]);
+  posix_spawn_file_actions_adddup2 (&actions, fd_slot[0], 0);
+  posix_spawn_file_actions_adddup2 (&actions, fd_slot[1], 1);
+  posix_spawn_file_actions_adddup2 (&actions, fd_slot[2], 2);
+
+  while (--max_fd > 2)
+    posix_spawn_file_actions_addclose (&actions, max_fd);
+
+  if (posix_spawnp (&pid, exec_file, &actions, attrp, exec_argv, environ) != 0)
+    {
+      int errno_save = errno;
+      free (exec_file);
+      errno = errno_save;
+      SCM_SYSERROR;
+    }
+
+  return scm_from_int (pid);
+}
+#undef FUNC_NAME
+
 static void
 restore_sigaction (SCM pair)
 {
@@ -2381,6 +2451,7 @@ static void
 scm_init_popen (void)
 {
   scm_c_define_gsubr ("piped-process", 2, 2, 0, scm_piped_process);
+  scm_c_define_gsubr ("spawn*", 5, 0, 0, scm_spawn_process);
 }
 #endif /* HAVE_START_CHILD */
 
-- 
2.37.2






^ permalink raw reply related	[flat|nested] 36+ messages in thread

* bug#52835: [PATCH v5 3/3] Move popen and posix procedures to spawn*.
  2022-09-05  6:48         ` bug#52835: [PATCH v5 0/3] Move spawning procedures to posix_spawn Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2022-09-05  6:48           ` bug#52835: [PATCH v5 1/3] Update gnulib to 0.1.5414-8204d and add posix_spawn, posix_spawnp Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2022-09-05  6:48           ` bug#52835: [PATCH v5 2/3] Add spawn* Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
@ 2022-09-05  6:48           ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2022-11-29 15:05             ` bug#52835: [PATCH 0/2] Fix spawning a child not setting standard fds properly Ludovic Courtès
  2 siblings, 1 reply; 36+ messages in thread
From: Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language @ 2022-09-05  6:48 UTC (permalink / raw)
  To: 52835; +Cc: Timothy Sample, Josselin Poiret

* libguile/posix.c (renumber_file_descriptor, start_child,
scm_piped_process): Remove functions.
(scm_port_to_fd_with_default): New helper function.
(scm_system_star): Rewrite using scm_spawn_process.
(scm_init_popen): Remove the definition of piped-process.
(scm_init_posix): Now make popen available unconditionally.

* module/ice-9/popen.scm (port-with-defaults): New helper procedure.
(spawn): New procedure.
(open-process): Rewrite using spawn.
(pipeline): Rewrite using spawn*.

* test-suite/tests/popen.test ("piped-process", "piped-process:
with-output"): Removed tests.
("spawn", "spawn: with output"): Added tests.
* test-suite/tests/posix.test ("http://bugs.gnu.org/13166", "exit code
for nonexistent file", "https://bugs.gnu.org/55596"): Remove obsolete
tests.
("exception for nonexistent file"): Add test.
---
 libguile/posix.c            | 218 +++---------------------------------
 module/ice-9/popen.scm      |  83 ++++++++++----
 test-suite/tests/popen.test |  14 +--
 test-suite/tests/posix.test |  36 +++---
 4 files changed, 102 insertions(+), 249 deletions(-)

diff --git a/libguile/posix.c b/libguile/posix.c
index 5d287ff2a..c35346f9f 100644
--- a/libguile/posix.c
+++ b/libguile/posix.c
@@ -73,6 +73,7 @@
 #include "fports.h"
 #include "gettext.h"
 #include "gsubr.h"
+#include "ioext.h"
 #include "list.h"
 #include "modules.h"
 #include "numbers.h"
@@ -1280,199 +1281,6 @@ SCM_DEFINE (scm_fork, "primitive-fork", 0, 0, 0,
 #undef FUNC_NAME
 #endif /* HAVE_FORK */
 
-#ifdef HAVE_FORK
-/* 'renumber_file_descriptor' is a helper function for 'start_child'
-   below, and is specialized for that particular environment where it
-   doesn't make sense to report errors via exceptions.  It uses dup(2)
-   to duplicate the file descriptor FD, closes the original FD, and
-   returns the new descriptor.  If dup(2) fails, print an error message
-   to ERR and abort.  */
-static int
-renumber_file_descriptor (int fd, int err)
-{
-  int new_fd;
-
-  do
-    new_fd = dup (fd);
-  while (new_fd == -1 && errno == EINTR);
-
-  if (new_fd == -1)
-    {
-      /* At this point we are in the child process before exec.  We
-         cannot safely raise an exception in this environment.  */
-      const char *msg = strerror (errno);
-      fprintf (fdopen (err, "a"), "start_child: dup failed: %s\n", msg);
-      _exit (127);  /* Use exit status 127, as with other exec errors. */
-    }
-
-  close (fd);
-  return new_fd;
-}
-#endif /* HAVE_FORK */
-
-#ifdef HAVE_FORK
-#define HAVE_START_CHILD 1
-/* Since Guile uses threads, we have to be very careful to avoid calling
-   functions that are not async-signal-safe in the child.  That's why
-   this function is implemented in C.  */
-static pid_t
-start_child (const char *exec_file, char **exec_argv,
-	     int reading, int c2p[2], int writing, int p2c[2],
-             int in, int out, int err)
-{
-  int pid;
-  int max_fd = 1024;
-
-#if defined (HAVE_GETRLIMIT) && defined (RLIMIT_NOFILE)
-  {
-    struct rlimit lim = { 0, 0 };
-    if (getrlimit (RLIMIT_NOFILE, &lim) == 0)
-      max_fd = lim.rlim_cur;
-  }
-#endif
-
-  pid = fork ();
-
-  if (pid != 0)
-    /* The parent, with either and error (pid == -1), or the PID of the
-       child.  Return directly in either case.  */
-    return pid;
-
-  /* The child.  */
-  if (reading)
-    close (c2p[0]);
-  if (writing)
-    close (p2c[1]);
-
-  /* Close all file descriptors in ports inherited from the parent
-     except for in, out, and err.  Heavy-handed, but robust.  */
-  while (max_fd--)
-    if (max_fd != in && max_fd != out && max_fd != err)
-      close (max_fd);
-
-  /* Ignore errors on these open() calls.  */
-  if (in == -1)
-    in = open ("/dev/null", O_RDONLY);
-  if (out == -1)
-    out = open ("/dev/null", O_WRONLY);
-  if (err == -1)
-    err = open ("/dev/null", O_WRONLY);
-
-  if (in > 0)
-    {
-      if (out == 0)
-        out = renumber_file_descriptor (out, err);
-      if (err == 0)
-        err = renumber_file_descriptor (err, err);
-      do dup2 (in, 0); while (errno == EINTR);
-      close (in);
-    }
-  if (out > 1)
-    {
-      if (err == 1)
-        err = renumber_file_descriptor (err, err);
-      do dup2 (out, 1); while (errno == EINTR);
-      if (out > 2)
-        close (out);
-    }
-  if (err > 2)
-    {
-      do dup2 (err, 2); while (errno == EINTR);
-      close (err);
-    }
-
-  execvp (exec_file, exec_argv);
-
-  /* The exec failed!  There is nothing sensible to do.  */
-  {
-    const char *msg = strerror (errno);
-    fprintf (fdopen (2, "a"), "In execvp of %s: %s\n",
-             exec_file, msg);
-  }
-
-  /* Use exit status 127, like shells in this case, as per POSIX
-     <http://pubs.opengroup.org/onlinepubs/007904875/utilities/xcu_chap02.html#tag_02_09_01_01>.  */
-  _exit (127);
-
-  /* Not reached.  */
-  return -1;
-}
-#endif
-
-#ifdef HAVE_START_CHILD
-static SCM
-scm_piped_process (SCM prog, SCM args, SCM from, SCM to)
-#define FUNC_NAME "piped-process"
-{
-  int reading, writing;
-  int c2p[2]; /* Child to parent.  */
-  int p2c[2]; /* Parent to child.  */
-  int in = -1, out = -1, err = -1;
-  int pid;
-  char *exec_file;
-  char **exec_argv;
-
-  exec_file = scm_to_locale_string (prog);
-  exec_argv = scm_i_allocate_string_pointers (scm_cons (prog, args));
-
-  reading = scm_is_pair (from);
-  writing = scm_is_pair (to);
-
-  if (reading)
-    {
-      c2p[0] = scm_to_int (scm_car (from));
-      c2p[1] = scm_to_int (scm_cdr (from));
-      out = c2p[1];
-    }
-
-  if (writing)
-    {
-      p2c[0] = scm_to_int (scm_car (to));
-      p2c[1] = scm_to_int (scm_cdr (to));
-      in = p2c[0];
-    }
-
-  {
-    SCM port;
-
-    if (SCM_OPOUTFPORTP ((port = scm_current_error_port ())))
-      err = SCM_FPORT_FDES (port);
-    if (out == -1 && SCM_OPOUTFPORTP ((port = scm_current_output_port ())))
-      out = SCM_FPORT_FDES (port);
-    if (in == -1 && SCM_OPINFPORTP ((port = scm_current_input_port ())))
-      in = SCM_FPORT_FDES (port);
-  }
-
-  pid = start_child (exec_file, exec_argv, reading, c2p, writing, p2c,
-                     in, out, err);
-
-  if (pid == -1)
-    {
-      int errno_save = errno;
-      free (exec_file);
-      if (reading)
-        {
-          close (c2p[0]);
-          close (c2p[1]);
-        }
-      if (writing)
-        {
-          close (p2c[0]);
-          close (p2c[1]);
-        }
-      errno = errno_save;
-      SCM_SYSERROR;
-    }
-
-  if (reading)
-    close (c2p[1]);
-  if (writing)
-    close (p2c[0]);
-
-  return scm_from_int (pid);
-}
-#undef FUNC_NAME
-
 static SCM
 scm_spawn_process (SCM prog, SCM args, SCM scm_in, SCM scm_out, SCM scm_err)
 #define FUNC_NAME "spawn*"
@@ -1563,6 +1371,15 @@ scm_dynwind_sigaction (int sig, SCM handler, SCM flags)
                                        SCM_F_WIND_EXPLICITLY);
 }
 
+static SCM
+scm_port_to_fd_with_default (SCM port, int mode)
+{
+  if (!SCM_FPORTP (port))
+    return  scm_from_int (open_or_open64 ("/dev/null", mode));
+  return scm_fileno (port);
+
+}
+
 SCM_DEFINE (scm_system_star, "system*", 0, 0, 1,
            (SCM args),
 "Execute the command indicated by @var{args}.  The first element must\n"
@@ -1589,7 +1406,6 @@ SCM_DEFINE (scm_system_star, "system*", 0, 0, 1,
   if (scm_is_null (args))
     SCM_WRONG_NUM_ARGS ();
   prog = scm_car (args);
-  args = scm_cdr (args);
 
   scm_dynwind_begin (0);
   /* Make sure the child can't kill us (as per normal system call).  */
@@ -1602,7 +1418,13 @@ SCM_DEFINE (scm_system_star, "system*", 0, 0, 1,
                          SCM_UNDEFINED);
 #endif
 
-  pid = scm_piped_process (prog, args, SCM_UNDEFINED, SCM_UNDEFINED);
+  SCM in, out, err;
+
+  in = scm_port_to_fd_with_default (scm_current_input_port (), O_RDONLY);
+  out = scm_port_to_fd_with_default (scm_current_output_port (), O_WRONLY);
+  err = scm_port_to_fd_with_default (scm_current_error_port (), O_WRONLY);
+
+  pid = scm_spawn_process (prog, args, in, out, err);
   SCM_SYSCALL (wait_result = waitpid (scm_to_int (pid), &status, 0));
   if (wait_result == -1)
     SCM_SYSERROR;
@@ -1612,7 +1434,6 @@ SCM_DEFINE (scm_system_star, "system*", 0, 0, 1,
   return scm_from_int (status);
 }
 #undef FUNC_NAME
-#endif /* HAVE_START_CHILD */
 
 #ifdef HAVE_UNAME
 SCM_DEFINE (scm_uname, "uname", 0, 0, 0,
@@ -2446,14 +2267,11 @@ SCM_DEFINE (scm_gethostname, "gethostname", 0, 0, 0,
 #endif /* HAVE_GETHOSTNAME */
 
 \f
-#ifdef HAVE_START_CHILD
 static void
 scm_init_popen (void)
 {
-  scm_c_define_gsubr ("piped-process", 2, 2, 0, scm_piped_process);
   scm_c_define_gsubr ("spawn*", 5, 0, 0, scm_spawn_process);
 }
-#endif /* HAVE_START_CHILD */
 
 void
 scm_init_posix ()
@@ -2566,11 +2384,9 @@ scm_init_posix ()
 #ifdef HAVE_FORK
   scm_add_feature ("fork");
 #endif	/* HAVE_FORK */
-#ifdef HAVE_START_CHILD
   scm_add_feature ("popen");
   scm_c_register_extension ("libguile-" SCM_EFFECTIVE_VERSION,
                             "scm_init_popen",
 			    (scm_t_extension_init_func) scm_init_popen,
 			    NULL);
-#endif /* HAVE_START_CHILD */
 }
diff --git a/module/ice-9/popen.scm b/module/ice-9/popen.scm
index e638726a4..533282f4d 100644
--- a/module/ice-9/popen.scm
+++ b/module/ice-9/popen.scm
@@ -25,12 +25,37 @@
   #:use-module (srfi srfi-1)
   #:use-module (srfi srfi-9)
   #:export (port/pid-table open-pipe* open-pipe close-pipe open-input-pipe
-            open-output-pipe open-input-output-pipe pipeline))
+            open-output-pipe open-input-output-pipe pipeline
+            spawn* spawn))
 
 (eval-when (expand load eval)
   (load-extension (string-append "libguile-" (effective-version))
                   "scm_init_popen"))
 
+(define (port-with-defaults port default-mode)
+  (if (file-port? port)
+      port
+      (open-file "/dev/null" default-mode)))
+
+(define* (spawn exec-file argv #:key
+                             (in (current-input-port))
+                             (out (current-output-port))
+                             (err (current-error-port)))
+  (let* ((in (port-with-defaults in "r"))
+         (out (port-with-defaults out "w"))
+         (err (port-with-defaults err "w"))
+         ;; Increment port revealed counts while to prevent ports GC'ing and
+         ;; closing the associated fds while we spawn the process.
+         (result (spawn* exec-file
+                         argv
+                         (port->fdes in)
+                         (port->fdes out)
+                         (port->fdes err))))
+    (release-port-handle in)
+    (release-port-handle out)
+    (release-port-handle err)
+    result))
+
 (define-record-type <pipe-info>
   (make-pipe-info pid)
   pipe-info?
@@ -92,13 +117,13 @@
 
 (define (open-process mode command . args)
   "Backwards compatible implementation of the former procedure in
-libguile/posix.c (scm_open_process) replaced by
-scm_piped_process. Executes the program @var{command} with optional
-arguments @var{args} (all strings) in a subprocess.  A port to the
-process (based on pipes) is created and returned.  @var{mode} specifies
-whether an input, an output or an input-output port to the process is
-created: it should be the value of @code{OPEN_READ}, @code{OPEN_WRITE}
-or @code{OPEN_BOTH}."
+libguile/posix.c (scm_open_process) replaced by scm_piped_process, now
+replaced by scm_spawn_process. Executes the program @var{command} with
+optional arguments @var{args} (all strings) in a subprocess.  A port to
+the process (based on pipes) is created and returned.  @var{mode}
+specifies whether an input, an output or an input-output port to the
+process is created: it should be the value of @code{OPEN_READ},
+@code{OPEN_WRITE} or @code{OPEN_BOTH}."
   (define (unbuffered port)
     (setvbuf port 'none)
     port)
@@ -107,19 +132,25 @@ or @code{OPEN_BOTH}."
     (and ports
          (cons (port->fdes (car ports)) (port->fdes (cdr ports)))))
 
-  (let* ((from (and (or (string=? mode OPEN_READ)
-                        (string=? mode OPEN_BOTH))
-                    (pipe)))
-         (to (and (or (string=? mode OPEN_WRITE)
-                      (string=? mode OPEN_BOTH))
-                  (pipe)))
-         (pid (piped-process command args
-                             (fdes-pair from)
-                             (fdes-pair to))))
+  (let* ((child-to-parent (and (or (string=? mode OPEN_READ)
+                                   (string=? mode OPEN_BOTH))
+                               (pipe)))
+         (parent-to-child (and (or (string=? mode OPEN_WRITE)
+                                   (string=? mode OPEN_BOTH))
+                               (pipe)))
+         (in (or (and=> parent-to-child car) (current-input-port)))
+         (out (or (and=> child-to-parent cdr) (current-output-port)))
+         (pid (spawn command (cons command args)
+                     #:in in
+                     #:out out)))
+    (when child-to-parent
+      (close (cdr child-to-parent)))
+    (when parent-to-child
+      (close (car parent-to-child)))
     ;; The original 'open-process' procedure would return unbuffered
     ;; ports; do the same here.
-    (values (and from (unbuffered (car from)))
-            (and to (unbuffered (cdr to)))
+    (values (and child-to-parent (unbuffered (car child-to-parent)))
+            (and parent-to-child (unbuffered (cdr parent-to-child)))
             pid)))
 
 (define (open-pipe* mode command . args)
@@ -224,10 +255,16 @@ a list of PIDs of the processes executing the @var{commands}."
 	 (pipeline (fold (lambda (from proc prev)
                            (let* ((to (car prev))
                                   (pids (cdr prev))
-                                  (pid (piped-process (car proc)
-                                                      (cdr proc)
-                                                      from
-                                                      to)))
+                                  (pid (spawn* (car proc)
+                                               proc
+                                               (car to)
+                                               (cdr from)
+                                               (port->fdes
+                                                (port-with-defaults
+                                                 (current-error-port)
+                                                 "w")))))
+                             (close-fdes (car to))
+                             (close-fdes (cdr from))
                              (cons from (cons pid pids))))
                          `(,to)
                          pipes
diff --git a/test-suite/tests/popen.test b/test-suite/tests/popen.test
index 3df863375..fd810e376 100644
--- a/test-suite/tests/popen.test
+++ b/test-suite/tests/popen.test
@@ -257,18 +257,18 @@ exec 2>~a; read REPLY"
     (list (read-string from)
           (status:exit-val (cdr (waitpid pid))))))
 
-(pass-if-equal "piped-process"
+(pass-if-equal "spawn"
     42
   (status:exit-val
-   (cdr (waitpid ((@@ (ice-9 popen) piped-process)
-                  "./meta/guile" '("-c" "(exit 42)"))))))
+   (cdr (waitpid (spawn
+                  "./meta/guile" '("./meta/guile" "-c" "(exit 42)"))))))
 
-(pass-if-equal "piped-process: with output"
+(pass-if-equal "spawn: with output"
     '("foo bar\n" 0)
   (let* ((p (pipe))
-         (pid ((@@ (ice-9 popen) piped-process) "echo" '("foo" "bar")
-               (cons (port->fdes (car p))
-                     (port->fdes (cdr p))))))
+         (pid (spawn "echo" '("echo" "foo" "bar")
+                     #:out (cdr p))))
+    (close (cdr p))
     (list (read-string (car p))
           (status:exit-val (cdr (waitpid pid))))))
 
diff --git a/test-suite/tests/posix.test b/test-suite/tests/posix.test
index 500dbb94a..157f21e24 100644
--- a/test-suite/tests/posix.test
+++ b/test-suite/tests/posix.test
@@ -236,24 +236,24 @@
 
 (with-test-prefix "system*"
 
-  (pass-if "http://bugs.gnu.org/13166"
-    ;; With Guile up to 2.0.7 included, the child process launched by
-    ;; `system*' would remain alive after an `execvp' failure.
-    (let ((me (getpid)))
-      (and (not (zero? (system* "something-that-does-not-exist")))
-           (= me (getpid)))))
-
-  (pass-if-equal "exit code for nonexistent file"
-      127                                         ;aka. EX_NOTFOUND
-    (status:exit-val (system* "something-that-does-not-exist")))
-
-  (pass-if-equal "https://bugs.gnu.org/55596"
-      127
-    ;; The parameterization below used to cause 'start_child' to close
-    ;; fd 2 in the child process, which in turn would cause it to
-    ;; segfault, leading to a wrong exit code.
-    (parameterize ((current-output-port (current-error-port)))
-      (status:exit-val (system* "something-that-does-not-exist")))))
+  (pass-if-equal "exception for nonexistent file"
+      2 ; ENOENT
+      (call-with-prompt 'escape
+        (lambda ()
+          (with-exception-handler
+              (lambda (exn)
+                (let* ((kind (exception-kind exn))
+                       (errno (and (eq? kind 'system-error)
+                                   (car (car
+                                         (cdr (cdr (cdr (exception-args
+                                                        exn)))))))))
+                  (abort-to-prompt 'escape errno)))
+            (lambda ()
+              (status:exit-val (system*
+                                "something-that-does-not-exist")))
+            #:unwind? #t))
+        (lambda (k arg)
+          arg))))
 
 ;;
 ;; crypt
-- 
2.37.2






^ permalink raw reply related	[flat|nested] 36+ messages in thread

* bug#52835: [PATCH 0/2] Fix spawning a child not setting standard fds properly
  2022-09-05  6:48           ` bug#52835: [PATCH v5 3/3] Move popen and posix procedures to spawn* Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
@ 2022-11-29 15:05             ` Ludovic Courtès
  2022-12-11 20:16               ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  0 siblings, 1 reply; 36+ messages in thread
From: Ludovic Courtès @ 2022-11-29 15:05 UTC (permalink / raw)
  To: Josselin Poiret; +Cc: 52835, Timothy Sample

Hi Josselin,

Sorry for taking so long to come back to you.  I think this is great
work!  I pushed it as ‘wip-posix-spawn’ so others can give it a try.

Josselin Poiret <dev@jpoiret.xyz> skribis:

> * libguile/posix.c (renumber_file_descriptor, start_child,
> scm_piped_process): Remove functions.
> (scm_port_to_fd_with_default): New helper function.
> (scm_system_star): Rewrite using scm_spawn_process.
> (scm_init_popen): Remove the definition of piped-process.
> (scm_init_posix): Now make popen available unconditionally.
>
> * module/ice-9/popen.scm (port-with-defaults): New helper procedure.
> (spawn): New procedure.
> (open-process): Rewrite using spawn.
> (pipeline): Rewrite using spawn*.
>
> * test-suite/tests/popen.test ("piped-process", "piped-process:
> with-output"): Removed tests.
> ("spawn", "spawn: with output"): Added tests.
> * test-suite/tests/posix.test ("http://bugs.gnu.org/13166", "exit code
> for nonexistent file", "https://bugs.gnu.org/55596"): Remove obsolete
> tests.
> ("exception for nonexistent file"): Add test.
> ---
>  libguile/posix.c            | 218 +++---------------------------------
>  module/ice-9/popen.scm      |  83 ++++++++++----
>  test-suite/tests/popen.test |  14 +--
>  test-suite/tests/posix.test |  36 +++---
>  4 files changed, 102 insertions(+), 249 deletions(-)

More deletions than insertions. 👍

That scary-looking Gnulib update seems to have worked well.

I have mostly cosmetic/polishing comments and one issue with ‘system*’.
I can actually do that on your behalf if you’re unavailable these days;
let me know what you prefer.

>  static SCM
>  scm_spawn_process (SCM prog, SCM args, SCM scm_in, SCM scm_out, SCM scm_err)
>  #define FUNC_NAME "spawn*"

For top-level functions, please add a comment above explaining what it
does.

I would call this one ‘primitive-spawn’ rather than ‘spawn*’ and keep it
private to (ice-9 popen).

> +(define* (spawn exec-file argv #:key
> +                             (in (current-input-port))
> +                             (out (current-output-port))
> +                             (err (current-error-port)))

Please add a docstring.  It may also be worth documenting it in the
manual given that it’s public.

> +  (let* ((in (port-with-defaults in "r"))
> +         (out (port-with-defaults out "w"))
> +         (err (port-with-defaults err "w"))

I’d make it “r0” and “w0” since we’re doing to throw the ports away
right after.

We could even avoid allocating a port when we’re going to use /dev/null
(and thus go with ‘open-fdes’ directly), but that’s a micro-optimization
we can keep for later.

> +++ b/test-suite/tests/posix.test
> @@ -236,24 +236,24 @@
>  
>  (with-test-prefix "system*"
>  
> -  (pass-if "http://bugs.gnu.org/13166"
> -    ;; With Guile up to 2.0.7 included, the child process launched by
> -    ;; `system*' would remain alive after an `execvp' failure.
> -    (let ((me (getpid)))
> -      (and (not (zero? (system* "something-that-does-not-exist")))
> -           (= me (getpid)))))

I’d keep this one, I guess it doesn’t hurt?

> -  (pass-if-equal "exit code for nonexistent file"
> -      127                                         ;aka. EX_NOTFOUND
> -    (status:exit-val (system* "something-that-does-not-exist")))

It’s good that we have better error reporting thanks to ‘posix_spawn’.

However, I don’t think we can change that in 3.0.  What about, for 3.0,
adding a layer around ‘spawn’ so that ‘system*’ still returns 127 when
‘spawn’ throws to ‘system-error’?

> -  (pass-if-equal "https://bugs.gnu.org/55596"
> -      127
> -    ;; The parameterization below used to cause 'start_child' to close
> -    ;; fd 2 in the child process, which in turn would cause it to
> -    ;; segfault, leading to a wrong exit code.
> -    (parameterize ((current-output-port (current-error-port)))
> -      (status:exit-val (system* "something-that-does-not-exist")))))

Likewise we should keep this one.

> +  (pass-if-equal "exception for nonexistent file"
> +      2 ; ENOENT
> +      (call-with-prompt 'escape
> +        (lambda ()
> +          (with-exception-handler
> +              (lambda (exn)
> +                (let* ((kind (exception-kind exn))
> +                       (errno (and (eq? kind 'system-error)
> +                                   (car (car
> +                                         (cdr (cdr (cdr (exception-args
> +                                                        exn)))))))))
> +                  (abort-to-prompt 'escape errno)))
> +            (lambda ()
> +              (status:exit-val (system*
> +                                "something-that-does-not-exist")))
> +            #:unwind? #t))
> +        (lambda (k arg)
> +          arg))))

We’ll have to leave this change for the next major series of Guile.

Thanks!

Ludo’.





^ permalink raw reply	[flat|nested] 36+ messages in thread

* bug#52835: [PATCH 0/2] Fix spawning a child not setting standard fds properly
  2022-11-29 15:05             ` bug#52835: [PATCH 0/2] Fix spawning a child not setting standard fds properly Ludovic Courtès
@ 2022-12-11 20:16               ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2022-12-12 23:49                 ` Ludovic Courtès
  0 siblings, 1 reply; 36+ messages in thread
From: Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language @ 2022-12-11 20:16 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: 52835, Timothy Sample

Hi Ludo, 

Ludovic Courtès <ludo@gnu.org> writes:

> For top-level functions, please add a comment above explaining what it
> does.

Completely forgot about that.  I will do it at some point, however we
will need to settle on how to resolve the issue at the bottom first.

> I would call this one ‘primitive-spawn’ rather than ‘spawn*’ and keep it
> private to (ice-9 popen).

Is there any reason we would want this to not be accessible to the user?
There are already a bunch of functions that manipulate raw fdes, and
people might want to directly use this to not have to care about ports.

> Please add a docstring.  It may also be worth documenting it in the
> manual given that it’s public.
>
>> +  (let* ((in (port-with-defaults in "r"))
>> +         (out (port-with-defaults out "w"))
>> +         (err (port-with-defaults err "w"))
>
> I’d make it “r0” and “w0” since we’re doing to throw the ports away
> right after.

Sure.

> We could even avoid allocating a port when we’re going to use /dev/null
> (and thus go with ‘open-fdes’ directly), but that’s a micro-optimization
> we can keep for later.

Right.  I chose to keep the code simple for now, it's too much trouble
having to choose between using ports and fdes.  Note that I did a small
benchmark and system* with PATCH v5 is 3x faster than on 3.0.8.  vfork
is working wonders.

>> +++ b/test-suite/tests/posix.test
>> @@ -236,24 +236,24 @@
>>  
>>  (with-test-prefix "system*"
>>  
>> -  (pass-if "http://bugs.gnu.org/13166"
>> -    ;; With Guile up to 2.0.7 included, the child process launched by
>> -    ;; `system*' would remain alive after an `execvp' failure.
>> -    (let ((me (getpid)))
>> -      (and (not (zero? (system* "something-that-does-not-exist")))
>> -           (= me (getpid)))))
>
> I’d keep this one, I guess it doesn’t hurt?

As is, it doesn't work since system* would throw a system exception
because spawn is able to catch that error.  Previously, the child would
fail its execvp and die with exit code 127, which system* would return.

>> -  (pass-if-equal "exit code for nonexistent file"
>> -      127                                         ;aka. EX_NOTFOUND
>> -    (status:exit-val (system* "something-that-does-not-exist")))
>
> It’s good that we have better error reporting thanks to ‘posix_spawn’.
>
> However, I don’t think we can change that in 3.0.  What about, for 3.0,
> adding a layer around ‘spawn’ so that ‘system*’ still returns 127 when
> ‘spawn’ throws to ‘system-error’?

So I've been working on something that would do this, but I noticed that
we have no way to be strictly backwards-compatible: if there's an error
like ENOFILE, we can't get a pid from posix_spawn, and so piped-process
won't have anything to return, whereas before it would return the pid of
the failing child.  I'm not sure there's a way to emulate that, unless
we just fork a child that instantly returns 127.  Doesn't seem great
though.

WDYT?
-- 
Josselin Poiret





^ permalink raw reply	[flat|nested] 36+ messages in thread

* bug#52835: [PATCH 0/2] Fix spawning a child not setting standard fds properly
  2022-12-11 20:16               ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
@ 2022-12-12 23:49                 ` Ludovic Courtès
  2022-12-22 12:49                   ` bug#52835: [PATCH v6 0/3] Move spawning procedures to posix_spawn Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  0 siblings, 1 reply; 36+ messages in thread
From: Ludovic Courtès @ 2022-12-12 23:49 UTC (permalink / raw)
  To: Josselin Poiret; +Cc: 52835, Timothy Sample

Hello,

Josselin Poiret <dev@jpoiret.xyz> skribis:

>> I would call this one ‘primitive-spawn’ rather than ‘spawn*’ and keep it
>> private to (ice-9 popen).
>
> Is there any reason we would want this to not be accessible to the user?
> There are already a bunch of functions that manipulate raw fdes, and
> people might want to directly use this to not have to care about ports.

Yeah, on second thought I think you’re right: it be can be useful to
have it exposed to users.

In fact, I think we should provide interfaces that make ‘primitive-fork’
unnecessary for most use cases.  Exposing that procedure is a step in
that direction.

>> We could even avoid allocating a port when we’re going to use /dev/null
>> (and thus go with ‘open-fdes’ directly), but that’s a micro-optimization
>> we can keep for later.
>
> Right.  I chose to keep the code simple for now, it's too much trouble
> having to choose between using ports and fdes.  Note that I did a small
> benchmark and system* with PATCH v5 is 3x faster than on 3.0.8.  vfork
> is working wonders.

Nice!

>>> +++ b/test-suite/tests/posix.test
>>> @@ -236,24 +236,24 @@
>>>  
>>>  (with-test-prefix "system*"
>>>  
>>> -  (pass-if "http://bugs.gnu.org/13166"
>>> -    ;; With Guile up to 2.0.7 included, the child process launched by
>>> -    ;; `system*' would remain alive after an `execvp' failure.
>>> -    (let ((me (getpid)))
>>> -      (and (not (zero? (system* "something-that-does-not-exist")))
>>> -           (= me (getpid)))))
>>
>> I’d keep this one, I guess it doesn’t hurt?
>
> As is, it doesn't work since system* would throw a system exception
> because spawn is able to catch that error.  Previously, the child would
> fail its execvp and die with exit code 127, which system* would return.
>
>>> -  (pass-if-equal "exit code for nonexistent file"
>>> -      127                                         ;aka. EX_NOTFOUND
>>> -    (status:exit-val (system* "something-that-does-not-exist")))
>>
>> It’s good that we have better error reporting thanks to ‘posix_spawn’.
>>
>> However, I don’t think we can change that in 3.0.  What about, for 3.0,
>> adding a layer around ‘spawn’ so that ‘system*’ still returns 127 when
>> ‘spawn’ throws to ‘system-error’?
>
> So I've been working on something that would do this, but I noticed that
> we have no way to be strictly backwards-compatible: if there's an error
> like ENOFILE, we can't get a pid from posix_spawn, and so piped-process
> won't have anything to return, whereas before it would return the pid of
> the failing child.  I'm not sure there's a way to emulate that, unless
> we just fork a child that instantly returns 127.  Doesn't seem great
> though.

Right now ‘system*’ does:

  pid = scm_spawn_process (prog, args, in, out, err);
  SCM_SYSCALL (wait_result = waitpid (scm_to_int (pid), &status, 0));
  if (wait_result == -1)
    SCM_SYSERROR;

How about introducing decomposing ‘scm_spawn_process’ so that we have a
lower-level function we could use (‘spawn_process’ below), roughly like
so:

  ret = spawn_process (proc, args, in, out, err, &pid);
  if (ret != 0)
    {
      if (ret == ENOMEM)
        {
          errno = ENOMEM;
          SCM_SYSERROR;
        }
      else
        /* Emulate old-style failure.  TODO: In 3.2, turn that into an
           exception */
        status = 127 << 8;
    }
  else
    SCM_SYSCALL (wait_result = waitpid (scm_to_int (pid), &status, 0));

Does that make sense?

It’s a bit of work to emulate that suboptimal behavior, but I think it’s
important not to change that in 3.0.

Thanks for your feedback!

Ludo’.





^ permalink raw reply	[flat|nested] 36+ messages in thread

* bug#52835: [PATCH v6 0/3] Move spawning procedures to posix_spawn.
  2022-12-12 23:49                 ` Ludovic Courtès
@ 2022-12-22 12:49                   ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2022-12-22 12:49                     ` bug#52835: [PATCH v6 1/3] Add spawn* Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
                                       ` (3 more replies)
  0 siblings, 4 replies; 36+ messages in thread
From: Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language @ 2022-12-22 12:49 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: 52835, Timothy Sample, Josselin Poiret

Hello Ludo,

Here is hopefully the last reroll of this patchset.  First of all, I did not
include the gnulib patch again because it still applies cleanly and it is
extremely large, but it should be applied before those 3 patches.

The first two patches should be applied on the current major release, while the
third one should be applied on the next major release to finish the migration to
spawn.

The first patch adds the new spawn* procedure, using an internal do_spawn
function.  The second patch changes system* and piped-process to use this new
function, but it still tries to mimick the old behavior of start_child by
inspecting the possible errnos, and spawning a dummy child that instantly exits
with code 127 in some cases.

The third patch gets rid of those special cases, which makes system* and friends
throw more exceptions instead of having the child fail with exit code 127 (note
that YMMV depending on how spawn is implemented for your system).

I've added docstrings to user-facing Guile procedures, and also did the
micro-optimization we talked about, since I had already factorized do_spawn.

The tests seem to pass both with and without 3.

One nice thing I've noticed is that gnulib has posix_spawn for WinNT as well,
which means it might be okay to remove the dependency on having fork for
system*, among others!

WDYT?

Josselin Poiret (3):
  Add spawn*.
  Make system* and piped-process internally use spawn.
  Move popen and posix procedures to spawn*.

 libguile/posix.c            | 248 +++++++++++-------------------------
 libguile/posix.h            |   2 +
 module/ice-9/popen.scm      |  87 +++++++++----
 test-suite/tests/popen.test |  14 +-
 test-suite/tests/posix.test |  36 +++---
 5 files changed, 161 insertions(+), 226 deletions(-)


base-commit: f3ea8f7fa1d84a559c7bf834fe5b675abe0ae7b8
prerequisite-patch-id: 71184f71260952109165ec62c588c2b646e238f6
-- 
2.38.1






^ permalink raw reply	[flat|nested] 36+ messages in thread

* bug#52835: [PATCH v6 1/3] Add spawn*.
  2022-12-22 12:49                   ` bug#52835: [PATCH v6 0/3] Move spawning procedures to posix_spawn Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
@ 2022-12-22 12:49                     ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2022-12-22 12:49                     ` bug#52835: [PATCH v6 2/3] Make system* and piped-process internally use spawn Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
                                       ` (2 subsequent siblings)
  3 siblings, 0 replies; 36+ messages in thread
From: Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language @ 2022-12-22 12:49 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: 52835, Timothy Sample, Josselin Poiret

* libguile/posix.c: Include spawn.h from Gnulib.
(do_spawn, scm_spawn_process): New functions.
---
 libguile/posix.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++
 libguile/posix.h |  2 ++
 2 files changed, 83 insertions(+)

diff --git a/libguile/posix.c b/libguile/posix.c
index b5352c2c4..e92625483 100644
--- a/libguile/posix.c
+++ b/libguile/posix.c
@@ -33,6 +33,7 @@
 #include <sys/types.h>
 #include <uniconv.h>
 #include <unistd.h>
+#include <spawn.h>
 
 #ifdef HAVE_SCHED_H
 # include <sched.h>
@@ -1426,6 +1427,86 @@ start_child (const char *exec_file, char **exec_argv,
 }
 #endif
 
+static int
+do_spawn (char *exec_file, char **exec_argv, char **exec_env, int in, int out, int err)
+{
+  int pid = -1;
+
+  posix_spawn_file_actions_t actions;
+  posix_spawnattr_t *attrp = NULL;
+
+  int max_fd = 1024;
+
+#if defined (HAVE_GETRLIMIT) && defined (RLIMIT_NOFILE)
+  {
+    struct rlimit lim = { 0, 0 };
+    if (getrlimit (RLIMIT_NOFILE, &lim) == 0)
+      max_fd = lim.rlim_cur;
+  }
+#endif
+
+  posix_spawn_file_actions_init (&actions);
+
+  int free_fd_slots = 0;
+  int fd_slot[3];
+
+  for (int fdnum = 3;free_fd_slots < 3 && fdnum < max_fd;fdnum++)
+    {
+      if (fdnum != in && fdnum != out && fdnum != err)
+        {
+          fd_slot[free_fd_slots] = fdnum;
+          free_fd_slots++;
+        }
+    }
+
+  /* Move the fds out of the way, so that duplicate fds or fds equal
+     to 0, 1, 2 don't trample each other */
+
+  posix_spawn_file_actions_adddup2 (&actions, in, fd_slot[0]);
+  posix_spawn_file_actions_adddup2 (&actions, out, fd_slot[1]);
+  posix_spawn_file_actions_adddup2 (&actions, err, fd_slot[2]);
+  posix_spawn_file_actions_adddup2 (&actions, fd_slot[0], 0);
+  posix_spawn_file_actions_adddup2 (&actions, fd_slot[1], 1);
+  posix_spawn_file_actions_adddup2 (&actions, fd_slot[2], 2);
+
+  while (--max_fd > 2)
+    posix_spawn_file_actions_addclose (&actions, max_fd);
+
+  if (posix_spawnp (&pid, exec_file, &actions, attrp, exec_argv, environ) != 0)
+      return -1;
+
+  return pid;
+}
+
+SCM_DEFINE (scm_spawn_process, "spawn*", 5, 0, 0,
+           (SCM prog, SCM args, SCM in, SCM out, SCM err),
+"Spawns a new child process executing @var{prog} with arguments\n"
+"@var{args}, with its standard input, output and error file descriptors\n"
+"set to @var{in}, @var{out}, @var{err}.")
+#define FUNC_NAME s_scm_spawn_process
+{
+  int pid;
+  char *exec_file;
+  char **exec_argv;
+  char **exec_env = environ;
+
+  exec_file = scm_to_locale_string (prog);
+  exec_argv = scm_i_allocate_string_pointers (args);
+
+  pid = do_spawn (exec_file, exec_argv, exec_env,
+                  scm_to_int (in),
+                  scm_to_int (out),
+                  scm_to_int (err));
+
+  free (exec_file);
+
+  if (pid == -1)
+      SCM_SYSERROR;
+
+  return scm_from_int (pid);
+}
+#undef FUNC_NAME
+
 #ifdef HAVE_START_CHILD
 static SCM
 scm_piped_process (SCM prog, SCM args, SCM from, SCM to)
diff --git a/libguile/posix.h b/libguile/posix.h
index 6504eaea8..c2703f9ab 100644
--- a/libguile/posix.h
+++ b/libguile/posix.h
@@ -69,6 +69,8 @@ SCM_API SCM scm_tmpnam (void);
 SCM_API SCM scm_tmpfile (void);
 SCM_API SCM scm_open_pipe (SCM pipestr, SCM modes);
 SCM_API SCM scm_close_pipe (SCM port);
+SCM_API SCM scm_spawn_process (SCM prog, SCM args,
+                               SCM in, SCM out, SCM err);
 SCM_API SCM scm_system_star (SCM cmds);
 SCM_API SCM scm_utime (SCM object, SCM actime, SCM modtime,
                        SCM actimens, SCM modtimens, SCM flags);
-- 
2.38.1






^ permalink raw reply related	[flat|nested] 36+ messages in thread

* bug#52835: [PATCH v6 2/3] Make system* and piped-process internally use spawn.
  2022-12-22 12:49                   ` bug#52835: [PATCH v6 0/3] Move spawning procedures to posix_spawn Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2022-12-22 12:49                     ` bug#52835: [PATCH v6 1/3] Add spawn* Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
@ 2022-12-22 12:49                     ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2022-12-22 12:49                     ` bug#52835: [PATCH v6 3/3] Move popen and posix procedures to spawn* Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2022-12-23 10:53                     ` bug#52835: [PATCH 0/2] Fix spawning a child not setting standard fds properly Ludovic Courtès
  3 siblings, 0 replies; 36+ messages in thread
From: Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language @ 2022-12-22 12:49 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: 52835, Timothy Sample, Josselin Poiret

* libguile/posix.c (scm_system_star, scm_piped_process): Use do_spawn.
(start_child): Remove function.
---
 libguile/posix.c | 181 ++++++++++-------------------------------------
 1 file changed, 39 insertions(+), 142 deletions(-)

diff --git a/libguile/posix.c b/libguile/posix.c
index e92625483..f9c36d7ac 100644
--- a/libguile/posix.c
+++ b/libguile/posix.c
@@ -1308,125 +1308,6 @@ SCM_DEFINE (scm_fork, "primitive-fork", 0, 0, 0,
 #undef FUNC_NAME
 #endif /* HAVE_FORK */
 
-#ifdef HAVE_FORK
-/* 'renumber_file_descriptor' is a helper function for 'start_child'
-   below, and is specialized for that particular environment where it
-   doesn't make sense to report errors via exceptions.  It uses dup(2)
-   to duplicate the file descriptor FD, closes the original FD, and
-   returns the new descriptor.  If dup(2) fails, print an error message
-   to ERR and abort.  */
-static int
-renumber_file_descriptor (int fd, int err)
-{
-  int new_fd;
-
-  do
-    new_fd = dup (fd);
-  while (new_fd == -1 && errno == EINTR);
-
-  if (new_fd == -1)
-    {
-      /* At this point we are in the child process before exec.  We
-         cannot safely raise an exception in this environment.  */
-      const char *msg = strerror (errno);
-      fprintf (fdopen (err, "a"), "start_child: dup failed: %s\n", msg);
-      _exit (127);  /* Use exit status 127, as with other exec errors. */
-    }
-
-  close (fd);
-  return new_fd;
-}
-#endif /* HAVE_FORK */
-
-#ifdef HAVE_FORK
-#define HAVE_START_CHILD 1
-/* Since Guile uses threads, we have to be very careful to avoid calling
-   functions that are not async-signal-safe in the child.  That's why
-   this function is implemented in C.  */
-static pid_t
-start_child (const char *exec_file, char **exec_argv,
-	     int reading, int c2p[2], int writing, int p2c[2],
-             int in, int out, int err)
-{
-  int pid;
-  int max_fd = 1024;
-
-#if defined (HAVE_GETRLIMIT) && defined (RLIMIT_NOFILE)
-  {
-    struct rlimit lim = { 0, 0 };
-    if (getrlimit (RLIMIT_NOFILE, &lim) == 0)
-      max_fd = lim.rlim_cur;
-  }
-#endif
-
-  pid = fork ();
-
-  if (pid != 0)
-    /* The parent, with either and error (pid == -1), or the PID of the
-       child.  Return directly in either case.  */
-    return pid;
-
-  /* The child.  */
-  if (reading)
-    close (c2p[0]);
-  if (writing)
-    close (p2c[1]);
-
-  /* Close all file descriptors in ports inherited from the parent
-     except for in, out, and err.  Heavy-handed, but robust.  */
-  while (max_fd--)
-    if (max_fd != in && max_fd != out && max_fd != err)
-      close (max_fd);
-
-  /* Ignore errors on these open() calls.  */
-  if (in == -1)
-    in = open ("/dev/null", O_RDONLY);
-  if (out == -1)
-    out = open ("/dev/null", O_WRONLY);
-  if (err == -1)
-    err = open ("/dev/null", O_WRONLY);
-
-  if (in > 0)
-    {
-      if (out == 0)
-        out = renumber_file_descriptor (out, err);
-      if (err == 0)
-        err = renumber_file_descriptor (err, err);
-      do dup2 (in, 0); while (errno == EINTR);
-      close (in);
-    }
-  if (out > 1)
-    {
-      if (err == 1)
-        err = renumber_file_descriptor (err, err);
-      do dup2 (out, 1); while (errno == EINTR);
-      if (out > 2)
-        close (out);
-    }
-  if (err > 2)
-    {
-      do dup2 (err, 2); while (errno == EINTR);
-      close (err);
-    }
-
-  execvp (exec_file, exec_argv);
-
-  /* The exec failed!  There is nothing sensible to do.  */
-  {
-    const char *msg = strerror (errno);
-    fprintf (fdopen (2, "a"), "In execvp of %s: %s\n",
-             exec_file, msg);
-  }
-
-  /* Use exit status 127, like shells in this case, as per POSIX
-     <http://pubs.opengroup.org/onlinepubs/007904875/utilities/xcu_chap02.html#tag_02_09_01_01>.  */
-  _exit (127);
-
-  /* Not reached.  */
-  return -1;
-}
-#endif
-
 static int
 do_spawn (char *exec_file, char **exec_argv, char **exec_env, int in, int out, int err)
 {
@@ -1507,7 +1388,7 @@ SCM_DEFINE (scm_spawn_process, "spawn*", 5, 0, 0,
 }
 #undef FUNC_NAME
 
-#ifdef HAVE_START_CHILD
+#ifdef HAVE_FORK
 static SCM
 scm_piped_process (SCM prog, SCM args, SCM from, SCM to)
 #define FUNC_NAME "piped-process"
@@ -1519,6 +1400,7 @@ scm_piped_process (SCM prog, SCM args, SCM from, SCM to)
   int pid;
   char *exec_file;
   char **exec_argv;
+  char **exec_env = environ;
 
   exec_file = scm_to_locale_string (prog);
   exec_argv = scm_i_allocate_string_pointers (scm_cons (prog, args));
@@ -1551,27 +1433,44 @@ scm_piped_process (SCM prog, SCM args, SCM from, SCM to)
       in = SCM_FPORT_FDES (port);
   }
 
-  pid = start_child (exec_file, exec_argv, reading, c2p, writing, p2c,
-                     in, out, err);
+  pid = do_spawn (exec_file, exec_argv, exec_env, in, out, err);
+  int errno_save = errno;
 
   if (pid == -1)
     {
-      int errno_save = errno;
-      free (exec_file);
-      if (reading)
-        {
-          close (c2p[0]);
-          close (c2p[1]);
-        }
-      if (writing)
-        {
-          close (p2c[0]);
-          close (p2c[1]);
-        }
-      errno = errno_save;
-      SCM_SYSERROR;
+      /* TODO This is a compatibility shim until the next major release */
+      switch (errno) {
+      /* If the error seemingly comes from fork */
+      case EAGAIN:
+      case ENOMEM:
+      case ENOSYS:
+        free (exec_file);
+
+        if (reading)
+          {
+            close (c2p[0]);
+          }
+        if (writing)
+          {
+            close (p2c[1]);
+          }
+        errno = errno_save;
+        SCM_SYSERROR;
+        break;
+      /* Else create a dummy process that exits with value 127 */
+      default:
+        dprintf (err, "In execvp of %s: %s\n", exec_file,
+                 strerror (errno_save));
+        pid = fork ();
+        if (pid == -1)
+          SCM_SYSERROR;
+        if (pid == 0)
+          _exit (127);
+      }
     }
 
+  free (exec_file);
+
   if (reading)
     close (c2p[1]);
   if (writing)
@@ -1651,7 +1550,7 @@ SCM_DEFINE (scm_system_star, "system*", 0, 0, 1,
   return scm_from_int (status);
 }
 #undef FUNC_NAME
-#endif /* HAVE_START_CHILD */
+#endif /* HAVE_FORK */
 
 #ifdef HAVE_UNAME
 SCM_DEFINE (scm_uname, "uname", 0, 0, 0,
@@ -2497,13 +2396,13 @@ SCM_DEFINE (scm_gethostname, "gethostname", 0, 0, 0,
 #endif /* HAVE_GETHOSTNAME */
 
 \f
-#ifdef HAVE_START_CHILD
+#ifdef HAVE_FORK
 static void
 scm_init_popen (void)
 {
   scm_c_define_gsubr ("piped-process", 2, 2, 0, scm_piped_process);
 }
-#endif /* HAVE_START_CHILD */
+#endif /* HAVE_FORK */
 
 void
 scm_init_posix ()
@@ -2621,12 +2520,10 @@ scm_init_posix ()
 
 #ifdef HAVE_FORK
   scm_add_feature ("fork");
-#endif	/* HAVE_FORK */
-#ifdef HAVE_START_CHILD
   scm_add_feature ("popen");
   scm_c_register_extension ("libguile-" SCM_EFFECTIVE_VERSION,
                             "scm_init_popen",
 			    (scm_t_extension_init_func) scm_init_popen,
 			    NULL);
-#endif /* HAVE_START_CHILD */
+#endif	/* HAVE_FORK */
 }
-- 
2.38.1






^ permalink raw reply related	[flat|nested] 36+ messages in thread

* bug#52835: [PATCH v6 3/3] Move popen and posix procedures to spawn*.
  2022-12-22 12:49                   ` bug#52835: [PATCH v6 0/3] Move spawning procedures to posix_spawn Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2022-12-22 12:49                     ` bug#52835: [PATCH v6 1/3] Add spawn* Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2022-12-22 12:49                     ` bug#52835: [PATCH v6 2/3] Make system* and piped-process internally use spawn Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
@ 2022-12-22 12:49                     ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2022-12-23 10:53                     ` bug#52835: [PATCH 0/2] Fix spawning a child not setting standard fds properly Ludovic Courtès
  3 siblings, 0 replies; 36+ messages in thread
From: Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language @ 2022-12-22 12:49 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: 52835, Timothy Sample, Josselin Poiret

* libguile/posix.c (scm_piped_process, scm_init_popen): Remove
functions.
(scm_port_to_fd_with_default): New helper function.
(scm_system_star): Rewrite using scm_spawn_process.
(scm_init_popen): Remove the definition of piped-process.
(scm_init_posix): Now make popen available unconditionally.

* module/ice-9/popen.scm (port-with-defaults): New helper procedure.
(spawn): New procedure.
(open-process): Rewrite using spawn.
(pipeline): Rewrite using spawn*.

* test-suite/tests/popen.test ("piped-process", "piped-process:
with-output"): Removed tests.
("spawn", "spawn: with output"): Added tests.
* test-suite/tests/posix.test ("http://bugs.gnu.org/13166", "exit code
for nonexistent file", "https://bugs.gnu.org/55596"): Remove obsolete
tests.
("exception for nonexistent file"): Add test.
---
 libguile/posix.c            | 144 ++++++++----------------------------
 module/ice-9/popen.scm      |  87 +++++++++++++++-------
 test-suite/tests/popen.test |  14 ++--
 test-suite/tests/posix.test |  36 ++++-----
 4 files changed, 118 insertions(+), 163 deletions(-)

diff --git a/libguile/posix.c b/libguile/posix.c
index f9c36d7ac..1401a9118 100644
--- a/libguile/posix.c
+++ b/libguile/posix.c
@@ -64,6 +64,7 @@
 #include "fports.h"
 #include "gettext.h"
 #include "gsubr.h"
+#include "ioext.h"
 #include "list.h"
 #include "modules.h"
 #include "numbers.h"
@@ -1388,98 +1389,6 @@ SCM_DEFINE (scm_spawn_process, "spawn*", 5, 0, 0,
 }
 #undef FUNC_NAME
 
-#ifdef HAVE_FORK
-static SCM
-scm_piped_process (SCM prog, SCM args, SCM from, SCM to)
-#define FUNC_NAME "piped-process"
-{
-  int reading, writing;
-  int c2p[2]; /* Child to parent.  */
-  int p2c[2]; /* Parent to child.  */
-  int in = -1, out = -1, err = -1;
-  int pid;
-  char *exec_file;
-  char **exec_argv;
-  char **exec_env = environ;
-
-  exec_file = scm_to_locale_string (prog);
-  exec_argv = scm_i_allocate_string_pointers (scm_cons (prog, args));
-
-  reading = scm_is_pair (from);
-  writing = scm_is_pair (to);
-
-  if (reading)
-    {
-      c2p[0] = scm_to_int (scm_car (from));
-      c2p[1] = scm_to_int (scm_cdr (from));
-      out = c2p[1];
-    }
-
-  if (writing)
-    {
-      p2c[0] = scm_to_int (scm_car (to));
-      p2c[1] = scm_to_int (scm_cdr (to));
-      in = p2c[0];
-    }
-
-  {
-    SCM port;
-
-    if (SCM_OPOUTFPORTP ((port = scm_current_error_port ())))
-      err = SCM_FPORT_FDES (port);
-    if (out == -1 && SCM_OPOUTFPORTP ((port = scm_current_output_port ())))
-      out = SCM_FPORT_FDES (port);
-    if (in == -1 && SCM_OPINFPORTP ((port = scm_current_input_port ())))
-      in = SCM_FPORT_FDES (port);
-  }
-
-  pid = do_spawn (exec_file, exec_argv, exec_env, in, out, err);
-  int errno_save = errno;
-
-  if (pid == -1)
-    {
-      /* TODO This is a compatibility shim until the next major release */
-      switch (errno) {
-      /* If the error seemingly comes from fork */
-      case EAGAIN:
-      case ENOMEM:
-      case ENOSYS:
-        free (exec_file);
-
-        if (reading)
-          {
-            close (c2p[0]);
-          }
-        if (writing)
-          {
-            close (p2c[1]);
-          }
-        errno = errno_save;
-        SCM_SYSERROR;
-        break;
-      /* Else create a dummy process that exits with value 127 */
-      default:
-        dprintf (err, "In execvp of %s: %s\n", exec_file,
-                 strerror (errno_save));
-        pid = fork ();
-        if (pid == -1)
-          SCM_SYSERROR;
-        if (pid == 0)
-          _exit (127);
-      }
-    }
-
-  free (exec_file);
-
-  if (reading)
-    close (c2p[1]);
-  if (writing)
-    close (p2c[0]);
-
-  return scm_from_int (pid);
-}
-#undef FUNC_NAME
-
 static void
 restore_sigaction (SCM pair)
 {
@@ -1501,6 +1410,15 @@ scm_dynwind_sigaction (int sig, SCM handler, SCM flags)
                                        SCM_F_WIND_EXPLICITLY);
 }
 
+static int
+port_to_fd_with_default (SCM port, int mode)
+{
+  if (!SCM_FPORTP (port))
+    return  open_or_open64 ("/dev/null", mode);
+  return SCM_FPORT_FDES (port);
+
+}
+
 SCM_DEFINE (scm_system_star, "system*", 0, 0, 1,
            (SCM args),
 "Execute the command indicated by @var{args}.  The first element must\n"
@@ -1521,13 +1439,14 @@ SCM_DEFINE (scm_system_star, "system*", 0, 0, 1,
 "Example: (system* \"echo\" \"foo\" \"bar\")")
 #define FUNC_NAME s_scm_system_star
 {
-  SCM prog, pid;
-  int status, wait_result;
+  int pid, status, wait_result;
+
+  int in, out, err;
+  char *exec_file;
+  char **exec_argv;
 
   if (scm_is_null (args))
     SCM_WRONG_NUM_ARGS ();
-  prog = scm_car (args);
-  args = scm_cdr (args);
 
   scm_dynwind_begin (0);
   /* Make sure the child can't kill us (as per normal system call).  */
@@ -1540,8 +1459,23 @@ SCM_DEFINE (scm_system_star, "system*", 0, 0, 1,
                          SCM_UNDEFINED);
 #endif
 
-  pid = scm_piped_process (prog, args, SCM_UNDEFINED, SCM_UNDEFINED);
-  SCM_SYSCALL (wait_result = waitpid (scm_to_int (pid), &status, 0));
+  exec_file = scm_to_locale_string (scm_car (args));
+  exec_argv = scm_i_allocate_string_pointers (args);
+
+  in = port_to_fd_with_default (scm_current_input_port (), O_RDONLY);
+  out = port_to_fd_with_default (scm_current_output_port (), O_WRONLY);
+  err = port_to_fd_with_default (scm_current_error_port (), O_WRONLY);
+
+  pid = do_spawn (exec_file, exec_argv, environ, in, out, err);
+  if (pid == -1)
+    {
+      int errno_save = errno;
+      free (exec_file);
+      errno = errno_save;
+      SCM_SYSERROR;
+    }
+
+  SCM_SYSCALL (wait_result = waitpid (pid, &status, 0));
   if (wait_result == -1)
     SCM_SYSERROR;
 
@@ -1550,7 +1484,6 @@ SCM_DEFINE (scm_system_star, "system*", 0, 0, 1,
   return scm_from_int (status);
 }
 #undef FUNC_NAME
-#endif /* HAVE_FORK */
 
 #ifdef HAVE_UNAME
 SCM_DEFINE (scm_uname, "uname", 0, 0, 0,
@@ -2396,14 +2329,6 @@ SCM_DEFINE (scm_gethostname, "gethostname", 0, 0, 0,
 #endif /* HAVE_GETHOSTNAME */
 
 \f
-#ifdef HAVE_FORK
-static void
-scm_init_popen (void)
-{
-  scm_c_define_gsubr ("piped-process", 2, 2, 0, scm_piped_process);
-}
-#endif /* HAVE_FORK */
-
 void
 scm_init_posix ()
 {
@@ -2520,10 +2445,5 @@ scm_init_posix ()
 
 #ifdef HAVE_FORK
   scm_add_feature ("fork");
-  scm_add_feature ("popen");
-  scm_c_register_extension ("libguile-" SCM_EFFECTIVE_VERSION,
-                            "scm_init_popen",
-			    (scm_t_extension_init_func) scm_init_popen,
-			    NULL);
 #endif	/* HAVE_FORK */
 }
diff --git a/module/ice-9/popen.scm b/module/ice-9/popen.scm
index e638726a4..547f56d5f 100644
--- a/module/ice-9/popen.scm
+++ b/module/ice-9/popen.scm
@@ -25,11 +25,34 @@
   #:use-module (srfi srfi-1)
   #:use-module (srfi srfi-9)
   #:export (port/pid-table open-pipe* open-pipe close-pipe open-input-pipe
-            open-output-pipe open-input-output-pipe pipeline))
+            open-output-pipe open-input-output-pipe pipeline spawn))
 
-(eval-when (expand load eval)
-  (load-extension (string-append "libguile-" (effective-version))
-                  "scm_init_popen"))
+(define (port-with-defaults port default-mode)
+  (if (file-port? port)
+      port
+      (open-file "/dev/null" default-mode)))
+
+(define* (spawn exec-file argv #:key
+                             (in (current-input-port))
+                             (out (current-output-port))
+                             (err (current-error-port)))
+  "Spawns a new child process executing @var{prog} with arguments
+@var{args}, with its standard input, output and error file descriptors
+set to @var{in}, @var{out}, @var{err}."
+  (let* ((in (port-with-defaults in "r"))
+         (out (port-with-defaults out "w"))
+         (err (port-with-defaults err "w"))
+         ;; Increment port revealed counts while to prevent ports GC'ing and
+         ;; closing the associated fds while we spawn the process.
+         (result (spawn* exec-file
+                         argv
+                         (port->fdes in)
+                         (port->fdes out)
+                         (port->fdes err))))
+    (release-port-handle in)
+    (release-port-handle out)
+    (release-port-handle err)
+    result))
 
 (define-record-type <pipe-info>
   (make-pipe-info pid)
@@ -92,13 +115,13 @@
 
 (define (open-process mode command . args)
   "Backwards compatible implementation of the former procedure in
-libguile/posix.c (scm_open_process) replaced by
-scm_piped_process. Executes the program @var{command} with optional
-arguments @var{args} (all strings) in a subprocess.  A port to the
-process (based on pipes) is created and returned.  @var{mode} specifies
-whether an input, an output or an input-output port to the process is
-created: it should be the value of @code{OPEN_READ}, @code{OPEN_WRITE}
-or @code{OPEN_BOTH}."
+libguile/posix.c (scm_open_process) replaced by scm_piped_process, now
+replaced by scm_spawn_process. Executes the program @var{command} with
+optional arguments @var{args} (all strings) in a subprocess.  A port to
+the process (based on pipes) is created and returned.  @var{mode}
+specifies whether an input, an output or an input-output port to the
+process is created: it should be the value of @code{OPEN_READ},
+@code{OPEN_WRITE} or @code{OPEN_BOTH}."
   (define (unbuffered port)
     (setvbuf port 'none)
     port)
@@ -107,19 +130,25 @@ or @code{OPEN_BOTH}."
     (and ports
          (cons (port->fdes (car ports)) (port->fdes (cdr ports)))))
 
-  (let* ((from (and (or (string=? mode OPEN_READ)
-                        (string=? mode OPEN_BOTH))
-                    (pipe)))
-         (to (and (or (string=? mode OPEN_WRITE)
-                      (string=? mode OPEN_BOTH))
-                  (pipe)))
-         (pid (piped-process command args
-                             (fdes-pair from)
-                             (fdes-pair to))))
+  (let* ((child-to-parent (and (or (string=? mode OPEN_READ)
+                                   (string=? mode OPEN_BOTH))
+                               (pipe)))
+         (parent-to-child (and (or (string=? mode OPEN_WRITE)
+                                   (string=? mode OPEN_BOTH))
+                               (pipe)))
+         (in (or (and=> parent-to-child car) (current-input-port)))
+         (out (or (and=> child-to-parent cdr) (current-output-port)))
+         (pid (spawn command (cons command args)
+                     #:in in
+                     #:out out)))
+    (when child-to-parent
+      (close (cdr child-to-parent)))
+    (when parent-to-child
+      (close (car parent-to-child)))
     ;; The original 'open-process' procedure would return unbuffered
     ;; ports; do the same here.
-    (values (and from (unbuffered (car from)))
-            (and to (unbuffered (cdr to)))
+    (values (and child-to-parent (unbuffered (car child-to-parent)))
+            (and parent-to-child (unbuffered (cdr parent-to-child)))
             pid)))
 
 (define (open-pipe* mode command . args)
@@ -224,10 +253,16 @@ a list of PIDs of the processes executing the @var{commands}."
 	 (pipeline (fold (lambda (from proc prev)
                            (let* ((to (car prev))
                                   (pids (cdr prev))
-                                  (pid (piped-process (car proc)
-                                                      (cdr proc)
-                                                      from
-                                                      to)))
+                                  (pid (spawn* (car proc)
+                                               proc
+                                               (car to)
+                                               (cdr from)
+                                               (port->fdes
+                                                (port-with-defaults
+                                                 (current-error-port)
+                                                 "w")))))
+                             (close-fdes (car to))
+                             (close-fdes (cdr from))
                              (cons from (cons pid pids))))
                          `(,to)
                          pipes
diff --git a/test-suite/tests/popen.test b/test-suite/tests/popen.test
index 3df863375..fd810e376 100644
--- a/test-suite/tests/popen.test
+++ b/test-suite/tests/popen.test
@@ -257,18 +257,18 @@ exec 2>~a; read REPLY"
     (list (read-string from)
           (status:exit-val (cdr (waitpid pid))))))
 
-(pass-if-equal "piped-process"
+(pass-if-equal "spawn"
     42
   (status:exit-val
-   (cdr (waitpid ((@@ (ice-9 popen) piped-process)
-                  "./meta/guile" '("-c" "(exit 42)"))))))
+   (cdr (waitpid (spawn
+                  "./meta/guile" '("./meta/guile" "-c" "(exit 42)"))))))
 
-(pass-if-equal "piped-process: with output"
+(pass-if-equal "spawn: with output"
     '("foo bar\n" 0)
   (let* ((p (pipe))
-         (pid ((@@ (ice-9 popen) piped-process) "echo" '("foo" "bar")
-               (cons (port->fdes (car p))
-                     (port->fdes (cdr p))))))
+         (pid (spawn "echo" '("echo" "foo" "bar")
+                     #:out (cdr p))))
+    (close (cdr p))
     (list (read-string (car p))
           (status:exit-val (cdr (waitpid pid))))))
 
diff --git a/test-suite/tests/posix.test b/test-suite/tests/posix.test
index bfc6f168e..5c971f4f7 100644
--- a/test-suite/tests/posix.test
+++ b/test-suite/tests/posix.test
@@ -340,24 +340,24 @@
 
 (with-test-prefix "system*"
 
-  (pass-if "http://bugs.gnu.org/13166"
-    ;; With Guile up to 2.0.7 included, the child process launched by
-    ;; `system*' would remain alive after an `execvp' failure.
-    (let ((me (getpid)))
-      (and (not (zero? (system* "something-that-does-not-exist")))
-           (= me (getpid)))))
-
-  (pass-if-equal "exit code for nonexistent file"
-      127                                         ;aka. EX_NOTFOUND
-    (status:exit-val (system* "something-that-does-not-exist")))
-
-  (pass-if-equal "https://bugs.gnu.org/55596"
-      127
-    ;; The parameterization below used to cause 'start_child' to close
-    ;; fd 2 in the child process, which in turn would cause it to
-    ;; segfault, leading to a wrong exit code.
-    (parameterize ((current-output-port (current-error-port)))
-      (status:exit-val (system* "something-that-does-not-exist")))))
+  (pass-if-equal "exception for nonexistent file"
+      2 ; ENOENT
+      (call-with-prompt 'escape
+        (lambda ()
+          (with-exception-handler
+              (lambda (exn)
+                (let* ((kind (exception-kind exn))
+                       (errno (and (eq? kind 'system-error)
+                                   (car (car
+                                         (cdr (cdr (cdr (exception-args
+                                                        exn)))))))))
+                  (abort-to-prompt 'escape errno)))
+            (lambda ()
+              (status:exit-val (system*
+                                "something-that-does-not-exist")))
+            #:unwind? #t))
+        (lambda (k arg)
+          arg))))
 
 ;;
 ;; crypt
-- 
2.38.1






^ permalink raw reply related	[flat|nested] 36+ messages in thread

* bug#52835: [PATCH 0/2] Fix spawning a child not setting standard fds properly
  2022-12-22 12:49                   ` bug#52835: [PATCH v6 0/3] Move spawning procedures to posix_spawn Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
                                       ` (2 preceding siblings ...)
  2022-12-22 12:49                     ` bug#52835: [PATCH v6 3/3] Move popen and posix procedures to spawn* Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
@ 2022-12-23 10:53                     ` Ludovic Courtès
  2022-12-23 17:15                       ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  3 siblings, 1 reply; 36+ messages in thread
From: Ludovic Courtès @ 2022-12-23 10:53 UTC (permalink / raw)
  To: Josselin Poiret; +Cc: 52835, Timothy Sample

Hi Josselin,

Josselin Poiret <dev@jpoiret.xyz> skribis:

> Here is hopefully the last reroll of this patchset.  First of all, I did not
> include the gnulib patch again because it still applies cleanly and it is
> extremely large, but it should be applied before those 3 patches.

Yay!

> The first two patches should be applied on the current major release, while the
> third one should be applied on the next major release to finish the migration to
> spawn.

I pushed it to ‘wip-posix-spawn’ along with fixups I’m proposing, mostly
along the lines of what I suggested in
<https://issues.guix.gnu.org/52835#18>:

  • Avoiding the extra ‘fork’ in ‘system*’ upon error;

  • Keep ‘scm_spawn_process’ internal.

I also added Andrew Whatson’s patch from
<https://issues.guix.gnu.org/59321>.

If that’s fine with you, I can squash the “fixup!” commits and merge the
branch.  Let me know!

Earlier we agreed it’d be nice to expose ‘spawn*’/‘primitive-spawn’.  I
still think it’s a good idea, but the interface would need some work IMO
to be more generally useful.  In essence, we could provide something
similar to ‘fork+exec-command’ in the Shepherd, where one can pass
environment variables, stdin/stdout/stderr, etc., all that with keyword
arguments and reasonable defaults.

It’s a bit of extra work though so we can discuss that later,
separately.

Thank you!

Ludo’.





^ permalink raw reply	[flat|nested] 36+ messages in thread

* bug#52835: [PATCH 0/2] Fix spawning a child not setting standard fds properly
  2022-12-23 10:53                     ` bug#52835: [PATCH 0/2] Fix spawning a child not setting standard fds properly Ludovic Courtès
@ 2022-12-23 17:15                       ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2022-12-23 17:17                         ` bug#52835: [PATCH v7 1/2] Add spawn* and spawn Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2022-12-25 16:58                         ` Ludovic Courtès
  0 siblings, 2 replies; 36+ messages in thread
From: Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language @ 2022-12-23 17:15 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: 52835, Timothy Sample

Hi Ludo, thanks for the quick review and fixes.

> I pushed it to ‘wip-posix-spawn’ along with fixups I’m proposing, mostly
> along the lines of what I suggested in
> <https://issues.guix.gnu.org/52835#18>:

Nice but also see below.

> I also added Andrew Whatson’s patch from
> <https://issues.guix.gnu.org/59321>.

Great, hadn't see that one go by!

> If that’s fine with you, I can squash the “fixup!” commits and merge the
> branch.  Let me know!
>
> Earlier we agreed it’d be nice to expose ‘spawn*’/‘primitive-spawn’.  I
> still think it’s a good idea, but the interface would need some work IMO
> to be more generally useful.  In essence, we could provide something
> similar to ‘fork+exec-command’ in the Shepherd, where one can pass
> environment variables, stdin/stdout/stderr, etc., all that with keyword
> arguments and reasonable defaults.

I've just polished it up a bit: the `spawn*` procedure defined in C now
takes another argument, a list of environment variables.  I think this
interface is good enough to cover most use cases, if anyone needs
something more complicated they should go through their own C code.
I've added a convenience module (ice-9 spawn) with a `spawn` procedure
in it, which takes an optional argument list which defaults to just the
executable, and optional environment variables as well as in, out and
err ports.  I also think everything in (ice-9 popen) should be migrated
on the next major release, as well as being re-implemented in terms of
`spawn` purely, so that the change is immediately noticeable.

We're reaching the bike-shedding time now, but IMHO having such a
`spawn*` exposed to the user seems fine, it's a pretty simple "raw"
interface with fdes, and there is a convenience `spawn` function that is
nicer for users.

Do we need to add a documentation page as well?

Best,
-- 
Josselin Poiret





^ permalink raw reply	[flat|nested] 36+ messages in thread

* bug#52835: [PATCH v7 1/2] Add spawn* and spawn.
  2022-12-23 17:15                       ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
@ 2022-12-23 17:17                         ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2022-12-23 17:17                           ` bug#52835: [PATCH v7 2/2] Make system* and piped-process internally use spawn Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2022-12-25 17:03                           ` Ludovic Courtès
  2022-12-25 16:58                         ` Ludovic Courtès
  1 sibling, 2 replies; 36+ messages in thread
From: Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language @ 2022-12-23 17:17 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: 52835, Josselin Poiret

* libguile/posix.c: Include spawn.h from Gnulib.
(do_spawn, scm_spawn_process): New functions.
* module/ice-9/spawn.scm: New file
(spawn): New procedure.
---
 libguile/posix.c       | 82 ++++++++++++++++++++++++++++++++++++++++++
 libguile/posix.h       |  2 ++
 module/ice-9/spawn.scm | 54 ++++++++++++++++++++++++++++
 3 files changed, 138 insertions(+)
 create mode 100644 module/ice-9/spawn.scm

diff --git a/libguile/posix.c b/libguile/posix.c
index b5352c2c4..52dc11e57 100644
--- a/libguile/posix.c
+++ b/libguile/posix.c
@@ -33,6 +33,7 @@
 #include <sys/types.h>
 #include <uniconv.h>
 #include <unistd.h>
+#include <spawn.h>
 
 #ifdef HAVE_SCHED_H
 # include <sched.h>
@@ -1426,6 +1427,87 @@ start_child (const char *exec_file, char **exec_argv,
 }
 #endif
 
+static pid_t
+do_spawn (char *exec_file, char **exec_argv, char **exec_env, int in, int out, int err)
+{
+  pid_t pid = -1;
+
+  posix_spawn_file_actions_t actions;
+  posix_spawnattr_t *attrp = NULL;
+
+  int max_fd = 1024;
+
+#if defined (HAVE_GETRLIMIT) && defined (RLIMIT_NOFILE)
+  {
+    struct rlimit lim = { 0, 0 };
+    if (getrlimit (RLIMIT_NOFILE, &lim) == 0)
+      max_fd = lim.rlim_cur;
+  }
+#endif
+
+  posix_spawn_file_actions_init (&actions);
+
+  int free_fd_slots = 0;
+  int fd_slot[3];
+
+  for (int fdnum = 3;free_fd_slots < 3 && fdnum < max_fd;fdnum++)
+    {
+      if (fdnum != in && fdnum != out && fdnum != err)
+        {
+          fd_slot[free_fd_slots] = fdnum;
+          free_fd_slots++;
+        }
+    }
+
+  /* Move the fds out of the way, so that duplicate fds or fds equal
+     to 0, 1, 2 don't trample each other */
+
+  posix_spawn_file_actions_adddup2 (&actions, in, fd_slot[0]);
+  posix_spawn_file_actions_adddup2 (&actions, out, fd_slot[1]);
+  posix_spawn_file_actions_adddup2 (&actions, err, fd_slot[2]);
+  posix_spawn_file_actions_adddup2 (&actions, fd_slot[0], 0);
+  posix_spawn_file_actions_adddup2 (&actions, fd_slot[1], 1);
+  posix_spawn_file_actions_adddup2 (&actions, fd_slot[2], 2);
+
+  while (--max_fd > 2)
+    posix_spawn_file_actions_addclose (&actions, max_fd);
+
+  if (posix_spawnp (&pid, exec_file, &actions, attrp, exec_argv, exec_env) != 0)
+    return -1;
+
+  return pid;
+}
+
+SCM_DEFINE (scm_spawn_process, "spawn*", 6, 0, 0,
+            (SCM prog, SCM args, SCM env, SCM in, SCM out, SCM err),
+            "Spawns a new child process executing @var{prog} with arguments\n"
+            "@var{args}, with its standard input, output and error file descriptors\n"
+            "set to @var{in}, @var{out}, @var{err}, and environment to @var{env}.")
+#define FUNC_NAME s_scm_spawn_process
+{
+  int pid;
+  char *exec_file;
+  char **exec_argv;
+  char **exec_env;
+
+  exec_file = scm_to_locale_string (prog);
+  exec_argv = scm_i_allocate_string_pointers (args);
+  exec_env = scm_i_allocate_string_pointers (env);
+
+  pid = do_spawn (exec_file, exec_argv, exec_env,
+                  scm_to_int (in),
+                  scm_to_int (out),
+                  scm_to_int (err));
+
+  free (exec_file);
+
+  if (pid == -1)
+    SCM_SYSERROR;
+
+  return scm_from_int (pid);
+}
+#undef FUNC_NAME
+
 #ifdef HAVE_START_CHILD
 static SCM
 scm_piped_process (SCM prog, SCM args, SCM from, SCM to)
diff --git a/libguile/posix.h b/libguile/posix.h
index 6504eaea8..35c502bc1 100644
--- a/libguile/posix.h
+++ b/libguile/posix.h
@@ -69,6 +69,8 @@ SCM_API SCM scm_tmpnam (void);
 SCM_API SCM scm_tmpfile (void);
 SCM_API SCM scm_open_pipe (SCM pipestr, SCM modes);
 SCM_API SCM scm_close_pipe (SCM port);
+SCM_API SCM scm_spawn_process (SCM prog, SCM args, SCM env,
+                               SCM in, SCM out, SCM err);
 SCM_API SCM scm_system_star (SCM cmds);
 SCM_API SCM scm_utime (SCM object, SCM actime, SCM modtime,
                        SCM actimens, SCM modtimens, SCM flags);
diff --git a/module/ice-9/spawn.scm b/module/ice-9/spawn.scm
new file mode 100644
index 000000000..ae4f54efa
--- /dev/null
+++ b/module/ice-9/spawn.scm
@@ -0,0 +1,54 @@
+;; Spawning programs
+
+;;;; Copyright (C) 2022
+;;;;   Free Software Foundation, Inc.
+;;;;
+;;;; This library 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 License, or (at your option) any later version.
+;;;;
+;;;; This library 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
+;;;; Lesser General Public License for more details.
+;;;;
+;;;; You should have received a copy of the GNU Lesser General Public
+;;;; License along with this library; if not, write to the Free Software
+;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+;;;;
+
+(define-module (ice-9 spawn)
+  #:export (spawn))
+
+(define (port-with-defaults port default-mode)
+  (if (file-port? port)
+      port
+      (open-file "/dev/null" default-mode)))
+
+(define* (spawn exec-file
+                #:optional (args (list exec-file))
+                #:key      (env (environ))
+                           (in (current-input-port))
+                           (out (current-output-port))
+                           (err (current-error-port)))
+  "Spawns a new process running the program @var{exec} with arguments
+@var{args}, in the environment specified by the list of environment
+variable strings @var{env}, and with standard input, output and error
+set to the ports specified by @var{in}, @var{out}, @var{err}.  Note that
+the last part only works with fd-backed ports."
+  (let* ((in (port-with-defaults in "r"))
+         (out (port-with-defaults out "w"))
+         (err (port-with-defaults err "w"))
+         ;; Increment port revealed counts while to prevent ports GC'ing and
+         ;; closing the associated fds while we spawn the process.
+         (result (spawn* exec-file
+                         args
+                         env
+                         (port->fdes in)
+                         (port->fdes out)
+                         (port->fdes err))))
+    (release-port-handle in)
+    (release-port-handle out)
+    (release-port-handle err)
+    result))

base-commit: 4711d45176e9b75cef43699ed514669276af62fe
-- 
2.38.1






^ permalink raw reply related	[flat|nested] 36+ messages in thread

* bug#52835: [PATCH v7 2/2] Make system* and piped-process internally use spawn.
  2022-12-23 17:17                         ` bug#52835: [PATCH v7 1/2] Add spawn* and spawn Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
@ 2022-12-23 17:17                           ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2022-12-25 17:04                             ` bug#52835: [PATCH 0/2] Fix spawning a child not setting standard fds properly Ludovic Courtès
  2022-12-25 17:03                           ` Ludovic Courtès
  1 sibling, 1 reply; 36+ messages in thread
From: Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language @ 2022-12-23 17:17 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: 52835, Josselin Poiret

* libguile/posix.c (scm_system_star, scm_piped_process): Use do_spawn.
(start_child): Remove function.

Co-authored-by: Ludovic Courtès <ludo@gnu.org>
---
 libguile/posix.c | 233 ++++++++++++++++-------------------------------
 1 file changed, 78 insertions(+), 155 deletions(-)

diff --git a/libguile/posix.c b/libguile/posix.c
index 52dc11e57..ecc2b186e 100644
--- a/libguile/posix.c
+++ b/libguile/posix.c
@@ -77,6 +77,7 @@
 #include "threads.h"
 #include "values.h"
 #include "vectors.h"
+#include "verify.h"
 #include "version.h"
 
 #if (SCM_ENABLE_DEPRECATED == 1)
@@ -95,6 +96,13 @@
 # define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
 #endif
 
+#ifndef W_EXITCODE
+/* Macro for constructing a status value.  Found in glibc.  */
+# define W_EXITCODE(ret, sig)   ((ret) << 8 | (sig))
+#endif
+verify (WEXITSTATUS (W_EXITCODE (127, 0)) == 127);
+
+
 #include <signal.h>
 
 #ifdef HAVE_GRP_H
@@ -1308,125 +1316,6 @@ SCM_DEFINE (scm_fork, "primitive-fork", 0, 0, 0,
 #undef FUNC_NAME
 #endif /* HAVE_FORK */
 
-#ifdef HAVE_FORK
-/* 'renumber_file_descriptor' is a helper function for 'start_child'
-   below, and is specialized for that particular environment where it
-   doesn't make sense to report errors via exceptions.  It uses dup(2)
-   to duplicate the file descriptor FD, closes the original FD, and
-   returns the new descriptor.  If dup(2) fails, print an error message
-   to ERR and abort.  */
-static int
-renumber_file_descriptor (int fd, int err)
-{
-  int new_fd;
-
-  do
-    new_fd = dup (fd);
-  while (new_fd == -1 && errno == EINTR);
-
-  if (new_fd == -1)
-    {
-      /* At this point we are in the child process before exec.  We
-         cannot safely raise an exception in this environment.  */
-      const char *msg = strerror (errno);
-      fprintf (fdopen (err, "a"), "start_child: dup failed: %s\n", msg);
-      _exit (127);  /* Use exit status 127, as with other exec errors. */
-    }
-
-  close (fd);
-  return new_fd;
-}
-#endif /* HAVE_FORK */
-
-#ifdef HAVE_FORK
-#define HAVE_START_CHILD 1
-/* Since Guile uses threads, we have to be very careful to avoid calling
-   functions that are not async-signal-safe in the child.  That's why
-   this function is implemented in C.  */
-static pid_t
-start_child (const char *exec_file, char **exec_argv,
-	     int reading, int c2p[2], int writing, int p2c[2],
-             int in, int out, int err)
-{
-  int pid;
-  int max_fd = 1024;
-
-#if defined (HAVE_GETRLIMIT) && defined (RLIMIT_NOFILE)
-  {
-    struct rlimit lim = { 0, 0 };
-    if (getrlimit (RLIMIT_NOFILE, &lim) == 0)
-      max_fd = lim.rlim_cur;
-  }
-#endif
-
-  pid = fork ();
-
-  if (pid != 0)
-    /* The parent, with either and error (pid == -1), or the PID of the
-       child.  Return directly in either case.  */
-    return pid;
-
-  /* The child.  */
-  if (reading)
-    close (c2p[0]);
-  if (writing)
-    close (p2c[1]);
-
-  /* Close all file descriptors in ports inherited from the parent
-     except for in, out, and err.  Heavy-handed, but robust.  */
-  while (max_fd--)
-    if (max_fd != in && max_fd != out && max_fd != err)
-      close (max_fd);
-
-  /* Ignore errors on these open() calls.  */
-  if (in == -1)
-    in = open ("/dev/null", O_RDONLY);
-  if (out == -1)
-    out = open ("/dev/null", O_WRONLY);
-  if (err == -1)
-    err = open ("/dev/null", O_WRONLY);
-
-  if (in > 0)
-    {
-      if (out == 0)
-        out = renumber_file_descriptor (out, err);
-      if (err == 0)
-        err = renumber_file_descriptor (err, err);
-      do dup2 (in, 0); while (errno == EINTR);
-      close (in);
-    }
-  if (out > 1)
-    {
-      if (err == 1)
-        err = renumber_file_descriptor (err, err);
-      do dup2 (out, 1); while (errno == EINTR);
-      if (out > 2)
-        close (out);
-    }
-  if (err > 2)
-    {
-      do dup2 (err, 2); while (errno == EINTR);
-      close (err);
-    }
-
-  execvp (exec_file, exec_argv);
-
-  /* The exec failed!  There is nothing sensible to do.  */
-  {
-    const char *msg = strerror (errno);
-    fprintf (fdopen (2, "a"), "In execvp of %s: %s\n",
-             exec_file, msg);
-  }
-
-  /* Use exit status 127, like shells in this case, as per POSIX
-     <http://pubs.opengroup.org/onlinepubs/007904875/utilities/xcu_chap02.html#tag_02_09_01_01>.  */
-  _exit (127);
-
-  /* Not reached.  */
-  return -1;
-}
-#endif
-
 static pid_t
 do_spawn (char *exec_file, char **exec_argv, char **exec_env, int in, int out, int err)
 {
@@ -1508,18 +1397,18 @@ SCM_DEFINE (scm_spawn_process, "spawn*", 6, 0, 0,
 }
 #undef FUNC_NAME
 
-#ifdef HAVE_START_CHILD
-static SCM
-scm_piped_process (SCM prog, SCM args, SCM from, SCM to)
+#ifdef HAVE_FORK
+static int
+piped_process (pid_t *pid, SCM prog, SCM args, SCM from, SCM to)
 #define FUNC_NAME "piped-process"
 {
   int reading, writing;
   int c2p[2]; /* Child to parent.  */
   int p2c[2]; /* Parent to child.  */
   int in = -1, out = -1, err = -1;
-  int pid;
   char *exec_file;
   char **exec_argv;
+  char **exec_env = environ;
 
   exec_file = scm_to_locale_string (prog);
   exec_argv = scm_i_allocate_string_pointers (scm_cons (prog, args));
@@ -1552,32 +1441,57 @@ scm_piped_process (SCM prog, SCM args, SCM from, SCM to)
       in = SCM_FPORT_FDES (port);
   }
 
-  pid = start_child (exec_file, exec_argv, reading, c2p, writing, p2c,
-                     in, out, err);
-
-  if (pid == -1)
-    {
-      int errno_save = errno;
-      free (exec_file);
-      if (reading)
-        {
-          close (c2p[0]);
-          close (c2p[1]);
-        }
-      if (writing)
-        {
-          close (p2c[0]);
-          close (p2c[1]);
-        }
-      errno = errno_save;
-      SCM_SYSERROR;
-    }
+  *pid = do_spawn (exec_file, exec_argv, exec_env, in, out, err);
+  int errno_save = (*pid < 0) ? errno : 0;
 
   if (reading)
     close (c2p[1]);
   if (writing)
     close (p2c[0]);
 
+  if (*pid == -1)
+    switch (errno_save)
+      {
+        /* Errors that seemingly come from fork.  */
+      case EAGAIN:
+      case ENOMEM:
+      case ENOSYS:
+        errno = err;
+        free (exec_file);
+        SCM_SYSERROR;
+        break;
+
+      default:    /* ENOENT, etc. */
+        /* Create a dummy process that exits with value 127.  */
+        dprintf (err, "In execvp of %s: %s\n", exec_file,
+                 strerror (errno_save));
+      }
+
+  free (exec_file);
+
+  return errno_save;
+}
+#undef FUNC_NAME
+
+static SCM
+scm_piped_process (SCM prog, SCM args, SCM from, SCM to)
+#define FUNC_NAME "piped-process"
+{
+  pid_t pid;
+
+  (void) piped_process (&pid, prog, args, from, to);
+  if (pid == -1)
+    {
+      /* Create a dummy process that exits with value 127 to mimic the
+         previous fork + exec implementation.  TODO: This is a
+         compatibility shim to remove in the next stable series.  */
+      pid = fork ();
+      if (pid == -1)
+        SCM_SYSERROR;
+      if (pid == 0)
+        _exit (127);
+    }
+
   return scm_from_int (pid);
 }
 #undef FUNC_NAME
@@ -1623,8 +1537,9 @@ SCM_DEFINE (scm_system_star, "system*", 0, 0, 1,
 "Example: (system* \"echo\" \"foo\" \"bar\")")
 #define FUNC_NAME s_scm_system_star
 {
-  SCM prog, pid;
-  int status, wait_result;
+  SCM prog;
+  pid_t pid;
+  int err, status, wait_result;
 
   if (scm_is_null (args))
     SCM_WRONG_NUM_ARGS ();
@@ -1642,17 +1557,27 @@ SCM_DEFINE (scm_system_star, "system*", 0, 0, 1,
                          SCM_UNDEFINED);
 #endif
 
-  pid = scm_piped_process (prog, args, SCM_UNDEFINED, SCM_UNDEFINED);
-  SCM_SYSCALL (wait_result = waitpid (scm_to_int (pid), &status, 0));
-  if (wait_result == -1)
-    SCM_SYSERROR;
+  err = piped_process (&pid, prog, args,
+                       SCM_UNDEFINED, SCM_UNDEFINED);
+  if (err != 0)
+    /* ERR might be ENOENT or similar.  For backward compatibility with
+       the previous implementation based on fork + exec, pretend the
+       child process exited with code 127.  TODO: Remove this
+       compatibility shim in the next stable series.  */
+    status = W_EXITCODE (127, 0);
+  else
+    {
+      SCM_SYSCALL (wait_result = waitpid (pid, &status, 0));
+      if (wait_result == -1)
+        SCM_SYSERROR;
+    }
 
   scm_dynwind_end ();
 
   return scm_from_int (status);
 }
 #undef FUNC_NAME
-#endif /* HAVE_START_CHILD */
+#endif /* HAVE_FORK */
 
 #ifdef HAVE_UNAME
 SCM_DEFINE (scm_uname, "uname", 0, 0, 0,
@@ -2498,13 +2423,13 @@ SCM_DEFINE (scm_gethostname, "gethostname", 0, 0, 0,
 #endif /* HAVE_GETHOSTNAME */
 
 \f
-#ifdef HAVE_START_CHILD
+#ifdef HAVE_FORK
 static void
 scm_init_popen (void)
 {
   scm_c_define_gsubr ("piped-process", 2, 2, 0, scm_piped_process);
 }
-#endif /* HAVE_START_CHILD */
+#endif /* HAVE_FORK */
 
 void
 scm_init_posix ()
@@ -2622,12 +2547,10 @@ scm_init_posix ()
 
 #ifdef HAVE_FORK
   scm_add_feature ("fork");
-#endif	/* HAVE_FORK */
-#ifdef HAVE_START_CHILD
   scm_add_feature ("popen");
   scm_c_register_extension ("libguile-" SCM_EFFECTIVE_VERSION,
                             "scm_init_popen",
 			    (scm_t_extension_init_func) scm_init_popen,
 			    NULL);
-#endif /* HAVE_START_CHILD */
+#endif	/* HAVE_FORK */
 }
-- 
2.38.1






^ permalink raw reply related	[flat|nested] 36+ messages in thread

* bug#52835: [PATCH 0/2] Fix spawning a child not setting standard fds properly
  2022-12-23 17:15                       ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2022-12-23 17:17                         ` bug#52835: [PATCH v7 1/2] Add spawn* and spawn Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
@ 2022-12-25 16:58                         ` Ludovic Courtès
  2023-01-07 16:07                           ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  1 sibling, 1 reply; 36+ messages in thread
From: Ludovic Courtès @ 2022-12-25 16:58 UTC (permalink / raw)
  To: Josselin Poiret; +Cc: 52835, Timothy Sample

Hi Josselin,

Josselin Poiret <dev@jpoiret.xyz> skribis:

> I've added a convenience module (ice-9 spawn) with a `spawn` procedure
> in it, which takes an optional argument list which defaults to just the
> executable, and optional environment variables as well as in, out and
> err ports.  I also think everything in (ice-9 popen) should be migrated
> on the next major release, as well as being re-implemented in terms of
> `spawn` purely, so that the change is immediately noticeable.

OK.

> We're reaching the bike-shedding time now, but IMHO having such a
> `spawn*` exposed to the user seems fine, it's a pretty simple "raw"
> interface with fdes, and there is a convenience `spawn` function that is
> nicer for users.

‘spawn*’ is expressive enough, but a procedure with 6 positional
arguments cannot be exposed as-is IMO.

One tiny thing that’s missing is a boolean to choose between
‘posix_spawn’ and ‘posix_spawnp’.

So we need either ‘spawn’ defined in Scheme as you did, or directly use
‘scm_c_bind_keyword_arguments’ right in ‘scm_spawn_process’ (info
"(guile) Keyword Procedures"), to avoid ending up with two procedures.
I’m fine either way.

> Do we need to add a documentation page as well?

Yes, please.  :-)  I realize I’m asking a lot of things, so let me know
if you’d like to share the workload somehow.

Doc could go in the “Processes” section, or possibly in a new section
we’d add right after it, “Spawning Programs”.  We should probably add a
“@quotation Note” in the doc of ‘primitive-fork’ that briefly explains
why people should probably use ‘spawn’ rather than fork + exec.

Some cosmetic suggestions follow…

Thanks,
Ludo’.





^ permalink raw reply	[flat|nested] 36+ messages in thread

* bug#52835: [PATCH 0/2] Fix spawning a child not setting standard fds properly
  2022-12-23 17:17                         ` bug#52835: [PATCH v7 1/2] Add spawn* and spawn Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2022-12-23 17:17                           ` bug#52835: [PATCH v7 2/2] Make system* and piped-process internally use spawn Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
@ 2022-12-25 17:03                           ` Ludovic Courtès
  1 sibling, 0 replies; 36+ messages in thread
From: Ludovic Courtès @ 2022-12-25 17:03 UTC (permalink / raw)
  To: Josselin Poiret; +Cc: 52835

Josselin Poiret <dev@jpoiret.xyz> skribis:

> * libguile/posix.c: Include spawn.h from Gnulib.
> (do_spawn, scm_spawn_process): New functions.
> * module/ice-9/spawn.scm: New file
> (spawn): New procedure.
> ---
>  libguile/posix.c       | 82 ++++++++++++++++++++++++++++++++++++++++++
>  libguile/posix.h       |  2 ++
>  module/ice-9/spawn.scm | 54 ++++++++++++++++++++++++++++
>  3 files changed, 138 insertions(+)

The new module should be added to ‘am/bootstrap.am’.

> +SCM_API SCM scm_spawn_process (SCM prog, SCM args, SCM env,
> +                               SCM in, SCM out, SCM err);

Let’s keep it ‘SCM_INTERNAL’.

> +(define* (spawn exec-file
> +                #:optional (args (list exec-file))
> +                #:key      (env (environ))
> +                           (in (current-input-port))
> +                           (out (current-output-port))
> +                           (err (current-error-port)))

s/exec-file/program/
s/args/arguments/
s/env/environment/

s/in/standard-input/
s/out/standard-output/
s/err/standard-error/

Maybe we could allow these two be either ports or file descriptors?

> +  "Spawns a new process running the program @var{exec} with arguments
> +@var{args}, in the environment specified by the list of environment
> +variable strings @var{env}, and with standard input, output and error
> +set to the ports specified by @var{in}, @var{out}, @var{err}.  Note that
> +the last part only works with fd-backed ports."
> +  (let* ((in (port-with-defaults in "r"))
> +         (out (port-with-defaults out "w"))
> +         (err (port-with-defaults err "w"))
> +         ;; Increment port revealed counts while to prevent ports GC'ing and
> +         ;; closing the associated fds while we spawn the process.
> +         (result (spawn* exec-file
> +                         args
> +                         env
> +                         (port->fdes in)
> +                         (port->fdes out)
> +                         (port->fdes err))))

I believe ‘spawn*’ is unbound here because it’s defined by
‘scm_init_popen’, which is called within the (ice-9 popen) module.

Ludo’.





^ permalink raw reply	[flat|nested] 36+ messages in thread

* bug#52835: [PATCH 0/2] Fix spawning a child not setting standard fds properly
  2022-12-23 17:17                           ` bug#52835: [PATCH v7 2/2] Make system* and piped-process internally use spawn Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
@ 2022-12-25 17:04                             ` Ludovic Courtès
  0 siblings, 0 replies; 36+ messages in thread
From: Ludovic Courtès @ 2022-12-25 17:04 UTC (permalink / raw)
  To: Josselin Poiret; +Cc: 52835

Josselin Poiret <dev@jpoiret.xyz> skribis:

> * libguile/posix.c (scm_system_star, scm_piped_process): Use do_spawn.
> (start_child): Remove function.

LGTM, thanks!





^ permalink raw reply	[flat|nested] 36+ messages in thread

* bug#52835: [PATCH 0/2] Fix spawning a child not setting standard fds properly
  2022-12-25 16:58                         ` Ludovic Courtès
@ 2023-01-07 16:07                           ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2023-01-07 16:07                             ` bug#52835: [PATCH v8 1/2] Add spawn Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2023-01-12 22:02                             ` bug#52835: [PATCH 0/2] Fix spawning a child not setting standard fds properly Ludovic Courtès
  0 siblings, 2 replies; 36+ messages in thread
From: Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language @ 2023-01-07 16:07 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: 52835, Timothy Sample

Hi Ludo,

Happy new year!

Ludovic Courtès <ludo@gnu.org> writes:

> ‘spawn*’ is expressive enough, but a procedure with 6 positional
> arguments cannot be exposed as-is IMO.
>
> One tiny thing that’s missing is a boolean to choose between
> ‘posix_spawn’ and ‘posix_spawnp’.
>
> So we need either ‘spawn’ defined in Scheme as you did, or directly use
> ‘scm_c_bind_keyword_arguments’ right in ‘scm_spawn_process’ (info
> "(guile) Keyword Procedures"), to avoid ending up with two procedures.
> I’m fine either way.

I've done the above by using the C functions to bind keyword arguments,
and added the #:use-path? keyword argument.  One annoying thing though
is that since it uses keyword arguments, the first line of the
documentation generated by SCM_DEFINE only mentions "spawn program
. keyword_args".

>> Do we need to add a documentation page as well?
>
> Yes, please.  :-)  I realize I’m asking a lot of things, so let me know
> if you’d like to share the workload somehow.
>
> Doc could go in the “Processes” section, or possibly in a new section
> we’d add right after it, “Spawning Programs”.  We should probably add a
> “@quotation Note” in the doc of ‘primitive-fork’ that briefly explains
> why people should probably use ‘spawn’ rather than fork + exec.

I've opted to put it right below primitive-fork, and slightly rewrite
the part about pipes in primitive-fork's description to also mention
spawn.  Let me know if the documentation is not descriptive enough.

WDYT?
-- 
Josselin Poiret





^ permalink raw reply	[flat|nested] 36+ messages in thread

* bug#52835: [PATCH v8 1/2] Add spawn.
  2023-01-07 16:07                           ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
@ 2023-01-07 16:07                             ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2023-01-07 16:07                               ` bug#52835: [PATCH v8 2/2] Make system* and piped-process internally use spawn Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2023-01-12 22:02                             ` bug#52835: [PATCH 0/2] Fix spawning a child not setting standard fds properly Ludovic Courtès
  1 sibling, 1 reply; 36+ messages in thread
From: Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language @ 2023-01-07 16:07 UTC (permalink / raw)
  To: Josselin Poiret, Ludovic Courtès; +Cc: 52835

* libguile/posix.c: Include spawn.h from Gnulib.
(do_spawn, scm_spawn_process): New functions.
---
 doc/ref/posix.texi |  34 ++++++++--
 libguile/posix.c   | 162 ++++++++++++++++++++++++++++++++++++++++++++-
 libguile/posix.h   |   1 +
 3 files changed, 192 insertions(+), 5 deletions(-)

diff --git a/doc/ref/posix.texi b/doc/ref/posix.texi
index bde0f150c..36e1f5040 100644
--- a/doc/ref/posix.texi
+++ b/doc/ref/posix.texi
@@ -2045,15 +2045,41 @@ safe to call after a multithreaded fork, which is a very limited set.
 Guile issues a warning if it detects a fork from a multi-threaded
 program.
 
-If you are going to @code{exec} soon after forking, the procedures in
-@code{(ice-9 popen)} may be useful to you, as they fork and exec within
-an async-signal-safe function carefully written to ensure robust program
-behavior, even in the presence of threads.  @xref{Pipes}, for more.
+@quotation Note
+If you are only looking to fork+exec with some pipes set up, using pipes
+or the more primitive @code{spawn} will be more robust (e.g. in the
+presence of threads), and is more portable.  @xref{Pipes} for more.
+@end quotation
 
 This procedure has been renamed from @code{fork} to avoid a naming conflict
 with the scsh fork.
 @end deffn
 
+@deffn {Scheme Procedure} spawn program [#:args=(list program)] @
+       [#:env=(environ)] [#:in=(fileno (current-input-port))] @
+       [#:out=(fileno (current-output-port))] @
+       [#:err=(fileno (current-error-port))] @
+       [#:use-path?=#t]
+
+Spawns a new child process executing @var{program} with argument list
+@var{args} (which must include the name of the executable as a first
+element), with its environment variables set to @var{env} and standard
+input/output/error file descriptors to @var{in}, @var{out}, @var{err},
+after closing all other file descriptors.  When @var{use-path?} is
+false, @var{program} should be a path to an executable file, but when
+@var{use-path?} is true, the environment variable @code{PATH} is
+searched to find the corresponding executable.
+
+Failure to exec in the child may be caught early and reported as an
+exception, or the child may also exit with return code 127, depending on
+how spawn is implemented for the specific system.  You therefore must be
+able to handle both cases.
+
+The return value is the pid of the spawned child process.
+
+This procedure is portable and should be thread-safe.
+@end deffn
+
 @deffn {Scheme Procedure} nice incr
 @deffnx {C Function} scm_nice (incr)
 @cindex process priority
diff --git a/libguile/posix.c b/libguile/posix.c
index b5352c2c4..f79875075 100644
--- a/libguile/posix.c
+++ b/libguile/posix.c
@@ -33,6 +33,7 @@
 #include <sys/types.h>
 #include <uniconv.h>
 #include <unistd.h>
+#include <spawn.h>
 
 #ifdef HAVE_SCHED_H
 # include <sched.h>
@@ -63,6 +64,7 @@
 #include "fports.h"
 #include "gettext.h"
 #include "gsubr.h"
+#include "keywords.h"
 #include "list.h"
 #include "modules.h"
 #include "numbers.h"
@@ -1426,6 +1428,158 @@ start_child (const char *exec_file, char **exec_argv,
 }
 #endif
 
+static pid_t
+do_spawn (char *exec_file, char **exec_argv, char **exec_env,
+          int in, int out, int err, int spawnp)
+{
+  pid_t pid = -1;
+
+  posix_spawn_file_actions_t actions;
+  posix_spawnattr_t *attrp = NULL;
+
+  int max_fd = 1024;
+
+#if defined (HAVE_GETRLIMIT) && defined (RLIMIT_NOFILE)
+  {
+    struct rlimit lim = { 0, 0 };
+    if (getrlimit (RLIMIT_NOFILE, &lim) == 0)
+      max_fd = lim.rlim_cur;
+  }
+#endif
+
+  posix_spawn_file_actions_init (&actions);
+
+  int free_fd_slots = 0;
+  int fd_slot[3];
+
+  for (int fdnum = 3;free_fd_slots < 3 && fdnum < max_fd;fdnum++)
+    {
+      if (fdnum != in && fdnum != out && fdnum != err)
+        {
+          fd_slot[free_fd_slots] = fdnum;
+          free_fd_slots++;
+        }
+    }
+
+  /* Move the fds out of the way, so that duplicate fds or fds equal
+     to 0, 1, 2 don't trample each other */
+
+  posix_spawn_file_actions_adddup2 (&actions, in, fd_slot[0]);
+  posix_spawn_file_actions_adddup2 (&actions, out, fd_slot[1]);
+  posix_spawn_file_actions_adddup2 (&actions, err, fd_slot[2]);
+  posix_spawn_file_actions_adddup2 (&actions, fd_slot[0], 0);
+  posix_spawn_file_actions_adddup2 (&actions, fd_slot[1], 1);
+  posix_spawn_file_actions_adddup2 (&actions, fd_slot[2], 2);
+
+  while (--max_fd > 2)
+    posix_spawn_file_actions_addclose (&actions, max_fd);
+
+  int res = -1;
+  if (spawnp)
+    res = posix_spawnp (&pid, exec_file, &actions, attrp,
+                        exec_argv, exec_env);
+  else
+    res = posix_spawn (&pid, exec_file, &actions, attrp,
+                       exec_argv, exec_env);
+  if (res != 0)
+    return -1;
+
+  return pid;
+}
+
+SCM k_args, k_env, k_in, k_out, k_err, k_use_path;
+
+SCM_DEFINE (scm_spawn_process, "spawn", 1, 0, 1,
+            (SCM program, SCM keyword_args),
+            "Spawns a new child process executing @var{program} with no arguments.\n\n"
+            "If the boolean keyword argument @code{#:use-path?} is provided, it\n"
+            "selects whether the @code{PATH} environment variable should be\n"
+            "inspected to find @var{program}.  It is true by default.\n\n"
+            "If the keyword arguments @code{#:args}, @code{#:env}, are provided,\n"
+            "they respectively modify the arguments or the environment of the\n"
+            "spawning program.\n\n"
+            "If the keyword arguments @code{#:in}, @code{#:out} or @code{#:err}\n"
+            "are provided, they respectively modify the default input, output\n"
+            "and error file descriptor of the spawning program to these values.")
+#define FUNC_NAME s_scm_spawn_process
+{
+  SCM args, env, in_scm, out_scm, err_scm, use_path;
+  args = SCM_UNDEFINED;
+  env = SCM_UNDEFINED;
+  in_scm = SCM_UNDEFINED;
+  out_scm = SCM_UNDEFINED;
+  err_scm = SCM_UNDEFINED;
+  use_path = SCM_BOOL_T;
+
+  scm_c_bind_keyword_arguments (FUNC_NAME, keyword_args, 0,
+                                k_args, &args,
+                                k_env, &env,
+                                k_in, &in_scm,
+                                k_out, &out_scm,
+                                k_err, &err_scm,
+                                k_use_path, &use_path,
+                                SCM_UNDEFINED);
+
+  int pid = -1;
+  char *exec_file;
+  char **exec_argv;
+  char **exec_env;
+  int in, out, err;
+
+  exec_file = scm_to_locale_string (program);
+
+  if (SCM_UNBNDP (args))
+    {
+      /* We use scm_gc_malloc here because that's the same as what
+         scm_i_allocate_string_pointers would do. */
+      exec_argv = scm_gc_malloc (2 * sizeof (char *),
+                                 "string pointers");
+      exec_argv[0] = exec_file;
+      exec_argv[1] = NULL;
+    }
+  else
+    {
+      exec_argv = scm_i_allocate_string_pointers (args);
+      if (exec_argv[0] == NULL)
+        {
+          free (exec_file);
+          scm_misc_error (FUNC_NAME, "Argument list must not be empty.",
+                          SCM_EOL);
+        }
+    }
+
+  if (SCM_UNBNDP (env))
+    exec_env = environ;
+  else
+    exec_env = scm_i_allocate_string_pointers (env);
+
+  if (SCM_UNBNDP (in_scm))
+    in = SCM_FPORT_FDES (scm_current_input_port ());
+  else
+    in = scm_to_int (in_scm);
+
+  if (SCM_UNBNDP (out_scm))
+    out = SCM_FPORT_FDES (scm_current_output_port ());
+  else
+    out = scm_to_int (out_scm);
+
+  if (SCM_UNBNDP (err_scm))
+    err = SCM_FPORT_FDES (scm_current_error_port ());
+  else
+    err = scm_to_int (err_scm);
+
+  pid = do_spawn (exec_file, exec_argv, exec_env,
+                  in, out, err, scm_to_bool (use_path));
+
+  free (exec_file);
+
+  if (pid == -1)
+    SCM_SYSERROR;
+
+  return scm_from_int (pid);
+}
+#undef FUNC_NAME
+
 #ifdef HAVE_START_CHILD
 static SCM
 scm_piped_process (SCM prog, SCM args, SCM from, SCM to)
@@ -2547,5 +2701,11 @@ scm_init_posix ()
                             "scm_init_popen",
 			    (scm_t_extension_init_func) scm_init_popen,
 			    NULL);
-#endif /* HAVE_START_CHILD */
+#endif /* HAVE_FORK */
+  k_args     = scm_from_utf8_keyword ("args");
+  k_env      = scm_from_utf8_keyword ("env");
+  k_in       = scm_from_utf8_keyword ("in");
+  k_out      = scm_from_utf8_keyword ("out");
+  k_err      = scm_from_utf8_keyword ("err");
+  k_use_path = scm_from_utf8_keyword ("use-path?");
 }
diff --git a/libguile/posix.h b/libguile/posix.h
index 6504eaea8..5eeafd4cb 100644
--- a/libguile/posix.h
+++ b/libguile/posix.h
@@ -69,6 +69,7 @@ SCM_API SCM scm_tmpnam (void);
 SCM_API SCM scm_tmpfile (void);
 SCM_API SCM scm_open_pipe (SCM pipestr, SCM modes);
 SCM_API SCM scm_close_pipe (SCM port);
+SCM_API SCM scm_spawn_process (SCM prog, SCM keyword_args);
 SCM_API SCM scm_system_star (SCM cmds);
 SCM_API SCM scm_utime (SCM object, SCM actime, SCM modtime,
                        SCM actimens, SCM modtimens, SCM flags);

base-commit: 4711d45176e9b75cef43699ed514669276af62fe
-- 
2.38.1






^ permalink raw reply related	[flat|nested] 36+ messages in thread

* bug#52835: [PATCH v8 2/2] Make system* and piped-process internally use spawn.
  2023-01-07 16:07                             ` bug#52835: [PATCH v8 1/2] Add spawn Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
@ 2023-01-07 16:07                               ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  0 siblings, 0 replies; 36+ messages in thread
From: Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language @ 2023-01-07 16:07 UTC (permalink / raw)
  To: Josselin Poiret, Ludovic Courtès; +Cc: 52835

* libguile/posix.c (scm_system_star, scm_piped_process): Use do_spawn.
(start_child): Remove function.

Co-authored-by: Ludovic Courtès <ludo@gnu.org>
---
 libguile/posix.c | 231 ++++++++++++++++-------------------------------
 1 file changed, 77 insertions(+), 154 deletions(-)

diff --git a/libguile/posix.c b/libguile/posix.c
index f79875075..2c6c3c84a 100644
--- a/libguile/posix.c
+++ b/libguile/posix.c
@@ -78,6 +78,7 @@
 #include "threads.h"
 #include "values.h"
 #include "vectors.h"
+#include "verify.h"
 #include "version.h"
 
 #if (SCM_ENABLE_DEPRECATED == 1)
@@ -96,6 +97,13 @@
 # define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
 #endif
 
+#ifndef W_EXITCODE
+/* Macro for constructing a status value.  Found in glibc.  */
+# define W_EXITCODE(ret, sig)   ((ret) << 8 | (sig))
+#endif
+verify (WEXITSTATUS (W_EXITCODE (127, 0)) == 127);
+
+
 #include <signal.h>
 
 #ifdef HAVE_GRP_H
@@ -1309,125 +1317,6 @@ SCM_DEFINE (scm_fork, "primitive-fork", 0, 0, 0,
 #undef FUNC_NAME
 #endif /* HAVE_FORK */
 
-#ifdef HAVE_FORK
-/* 'renumber_file_descriptor' is a helper function for 'start_child'
-   below, and is specialized for that particular environment where it
-   doesn't make sense to report errors via exceptions.  It uses dup(2)
-   to duplicate the file descriptor FD, closes the original FD, and
-   returns the new descriptor.  If dup(2) fails, print an error message
-   to ERR and abort.  */
-static int
-renumber_file_descriptor (int fd, int err)
-{
-  int new_fd;
-
-  do
-    new_fd = dup (fd);
-  while (new_fd == -1 && errno == EINTR);
-
-  if (new_fd == -1)
-    {
-      /* At this point we are in the child process before exec.  We
-         cannot safely raise an exception in this environment.  */
-      const char *msg = strerror (errno);
-      fprintf (fdopen (err, "a"), "start_child: dup failed: %s\n", msg);
-      _exit (127);  /* Use exit status 127, as with other exec errors. */
-    }
-
-  close (fd);
-  return new_fd;
-}
-#endif /* HAVE_FORK */
-
-#ifdef HAVE_FORK
-#define HAVE_START_CHILD 1
-/* Since Guile uses threads, we have to be very careful to avoid calling
-   functions that are not async-signal-safe in the child.  That's why
-   this function is implemented in C.  */
-static pid_t
-start_child (const char *exec_file, char **exec_argv,
-	     int reading, int c2p[2], int writing, int p2c[2],
-             int in, int out, int err)
-{
-  int pid;
-  int max_fd = 1024;
-
-#if defined (HAVE_GETRLIMIT) && defined (RLIMIT_NOFILE)
-  {
-    struct rlimit lim = { 0, 0 };
-    if (getrlimit (RLIMIT_NOFILE, &lim) == 0)
-      max_fd = lim.rlim_cur;
-  }
-#endif
-
-  pid = fork ();
-
-  if (pid != 0)
-    /* The parent, with either and error (pid == -1), or the PID of the
-       child.  Return directly in either case.  */
-    return pid;
-
-  /* The child.  */
-  if (reading)
-    close (c2p[0]);
-  if (writing)
-    close (p2c[1]);
-
-  /* Close all file descriptors in ports inherited from the parent
-     except for in, out, and err.  Heavy-handed, but robust.  */
-  while (max_fd--)
-    if (max_fd != in && max_fd != out && max_fd != err)
-      close (max_fd);
-
-  /* Ignore errors on these open() calls.  */
-  if (in == -1)
-    in = open ("/dev/null", O_RDONLY);
-  if (out == -1)
-    out = open ("/dev/null", O_WRONLY);
-  if (err == -1)
-    err = open ("/dev/null", O_WRONLY);
-
-  if (in > 0)
-    {
-      if (out == 0)
-        out = renumber_file_descriptor (out, err);
-      if (err == 0)
-        err = renumber_file_descriptor (err, err);
-      do dup2 (in, 0); while (errno == EINTR);
-      close (in);
-    }
-  if (out > 1)
-    {
-      if (err == 1)
-        err = renumber_file_descriptor (err, err);
-      do dup2 (out, 1); while (errno == EINTR);
-      if (out > 2)
-        close (out);
-    }
-  if (err > 2)
-    {
-      do dup2 (err, 2); while (errno == EINTR);
-      close (err);
-    }
-
-  execvp (exec_file, exec_argv);
-
-  /* The exec failed!  There is nothing sensible to do.  */
-  {
-    const char *msg = strerror (errno);
-    fprintf (fdopen (2, "a"), "In execvp of %s: %s\n",
-             exec_file, msg);
-  }
-
-  /* Use exit status 127, like shells in this case, as per POSIX
-     <http://pubs.opengroup.org/onlinepubs/007904875/utilities/xcu_chap02.html#tag_02_09_01_01>.  */
-  _exit (127);
-
-  /* Not reached.  */
-  return -1;
-}
-#endif
-
 static pid_t
 do_spawn (char *exec_file, char **exec_argv, char **exec_env,
           int in, int out, int err, int spawnp)
@@ -1580,18 +1469,18 @@ SCM_DEFINE (scm_spawn_process, "spawn", 1, 0, 1,
 }
 #undef FUNC_NAME
 
-#ifdef HAVE_START_CHILD
-static SCM
-scm_piped_process (SCM prog, SCM args, SCM from, SCM to)
+#ifdef HAVE_FORK
+static int
+piped_process (pid_t *pid, SCM prog, SCM args, SCM from, SCM to)
 #define FUNC_NAME "piped-process"
 {
   int reading, writing;
   int c2p[2]; /* Child to parent.  */
   int p2c[2]; /* Parent to child.  */
   int in = -1, out = -1, err = -1;
-  int pid;
   char *exec_file;
   char **exec_argv;
+  char **exec_env = environ;
 
   exec_file = scm_to_locale_string (prog);
   exec_argv = scm_i_allocate_string_pointers (scm_cons (prog, args));
@@ -1624,32 +1513,57 @@ scm_piped_process (SCM prog, SCM args, SCM from, SCM to)
       in = SCM_FPORT_FDES (port);
   }
 
-  pid = start_child (exec_file, exec_argv, reading, c2p, writing, p2c,
-                     in, out, err);
-
-  if (pid == -1)
-    {
-      int errno_save = errno;
-      free (exec_file);
-      if (reading)
-        {
-          close (c2p[0]);
-          close (c2p[1]);
-        }
-      if (writing)
-        {
-          close (p2c[0]);
-          close (p2c[1]);
-        }
-      errno = errno_save;
-      SCM_SYSERROR;
-    }
+  *pid = do_spawn (exec_file, exec_argv, exec_env, in, out, err, 1);
+  int errno_save = (*pid < 0) ? errno : 0;
 
   if (reading)
     close (c2p[1]);
   if (writing)
     close (p2c[0]);
 
+  if (*pid == -1)
+    switch (errno_save)
+      {
+        /* Errors that seemingly come from fork.  */
+      case EAGAIN:
+      case ENOMEM:
+      case ENOSYS:
+        errno = err;
+        free (exec_file);
+        SCM_SYSERROR;
+        break;
+
+      default:    /* ENOENT, etc. */
+        /* Create a dummy process that exits with value 127.  */
+        dprintf (err, "In execvp of %s: %s\n", exec_file,
+                 strerror (errno_save));
+      }
+
+  free (exec_file);
+
+  return errno_save;
+}
+#undef FUNC_NAME
+
+static SCM
+scm_piped_process (SCM prog, SCM args, SCM from, SCM to)
+#define FUNC_NAME "piped-process"
+{
+  pid_t pid;
+
+  (void) piped_process (&pid, prog, args, from, to);
+  if (pid == -1)
+    {
+      /* Create a dummy process that exits with value 127 to mimic the
+         previous fork + exec implementation.  TODO: This is a
+         compatibility shim to remove in the next stable series.  */
+      pid = fork ();
+      if (pid == -1)
+        SCM_SYSERROR;
+      if (pid == 0)
+        _exit (127);
+    }
+
   return scm_from_int (pid);
 }
 #undef FUNC_NAME
@@ -1695,8 +1609,9 @@ SCM_DEFINE (scm_system_star, "system*", 0, 0, 1,
 "Example: (system* \"echo\" \"foo\" \"bar\")")
 #define FUNC_NAME s_scm_system_star
 {
-  SCM prog, pid;
-  int status, wait_result;
+  SCM prog;
+  pid_t pid;
+  int err, status, wait_result;
 
   if (scm_is_null (args))
     SCM_WRONG_NUM_ARGS ();
@@ -1714,17 +1629,27 @@ SCM_DEFINE (scm_system_star, "system*", 0, 0, 1,
                          SCM_UNDEFINED);
 #endif
 
-  pid = scm_piped_process (prog, args, SCM_UNDEFINED, SCM_UNDEFINED);
-  SCM_SYSCALL (wait_result = waitpid (scm_to_int (pid), &status, 0));
-  if (wait_result == -1)
-    SCM_SYSERROR;
+  err = piped_process (&pid, prog, args,
+                       SCM_UNDEFINED, SCM_UNDEFINED);
+  if (err != 0)
+    /* ERR might be ENOENT or similar.  For backward compatibility with
+       the previous implementation based on fork + exec, pretend the
+       child process exited with code 127.  TODO: Remove this
+       compatibility shim in the next stable series.  */
+    status = W_EXITCODE (127, 0);
+  else
+    {
+      SCM_SYSCALL (wait_result = waitpid (pid, &status, 0));
+      if (wait_result == -1)
+        SCM_SYSERROR;
+    }
 
   scm_dynwind_end ();
 
   return scm_from_int (status);
 }
 #undef FUNC_NAME
-#endif /* HAVE_START_CHILD */
+#endif /* HAVE_FORK */
 
 #ifdef HAVE_UNAME
 SCM_DEFINE (scm_uname, "uname", 0, 0, 0,
@@ -2570,13 +2495,13 @@ SCM_DEFINE (scm_gethostname, "gethostname", 0, 0, 0,
 #endif /* HAVE_GETHOSTNAME */
 
 \f
-#ifdef HAVE_START_CHILD
+#ifdef HAVE_FORK
 static void
 scm_init_popen (void)
 {
   scm_c_define_gsubr ("piped-process", 2, 2, 0, scm_piped_process);
 }
-#endif /* HAVE_START_CHILD */
+#endif /* HAVE_FORK */
 
 void
 scm_init_posix ()
@@ -2694,8 +2619,6 @@ scm_init_posix ()
 
 #ifdef HAVE_FORK
   scm_add_feature ("fork");
-#endif	/* HAVE_FORK */
-#ifdef HAVE_START_CHILD
   scm_add_feature ("popen");
   scm_c_register_extension ("libguile-" SCM_EFFECTIVE_VERSION,
                             "scm_init_popen",
-- 
2.38.1






^ permalink raw reply related	[flat|nested] 36+ messages in thread

* bug#52835: [PATCH 0/2] Fix spawning a child not setting standard fds properly
  2023-01-07 16:07                           ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2023-01-07 16:07                             ` bug#52835: [PATCH v8 1/2] Add spawn Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
@ 2023-01-12 22:02                             ` Ludovic Courtès
  1 sibling, 0 replies; 36+ messages in thread
From: Ludovic Courtès @ 2023-01-12 22:02 UTC (permalink / raw)
  To: Josselin Poiret; +Cc: 52835, Timothy Sample

Hi Josselin, and a happy new year full of good hacks!  :-)

Josselin Poiret <dev@jpoiret.xyz> skribis:

> I've done the above by using the C functions to bind keyword arguments,
> and added the #:use-path? keyword argument.  One annoying thing though
> is that since it uses keyword arguments, the first line of the
> documentation generated by SCM_DEFINE only mentions "spawn program
> . keyword_args".

That’s OK.

> I've opted to put it right below primitive-fork, and slightly rewrite
> the part about pipes in primitive-fork's description to also mention
> spawn.  Let me know if the documentation is not descriptive enough.

It looks good to me.

A few suggestions of mine got lost, so I pushed a new ‘wip-posix-spawn’
with additional commits taking those into account and adding tests.  The
changes in this v8.1 are:

  - make 'arguments' positional rather than keyword
  - rename keyword arguments to avoid abbreviations
  - add example in the manual
  - mark 'scm_spawn_process' as SCM_INTERNAL
  - add tests

Because this is now a core binding and no longer in (ice-9 spawn), I
hope ‘spawn’ is not clashing with someone else’s library, though the
worst that could happen is a run-time warning “module X overrides core
binding 'spawn'”.

I’m very pleased with the branch and could finally merge if you agree!
(I’ll put myself as co-author and take the blame for half of the bugs.
:-))

Ah yes, one thing that came to mind: we could change #:input #f to mean
“close file descriptor 0”, and so on.  Let’s first merge this, though.

Thoughts?

Ludo’.





^ permalink raw reply	[flat|nested] 36+ messages in thread

* bug#52835: [PATCH 0/2] Fix spawning a child not setting standard fds properly
  2021-12-27 21:25 bug#52835: [PATCH 0/2] Fix spawning a child not setting standard fds properly Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
                   ` (2 preceding siblings ...)
  2021-12-28 15:40 ` bug#52835: [PATCH 0/2] Fix spawning a child not setting standard fds properly Timothy Sample
@ 2023-01-13  1:11 ` Andrew Whatson via Bug reports for GUILE, GNU's Ubiquitous Extension Language
  2023-01-13 15:20   ` Ludovic Courtès
  3 siblings, 1 reply; 36+ messages in thread
From: Andrew Whatson via Bug reports for GUILE, GNU's Ubiquitous Extension Language @ 2023-01-13  1:11 UTC (permalink / raw)
  To: 52835

Hello Josselin & Ludo,

Thanks for your work on this, posix_spawn is a nice improvement!

My comments on the changes in the wip-posix-spawn branch follow.

In doc/ref/posix.texi:

> @quotation Note
> If you are only looking to fork+exec with some pipes set up, using 
> pipes
> or the more @code{spawn} procedure described below will be more robust
> (in particular in multi-threaded contexts), more portable, and usually
> more efficient.
> @end quotation

Should be "... the more primitive @code{spawn} procedure".

> @deffn {Scheme Procedure} spawn @var{program} @var{arguments} @
>        [#:environment=(environ)] @
>        [#:input=(current-input-port)] @
>        [#:output=(current-output-port)] @
>        [#:error=(current-error-port)] @
>        [#:search-path?=#t]
> Spawn a new child process executing @var{program} with the
> given @var{arguments}, a list of one or more strings, and
> return its PID.  Raise a @code{system-error} exception if
> @var{program} could not be found or could not be executed.

The description of arguments as "a list of one or more strings" is
surprising, I think some users might expect to be able to pass zero
arguments, but we don't explain what the single argument should be.

An earlier version of the docs for this function clarified this with
"(which must include the name of the executable as a first element)".
The manual for exec(3) says "the first argument, by convention, should
point to the filename associated with the file being executed."

Maybe we could clarify in a second paragraph: "By convention, the first
element of @var{arguments} should be the name of the program being
executed.  If calling a C program, for example, this will be passed as
the value for @code{argv[0]}."

In libguile/posix.c, piped_process, around line 1565:

> if (*pid == -1)
>   switch (errno_save)
>     {
>       /* Errors that seemingly come from fork.  */
>     case EAGAIN:
>     case ENOMEM:
>     case ENOSYS:
>       errno = err;
>       free (exec_file);
>       SCM_SYSERROR;
>       break;
> 
>     default:    /* ENOENT, etc. */
>       /* Create a dummy process that exits with value 127.  */
>       dprintf (err, "In execvp of %s: %s\n", exec_file,
>                strerror (errno_save));
>     }

The "dummy process" comment here is misleading, this function simply
returns the error code.  Its callers 'scm_piped_process' and
'scm_system_star' are responsible for simulating exit code 127, and are
already well commented.  Probably just remove this redundant comment.

Otherwise, looks good to me :)

Thanks again!

Cheers,
Andrew






^ permalink raw reply	[flat|nested] 36+ messages in thread

* bug#52835: [PATCH 0/2] Fix spawning a child not setting standard fds properly
  2023-01-13  1:11 ` Andrew Whatson via Bug reports for GUILE, GNU's Ubiquitous Extension Language
@ 2023-01-13 15:20   ` Ludovic Courtès
  0 siblings, 0 replies; 36+ messages in thread
From: Ludovic Courtès @ 2023-01-13 15:20 UTC (permalink / raw)
  To: Andrew Whatson; +Cc: 52835-done, Josselin Poiret

Hi Andrew & Josselin,

Andrew Whatson <whatson@tailcall.au> skribis:

> Thanks for your work on this, posix_spawn is a nice improvement!
>
> My comments on the changes in the wip-posix-spawn branch follow.

As discussed on IRC, I took your comments into account.  I also added a
‘system*’ test based on what Josselin provided at the beginning of this
bug report (let’s not forget we were initially fixing an actual bug :-))
and updated ‘NEWS’:

  527c257d6 Make 'system*' and 'piped-process' internally use 'spawn'.
  551929e4f Add 'spawn'.
  edfca3b7e Update gnulib to 0.1.5414-8204d and add posix_spawn, posix_spawnp.

Let me know if you notice anything fishy!

Thanks a lot, Josselin, for your hard work and for your patience.

Ludo’.





^ permalink raw reply	[flat|nested] 36+ messages in thread

end of thread, other threads:[~2023-01-13 15:20 UTC | newest]

Thread overview: 36+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-27 21:25 bug#52835: [PATCH 0/2] Fix spawning a child not setting standard fds properly Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
2021-12-27 21:35 ` bug#52835: [PATCH 1/2] Fix child spawning closing standard fds prematurely Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
2021-12-27 21:35 ` bug#52835: [PATCH 2/2] Remove unused renumber_file_descriptor Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
2021-12-27 21:49   ` bug#52835: [PATCH v2 " Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
2021-12-28 15:40 ` bug#52835: [PATCH 0/2] Fix spawning a child not setting standard fds properly Timothy Sample
2021-12-28 17:25   ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
2022-02-07 16:55     ` bug#52835: [PATCH v3] Fix child spawning closing standard fds prematurely Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
2022-05-28 12:46       ` bug#52835: [PATCH v4 0/4] Improve safety of start_child and piped-process Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
2022-05-28 12:46         ` bug#52835: [PATCH v4 1/4] Fix child spawning closing standard fds prematurely Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
2022-05-28 12:46         ` bug#52835: [PATCH v4 2/4] Avoid double closes in piped-process Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
2022-05-28 12:46         ` bug#52835: [PATCH v4 3/4] Remove useless closing code in start_child Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
2022-05-28 12:46         ` bug#52835: [PATCH v4 4/4] Make start_child propagate the child errno to the parent Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
2022-09-05  6:48         ` bug#52835: [PATCH v5 0/3] Move spawning procedures to posix_spawn Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
2022-09-05  6:48           ` bug#52835: [PATCH v5 1/3] Update gnulib to 0.1.5414-8204d and add posix_spawn, posix_spawnp Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
2022-09-05  6:48           ` bug#52835: [PATCH v5 2/3] Add spawn* Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
2022-09-05  6:48           ` bug#52835: [PATCH v5 3/3] Move popen and posix procedures to spawn* Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
2022-11-29 15:05             ` bug#52835: [PATCH 0/2] Fix spawning a child not setting standard fds properly Ludovic Courtès
2022-12-11 20:16               ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
2022-12-12 23:49                 ` Ludovic Courtès
2022-12-22 12:49                   ` bug#52835: [PATCH v6 0/3] Move spawning procedures to posix_spawn Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
2022-12-22 12:49                     ` bug#52835: [PATCH v6 1/3] Add spawn* Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
2022-12-22 12:49                     ` bug#52835: [PATCH v6 2/3] Make system* and piped-process internally use spawn Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
2022-12-22 12:49                     ` bug#52835: [PATCH v6 3/3] Move popen and posix procedures to spawn* Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
2022-12-23 10:53                     ` bug#52835: [PATCH 0/2] Fix spawning a child not setting standard fds properly Ludovic Courtès
2022-12-23 17:15                       ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
2022-12-23 17:17                         ` bug#52835: [PATCH v7 1/2] Add spawn* and spawn Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
2022-12-23 17:17                           ` bug#52835: [PATCH v7 2/2] Make system* and piped-process internally use spawn Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
2022-12-25 17:04                             ` bug#52835: [PATCH 0/2] Fix spawning a child not setting standard fds properly Ludovic Courtès
2022-12-25 17:03                           ` Ludovic Courtès
2022-12-25 16:58                         ` Ludovic Courtès
2023-01-07 16:07                           ` Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
2023-01-07 16:07                             ` bug#52835: [PATCH v8 1/2] Add spawn Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
2023-01-07 16:07                               ` bug#52835: [PATCH v8 2/2] Make system* and piped-process internally use spawn Josselin Poiret via Bug reports for GUILE, GNU's Ubiquitous Extension Language
2023-01-12 22:02                             ` bug#52835: [PATCH 0/2] Fix spawning a child not setting standard fds properly Ludovic Courtès
2023-01-13  1:11 ` Andrew Whatson via Bug reports for GUILE, GNU's Ubiquitous Extension Language
2023-01-13 15:20   ` Ludovic Courtès

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).