public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 1/8] posix: Consolidate register-atfork
@ 2021-02-02 15:11 Adhemerval Zanella
  2021-02-02 15:11 ` [PATCH 2/8] linux: Use __libc_single_threaded on fork Adhemerval Zanella
                   ` (7 more replies)
  0 siblings, 8 replies; 38+ messages in thread
From: Adhemerval Zanella @ 2021-02-02 15:11 UTC (permalink / raw)
  To: libc-alpha

Both htl and nptl uses a different data structure to implement atfork
handlers.  The nptl one was refactored by 27761a1042d to use a dynarray
which simplifies the code.

This patch moves the nptl one to be the generic implementation and
replace Hurd linked one.  Different than previous NPTL, Hurd also uses
a global lock, so performance should be similar.

Checked on x86_64-linux-gnu, i686-linux-gnu, and with a build for
i686-gnu.
---
 htl/Makefile                      |   2 +-
 htl/register-atfork.c             | 157 ------------------------------
 include/register-atfork.h         |  63 ++++++++++++
 nptl/Makefile                     |   1 -
 posix/Makefile                    |   2 +-
 {nptl => posix}/register-atfork.c |   8 +-
 sysdeps/mach/hurd/fork.c          |  15 +--
 sysdeps/nptl/fork.h               |  42 +-------
 8 files changed, 73 insertions(+), 217 deletions(-)
 delete mode 100644 htl/register-atfork.c
 create mode 100644 include/register-atfork.h
 rename {nptl => posix}/register-atfork.c (97%)

diff --git a/htl/Makefile b/htl/Makefile
index 38d9f8c590..2dfe19c17f 100644
--- a/htl/Makefile
+++ b/htl/Makefile
@@ -166,7 +166,7 @@ headers :=				\
 
 distribute :=
 
-routines := forward libc_pthread_init alloca_cutoff register-atfork pt-atfork
+routines := forward libc_pthread_init alloca_cutoff pt-atfork
 shared-only-routines = forward
 static-only-routines = pt-atfork
 
diff --git a/htl/register-atfork.c b/htl/register-atfork.c
deleted file mode 100644
index 8be132f981..0000000000
--- a/htl/register-atfork.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/* Atfork handling.  Hurd pthread version.
-   Copyright (C) 2002-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/>.  */
-
-#include <errno.h>
-#include <stdlib.h>
-#include <libc-lock.h>
-#include <fork.h>
-
-struct atfork
-{
-  void (*prepare) (void);
-  void (*parent) (void);
-  void (*child) (void);
-  void *dso_handle;
-  struct atfork *prev;
-  struct atfork *next;
-};
-
-/* TODO: better locking */
-__libc_lock_define_initialized (static, atfork_lock);
-static struct atfork *fork_handlers, *fork_last_handler;
-
-static void
-atfork_pthread_prepare (void)
-{
-  struct atfork *handlers, *last_handler;
-
-  __libc_lock_lock (atfork_lock);
-  handlers = fork_handlers;
-  last_handler = fork_last_handler;
-  __libc_lock_unlock (atfork_lock);
-
-  if (last_handler == NULL)
-    return;
-
-  while (1)
-    {
-      if (last_handler->prepare != NULL)
-	last_handler->prepare ();
-      if (last_handler == handlers)
-	break;
-      last_handler = last_handler->prev;
-    }
-}
-text_set_element (_hurd_atfork_prepare_hook, atfork_pthread_prepare);
-
-static void
-atfork_pthread_parent (void)
-{
-  struct atfork *handlers;
-
-  __libc_lock_lock (atfork_lock);
-  handlers = fork_handlers;
-  __libc_lock_unlock (atfork_lock);
-
-  while (handlers != NULL)
-    {
-      if (handlers->parent != NULL)
-	handlers->parent ();
-      handlers = handlers->next;
-    }
-}
-text_set_element (_hurd_atfork_parent_hook, atfork_pthread_parent);
-
-static void
-atfork_pthread_child (void)
-{
-  struct atfork *handlers;
-
-  __libc_lock_lock (atfork_lock);
-  handlers = fork_handlers;
-  __libc_lock_unlock (atfork_lock);
-
-  while (handlers != NULL)
-    {
-      if (handlers->child != NULL)
-	handlers->child ();
-      handlers = handlers->next;
-    }
-}
-text_set_element (_hurd_atfork_child_hook, atfork_pthread_child);
-
-int
-__register_atfork (void (*prepare) (void),
-		   void (*parent) (void),
-		   void (*child) (void),
-		   void *dso_handle)
-{
-  struct atfork *new = malloc (sizeof (*new));
-  if (new == NULL)
-    return errno;
-
-  new->prepare = prepare;
-  new->parent = parent;
-  new->child = child;
-  new->dso_handle = dso_handle;
-  new->next = NULL;
-
-  __libc_lock_lock (atfork_lock);
-  new->prev = fork_last_handler;
-  if (fork_last_handler != NULL)
-    fork_last_handler->next = new;
-  if (fork_handlers == NULL)
-    fork_handlers = new;
-  fork_last_handler = new;
-  __libc_lock_unlock (atfork_lock);
-
-  return 0;
-}
-libc_hidden_def (__register_atfork)
-
-void
-__unregister_atfork (void *dso_handle)
-{
-  struct atfork **handlers, *prev = NULL, *next;
-  __libc_lock_lock (atfork_lock);
-  handlers = &fork_handlers;
-  while (*handlers != NULL)
-    {
-      if ((*handlers)->dso_handle == dso_handle)
-	{
-	  /* Drop this handler from the list.  */
-	  if (*handlers == fork_last_handler)
-	    {
-	      /* Was last, new last is prev, if any.  */
-	      fork_last_handler = prev;
-	    }
-
-	  next = (*handlers)->next;
-	  if (next != NULL)
-	    next->prev = prev;
-	  *handlers = next;
-	}
-      else
-	{
-	  /* Just proceed to next handler.  */
-	  prev = *handlers;
-	  handlers = &prev->next;
-	}
-    }
-  __libc_lock_unlock (atfork_lock);
-}
diff --git a/include/register-atfork.h b/include/register-atfork.h
new file mode 100644
index 0000000000..fadde14700
--- /dev/null
+++ b/include/register-atfork.h
@@ -0,0 +1,63 @@
+/* Internal pthread_atfork definitions.
+   Copyright (C) 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/>.  */
+
+#ifndef _REGISTER_ATFORK_H
+#define _REGISTER_ATFORK_H
+
+/* Elements of the fork handler lists.  */
+struct fork_handler
+{
+  void (*prepare_handler) (void);
+  void (*parent_handler) (void);
+  void (*child_handler) (void);
+  void *dso_handle;
+};
+
+/* Function to call to unregister fork handlers.  */
+extern void __unregister_atfork (void *dso_handle) attribute_hidden;
+#define UNREGISTER_ATFORK(dso_handle) __unregister_atfork (dso_handle)
+
+enum __run_fork_handler_type
+{
+  atfork_run_prepare,
+  atfork_run_child,
+  atfork_run_parent
+};
+
+/* Run the atfork handlers and lock/unlock the internal lock depending
+   of the WHO argument:
+
+   - atfork_run_prepare: run all the PREPARE_HANDLER in reverse order of
+			 insertion and locks the internal lock.
+   - atfork_run_child: run all the CHILD_HANDLER and unlocks the internal
+		       lock.
+   - atfork_run_parent: run all the PARENT_HANDLER and unlocks the internal
+			lock.
+
+   Perform locking only if DO_LOCKING.  */
+extern void __run_fork_handlers (enum __run_fork_handler_type who,
+				 _Bool do_locking) attribute_hidden;
+
+/* C library side function to register new fork handlers.  */
+extern int __register_atfork (void (*__prepare) (void),
+			      void (*__parent) (void),
+			      void (*__child) (void),
+			      void *dso_handle);
+libc_hidden_proto (__register_atfork)
+
+#endif
diff --git a/nptl/Makefile b/nptl/Makefile
index 0282e07390..85645d9dab 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -68,7 +68,6 @@ routines = \
   pthread_self \
   pthread_setschedparam \
   pthread_sigmask \
-  register-atfork \
 
 shared-only-routines = forward
 static-only-routines = pthread_atfork
diff --git a/posix/Makefile b/posix/Makefile
index 956ef7d397..b7d92a5cc9 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -39,7 +39,7 @@ routines :=								      \
 	times								      \
 	wait waitpid wait3 wait4 waitid					      \
 	alarm sleep pause nanosleep					      \
-	fork vfork _exit						      \
+	fork vfork _exit register-atfork				      \
 	execve fexecve execv execle execl execvp execlp execvpe		      \
 	getpid getppid							      \
 	getuid geteuid getgid getegid getgroups setuid setgid group_member    \
diff --git a/nptl/register-atfork.c b/posix/register-atfork.c
similarity index 97%
rename from nptl/register-atfork.c
rename to posix/register-atfork.c
index 30c16fba40..6fd9e4c56a 100644
--- a/nptl/register-atfork.c
+++ b/posix/register-atfork.c
@@ -16,11 +16,9 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fork.h>
-#include <atomic.h>
+#include <libc-lock.h>
+#include <stdbool.h>
+#include <register-atfork.h>
 
 #define DYNARRAY_ELEMENT           struct fork_handler
 #define DYNARRAY_STRUCT            fork_handler_list
diff --git a/sysdeps/mach/hurd/fork.c b/sysdeps/mach/hurd/fork.c
index fb6c7ee8b7..436d741f32 100644
--- a/sysdeps/mach/hurd/fork.c
+++ b/sysdeps/mach/hurd/fork.c
@@ -29,6 +29,7 @@
 #include <tls.h>
 #include <malloc/malloc-internal.h>
 #include <nss/nss_database.h>
+#include <register-atfork.h>
 
 #undef __fork
 
@@ -36,12 +37,6 @@
 /* Things that want to be locked while forking.  */
 symbol_set_declare (_hurd_fork_locks)
 
-
-/* Application callbacks registered through pthread_atfork.  */
-DEFINE_HOOK (_hurd_atfork_prepare_hook, (void));
-DEFINE_HOOK (_hurd_atfork_child_hook, (void));
-DEFINE_HOOK (_hurd_atfork_parent_hook, (void));
-
 /* Things that want to be called before we fork, to prepare the parent for
    task_create, when the new child task will inherit our address space.  */
 DEFINE_HOOK (_hurd_fork_prepare_hook, (void));
@@ -71,7 +66,7 @@ __fork (void)
   struct hurd_sigstate *volatile ss;
   struct nss_database_data nss_database_data;
 
-  RUN_HOOK (_hurd_atfork_prepare_hook, ());
+  __run_fork_handlers (atfork_run_prepare, true);
 
   ss = _hurd_self_sigstate ();
   __spin_lock (&ss->critical_section_lock);
@@ -723,10 +718,8 @@ __fork (void)
 
   if (!err)
     {
-      if (pid != 0)
-	RUN_HOOK (_hurd_atfork_parent_hook, ());
-      else
-	RUN_HOOK (_hurd_atfork_child_hook, ());
+      __run_fork_handlers (pid == 0 ? atfork_run_child : atfork_run_parent,
+			   true);
     }
 
   return err ? __hurd_fail (err) : pid;
diff --git a/sysdeps/nptl/fork.h b/sysdeps/nptl/fork.h
index 25002287b1..5246754290 100644
--- a/sysdeps/nptl/fork.h
+++ b/sysdeps/nptl/fork.h
@@ -17,50 +17,10 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <lowlevellock.h>
+#include <register-atfork.h>
 
 /* The fork generation counter, defined in libpthread.  */
 extern unsigned long int __fork_generation attribute_hidden;
 
 /* Pointer to the fork generation counter in the thread library.  */
 extern unsigned long int *__fork_generation_pointer attribute_hidden;
-
-/* Elements of the fork handler lists.  */
-struct fork_handler
-{
-  void (*prepare_handler) (void);
-  void (*parent_handler) (void);
-  void (*child_handler) (void);
-  void *dso_handle;
-};
-
-/* Function to call to unregister fork handlers.  */
-extern void __unregister_atfork (void *dso_handle) attribute_hidden;
-#define UNREGISTER_ATFORK(dso_handle) __unregister_atfork (dso_handle)
-
-enum __run_fork_handler_type
-{
-  atfork_run_prepare,
-  atfork_run_child,
-  atfork_run_parent
-};
-
-/* Run the atfork handlers and lock/unlock the internal lock depending
-   of the WHO argument:
-
-   - atfork_run_prepare: run all the PREPARE_HANDLER in reverse order of
-			 insertion and locks the internal lock.
-   - atfork_run_child: run all the CHILD_HANDLER and unlocks the internal
-		       lock.
-   - atfork_run_parent: run all the PARENT_HANDLER and unlocks the internal
-			lock.
-
-   Perform locking only if DO_LOCKING.  */
-extern void __run_fork_handlers (enum __run_fork_handler_type who,
-				 _Bool do_locking) attribute_hidden;
-
-/* C library side function to register new fork handlers.  */
-extern int __register_atfork (void (*__prepare) (void),
-			      void (*__parent) (void),
-			      void (*__child) (void),
-			      void *dso_handle);
-libc_hidden_proto (__register_atfork)
-- 
2.25.1


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

* [PATCH 2/8] linux: Use __libc_single_threaded on fork
  2021-02-02 15:11 [PATCH 1/8] posix: Consolidate register-atfork Adhemerval Zanella
@ 2021-02-02 15:11 ` Adhemerval Zanella
  2021-02-02 15:15   ` Andreas Schwab
  2021-02-02 15:11 ` [PATCH 3/8] posix: Consolidate fork implementation Adhemerval Zanella
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 38+ messages in thread
From: Adhemerval Zanella @ 2021-02-02 15:11 UTC (permalink / raw)
  To: libc-alpha

Checked on x86_64-linux-gnu.
---
 sysdeps/nptl/fork.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/sysdeps/nptl/fork.c b/sysdeps/nptl/fork.c
index 26703d958f..b40b28aa4c 100644
--- a/sysdeps/nptl/fork.c
+++ b/sysdeps/nptl/fork.c
@@ -33,6 +33,7 @@
 #include <futex-internal.h>
 #include <malloc/malloc-internal.h>
 #include <nss/nss_database.h>
+#include <sys/single_threaded.h>
 
 static void
 fresetlockfiles (void)
@@ -54,7 +55,7 @@ __libc_fork (void)
      handlers in the single-thread case, to make fork safer to use in
      signal handlers.  POSIX requires that fork is async-signal-safe,
      but our current fork implementation is not.  */
-  bool multiple_threads = THREAD_GETMEM (THREAD_SELF, header.multiple_threads);
+  bool multiple_threads = __libc_single_threaded;
 
   __run_fork_handlers (atfork_run_prepare, multiple_threads);
 
-- 
2.25.1


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

* [PATCH 3/8] posix: Consolidate fork implementation
  2021-02-02 15:11 [PATCH 1/8] posix: Consolidate register-atfork Adhemerval Zanella
  2021-02-02 15:11 ` [PATCH 2/8] linux: Use __libc_single_threaded on fork Adhemerval Zanella
@ 2021-02-02 15:11 ` Adhemerval Zanella
  2021-03-09 10:58   ` Florian Weimer
  2021-03-11 13:56   ` Andreas Schwab
  2021-02-02 15:11 ` [PATCH 4/8] nptl: Move fork into libc Adhemerval Zanella
                   ` (5 subsequent siblings)
  7 siblings, 2 replies; 38+ messages in thread
From: Adhemerval Zanella @ 2021-02-02 15:11 UTC (permalink / raw)
  To: libc-alpha

The Linux nptl implementation is used as base for generic fork
implementation to handle the internal locks and mutexes.  The
system specific bits are moved a new internal _Fork symbol.

(This new implementation will be used to provide a async-signal-safe
_Fork now that POSIX has clarified that fork might not be
async-signal-safe [1]).

For Hurd it means hat the __nss_database_fork_prepare_parent and
__nss_database_fork_subprocess will be run in a slight different
order.

[1] https://austingroupbugs.net/view.php?id=62
---
 include/unistd.h                      |   2 +
 posix/Makefile                        |   3 +-
 posix/_Fork.c                         |  34 ++++++
 posix/fork.c                          | 106 ++++++++++++++---
 sysdeps/mach/hurd/{fork.c => _Fork.c} |  23 +---
 sysdeps/nptl/_Fork.c                  |  64 +++++++++++
 sysdeps/nptl/fork.c                   | 159 --------------------------
 sysdeps/unix/sysv/linux/arch-fork.h   |   3 +
 8 files changed, 200 insertions(+), 194 deletions(-)
 create mode 100644 posix/_Fork.c
 rename sysdeps/mach/hurd/{fork.c => _Fork.c} (97%)
 create mode 100644 sysdeps/nptl/_Fork.c
 delete mode 100644 sysdeps/nptl/fork.c

diff --git a/include/unistd.h b/include/unistd.h
index 54becbc9eb..5010d75d30 100644
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -135,6 +135,8 @@ libc_hidden_proto (__setresuid)
 libc_hidden_proto (__setresgid)
 extern __pid_t __vfork (void);
 libc_hidden_proto (__vfork)
+extern __pid_t _Fork (void);
+libc_hidden_proto (_Fork);
 extern int __ttyname_r (int __fd, char *__buf, size_t __buflen)
      attribute_hidden;
 extern int __isatty (int __fd) attribute_hidden;
diff --git a/posix/Makefile b/posix/Makefile
index b7d92a5cc9..b79b361fae 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -39,7 +39,7 @@ routines :=								      \
 	times								      \
 	wait waitpid wait3 wait4 waitid					      \
 	alarm sleep pause nanosleep					      \
-	fork vfork _exit register-atfork				      \
+	fork _Fork vfork _exit register-atfork				      \
 	execve fexecve execv execle execl execvp execlp execvpe		      \
 	getpid getppid							      \
 	getuid geteuid getgid getegid getgroups setuid setgid group_member    \
@@ -249,6 +249,7 @@ CFLAGS-execl.os = -fomit-frame-pointer
 CFLAGS-execvp.os = -fomit-frame-pointer
 CFLAGS-execlp.os = -fomit-frame-pointer
 CFLAGS-nanosleep.c += -fexceptions -fasynchronous-unwind-tables
+CFLAGS-fork.c = $(libio-mtsafe)
 
 tstgetopt-ARGS = -a -b -cfoobar --required foobar --optional=bazbug \
 		--none random --col --color --colour
diff --git a/posix/_Fork.c b/posix/_Fork.c
new file mode 100644
index 0000000000..4a998c04f1
--- /dev/null
+++ b/posix/_Fork.c
@@ -0,0 +1,34 @@
+/* _Fork implementation.  Generic version.
+   Copyright (C) 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/>.  */
+
+#include <errno.h>
+#include <unistd.h>
+
+/* Clone the calling process, creating an exact copy.  Return -1 for errors,
+   0 to the new process, and the process ID of the new process to the
+   old process.
+   Different than fork, this functions is marked as async-signal-safe by
+   POSIX (by Austin Group issue 62).  */
+pid_t
+_Fork (void)
+{
+  __set_errno (ENOSYS);
+  return -1;
+}
+libc_hidden_def (_Fork)
+stub_warning (_Fork)
diff --git a/posix/fork.c b/posix/fork.c
index 05bda04ac5..4c9e60f187 100644
--- a/posix/fork.c
+++ b/posix/fork.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991-2021 Free Software Foundation, Inc.
+/* fork - create a child process.
+   Copyright (C) 1991-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
@@ -15,20 +16,99 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <errno.h>
-#include <unistd.h>
+#include <fork.h>
+#include <libio/libioP.h>
+#include <ldsodefs.h>
+#include <malloc/malloc-internal.h>
+#include <nss/nss_database.h>
+#include <register-atfork.h>
+#include <stdio-lock.h>
+#include <sys/single_threaded.h>
 
+static void
+fresetlockfiles (void)
+{
+  _IO_ITER i;
+
+  for (i = _IO_iter_begin(); i != _IO_iter_end(); i = _IO_iter_next(i))
+    if ((_IO_iter_file (i)->_flags & _IO_USER_LOCK) == 0)
+      _IO_lock_init (*((_IO_lock_t *) _IO_iter_file(i)->_lock));
+}
 
-/* Clone the calling process, creating an exact copy.
-   Return -1 for errors, 0 to the new process,
-   and the process ID of the new process to the old process.  */
-int
-__fork (void)
+pid_t
+__libc_fork (void)
 {
-  __set_errno (ENOSYS);
-  return -1;
+  /* Determine if we are running multiple threads.  We skip some fork
+     handlers in the single-thread case, to make fork safer to use in
+     signal handlers.  POSIX requires that fork is async-signal-safe,
+     but our current fork implementation is not.  */
+  bool multiple_threads = __libc_single_threaded;
+
+  __run_fork_handlers (atfork_run_prepare, multiple_threads);
+
+  struct nss_database_data nss_database_data;
+
+  /* If we are not running multiple threads, we do not have to
+     preserve lock state.  If fork runs from a signal handler, only
+     async-signal-safe functions can be used in the child.  These data
+     structures are only used by unsafe functions, so their state does
+     not matter if fork was called from a signal handler.  */
+  if (multiple_threads)
+    {
+      call_function_static_weak (__nss_database_fork_prepare_parent,
+				 &nss_database_data);
+
+      _IO_list_lock ();
+
+      /* Acquire malloc locks.  This needs to come last because fork
+	 handlers may use malloc, and the libio list lock has an
+	 indirect malloc dependency as well (via the getdelim
+	 function).  */
+      call_function_static_weak (__malloc_fork_lock_parent);
+    }
+
+  pid_t pid = _Fork ();
+
+  if (pid == 0)
+    {
+      /* Reset the lock state in the multi-threaded case.  */
+      if (multiple_threads)
+	{
+	  /* Release malloc locks.  */
+	  call_function_static_weak (__malloc_fork_unlock_child);
+
+	  /* Reset the file list.  These are recursive mutexes.  */
+	  fresetlockfiles ();
+
+	  /* Reset locks in the I/O code.  */
+	  _IO_list_resetlock ();
+
+	  call_function_static_weak (__nss_database_fork_subprocess,
+				     &nss_database_data);
+	}
+
+      /* Reset the lock the dynamic loader uses to protect its data.  */
+      __rtld_lock_initialize (GL(dl_load_lock));
+    }
+  else
+    {
+      /* Release acquired locks in the multi-threaded case.  */
+      if (multiple_threads)
+	{
+	  /* Release malloc locks, parent process variant.  */
+	  call_function_static_weak (__malloc_fork_unlock_parent);
+
+	  /* We execute this even if the 'fork' call failed.  */
+	  _IO_list_unlock ();
+	}
+    }
+
+  /* Run the handlers registered for the parent.  */
+  __run_fork_handlers (pid == 0 ? atfork_run_child : atfork_run_parent,
+		       multiple_threads);
+
+  return pid;
 }
+weak_alias (__libc_fork, __fork)
 libc_hidden_def (__fork)
-stub_warning (fork)
-
-weak_alias (__fork, fork)
+weak_alias (__libc_fork, fork)
diff --git a/sysdeps/mach/hurd/fork.c b/sysdeps/mach/hurd/_Fork.c
similarity index 97%
rename from sysdeps/mach/hurd/fork.c
rename to sysdeps/mach/hurd/_Fork.c
index 436d741f32..73c7e746d9 100644
--- a/sysdeps/mach/hurd/fork.c
+++ b/sysdeps/mach/hurd/_Fork.c
@@ -28,8 +28,6 @@
 #include "hurdmalloc.h"		/* XXX */
 #include <tls.h>
 #include <malloc/malloc-internal.h>
-#include <nss/nss_database.h>
-#include <register-atfork.h>
 
 #undef __fork
 
@@ -57,16 +55,13 @@ DEFINE_HOOK (_hurd_fork_parent_hook, (void));
    Return -1 for errors, 0 to the new process,
    and the process ID of the new process to the old process.  */
 pid_t
-__fork (void)
+_Fork (void)
 {
   jmp_buf env;
   pid_t pid;
   size_t i;
   error_t err;
   struct hurd_sigstate *volatile ss;
-  struct nss_database_data nss_database_data;
-
-  __run_fork_handlers (atfork_run_prepare, true);
 
   ss = _hurd_self_sigstate ();
   __spin_lock (&ss->critical_section_lock);
@@ -106,9 +101,6 @@ __fork (void)
       /* Run things that prepare for forking before we create the task.  */
       RUN_HOOK (_hurd_fork_prepare_hook, ());
 
-      call_function_static_weak (__nss_database_fork_prepare_parent,
-				 &nss_database_data);
-
       /* Lock things that want to be locked before we fork.  */
       {
 	void *const *p;
@@ -666,9 +658,6 @@ __fork (void)
       _hurd_malloc_fork_child ();
       call_function_static_weak (__malloc_fork_unlock_child);
 
-      call_function_static_weak (__nss_database_fork_subprocess,
-				 &nss_database_data);
-
       /* Run things that want to run in the child task to set up.  */
       RUN_HOOK (_hurd_fork_child_hook, ());
 
@@ -716,14 +705,6 @@ __fork (void)
 
   _hurd_critical_section_unlock (ss);
 
-  if (!err)
-    {
-      __run_fork_handlers (pid == 0 ? atfork_run_child : atfork_run_parent,
-			   true);
-    }
-
   return err ? __hurd_fail (err) : pid;
 }
-libc_hidden_def (__fork)
-
-weak_alias (__fork, fork)
+libc_hidden_def (_Fork)
diff --git a/sysdeps/nptl/_Fork.c b/sysdeps/nptl/_Fork.c
new file mode 100644
index 0000000000..9c701bc3d7
--- /dev/null
+++ b/sysdeps/nptl/_Fork.c
@@ -0,0 +1,64 @@
+/* _Fork implementation.  Linux version.
+   Copyright (C) 2021 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   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/>.  */
+
+#include <arch-fork.h>
+#include <nptl/pthreadP.h>
+
+/* Pointer to the fork generation counter in the thread library.  */
+extern unsigned long int *__fork_generation_pointer attribute_hidden;
+
+pid_t
+_Fork (void)
+{
+  pid_t pid = arch_fork (&THREAD_SELF->tid);
+  if (pid == 0)
+    {
+      struct pthread *self = THREAD_SELF;
+
+      /* See __pthread_once.  */
+      if (__fork_generation_pointer != NULL)
+	*__fork_generation_pointer += __PTHREAD_ONCE_FORK_GEN_INCR;
+
+      /* Initialize the robust mutex list setting in the kernel which has
+	 been reset during the fork.  We do not check for errors because if
+	 it fails here, it must have failed at process startup as well and
+	 nobody could have used robust mutexes.
+	 Before we do that, we have to clear the list of robust mutexes
+	 because we do not inherit ownership of mutexes from the parent.
+	 We do not have to set self->robust_head.futex_offset since we do
+	 inherit the correct value from the parent.  We do not need to clear
+	 the pending operation because it must have been zero when fork was
+	 called.  */
+#if __PTHREAD_MUTEX_HAVE_PREV
+      self->robust_prev = &self->robust_head;
+#endif
+      self->robust_head.list = &self->robust_head;
+#ifdef SHARED
+      if (__builtin_expect (__libc_pthread_functions_init, 0))
+	PTHFCT_CALL (ptr_set_robust, (self));
+#else
+      extern __typeof (__nptl_set_robust) __nptl_set_robust
+	__attribute__((weak));
+      if (__builtin_expect (__nptl_set_robust != NULL, 0))
+	__nptl_set_robust (self);
+#endif
+    }
+  return pid;
+}
+libc_hidden_def (_Fork)
diff --git a/sysdeps/nptl/fork.c b/sysdeps/nptl/fork.c
deleted file mode 100644
index b40b28aa4c..0000000000
--- a/sysdeps/nptl/fork.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/* Copyright (C) 2002-2021 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
-
-   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/>.  */
-
-#include <assert.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sysdep.h>
-#include <libio/libioP.h>
-#include <tls.h>
-#include <hp-timing.h>
-#include <ldsodefs.h>
-#include <stdio-lock.h>
-#include <atomic.h>
-#include <nptl/pthreadP.h>
-#include <fork.h>
-#include <arch-fork.h>
-#include <futex-internal.h>
-#include <malloc/malloc-internal.h>
-#include <nss/nss_database.h>
-#include <sys/single_threaded.h>
-
-static void
-fresetlockfiles (void)
-{
-  _IO_ITER i;
-
-  for (i = _IO_iter_begin(); i != _IO_iter_end(); i = _IO_iter_next(i))
-    if ((_IO_iter_file (i)->_flags & _IO_USER_LOCK) == 0)
-      _IO_lock_init (*((_IO_lock_t *) _IO_iter_file(i)->_lock));
-}
-
-
-pid_t
-__libc_fork (void)
-{
-  pid_t pid;
-
-  /* Determine if we are running multiple threads.  We skip some fork
-     handlers in the single-thread case, to make fork safer to use in
-     signal handlers.  POSIX requires that fork is async-signal-safe,
-     but our current fork implementation is not.  */
-  bool multiple_threads = __libc_single_threaded;
-
-  __run_fork_handlers (atfork_run_prepare, multiple_threads);
-
-  struct nss_database_data nss_database_data;
-
-  /* If we are not running multiple threads, we do not have to
-     preserve lock state.  If fork runs from a signal handler, only
-     async-signal-safe functions can be used in the child.  These data
-     structures are only used by unsafe functions, so their state does
-     not matter if fork was called from a signal handler.  */
-  if (multiple_threads)
-    {
-      call_function_static_weak (__nss_database_fork_prepare_parent,
-				 &nss_database_data);
-
-      _IO_list_lock ();
-
-      /* Acquire malloc locks.  This needs to come last because fork
-	 handlers may use malloc, and the libio list lock has an
-	 indirect malloc dependency as well (via the getdelim
-	 function).  */
-      call_function_static_weak (__malloc_fork_lock_parent);
-    }
-
-  pid = arch_fork (&THREAD_SELF->tid);
-
-  if (pid == 0)
-    {
-      struct pthread *self = THREAD_SELF;
-
-      /* See __pthread_once.  */
-      if (__fork_generation_pointer != NULL)
-	*__fork_generation_pointer += __PTHREAD_ONCE_FORK_GEN_INCR;
-
-      /* Initialize the robust mutex list setting in the kernel which has
-	 been reset during the fork.  We do not check for errors because if
-	 it fails here, it must have failed at process startup as well and
-	 nobody could have used robust mutexes.
-	 Before we do that, we have to clear the list of robust mutexes
-	 because we do not inherit ownership of mutexes from the parent.
-	 We do not have to set self->robust_head.futex_offset since we do
-	 inherit the correct value from the parent.  We do not need to clear
-	 the pending operation because it must have been zero when fork was
-	 called.  */
-#if __PTHREAD_MUTEX_HAVE_PREV
-      self->robust_prev = &self->robust_head;
-#endif
-      self->robust_head.list = &self->robust_head;
-#ifdef SHARED
-      if (__builtin_expect (__libc_pthread_functions_init, 0))
-	PTHFCT_CALL (ptr_set_robust, (self));
-#else
-      extern __typeof (__nptl_set_robust) __nptl_set_robust
-	__attribute__((weak));
-      if (__builtin_expect (__nptl_set_robust != NULL, 0))
-	__nptl_set_robust (self);
-#endif
-
-      /* Reset the lock state in the multi-threaded case.  */
-      if (multiple_threads)
-	{
-	  /* Release malloc locks.  */
-	  call_function_static_weak (__malloc_fork_unlock_child);
-
-	  /* Reset the file list.  These are recursive mutexes.  */
-	  fresetlockfiles ();
-
-	  /* Reset locks in the I/O code.  */
-	  _IO_list_resetlock ();
-
-	  call_function_static_weak (__nss_database_fork_subprocess,
-				     &nss_database_data);
-	}
-
-      /* Reset the lock the dynamic loader uses to protect its data.  */
-      __rtld_lock_initialize (GL(dl_load_lock));
-
-      /* Run the handlers registered for the child.  */
-      __run_fork_handlers (atfork_run_child, multiple_threads);
-    }
-  else
-    {
-      /* Release acquired locks in the multi-threaded case.  */
-      if (multiple_threads)
-	{
-	  /* Release malloc locks, parent process variant.  */
-	  call_function_static_weak (__malloc_fork_unlock_parent);
-
-	  /* We execute this even if the 'fork' call failed.  */
-	  _IO_list_unlock ();
-	}
-
-      /* Run the handlers registered for the parent.  */
-      __run_fork_handlers (atfork_run_parent, multiple_threads);
-    }
-
-  return pid;
-}
-weak_alias (__libc_fork, __fork)
-libc_hidden_def (__fork)
-weak_alias (__libc_fork, fork)
diff --git a/sysdeps/unix/sysv/linux/arch-fork.h b/sysdeps/unix/sysv/linux/arch-fork.h
index 35d9397ff8..b846da08f9 100644
--- a/sysdeps/unix/sysv/linux/arch-fork.h
+++ b/sysdeps/unix/sysv/linux/arch-fork.h
@@ -19,6 +19,9 @@
 #ifndef __ARCH_FORK_H
 #define __ARCH_FORK_H
 
+#include <sysdep.h>
+#include <sched.h>
+#include <signal.h>
 #include <unistd.h>
 
 /* Call the clone syscall with fork semantic.  The CTID address is used
-- 
2.25.1


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

* [PATCH 4/8] nptl: Move fork into libc
  2021-02-02 15:11 [PATCH 1/8] posix: Consolidate register-atfork Adhemerval Zanella
  2021-02-02 15:11 ` [PATCH 2/8] linux: Use __libc_single_threaded on fork Adhemerval Zanella
  2021-02-02 15:11 ` [PATCH 3/8] posix: Consolidate fork implementation Adhemerval Zanella
@ 2021-02-02 15:11 ` Adhemerval Zanella
  2021-03-08 13:42   ` Florian Weimer
  2021-02-02 15:11 ` [PATCH 5/8] posix: Do not clobber errno by atfork handlers Adhemerval Zanella
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 38+ messages in thread
From: Adhemerval Zanella @ 2021-02-02 15:11 UTC (permalink / raw)
  To: libc-alpha

This is part of the libpthread removal project:

   <https://sourceware.org/ml/libc-alpha/2019-10/msg00080.html>

Checked on x86_64-linux-gnu.
---
 nptl/Makefile                                 |  2 +-
 nptl/pt-fork.c                                | 49 -------------------
 .../sysv/linux/aarch64/libpthread.abilist     |  2 -
 .../unix/sysv/linux/alpha/libpthread.abilist  |  2 -
 .../unix/sysv/linux/arm/be/libpthread.abilist |  2 -
 .../unix/sysv/linux/arm/le/libpthread.abilist |  2 -
 .../unix/sysv/linux/hppa/libpthread.abilist   |  2 -
 .../unix/sysv/linux/i386/libpthread.abilist   |  2 -
 .../unix/sysv/linux/ia64/libpthread.abilist   |  2 -
 .../linux/m68k/coldfire/libpthread.abilist    |  2 -
 .../sysv/linux/m68k/m680x0/libpthread.abilist |  2 -
 .../linux/microblaze/be/libpthread.abilist    |  2 -
 .../linux/microblaze/le/libpthread.abilist    |  2 -
 .../sysv/linux/mips/mips32/libpthread.abilist |  2 -
 .../sysv/linux/mips/mips64/libpthread.abilist |  2 -
 .../unix/sysv/linux/nios2/libpthread.abilist  |  2 -
 .../powerpc/powerpc32/libpthread.abilist      |  2 -
 .../powerpc/powerpc64/be/libpthread.abilist   |  2 -
 .../powerpc/powerpc64/le/libpthread.abilist   |  2 -
 .../linux/s390/s390-32/libpthread.abilist     |  2 -
 .../linux/s390/s390-64/libpthread.abilist     |  2 -
 .../unix/sysv/linux/sh/be/libpthread.abilist  |  2 -
 .../unix/sysv/linux/sh/le/libpthread.abilist  |  2 -
 .../linux/sparc/sparc32/libpthread.abilist    |  2 -
 .../linux/sparc/sparc64/libpthread.abilist    |  2 -
 .../sysv/linux/x86_64/64/libpthread.abilist   |  2 -
 .../sysv/linux/x86_64/x32/libpthread.abilist  |  2 -
 27 files changed, 1 insertion(+), 100 deletions(-)
 delete mode 100644 nptl/pt-fork.c

diff --git a/nptl/Makefile b/nptl/Makefile
index 85645d9dab..3a8762d7b6 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -146,7 +146,7 @@ libpthread-routines = nptl-init nptlfreeres vars events version pt-interp \
 		      pt-longjmp pt-cleanup\
 		      cancellation \
 		      lowlevellock \
-		      pt-fork pt-fcntl \
+		      pt-fcntl \
 		      $(pthread-compat-wrappers) \
 		      pt-raise pt-system \
 		      flockfile ftrylockfile funlockfile \
diff --git a/nptl/pt-fork.c b/nptl/pt-fork.c
deleted file mode 100644
index 5d694cdbbe..0000000000
--- a/nptl/pt-fork.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/* ABI compatibility for 'fork' symbol in libpthread ABI.
-   Copyright (C) 2002-2021 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
-
-   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/>.  */
-
-#include <unistd.h>
-#include <shlib-compat.h>
-
-/* libpthread once had its own fork, though there was no apparent reason
-   for it.  There is no use in having a separate symbol in libpthread, but
-   the historical ABI requires it.  For static linking, there is no need to
-   provide anything here--the libc version will be linked in.  For shared
-   library ABI compatibility, there must be __fork and fork symbols in
-   libpthread.so.
-
-   With an IFUNC resolver, it would be possible to avoid the
-   indirection, but the IFUNC resolver might run before the
-   __libc_fork symbol has been relocated, in which case the IFUNC
-   resolver would not be able to provide the correct address.  */
-
-#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_22)
-
-static pid_t __attribute__ ((used))
-fork_compat (void)
-{
-  return __libc_fork ();
-}
-
-strong_alias (fork_compat, fork_alias)
-compat_symbol (libpthread, fork_alias, fork, GLIBC_2_0);
-
-strong_alias (fork_compat, __fork_alias)
-compat_symbol (libpthread, __fork_alias, __fork, GLIBC_2_0);
-
-#endif
diff --git a/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist b/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist
index c6b4ea2dc1..336ee51e7e 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist
@@ -5,7 +5,6 @@ GLIBC_2.17 __close F
 GLIBC_2.17 __connect F
 GLIBC_2.17 __errno_location F
 GLIBC_2.17 __fcntl F
-GLIBC_2.17 __fork F
 GLIBC_2.17 __h_errno_location F
 GLIBC_2.17 __libc_allocate_rtsig F
 GLIBC_2.17 __libc_current_sigrtmax F
@@ -54,7 +53,6 @@ GLIBC_2.17 close F
 GLIBC_2.17 connect F
 GLIBC_2.17 fcntl F
 GLIBC_2.17 flockfile F
-GLIBC_2.17 fork F
 GLIBC_2.17 fsync F
 GLIBC_2.17 ftrylockfile F
 GLIBC_2.17 funlockfile F
diff --git a/sysdeps/unix/sysv/linux/alpha/libpthread.abilist b/sysdeps/unix/sysv/linux/alpha/libpthread.abilist
index 390b6384d0..5c87b9baa0 100644
--- a/sysdeps/unix/sysv/linux/alpha/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libpthread.abilist
@@ -5,7 +5,6 @@ GLIBC_2.0 __close F
 GLIBC_2.0 __connect F
 GLIBC_2.0 __errno_location F
 GLIBC_2.0 __fcntl F
-GLIBC_2.0 __fork F
 GLIBC_2.0 __h_errno_location F
 GLIBC_2.0 __lseek F
 GLIBC_2.0 __open F
@@ -34,7 +33,6 @@ GLIBC_2.0 close F
 GLIBC_2.0 connect F
 GLIBC_2.0 fcntl F
 GLIBC_2.0 flockfile F
-GLIBC_2.0 fork F
 GLIBC_2.0 fsync F
 GLIBC_2.0 ftrylockfile F
 GLIBC_2.0 funlockfile F
diff --git a/sysdeps/unix/sysv/linux/arm/be/libpthread.abilist b/sysdeps/unix/sysv/linux/arm/be/libpthread.abilist
index b6c26c7a50..b0bb1d0e01 100644
--- a/sysdeps/unix/sysv/linux/arm/be/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/arm/be/libpthread.abilist
@@ -40,7 +40,6 @@ GLIBC_2.4 __close F
 GLIBC_2.4 __connect F
 GLIBC_2.4 __errno_location F
 GLIBC_2.4 __fcntl F
-GLIBC_2.4 __fork F
 GLIBC_2.4 __h_errno_location F
 GLIBC_2.4 __libc_allocate_rtsig F
 GLIBC_2.4 __libc_current_sigrtmax F
@@ -89,7 +88,6 @@ GLIBC_2.4 close F
 GLIBC_2.4 connect F
 GLIBC_2.4 fcntl F
 GLIBC_2.4 flockfile F
-GLIBC_2.4 fork F
 GLIBC_2.4 fsync F
 GLIBC_2.4 ftrylockfile F
 GLIBC_2.4 funlockfile F
diff --git a/sysdeps/unix/sysv/linux/arm/le/libpthread.abilist b/sysdeps/unix/sysv/linux/arm/le/libpthread.abilist
index b6c26c7a50..b0bb1d0e01 100644
--- a/sysdeps/unix/sysv/linux/arm/le/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/arm/le/libpthread.abilist
@@ -40,7 +40,6 @@ GLIBC_2.4 __close F
 GLIBC_2.4 __connect F
 GLIBC_2.4 __errno_location F
 GLIBC_2.4 __fcntl F
-GLIBC_2.4 __fork F
 GLIBC_2.4 __h_errno_location F
 GLIBC_2.4 __libc_allocate_rtsig F
 GLIBC_2.4 __libc_current_sigrtmax F
@@ -89,7 +88,6 @@ GLIBC_2.4 close F
 GLIBC_2.4 connect F
 GLIBC_2.4 fcntl F
 GLIBC_2.4 flockfile F
-GLIBC_2.4 fork F
 GLIBC_2.4 fsync F
 GLIBC_2.4 ftrylockfile F
 GLIBC_2.4 funlockfile F
diff --git a/sysdeps/unix/sysv/linux/hppa/libpthread.abilist b/sysdeps/unix/sysv/linux/hppa/libpthread.abilist
index cabc5af858..a7bb15be58 100644
--- a/sysdeps/unix/sysv/linux/hppa/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libpthread.abilist
@@ -13,7 +13,6 @@ GLIBC_2.2 __close F
 GLIBC_2.2 __connect F
 GLIBC_2.2 __errno_location F
 GLIBC_2.2 __fcntl F
-GLIBC_2.2 __fork F
 GLIBC_2.2 __h_errno_location F
 GLIBC_2.2 __libc_allocate_rtsig F
 GLIBC_2.2 __libc_current_sigrtmax F
@@ -56,7 +55,6 @@ GLIBC_2.2 close F
 GLIBC_2.2 connect F
 GLIBC_2.2 fcntl F
 GLIBC_2.2 flockfile F
-GLIBC_2.2 fork F
 GLIBC_2.2 fsync F
 GLIBC_2.2 ftrylockfile F
 GLIBC_2.2 funlockfile F
diff --git a/sysdeps/unix/sysv/linux/i386/libpthread.abilist b/sysdeps/unix/sysv/linux/i386/libpthread.abilist
index 18177307c8..017a9d9a86 100644
--- a/sysdeps/unix/sysv/linux/i386/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libpthread.abilist
@@ -5,7 +5,6 @@ GLIBC_2.0 __close F
 GLIBC_2.0 __connect F
 GLIBC_2.0 __errno_location F
 GLIBC_2.0 __fcntl F
-GLIBC_2.0 __fork F
 GLIBC_2.0 __h_errno_location F
 GLIBC_2.0 __lseek F
 GLIBC_2.0 __open F
@@ -34,7 +33,6 @@ GLIBC_2.0 close F
 GLIBC_2.0 connect F
 GLIBC_2.0 fcntl F
 GLIBC_2.0 flockfile F
-GLIBC_2.0 fork F
 GLIBC_2.0 fsync F
 GLIBC_2.0 ftrylockfile F
 GLIBC_2.0 funlockfile F
diff --git a/sysdeps/unix/sysv/linux/ia64/libpthread.abilist b/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
index 335f486cb5..6fb2e05072 100644
--- a/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
@@ -13,7 +13,6 @@ GLIBC_2.2 __close F
 GLIBC_2.2 __connect F
 GLIBC_2.2 __errno_location F
 GLIBC_2.2 __fcntl F
-GLIBC_2.2 __fork F
 GLIBC_2.2 __h_errno_location F
 GLIBC_2.2 __libc_allocate_rtsig F
 GLIBC_2.2 __libc_current_sigrtmax F
@@ -56,7 +55,6 @@ GLIBC_2.2 close F
 GLIBC_2.2 connect F
 GLIBC_2.2 fcntl F
 GLIBC_2.2 flockfile F
-GLIBC_2.2 fork F
 GLIBC_2.2 fsync F
 GLIBC_2.2 ftrylockfile F
 GLIBC_2.2 funlockfile F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
index b6c26c7a50..b0bb1d0e01 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
@@ -40,7 +40,6 @@ GLIBC_2.4 __close F
 GLIBC_2.4 __connect F
 GLIBC_2.4 __errno_location F
 GLIBC_2.4 __fcntl F
-GLIBC_2.4 __fork F
 GLIBC_2.4 __h_errno_location F
 GLIBC_2.4 __libc_allocate_rtsig F
 GLIBC_2.4 __libc_current_sigrtmax F
@@ -89,7 +88,6 @@ GLIBC_2.4 close F
 GLIBC_2.4 connect F
 GLIBC_2.4 fcntl F
 GLIBC_2.4 flockfile F
-GLIBC_2.4 fork F
 GLIBC_2.4 fsync F
 GLIBC_2.4 ftrylockfile F
 GLIBC_2.4 funlockfile F
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
index 18177307c8..017a9d9a86 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
@@ -5,7 +5,6 @@ GLIBC_2.0 __close F
 GLIBC_2.0 __connect F
 GLIBC_2.0 __errno_location F
 GLIBC_2.0 __fcntl F
-GLIBC_2.0 __fork F
 GLIBC_2.0 __h_errno_location F
 GLIBC_2.0 __lseek F
 GLIBC_2.0 __open F
@@ -34,7 +33,6 @@ GLIBC_2.0 close F
 GLIBC_2.0 connect F
 GLIBC_2.0 fcntl F
 GLIBC_2.0 flockfile F
-GLIBC_2.0 fork F
 GLIBC_2.0 fsync F
 GLIBC_2.0 ftrylockfile F
 GLIBC_2.0 funlockfile F
diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libpthread.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libpthread.abilist
index 60397187b6..9356f6183a 100644
--- a/sysdeps/unix/sysv/linux/microblaze/be/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/be/libpthread.abilist
@@ -5,7 +5,6 @@ GLIBC_2.18 __close F
 GLIBC_2.18 __connect F
 GLIBC_2.18 __errno_location F
 GLIBC_2.18 __fcntl F
-GLIBC_2.18 __fork F
 GLIBC_2.18 __h_errno_location F
 GLIBC_2.18 __libc_allocate_rtsig F
 GLIBC_2.18 __libc_current_sigrtmax F
@@ -54,7 +53,6 @@ GLIBC_2.18 close F
 GLIBC_2.18 connect F
 GLIBC_2.18 fcntl F
 GLIBC_2.18 flockfile F
-GLIBC_2.18 fork F
 GLIBC_2.18 fsync F
 GLIBC_2.18 ftrylockfile F
 GLIBC_2.18 funlockfile F
diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libpthread.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libpthread.abilist
index 60397187b6..9356f6183a 100644
--- a/sysdeps/unix/sysv/linux/microblaze/le/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/le/libpthread.abilist
@@ -5,7 +5,6 @@ GLIBC_2.18 __close F
 GLIBC_2.18 __connect F
 GLIBC_2.18 __errno_location F
 GLIBC_2.18 __fcntl F
-GLIBC_2.18 __fork F
 GLIBC_2.18 __h_errno_location F
 GLIBC_2.18 __libc_allocate_rtsig F
 GLIBC_2.18 __libc_current_sigrtmax F
@@ -54,7 +53,6 @@ GLIBC_2.18 close F
 GLIBC_2.18 connect F
 GLIBC_2.18 fcntl F
 GLIBC_2.18 flockfile F
-GLIBC_2.18 fork F
 GLIBC_2.18 fsync F
 GLIBC_2.18 ftrylockfile F
 GLIBC_2.18 funlockfile F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist b/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
index b35d7f19ca..7aff4d018b 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
@@ -5,7 +5,6 @@ GLIBC_2.0 __close F
 GLIBC_2.0 __connect F
 GLIBC_2.0 __errno_location F
 GLIBC_2.0 __fcntl F
-GLIBC_2.0 __fork F
 GLIBC_2.0 __h_errno_location F
 GLIBC_2.0 __lseek F
 GLIBC_2.0 __open F
@@ -34,7 +33,6 @@ GLIBC_2.0 close F
 GLIBC_2.0 connect F
 GLIBC_2.0 fcntl F
 GLIBC_2.0 flockfile F
-GLIBC_2.0 fork F
 GLIBC_2.0 fsync F
 GLIBC_2.0 ftrylockfile F
 GLIBC_2.0 funlockfile F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist b/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
index b35d7f19ca..7aff4d018b 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
@@ -5,7 +5,6 @@ GLIBC_2.0 __close F
 GLIBC_2.0 __connect F
 GLIBC_2.0 __errno_location F
 GLIBC_2.0 __fcntl F
-GLIBC_2.0 __fork F
 GLIBC_2.0 __h_errno_location F
 GLIBC_2.0 __lseek F
 GLIBC_2.0 __open F
@@ -34,7 +33,6 @@ GLIBC_2.0 close F
 GLIBC_2.0 connect F
 GLIBC_2.0 fcntl F
 GLIBC_2.0 flockfile F
-GLIBC_2.0 fork F
 GLIBC_2.0 fsync F
 GLIBC_2.0 ftrylockfile F
 GLIBC_2.0 funlockfile F
diff --git a/sysdeps/unix/sysv/linux/nios2/libpthread.abilist b/sysdeps/unix/sysv/linux/nios2/libpthread.abilist
index 924ad6e451..73b4dfbd8e 100644
--- a/sysdeps/unix/sysv/linux/nios2/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libpthread.abilist
@@ -5,7 +5,6 @@ GLIBC_2.21 __close F
 GLIBC_2.21 __connect F
 GLIBC_2.21 __errno_location F
 GLIBC_2.21 __fcntl F
-GLIBC_2.21 __fork F
 GLIBC_2.21 __h_errno_location F
 GLIBC_2.21 __libc_allocate_rtsig F
 GLIBC_2.21 __libc_current_sigrtmax F
@@ -54,7 +53,6 @@ GLIBC_2.21 close F
 GLIBC_2.21 connect F
 GLIBC_2.21 fcntl F
 GLIBC_2.21 flockfile F
-GLIBC_2.21 fork F
 GLIBC_2.21 fsync F
 GLIBC_2.21 ftrylockfile F
 GLIBC_2.21 funlockfile F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
index 13b41dafb6..0c68fb1b7c 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
@@ -5,7 +5,6 @@ GLIBC_2.0 __close F
 GLIBC_2.0 __connect F
 GLIBC_2.0 __errno_location F
 GLIBC_2.0 __fcntl F
-GLIBC_2.0 __fork F
 GLIBC_2.0 __h_errno_location F
 GLIBC_2.0 __lseek F
 GLIBC_2.0 __open F
@@ -34,7 +33,6 @@ GLIBC_2.0 close F
 GLIBC_2.0 connect F
 GLIBC_2.0 fcntl F
 GLIBC_2.0 flockfile F
-GLIBC_2.0 fork F
 GLIBC_2.0 fsync F
 GLIBC_2.0 ftrylockfile F
 GLIBC_2.0 funlockfile F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
index e9477a3584..c7f6167250 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
@@ -34,7 +34,6 @@ GLIBC_2.3 __close F
 GLIBC_2.3 __connect F
 GLIBC_2.3 __errno_location F
 GLIBC_2.3 __fcntl F
-GLIBC_2.3 __fork F
 GLIBC_2.3 __h_errno_location F
 GLIBC_2.3 __libc_allocate_rtsig F
 GLIBC_2.3 __libc_current_sigrtmax F
@@ -77,7 +76,6 @@ GLIBC_2.3 close F
 GLIBC_2.3 connect F
 GLIBC_2.3 fcntl F
 GLIBC_2.3 flockfile F
-GLIBC_2.3 fork F
 GLIBC_2.3 fsync F
 GLIBC_2.3 ftrylockfile F
 GLIBC_2.3 funlockfile F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
index c6b4ea2dc1..336ee51e7e 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
@@ -5,7 +5,6 @@ GLIBC_2.17 __close F
 GLIBC_2.17 __connect F
 GLIBC_2.17 __errno_location F
 GLIBC_2.17 __fcntl F
-GLIBC_2.17 __fork F
 GLIBC_2.17 __h_errno_location F
 GLIBC_2.17 __libc_allocate_rtsig F
 GLIBC_2.17 __libc_current_sigrtmax F
@@ -54,7 +53,6 @@ GLIBC_2.17 close F
 GLIBC_2.17 connect F
 GLIBC_2.17 fcntl F
 GLIBC_2.17 flockfile F
-GLIBC_2.17 fork F
 GLIBC_2.17 fsync F
 GLIBC_2.17 ftrylockfile F
 GLIBC_2.17 funlockfile F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
index 0a60f1cca2..a198e22445 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
@@ -5,7 +5,6 @@ GLIBC_2.0 __close F
 GLIBC_2.0 __connect F
 GLIBC_2.0 __errno_location F
 GLIBC_2.0 __fcntl F
-GLIBC_2.0 __fork F
 GLIBC_2.0 __h_errno_location F
 GLIBC_2.0 __lseek F
 GLIBC_2.0 __open F
@@ -34,7 +33,6 @@ GLIBC_2.0 close F
 GLIBC_2.0 connect F
 GLIBC_2.0 fcntl F
 GLIBC_2.0 flockfile F
-GLIBC_2.0 fork F
 GLIBC_2.0 fsync F
 GLIBC_2.0 ftrylockfile F
 GLIBC_2.0 funlockfile F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
index 0e99688824..6d166d5f97 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
@@ -15,7 +15,6 @@ GLIBC_2.2 __close F
 GLIBC_2.2 __connect F
 GLIBC_2.2 __errno_location F
 GLIBC_2.2 __fcntl F
-GLIBC_2.2 __fork F
 GLIBC_2.2 __h_errno_location F
 GLIBC_2.2 __libc_allocate_rtsig F
 GLIBC_2.2 __libc_current_sigrtmax F
@@ -58,7 +57,6 @@ GLIBC_2.2 close F
 GLIBC_2.2 connect F
 GLIBC_2.2 fcntl F
 GLIBC_2.2 flockfile F
-GLIBC_2.2 fork F
 GLIBC_2.2 fsync F
 GLIBC_2.2 ftrylockfile F
 GLIBC_2.2 funlockfile F
diff --git a/sysdeps/unix/sysv/linux/sh/be/libpthread.abilist b/sysdeps/unix/sysv/linux/sh/be/libpthread.abilist
index cabc5af858..a7bb15be58 100644
--- a/sysdeps/unix/sysv/linux/sh/be/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/sh/be/libpthread.abilist
@@ -13,7 +13,6 @@ GLIBC_2.2 __close F
 GLIBC_2.2 __connect F
 GLIBC_2.2 __errno_location F
 GLIBC_2.2 __fcntl F
-GLIBC_2.2 __fork F
 GLIBC_2.2 __h_errno_location F
 GLIBC_2.2 __libc_allocate_rtsig F
 GLIBC_2.2 __libc_current_sigrtmax F
@@ -56,7 +55,6 @@ GLIBC_2.2 close F
 GLIBC_2.2 connect F
 GLIBC_2.2 fcntl F
 GLIBC_2.2 flockfile F
-GLIBC_2.2 fork F
 GLIBC_2.2 fsync F
 GLIBC_2.2 ftrylockfile F
 GLIBC_2.2 funlockfile F
diff --git a/sysdeps/unix/sysv/linux/sh/le/libpthread.abilist b/sysdeps/unix/sysv/linux/sh/le/libpthread.abilist
index cabc5af858..a7bb15be58 100644
--- a/sysdeps/unix/sysv/linux/sh/le/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/sh/le/libpthread.abilist
@@ -13,7 +13,6 @@ GLIBC_2.2 __close F
 GLIBC_2.2 __connect F
 GLIBC_2.2 __errno_location F
 GLIBC_2.2 __fcntl F
-GLIBC_2.2 __fork F
 GLIBC_2.2 __h_errno_location F
 GLIBC_2.2 __libc_allocate_rtsig F
 GLIBC_2.2 __libc_current_sigrtmax F
@@ -56,7 +55,6 @@ GLIBC_2.2 close F
 GLIBC_2.2 connect F
 GLIBC_2.2 fcntl F
 GLIBC_2.2 flockfile F
-GLIBC_2.2 fork F
 GLIBC_2.2 fsync F
 GLIBC_2.2 ftrylockfile F
 GLIBC_2.2 funlockfile F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
index 390b6384d0..5c87b9baa0 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
@@ -5,7 +5,6 @@ GLIBC_2.0 __close F
 GLIBC_2.0 __connect F
 GLIBC_2.0 __errno_location F
 GLIBC_2.0 __fcntl F
-GLIBC_2.0 __fork F
 GLIBC_2.0 __h_errno_location F
 GLIBC_2.0 __lseek F
 GLIBC_2.0 __open F
@@ -34,7 +33,6 @@ GLIBC_2.0 close F
 GLIBC_2.0 connect F
 GLIBC_2.0 fcntl F
 GLIBC_2.0 flockfile F
-GLIBC_2.0 fork F
 GLIBC_2.0 fsync F
 GLIBC_2.0 ftrylockfile F
 GLIBC_2.0 funlockfile F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
index 335f486cb5..6fb2e05072 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
@@ -13,7 +13,6 @@ GLIBC_2.2 __close F
 GLIBC_2.2 __connect F
 GLIBC_2.2 __errno_location F
 GLIBC_2.2 __fcntl F
-GLIBC_2.2 __fork F
 GLIBC_2.2 __h_errno_location F
 GLIBC_2.2 __libc_allocate_rtsig F
 GLIBC_2.2 __libc_current_sigrtmax F
@@ -56,7 +55,6 @@ GLIBC_2.2 close F
 GLIBC_2.2 connect F
 GLIBC_2.2 fcntl F
 GLIBC_2.2 flockfile F
-GLIBC_2.2 fork F
 GLIBC_2.2 fsync F
 GLIBC_2.2 ftrylockfile F
 GLIBC_2.2 funlockfile F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
index 971269d2ef..f85ab1d3cd 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
@@ -13,7 +13,6 @@ GLIBC_2.2.5 __close F
 GLIBC_2.2.5 __connect F
 GLIBC_2.2.5 __errno_location F
 GLIBC_2.2.5 __fcntl F
-GLIBC_2.2.5 __fork F
 GLIBC_2.2.5 __h_errno_location F
 GLIBC_2.2.5 __libc_allocate_rtsig F
 GLIBC_2.2.5 __libc_current_sigrtmax F
@@ -56,7 +55,6 @@ GLIBC_2.2.5 close F
 GLIBC_2.2.5 connect F
 GLIBC_2.2.5 fcntl F
 GLIBC_2.2.5 flockfile F
-GLIBC_2.2.5 fork F
 GLIBC_2.2.5 fsync F
 GLIBC_2.2.5 ftrylockfile F
 GLIBC_2.2.5 funlockfile F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
index b9bf4324a9..0e24fcd6bf 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
@@ -5,7 +5,6 @@ GLIBC_2.16 __close F
 GLIBC_2.16 __connect F
 GLIBC_2.16 __errno_location F
 GLIBC_2.16 __fcntl F
-GLIBC_2.16 __fork F
 GLIBC_2.16 __h_errno_location F
 GLIBC_2.16 __libc_allocate_rtsig F
 GLIBC_2.16 __libc_current_sigrtmax F
@@ -54,7 +53,6 @@ GLIBC_2.16 close F
 GLIBC_2.16 connect F
 GLIBC_2.16 fcntl F
 GLIBC_2.16 flockfile F
-GLIBC_2.16 fork F
 GLIBC_2.16 fsync F
 GLIBC_2.16 ftrylockfile F
 GLIBC_2.16 funlockfile F
-- 
2.25.1


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

* [PATCH 5/8] posix: Do not clobber errno by atfork handlers
  2021-02-02 15:11 [PATCH 1/8] posix: Consolidate register-atfork Adhemerval Zanella
                   ` (2 preceding siblings ...)
  2021-02-02 15:11 ` [PATCH 4/8] nptl: Move fork into libc Adhemerval Zanella
@ 2021-02-02 15:11 ` Adhemerval Zanella
  2021-03-09 11:01   ` Florian Weimer
  2021-02-02 15:11 ` [PATCH 6/8] Consolidate pthread_atfork Adhemerval Zanella
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 38+ messages in thread
From: Adhemerval Zanella @ 2021-02-02 15:11 UTC (permalink / raw)
  To: libc-alpha

Checked on x86_64-linux-gnu.
---
 posix/fork.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/posix/fork.c b/posix/fork.c
index 4c9e60f187..7f27fb8338 100644
--- a/posix/fork.c
+++ b/posix/fork.c
@@ -68,7 +68,7 @@ __libc_fork (void)
     }
 
   pid_t pid = _Fork ();
-
+  int save_errno = errno;
   if (pid == 0)
     {
       /* Reset the lock state in the multi-threaded case.  */
@@ -107,6 +107,8 @@ __libc_fork (void)
   __run_fork_handlers (pid == 0 ? atfork_run_child : atfork_run_parent,
 		       multiple_threads);
 
+  if (pid < 0)
+    __set_errno (save_errno);
   return pid;
 }
 weak_alias (__libc_fork, __fork)
-- 
2.25.1


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

* [PATCH 6/8] Consolidate pthread_atfork
  2021-02-02 15:11 [PATCH 1/8] posix: Consolidate register-atfork Adhemerval Zanella
                   ` (3 preceding siblings ...)
  2021-02-02 15:11 ` [PATCH 5/8] posix: Do not clobber errno by atfork handlers Adhemerval Zanella
@ 2021-02-02 15:11 ` Adhemerval Zanella
  2021-03-09 11:09   ` Florian Weimer
  2021-02-02 15:11 ` [PATCH 7/8] support: Add xpthread_kill Adhemerval Zanella
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 38+ messages in thread
From: Adhemerval Zanella @ 2021-02-02 15:11 UTC (permalink / raw)
  To: libc-alpha

The pthread_atfork is similar between Linux and Hurd, only the compat
version bits differs.  The generic version is place at sysdeps/pthread
with a common name.

It also fixes an issue with Hurd license, where the static-only object
did not use LGPL.

Checked on x86_64-linux-gnu, i686-linux-gnu, and with a build for
i686-gnu.
---
 htl/Makefile                                  |  4 +-
 nptl/Makefile                                 |  3 --
 sysdeps/htl/old_pt-atfork.c                   | 26 ------------
 sysdeps/htl/pt-atfork.c                       | 41 -------------------
 sysdeps/htl/pthread_atfork_compat.h           |  2 +
 sysdeps/nptl/pthread_atfork_compat.h          |  2 +
 sysdeps/pthread/Makefile                      |  6 ++-
 {nptl => sysdeps/pthread}/pthread_atfork.c    |  0
 .../pthread/pthread_atfork_compat.c           | 11 +++--
 9 files changed, 16 insertions(+), 79 deletions(-)
 delete mode 100644 sysdeps/htl/old_pt-atfork.c
 delete mode 100644 sysdeps/htl/pt-atfork.c
 create mode 100644 sysdeps/htl/pthread_atfork_compat.h
 create mode 100644 sysdeps/nptl/pthread_atfork_compat.h
 rename {nptl => sysdeps/pthread}/pthread_atfork.c (100%)
 rename nptl/old_pthread_atfork.c => sysdeps/pthread/pthread_atfork_compat.c (76%)

diff --git a/htl/Makefile b/htl/Makefile
index 2dfe19c17f..062d66cbe9 100644
--- a/htl/Makefile
+++ b/htl/Makefile
@@ -121,7 +121,6 @@ libpthread-routines := pt-attr pt-attr-destroy pt-attr-getdetachstate	    \
 	pt-sigstate-destroy						    \
 	pt-sigstate							    \
 									    \
-	old_pt-atfork							    \
 	pt-kill								    \
 	pt-getcpuclockid						    \
 									    \
@@ -166,9 +165,8 @@ headers :=				\
 
 distribute :=
 
-routines := forward libc_pthread_init alloca_cutoff pt-atfork
+routines := forward libc_pthread_init alloca_cutoff
 shared-only-routines = forward
-static-only-routines = pt-atfork
 
 extra-libs := libpthread
 extra-libs-others := $(extra-libs)
diff --git a/nptl/Makefile b/nptl/Makefile
index 3a8762d7b6..31067a78ac 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -38,7 +38,6 @@ routines = \
   libc_pthread_init \
   old_pthread_cond_destroy \
   old_pthread_cond_init \
-  pthread_atfork \
   pthread_attr_copy \
   pthread_attr_destroy \
   pthread_attr_extension \
@@ -70,7 +69,6 @@ routines = \
   pthread_sigmask \
 
 shared-only-routines = forward
-static-only-routines = pthread_atfork
 
 # We need to provide certain routines for compatibility with existing
 # binaries.
@@ -134,7 +132,6 @@ libpthread-routines = nptl-init nptlfreeres vars events version pt-interp \
 		      pthread_cancel pthread_testcancel \
 		      pthread_setcancelstate pthread_setcanceltype \
 		      pthread_once \
-		      old_pthread_atfork \
 		      pthread_getcpuclockid \
 		      shm-directory \
 		      sem_init sem_destroy \
diff --git a/sysdeps/htl/old_pt-atfork.c b/sysdeps/htl/old_pt-atfork.c
deleted file mode 100644
index ca38d6ca42..0000000000
--- a/sysdeps/htl/old_pt-atfork.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Register fork handlers.  Generic version.
-   Copyright (C) 2002-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/>.  */
-
-#include <shlib-compat.h>
-
-#if SHLIB_COMPAT(libpthread, GLIBC_2_12, GLIBC_2_23)
-# define __pthread_atfork __dyn_pthread_atfork
-# include "pt-atfork.c"
-# undef __pthread_atfork
-compat_symbol (libpthread, __dyn_pthread_atfork, pthread_atfork, GLIBC_2_12);
-#endif
diff --git a/sysdeps/htl/pt-atfork.c b/sysdeps/htl/pt-atfork.c
deleted file mode 100644
index 3d115d3819..0000000000
--- a/sysdeps/htl/pt-atfork.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Register fork handlers.  Generic version.
-   Copyright (C) 2002-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/>.  */
-
-#include <pthread.h>
-#include <pt-internal.h>
-#include <fork.h>
-#include <dso_handle.h>
-
-/* Hide the symbol so that no definition but the one locally in the
-   executable or DSO is used.  */
-int
-#ifndef __pthread_atfork
-/* Don't mark the compatibility function as hidden.  */
-attribute_hidden
-#endif
-__pthread_atfork (void (*prepare) (void),
-		void (*parent) (void),
-		void (*child) (void))
-{
-  return __register_atfork (prepare, parent, child, __dso_handle);
-}
-#ifndef __pthread_atfork
-extern int pthread_atfork (void (*prepare) (void), void (*parent) (void),
-                           void (*child) (void)) attribute_hidden;
-weak_alias (__pthread_atfork, pthread_atfork)
-#endif
diff --git a/sysdeps/htl/pthread_atfork_compat.h b/sysdeps/htl/pthread_atfork_compat.h
new file mode 100644
index 0000000000..8943a148e8
--- /dev/null
+++ b/sysdeps/htl/pthread_atfork_compat.h
@@ -0,0 +1,2 @@
+#define PTHREAD_ATFORK_COMPAT_INTRODUCED  GLIBC_2_12
+#define PTHREAD_ATFORK_COMPAT_OBSOLETED   GLIBC_2_23
diff --git a/sysdeps/nptl/pthread_atfork_compat.h b/sysdeps/nptl/pthread_atfork_compat.h
new file mode 100644
index 0000000000..d3ab9373b3
--- /dev/null
+++ b/sysdeps/nptl/pthread_atfork_compat.h
@@ -0,0 +1,2 @@
+#define PTHREAD_ATFORK_COMPAT_INTRODUCED  GLIBC_2_0
+#define PTHREAD_ATFORK_COMPAT_OBSOLETED   GLIBC_2_3
diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile
index eeb64f9fb0..e6266495c6 100644
--- a/sysdeps/pthread/Makefile
+++ b/sysdeps/pthread/Makefile
@@ -29,7 +29,7 @@ endif
 ifneq (,$(filter $(subdir),htl nptl))
 headers += threads.h
 
-routines += thrd_current thrd_equal thrd_sleep thrd_yield
+routines += thrd_current thrd_equal thrd_sleep thrd_yield pthread_atfork
 
 libpthread-routines += thrd_create thrd_detach thrd_exit thrd_join \
 		       call_once \
@@ -37,7 +37,8 @@ libpthread-routines += thrd_create thrd_detach thrd_exit thrd_join \
 		       mtx_trylock mtx_unlock \
 		       cnd_broadcast \
 		       cnd_destroy cnd_init cnd_signal cnd_timedwait cnd_wait \
-		       tss_create tss_delete tss_get tss_set
+		       tss_create tss_delete tss_get tss_set \
+		       pthread_atfork_compat
 
 tests += tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \
 	 tst-cnd-timedwait tst-thrd-detach tst-mtx-basic tst-thrd-sleep \
@@ -109,6 +110,7 @@ tests += tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \
 	 tst-unwind-thread \
 	 tst-pt-vfork1 tst-pt-vfork2 tst-vfork1x tst-vfork2x \
 
+static-only-routines = pthread_atfork
 
 # Files which must not be linked with libpthread.
 tests-nolibpthread = tst-unload
diff --git a/nptl/pthread_atfork.c b/sysdeps/pthread/pthread_atfork.c
similarity index 100%
rename from nptl/pthread_atfork.c
rename to sysdeps/pthread/pthread_atfork.c
diff --git a/nptl/old_pthread_atfork.c b/sysdeps/pthread/pthread_atfork_compat.c
similarity index 76%
rename from nptl/old_pthread_atfork.c
rename to sysdeps/pthread/pthread_atfork_compat.c
index 01b7de633d..e01a408103 100644
--- a/nptl/old_pthread_atfork.c
+++ b/sysdeps/pthread/pthread_atfork_compat.c
@@ -1,6 +1,6 @@
-/* Copyright (C) 2002-2021 Free Software Foundation, Inc.
+/* Compat pthread_atfork implementation.
+   Copyright (C) 2002-2021 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -16,11 +16,14 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
+#include <pthread_atfork_compat.h>
 #include <shlib-compat.h>
 
-#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_3)
+#if SHLIB_COMPAT (libpthread, PTHREAD_ATFORK_COMPAT_INTRODUCED, \
+			      PTHREAD_ATFORK_COMPAT_OBSOLETED)
 # define __pthread_atfork __dyn_pthread_atfork
 # include "pthread_atfork.c"
 # undef __pthread_atfork
-compat_symbol (libpthread, __dyn_pthread_atfork, pthread_atfork, GLIBC_2_0);
+compat_symbol (libpthread, __dyn_pthread_atfork, pthread_atfork,
+	       PTHREAD_ATFORK_COMPAT_INTRODUCED);
 #endif
-- 
2.25.1


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

* [PATCH 7/8] support: Add xpthread_kill
  2021-02-02 15:11 [PATCH 1/8] posix: Consolidate register-atfork Adhemerval Zanella
                   ` (4 preceding siblings ...)
  2021-02-02 15:11 ` [PATCH 6/8] Consolidate pthread_atfork Adhemerval Zanella
@ 2021-02-02 15:11 ` Adhemerval Zanella
  2021-03-08 12:13   ` Florian Weimer
  2021-02-02 15:11 ` [PATCH 8/8] posix: Add _Fork [BZ #4737] Adhemerval Zanella
  2021-03-08 13:04 ` [PATCH 1/8] posix: Consolidate register-atfork Florian Weimer
  7 siblings, 1 reply; 38+ messages in thread
From: Adhemerval Zanella @ 2021-02-02 15:11 UTC (permalink / raw)
  To: libc-alpha

Checked on x86_64-linux-gnu.
---
 support/Makefile        |  1 +
 support/xpthread_kill.c | 26 ++++++++++++++++++++++++++
 support/xthread.h       |  2 ++
 3 files changed, 29 insertions(+)
 create mode 100644 support/xpthread_kill.c

diff --git a/support/Makefile b/support/Makefile
index bb9889efb4..112befe272 100644
--- a/support/Makefile
+++ b/support/Makefile
@@ -139,6 +139,7 @@ libsupport-routines = \
   xpthread_join \
   xpthread_key_create \
   xpthread_key_delete \
+  xpthread_kill \
   xpthread_mutex_consistent \
   xpthread_mutex_destroy \
   xpthread_mutex_init \
diff --git a/support/xpthread_kill.c b/support/xpthread_kill.c
new file mode 100644
index 0000000000..111a75d85e
--- /dev/null
+++ b/support/xpthread_kill.c
@@ -0,0 +1,26 @@
+/* pthread_kill with error checking.
+   Copyright (C) 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/>.  */
+
+#include <signal.h>
+#include <support/xthread.h>
+
+void
+xpthread_kill (pthread_t thr, int signo)
+{
+  xpthread_check_return ("pthread_kill", pthread_kill (thr, signo));
+}
diff --git a/support/xthread.h b/support/xthread.h
index c2086db347..1ba3f133ad 100644
--- a/support/xthread.h
+++ b/support/xthread.h
@@ -75,6 +75,8 @@ void xpthread_attr_setstacksize (pthread_attr_t *attr,
 void xpthread_attr_setguardsize (pthread_attr_t *attr,
 				 size_t guardsize);
 
+void xpthread_kill (pthread_t thr, int signo);
+
 /* Return the stack size used on support_set_small_thread_stack_size.  */
 size_t support_small_thread_stack_size (void);
 /* Set the stack size in ATTR to a small value, but still large enough
-- 
2.25.1


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

* [PATCH 8/8] posix: Add _Fork [BZ #4737]
  2021-02-02 15:11 [PATCH 1/8] posix: Consolidate register-atfork Adhemerval Zanella
                   ` (5 preceding siblings ...)
  2021-02-02 15:11 ` [PATCH 7/8] support: Add xpthread_kill Adhemerval Zanella
@ 2021-02-02 15:11 ` Adhemerval Zanella
  2021-02-02 15:48   ` Andreas Schwab
                     ` (2 more replies)
  2021-03-08 13:04 ` [PATCH 1/8] posix: Consolidate register-atfork Florian Weimer
  7 siblings, 3 replies; 38+ messages in thread
From: Adhemerval Zanella @ 2021-02-02 15:11 UTC (permalink / raw)
  To: libc-alpha

Austin Group issue 62 [1] droped the async-signal-safe requirement
for fork and provided a asignal-signal-safe _Fork replacement that
does not run the atfork handlers.  It will be included in the future
POSIX standard.

It allow to close a long standing issue to make fork AS-safe (BZ#4737).
As indicated on the bug, besides the internal lock for the atfork
handlers itself; there is no guarantee that the handlers itself will
not introduce more AS-safe issues.

The idea is synchronize fork with the required internal locks to allow
children in multithread processes to use mostly of standard function
(even though POSIX states only AS-safe function should be used).  On
signal handles, _Fork should be used intead and only AS-safe functions
should be used.

For testing, the new tst-_Fork only check basic usage.  I also added
a new tst-mallocfork3 which uses the same strategy to check for
deadlock of tst-mallocfork2 but using threads instead of subprocesses
(and it does deadlock if it replaces _Fork with fork).

[1] https://austingroupbugs.net/view.php?id=62
---
 malloc/Makefile                               |   3 +
 malloc/tst-mallocfork3.c                      | 213 +++++++++++++++++
 posix/Makefile                                |   3 +-
 posix/Versions                                |   3 +
 posix/fork.c                                  |   8 +-
 posix/tst-_Fork.c                             | 218 ++++++++++++++++++
 posix/unistd.h                                |   7 +
 sysdeps/mach/hurd/i386/libc.abilist           |   1 +
 sysdeps/unix/sysv/linux/aarch64/libc.abilist  |   1 +
 sysdeps/unix/sysv/linux/alpha/libc.abilist    |   1 +
 sysdeps/unix/sysv/linux/arc/libc.abilist      |   1 +
 sysdeps/unix/sysv/linux/arm/be/libc.abilist   |   1 +
 sysdeps/unix/sysv/linux/arm/le/libc.abilist   |   1 +
 sysdeps/unix/sysv/linux/csky/libc.abilist     |   1 +
 sysdeps/unix/sysv/linux/hppa/libc.abilist     |   1 +
 sysdeps/unix/sysv/linux/i386/libc.abilist     |   1 +
 sysdeps/unix/sysv/linux/ia64/libc.abilist     |   1 +
 .../sysv/linux/m68k/coldfire/libc.abilist     |   1 +
 .../unix/sysv/linux/m68k/m680x0/libc.abilist  |   1 +
 .../sysv/linux/microblaze/be/libc.abilist     |   1 +
 .../sysv/linux/microblaze/le/libc.abilist     |   1 +
 .../sysv/linux/mips/mips32/fpu/libc.abilist   |   1 +
 .../sysv/linux/mips/mips32/nofpu/libc.abilist |   1 +
 .../sysv/linux/mips/mips64/n32/libc.abilist   |   1 +
 .../sysv/linux/mips/mips64/n64/libc.abilist   |   1 +
 sysdeps/unix/sysv/linux/nios2/libc.abilist    |   1 +
 .../linux/powerpc/powerpc32/fpu/libc.abilist  |   1 +
 .../powerpc/powerpc32/nofpu/libc.abilist      |   1 +
 .../linux/powerpc/powerpc64/be/libc.abilist   |   1 +
 .../linux/powerpc/powerpc64/le/libc.abilist   |   1 +
 .../unix/sysv/linux/riscv/rv32/libc.abilist   |   1 +
 .../unix/sysv/linux/riscv/rv64/libc.abilist   |   1 +
 .../unix/sysv/linux/s390/s390-32/libc.abilist |   1 +
 .../unix/sysv/linux/s390/s390-64/libc.abilist |   1 +
 sysdeps/unix/sysv/linux/sh/be/libc.abilist    |   1 +
 sysdeps/unix/sysv/linux/sh/le/libc.abilist    |   1 +
 .../sysv/linux/sparc/sparc32/libc.abilist     |   1 +
 .../sysv/linux/sparc/sparc64/libc.abilist     |   1 +
 .../unix/sysv/linux/x86_64/64/libc.abilist    |   1 +
 .../unix/sysv/linux/x86_64/x32/libc.abilist   |   1 +
 40 files changed, 484 insertions(+), 4 deletions(-)
 create mode 100644 malloc/tst-mallocfork3.c
 create mode 100644 posix/tst-_Fork.c

diff --git a/malloc/Makefile b/malloc/Makefile
index 583bbefb0d..42852f47a2 100644
--- a/malloc/Makefile
+++ b/malloc/Makefile
@@ -31,6 +31,7 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \
 	 tst-malloc-backtrace tst-malloc-thread-exit \
 	 tst-malloc-thread-fail tst-malloc-fork-deadlock \
 	 tst-mallocfork2 \
+	 tst-mallocfork3 \
 	 tst-interpose-nothread \
 	 tst-interpose-thread \
 	 tst-alloc_buffer \
@@ -110,6 +111,8 @@ libmemusage-inhibit-o = $(filter-out .os,$(object-suffixes))
 $(objpfx)tst-malloc-backtrace: $(shared-thread-library)
 $(objpfx)tst-malloc-thread-exit: $(shared-thread-library)
 $(objpfx)tst-malloc-thread-fail: $(shared-thread-library)
+$(objpfx)tst-mallocfork3: $(shared-thread-library)
+$(objpfx)tst-mallocfork3-mcheck: $(shared-thread-library)
 $(objpfx)tst-malloc-fork-deadlock: $(shared-thread-library)
 $(objpfx)tst-malloc-stats-cancellation: $(shared-thread-library)
 $(objpfx)tst-malloc-backtrace-mcheck: $(shared-thread-library)
diff --git a/malloc/tst-mallocfork3.c b/malloc/tst-mallocfork3.c
new file mode 100644
index 0000000000..4ac99eea43
--- /dev/null
+++ b/malloc/tst-mallocfork3.c
@@ -0,0 +1,213 @@
+/* Test case for async-signal-safe _Fork (with respect to malloc).
+   Copyright (C) 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; see the file COPYING.LIB.  If
+   not, see <https://www.gnu.org/licenses/>.  */
+
+/* This test is similar to tst-mallocfork2.c, but specifically stress
+   the async-signal-safeness of _Fork on multithread environment.  */
+
+#include <array_length.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <support/check.h>
+#include <support/support.h>
+#include <support/xsignal.h>
+#include <support/xthread.h>
+#include <support/xunistd.h>
+#include <sys/wait.h>
+
+/* How many malloc objects to keep arond.  */
+enum { malloc_objects = 1009 };
+
+/* The maximum size of an object.  */
+enum { malloc_maximum_size = 70000 };
+
+/* How many iterations the test performs before exiting.  */
+enum { iterations = 10000 };
+
+/* Barrier for synchronization with the threads sending SIGUSR1
+   signals, to make it more likely that the signals arrive during a
+   fork/free/malloc call.  */
+static pthread_barrier_t barrier;
+
+/* Set to 1 if SIGUSR1 is received.  Used to detect a signal during
+   fork/free/malloc.  */
+static volatile sig_atomic_t sigusr1_received;
+
+/* Periodically set to 1, to indicate that the thread is making
+   progress.  Checked by liveness_signal_handler.  */
+static volatile sig_atomic_t progress_indicator = 1;
+
+/* Set to 1 if an error occurs in the signal handler.  */
+static volatile sig_atomic_t error_indicator = 0;
+
+static void
+sigusr1_handler (int signo)
+{
+  sigusr1_received = 1;
+
+  /* Perform a fork with a trivial subprocess.  */
+  pid_t pid = _Fork ();
+  if (pid == -1)
+    {
+      write_message ("error: fork\n");
+      error_indicator = 1;
+      return;
+    }
+  if (pid == 0)
+    _exit (0);
+  int status;
+  int ret = TEMP_FAILURE_RETRY (waitpid (pid, &status, 0));
+  if (ret < 0)
+    {
+      write_message ("error: waitpid\n");
+      error_indicator = 1;
+      return;
+    }
+  if (status != 0)
+    {
+      write_message ("error: unexpected exit status from subprocess\n");
+      error_indicator = 1;
+      return;
+    }
+}
+
+static void
+liveness_signal_handler (int signo)
+{
+  if (progress_indicator)
+    progress_indicator = 0;
+  else
+    write_message ("warning: thread seems to be stuck\n");
+}
+
+struct signal_send_args
+{
+  pthread_t target;
+  int signo;
+  bool sleep;
+};
+#define SIGNAL_SEND_GET_ARG(arg, field) \
+  (((struct signal_send_args *)(arg))->field)
+
+/* Send SIGNO to the parent thread.  If SLEEP, wait a second between
+   signals, otherwise use barriers to delay sending signals.  */
+static void *
+signal_sender (void *args)
+{
+  int signo = SIGNAL_SEND_GET_ARG (args, signo);
+  bool sleep = SIGNAL_SEND_GET_ARG (args, sleep);
+
+  pthread_t target = SIGNAL_SEND_GET_ARG (args, target);
+  while (true)
+    {
+      if (!sleep)
+        xpthread_barrier_wait (&barrier);
+      xpthread_kill (target, signo);
+      if (sleep)
+        usleep (1 * 1000 * 1000);
+      else
+        xpthread_barrier_wait (&barrier);
+    }
+  return NULL;
+}
+
+static pthread_t sigusr1_sender[5];
+static pthread_t sigusr2_sender;
+
+static int
+do_test (void)
+{
+  xsignal (SIGUSR1, sigusr1_handler);
+  xsignal (SIGUSR2, liveness_signal_handler);
+
+  pthread_t self = pthread_self ();
+
+  struct signal_send_args sigusr2_args = { self, SIGUSR2, true };
+  sigusr2_sender = xpthread_create (NULL, signal_sender, &sigusr2_args);
+
+  /* Send SIGUSR1 signals from several threads.  Hopefully, one
+     signal will hit one of the ciritical functions.  Use a barrier to
+     avoid sending signals while not running fork/free/malloc.  */
+  struct signal_send_args sigusr1_args = { self, SIGUSR1, false };
+  xpthread_barrier_init (&barrier, NULL,
+                         array_length (sigusr1_sender) + 1);
+  for (size_t i = 0; i < array_length (sigusr1_sender); ++i)
+    sigusr1_sender[i] = xpthread_create (NULL, signal_sender, &sigusr1_args);
+
+  void *objects[malloc_objects] = {};
+  unsigned int fork_signals = 0;
+  unsigned int free_signals = 0;
+  unsigned int malloc_signals = 0;
+  unsigned int seed = 1;
+  for (int i = 0; i < iterations; ++i)
+    {
+      progress_indicator = 1;
+      int slot = rand_r (&seed) % malloc_objects;
+      size_t size = rand_r (&seed) % malloc_maximum_size;
+
+      /* Occasionally do a fork first, to catch deadlocks there as
+         well (see bug 24161).  */
+      bool do_fork = (rand_r (&seed) % 7) == 0;
+
+      xpthread_barrier_wait (&barrier);
+      if (do_fork)
+        {
+          sigusr1_received = 0;
+          pid_t pid = _Fork ();
+          TEST_VERIFY_EXIT (pid != -1);
+          if (sigusr1_received)
+            ++fork_signals;
+          if (pid == 0)
+            _exit (0);
+          int status;
+          int ret = TEMP_FAILURE_RETRY (waitpid (pid, &status, 0));
+          if (ret < 0)
+            FAIL_EXIT1 ("waitpid: %m");
+          TEST_COMPARE (status, 0);
+        }
+      sigusr1_received = 0;
+      free (objects[slot]);
+      if (sigusr1_received)
+        ++free_signals;
+      sigusr1_received = 0;
+      objects[slot] = malloc (size);
+      if (sigusr1_received)
+        ++malloc_signals;
+      xpthread_barrier_wait (&barrier);
+
+      if (objects[slot] == NULL || error_indicator != 0)
+        {
+          printf ("error: malloc: %m\n");
+          return 1;
+        }
+    }
+
+  /* Clean up allocations.  */
+  for (int slot = 0; slot < malloc_objects; ++slot)
+    free (objects[slot]);
+
+  printf ("info: signals received during fork: %u\n", fork_signals);
+  printf ("info: signals received during free: %u\n", free_signals);
+  printf ("info: signals received during malloc: %u\n", malloc_signals);
+
+  return 0;
+}
+
+#define TIMEOUT 100
+#include <support/test-driver.c>
diff --git a/posix/Makefile b/posix/Makefile
index b79b361fae..f0836fc624 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -113,7 +113,7 @@ test-srcs	:= globtest
 tests           += wordexp-test tst-exec tst-spawn tst-spawn2 tst-spawn3
 endif
 ifeq (yesyes,$(build-shared)$(have-thread-library))
-tests		+= tst-getopt-cancel
+tests		+= tst-getopt-cancel tst-_Fork
 endif
 tests-static	= tst-exec-static tst-spawn-static
 tests		+= $(tests-static)
@@ -282,6 +282,7 @@ $(objpfx)ptestcases.h: PTESTS PTESTS2C.sed
 $(objpfx)runptests.o: $(objpfx)ptestcases.h
 
 $(objpfx)tst-getopt-cancel: $(shared-thread-library)
+$(objpfx)tst-_Fork: $(shared-thread-library)
 
 test-xfail-annexc = yes
 $(objpfx)annexc.out: $(objpfx)annexc
diff --git a/posix/Versions b/posix/Versions
index 7d06a6d0c0..acc7e4be65 100644
--- a/posix/Versions
+++ b/posix/Versions
@@ -147,6 +147,9 @@ libc {
   }
   GLIBC_2.30 {
   }
+  GLIBC_2.34 {
+    _Fork;
+  }
   GLIBC_PRIVATE {
     __libc_fork; __libc_pread; __libc_pwrite;
     __nanosleep_nocancel; __pause_nocancel;
diff --git a/posix/fork.c b/posix/fork.c
index 7f27fb8338..1c4481f9c2 100644
--- a/posix/fork.c
+++ b/posix/fork.c
@@ -40,9 +40,11 @@ __libc_fork (void)
 {
   /* Determine if we are running multiple threads.  We skip some fork
      handlers in the single-thread case, to make fork safer to use in
-     signal handlers.  POSIX requires that fork is async-signal-safe,
-     but our current fork implementation is not.  */
-  bool multiple_threads = __libc_single_threaded;
+     signal handlers.  Although POSIX has dropped async-signal-safe
+     requirement for fork (Austin Group tracker issue #62) this is
+     best effort to make is async-signal-safe at least for single-thread
+     case.  */
+  bool multiple_threads = __libc_single_threaded == 0;
 
   __run_fork_handlers (atfork_run_prepare, multiple_threads);
 
diff --git a/posix/tst-_Fork.c b/posix/tst-_Fork.c
new file mode 100644
index 0000000000..29a7ab6aaf
--- /dev/null
+++ b/posix/tst-_Fork.c
@@ -0,0 +1,218 @@
+/* Basic tests for _Fork.
+   Copyright (C) 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/>.  */
+
+#include <array_length.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include <stdbool.h>
+#include <support/check.h>
+#include <support/xsignal.h>
+#include <support/temp_file.h>
+#include <support/xunistd.h>
+#include <support/xthread.h>
+
+/* For single-thread, _Fork behaves like fork.  */
+static int
+singlethread_test (void)
+{
+  const char testdata1[] = "abcdefghijklmnopqrtuvwxz";
+  enum { testdatalen1 = array_length (testdata1) };
+  const char testdata2[] = "01234567890";
+  enum { testdatalen2 = array_length (testdata2) };
+
+  pid_t ppid = getpid ();
+
+  int tempfd = create_temp_file ("tst-_Fork", NULL);
+
+  /* Check if the opened file is shared between process by read and write
+     some data on parent and child processes.  */
+  xwrite (tempfd, testdata1, testdatalen1);
+  off_t off = xlseek (tempfd, 0, SEEK_CUR);
+  TEST_COMPARE (off, testdatalen1);
+
+  pid_t pid = _Fork ();
+  TEST_VERIFY_EXIT (pid != -1);
+  if (pid == 0)
+    {
+      TEST_VERIFY_EXIT (getpid () != ppid);
+      TEST_COMPARE (getppid(), ppid);
+
+      TEST_COMPARE (xlseek (tempfd, 0, SEEK_CUR), testdatalen1);
+
+      xlseek (tempfd, 0, SEEK_SET);
+      char buf[testdatalen1];
+      TEST_COMPARE (read (tempfd, buf, sizeof (buf)), testdatalen1);
+      TEST_COMPARE (memcmp (buf, testdata1, testdatalen1), 0);
+
+      xlseek (tempfd, 0, SEEK_SET);
+      xwrite (tempfd, testdata2, testdatalen2);
+
+      close (tempfd);
+
+      _exit (EXIT_SUCCESS);
+    }
+
+  int status;
+  xwaitpid (pid, &status, 0);
+  TEST_VERIFY (WIFEXITED (status));
+  TEST_COMPARE (WEXITSTATUS (status), EXIT_SUCCESS);
+
+  TEST_COMPARE (xlseek (tempfd, 0, SEEK_CUR), testdatalen2);
+
+  xlseek (tempfd, 0, SEEK_SET);
+  char buf[testdatalen2];
+  TEST_COMPARE (read (tempfd, buf, sizeof (buf)), testdatalen2);
+
+  TEST_COMPARE (memcmp (buf, testdata2, testdatalen2), 0);
+
+  return 0;
+}
+
+
+static volatile sig_atomic_t sigusr1_handler_ran;
+static pid_t sig_pid = -1;
+#define SIG_PID_EXIT_CODE 20
+
+static void
+sigusr1_handler (int signum)
+{
+  TEST_COMPARE (signum, SIGUSR1);
+
+  pid_t ppid = getpid ();
+
+  sig_pid = _Fork ();
+  TEST_VERIFY_EXIT (sig_pid != -1);
+  if (sig_pid == 0)
+    {
+      TEST_VERIFY_EXIT (getpid () != ppid);
+      TEST_COMPARE (getppid(), ppid);
+
+      _exit (SIG_PID_EXIT_CODE);
+    }
+
+  sigusr1_handler_ran = 1;
+}
+
+/* _Fork is async-signal-safe, so check if it can successfully issue
+    a new process in a signal handler.  */
+static int
+singlethread_signal_test (void)
+{
+  xsignal (SIGUSR1, &sigusr1_handler);
+  /* Assume synchronous signal handling.  */
+  xraise (SIGUSR1);
+  TEST_COMPARE (sigusr1_handler_ran, 1);
+
+  int status;
+  xwaitpid (sig_pid, &status, 0);
+  TEST_VERIFY (WIFEXITED (status));
+  TEST_COMPARE (WEXITSTATUS (status), SIG_PID_EXIT_CODE);
+
+  xsignal (SIGUSR1, SIG_DFL);
+
+  return 0;
+}
+
+
+static bool atfork_prepare_var;
+static bool atfork_parent_var;
+static bool atfork_child_var;
+
+static void
+atfork_prepare (void)
+{
+  atfork_prepare_var = true;
+}
+
+static void
+atfork_parent (void)
+{
+  atfork_parent_var = true;
+}
+
+static void
+atfork_child (void)
+{
+  atfork_child_var = true;
+}
+
+/* Different than fork, _Fork does not execute any pthread_atfork
+   handlers.  */
+static int
+singlethread_atfork_test (void)
+{
+  pthread_atfork (atfork_prepare, atfork_parent, atfork_child);
+  singlethread_test ();
+  TEST_COMPARE (atfork_prepare_var, false);
+  TEST_COMPARE (atfork_parent_var, false);
+  TEST_COMPARE (atfork_child_var, false);
+
+  return 0;
+}
+
+
+static void *
+mt_atfork_test (void *args)
+{
+  singlethread_atfork_test ();
+
+  return NULL;
+}
+
+static int
+multithread_atfork_test (void)
+{
+  pthread_t thr = xpthread_create (NULL, mt_atfork_test, NULL);
+  xpthread_join (thr);
+
+  return 0;
+}
+
+
+static void *
+mt_signal_test (void *args)
+{
+  singlethread_signal_test ();
+
+  return NULL;
+}
+
+static int
+multithread_signal_test (void)
+{
+  pthread_t thr = xpthread_create (NULL, mt_signal_test, NULL);
+  xpthread_join (thr);
+
+  return 0;
+}
+
+
+static int
+do_test (void)
+{
+  singlethread_atfork_test ();
+  singlethread_signal_test ();
+
+  multithread_atfork_test ();
+  multithread_signal_test ();
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/posix/unistd.h b/posix/unistd.h
index 3f22763379..670d471ac2 100644
--- a/posix/unistd.h
+++ b/posix/unistd.h
@@ -776,6 +776,13 @@ extern __pid_t fork (void) __THROWNL;
 extern __pid_t vfork (void) __THROW;
 #endif /* Use misc or XPG < 7. */
 
+#ifdef __USE_GNU
+/* This is similar to fork, however it does not run the atfork handlers
+   neither reinitialize any internal locks in multithread case.
+   Different than fork, _Fork is async-signal-safe.  */
+extern __pid_t _Fork (void) __THROWNL;
+#endif
+
 
 /* Return the pathname of the terminal FD is open on, or NULL on errors.
    The returned storage is good only until the next call to this function.  */
diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
index 509e9b7cb0..55834ca18b 100644
--- a/sysdeps/mach/hurd/i386/libc.abilist
+++ b/sysdeps/mach/hurd/i386/libc.abilist
@@ -2203,6 +2203,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index 4cc1c6a591..dc812707a2 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2171,3 +2171,4 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index 26ad9845e4..3b7e00c87b 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -2253,6 +2253,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist
index bb9dfd4daf..7a06fd731c 100644
--- a/sysdeps/unix/sysv/linux/arc/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arc/libc.abilist
@@ -1931,3 +1931,4 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
index 3b0a47e967..946568ac6a 100644
--- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
@@ -155,6 +155,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
 GLIBC_2.4 _IO_2_1_stdin_ D 0xa0
diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
index 9ab3924888..4d2d167974 100644
--- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
@@ -152,6 +152,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
 GLIBC_2.4 _IO_2_1_stdin_ D 0xa0
diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
index 14a84dac8f..d3092f5702 100644
--- a/sysdeps/unix/sysv/linux/csky/libc.abilist
+++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
@@ -2115,3 +2115,4 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index 5c8502f3d3..78a6fe365a 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -2074,6 +2074,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index ddc5837059..f21e646797 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -2241,6 +2241,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index e3b345b803..811da8c935 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -2106,6 +2106,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index 25f2d1c08f..1223fc32d7 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -156,6 +156,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0x98
 GLIBC_2.4 _IO_2_1_stdin_ D 0x98
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index c4891479d3..035d8d17fd 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -2186,6 +2186,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
index 143b0163b4..55d7144063 100644
--- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
@@ -2166,3 +2166,4 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
index 13d374a031..f4223a84cf 100644
--- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
@@ -2163,3 +2163,4 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index b2295f1937..1ccb65fe80 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -2157,6 +2157,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index 4c786070d0..27b7489778 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -2155,6 +2155,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index aa9c6a4dca..05b7afe7c8 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -2163,6 +2163,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index 5939588ad5..aa3845e160 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -2157,6 +2157,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index 92556c4237..efe35b8751 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2204,3 +2204,4 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index 26c93dff05..eda0349d39 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -2213,6 +2213,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index f04b167788..c51540783d 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -2246,6 +2246,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
index c2ca00709e..a508ef7e7a 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
@@ -2076,6 +2076,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
index 0ea50dc851..9366d54213 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
@@ -2366,3 +2366,4 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
index 0263e284d4..2a427fb493 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
@@ -1933,3 +1933,4 @@ GLIBC_2.33 wprintf F
 GLIBC_2.33 write F
 GLIBC_2.33 writev F
 GLIBC_2.33 wscanf F
+GLIBC_2.34 _Fork F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
index 1626c5351f..26dcd9ec47 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
@@ -2133,3 +2133,4 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index a66426eb4d..753b7a99fa 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -2211,6 +2211,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index ab351873ae..454f8d72ba 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -2112,6 +2112,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
index 22ceaa3d87..fe4d7b31ab 100644
--- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
@@ -2081,6 +2081,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
index d36f228192..7ef2df0f07 100644
--- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
@@ -2078,6 +2078,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index 59b4313280..380c51907a 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -2202,6 +2202,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index 266dcdfa08..3c3ad9188d 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -2129,6 +2129,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index 2744bba4af..aff31183eb 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -2088,6 +2088,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index ce2f4fb72b..fd6e98861c 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2185,3 +2185,4 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
-- 
2.25.1


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

* Re: [PATCH 2/8] linux: Use __libc_single_threaded on fork
  2021-02-02 15:11 ` [PATCH 2/8] linux: Use __libc_single_threaded on fork Adhemerval Zanella
@ 2021-02-02 15:15   ` Andreas Schwab
  2021-02-02 16:40     ` Adhemerval Zanella
  0 siblings, 1 reply; 38+ messages in thread
From: Andreas Schwab @ 2021-02-02 15:15 UTC (permalink / raw)
  To: Adhemerval Zanella via Libc-alpha

On Feb 02 2021, Adhemerval Zanella via Libc-alpha wrote:

> @@ -54,7 +55,7 @@ __libc_fork (void)
>       handlers in the single-thread case, to make fork safer to use in
>       signal handlers.  POSIX requires that fork is async-signal-safe,
>       but our current fork implementation is not.  */
> -  bool multiple_threads = THREAD_GETMEM (THREAD_SELF, header.multiple_threads);
> +  bool multiple_threads = __libc_single_threaded;

That looks backwards.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."

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

* Re: [PATCH 8/8] posix: Add _Fork [BZ #4737]
  2021-02-02 15:11 ` [PATCH 8/8] posix: Add _Fork [BZ #4737] Adhemerval Zanella
@ 2021-02-02 15:48   ` Andreas Schwab
  2021-02-02 18:22   ` Joseph Myers
  2021-02-11 15:26   ` [PATCH v2] " Adhemerval Zanella
  2 siblings, 0 replies; 38+ messages in thread
From: Andreas Schwab @ 2021-02-02 15:48 UTC (permalink / raw)
  To: Adhemerval Zanella via Libc-alpha

On Feb 02 2021, Adhemerval Zanella via Libc-alpha wrote:

> for fork and provided a asignal-signal-safe _Fork replacement that

s/asignal/async/

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."

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

* Re: [PATCH 2/8] linux: Use __libc_single_threaded on fork
  2021-02-02 15:15   ` Andreas Schwab
@ 2021-02-02 16:40     ` Adhemerval Zanella
  0 siblings, 0 replies; 38+ messages in thread
From: Adhemerval Zanella @ 2021-02-02 16:40 UTC (permalink / raw)
  To: Andreas Schwab, Adhemerval Zanella via Libc-alpha



On 02/02/2021 12:15, Andreas Schwab wrote:
> On Feb 02 2021, Adhemerval Zanella via Libc-alpha wrote:
> 
>> @@ -54,7 +55,7 @@ __libc_fork (void)
>>       handlers in the single-thread case, to make fork safer to use in
>>       signal handlers.  POSIX requires that fork is async-signal-safe,
>>       but our current fork implementation is not.  */
>> -  bool multiple_threads = THREAD_GETMEM (THREAD_SELF, header.multiple_threads);
>> +  bool multiple_threads = __libc_single_threaded;
> 
> That looks backwards.

Yes, I have fixed it locally but it seems I haven't update the branch
I sent upstream.

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

* Re: [PATCH 8/8] posix: Add _Fork [BZ #4737]
  2021-02-02 15:11 ` [PATCH 8/8] posix: Add _Fork [BZ #4737] Adhemerval Zanella
  2021-02-02 15:48   ` Andreas Schwab
@ 2021-02-02 18:22   ` Joseph Myers
  2021-02-11 15:26   ` [PATCH v2] " Adhemerval Zanella
  2 siblings, 0 replies; 38+ messages in thread
From: Joseph Myers @ 2021-02-02 18:22 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha

If this is meant to be a user-visible API, there should be a NEWS entry 
and it should be documented in the manual.

-- 
Joseph S. Myers
joseph@codesourcery.com

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

* [PATCH v2] posix: Add _Fork [BZ #4737]
  2021-02-02 15:11 ` [PATCH 8/8] posix: Add _Fork [BZ #4737] Adhemerval Zanella
  2021-02-02 15:48   ` Andreas Schwab
  2021-02-02 18:22   ` Joseph Myers
@ 2021-02-11 15:26   ` Adhemerval Zanella
  2021-02-11 16:21     ` Andreas Schwab
  2 siblings, 1 reply; 38+ messages in thread
From: Adhemerval Zanella @ 2021-02-11 15:26 UTC (permalink / raw)
  To: libc-alpha

Changes from previous version:

 * Added NEWS and manual entry.

--

Austin Group issue 62 [1] droped the async-signal-safe requirement
for fork and provided a async-signal-safe _Fork replacement that
does not run the atfork handlers.  It will be included in the future
POSIX standard.

It allow to close a long standing issue to make fork AS-safe (BZ#4737).
As indicated on the bug, besides the internal lock for the atfork
handlers itself; there is no guarantee that the handlers itself will
not introduce more AS-safe issues.

The idea is synchronize fork with the required internal locks to allow
children in multithread processes to use mostly of standard function
(even though POSIX states only AS-safe function should be used).  On
signal handles, _Fork should be used intead and only AS-safe functions
should be used.

For testing, the new tst-_Fork only check basic usage.  I also added
a new tst-mallocfork3 which uses the same strategy to check for
deadlock of tst-mallocfork2 but using threads instead of subprocesses
(and it does deadlock if it replaces _Fork with fork).

[1] https://austingroupbugs.net/view.php?id=62
---
 NEWS                                          |   8 +
 malloc/Makefile                               |   3 +
 malloc/tst-mallocfork3.c                      | 213 +++++++++++++++++
 manual/process.texi                           |  39 ++--
 posix/Makefile                                |   3 +-
 posix/Versions                                |   3 +
 posix/fork.c                                  |   6 +-
 posix/tst-_Fork.c                             | 218 ++++++++++++++++++
 posix/unistd.h                                |   7 +
 sysdeps/mach/hurd/i386/libc.abilist           |   1 +
 sysdeps/unix/sysv/linux/aarch64/libc.abilist  |   1 +
 sysdeps/unix/sysv/linux/alpha/libc.abilist    |   1 +
 sysdeps/unix/sysv/linux/arc/libc.abilist      |   1 +
 sysdeps/unix/sysv/linux/arm/be/libc.abilist   |   1 +
 sysdeps/unix/sysv/linux/arm/le/libc.abilist   |   1 +
 sysdeps/unix/sysv/linux/csky/libc.abilist     |   1 +
 sysdeps/unix/sysv/linux/hppa/libc.abilist     |   1 +
 sysdeps/unix/sysv/linux/i386/libc.abilist     |   1 +
 sysdeps/unix/sysv/linux/ia64/libc.abilist     |   1 +
 .../sysv/linux/m68k/coldfire/libc.abilist     |   1 +
 .../unix/sysv/linux/m68k/m680x0/libc.abilist  |   1 +
 .../sysv/linux/microblaze/be/libc.abilist     |   1 +
 .../sysv/linux/microblaze/le/libc.abilist     |   1 +
 .../sysv/linux/mips/mips32/fpu/libc.abilist   |   1 +
 .../sysv/linux/mips/mips32/nofpu/libc.abilist |   1 +
 .../sysv/linux/mips/mips64/n32/libc.abilist   |   1 +
 .../sysv/linux/mips/mips64/n64/libc.abilist   |   1 +
 sysdeps/unix/sysv/linux/nios2/libc.abilist    |   1 +
 .../linux/powerpc/powerpc32/fpu/libc.abilist  |   1 +
 .../powerpc/powerpc32/nofpu/libc.abilist      |   1 +
 .../linux/powerpc/powerpc64/be/libc.abilist   |   1 +
 .../linux/powerpc/powerpc64/le/libc.abilist   |   1 +
 .../unix/sysv/linux/riscv/rv32/libc.abilist   |   1 +
 .../unix/sysv/linux/riscv/rv64/libc.abilist   |   1 +
 .../unix/sysv/linux/s390/s390-32/libc.abilist |   1 +
 .../unix/sysv/linux/s390/s390-64/libc.abilist |   1 +
 sysdeps/unix/sysv/linux/sh/be/libc.abilist    |   1 +
 sysdeps/unix/sysv/linux/sh/le/libc.abilist    |   1 +
 .../sysv/linux/sparc/sparc32/libc.abilist     |   1 +
 .../sysv/linux/sparc/sparc64/libc.abilist     |   1 +
 .../unix/sysv/linux/x86_64/64/libc.abilist    |   1 +
 .../unix/sysv/linux/x86_64/x32/libc.abilist   |   1 +
 42 files changed, 515 insertions(+), 18 deletions(-)
 create mode 100644 malloc/tst-mallocfork3.c
 create mode 100644 posix/tst-_Fork.c

diff --git a/NEWS b/NEWS
index 85e84fe536..b196dd2474 100644
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,14 @@ Major new features:
   constant on Linux.  MINSIGSTKSZ is redefined to sysconf(_SC_MINSIGSTKSZ)
   and SIGSTKSZ is redefined to sysconf (_SC_SIGSTKSZ).
 
+* The function _Fork has been added as a async-signal-safe fork
+  replacement since Austin Group issue 62 droped the async-signal-safe
+  requirement for fork (and it will be included in the future POSIX
+  standard).  The new _Fork symbol does not issue any atfork handler neither
+  reset any internal state or lock (such as the malloc one) and only
+  setup a minimal state required to call async-signal-safe functions (such
+  as raise or execve).  This function is currently a GNU extension.
+
 Deprecated and removed features, and other changes affecting compatibility:
 
   [Add deprecations, removals and changes affecting compatibility here]
diff --git a/malloc/Makefile b/malloc/Makefile
index 583bbefb0d..42852f47a2 100644
--- a/malloc/Makefile
+++ b/malloc/Makefile
@@ -31,6 +31,7 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \
 	 tst-malloc-backtrace tst-malloc-thread-exit \
 	 tst-malloc-thread-fail tst-malloc-fork-deadlock \
 	 tst-mallocfork2 \
+	 tst-mallocfork3 \
 	 tst-interpose-nothread \
 	 tst-interpose-thread \
 	 tst-alloc_buffer \
@@ -110,6 +111,8 @@ libmemusage-inhibit-o = $(filter-out .os,$(object-suffixes))
 $(objpfx)tst-malloc-backtrace: $(shared-thread-library)
 $(objpfx)tst-malloc-thread-exit: $(shared-thread-library)
 $(objpfx)tst-malloc-thread-fail: $(shared-thread-library)
+$(objpfx)tst-mallocfork3: $(shared-thread-library)
+$(objpfx)tst-mallocfork3-mcheck: $(shared-thread-library)
 $(objpfx)tst-malloc-fork-deadlock: $(shared-thread-library)
 $(objpfx)tst-malloc-stats-cancellation: $(shared-thread-library)
 $(objpfx)tst-malloc-backtrace-mcheck: $(shared-thread-library)
diff --git a/malloc/tst-mallocfork3.c b/malloc/tst-mallocfork3.c
new file mode 100644
index 0000000000..4ac99eea43
--- /dev/null
+++ b/malloc/tst-mallocfork3.c
@@ -0,0 +1,213 @@
+/* Test case for async-signal-safe _Fork (with respect to malloc).
+   Copyright (C) 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; see the file COPYING.LIB.  If
+   not, see <https://www.gnu.org/licenses/>.  */
+
+/* This test is similar to tst-mallocfork2.c, but specifically stress
+   the async-signal-safeness of _Fork on multithread environment.  */
+
+#include <array_length.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <support/check.h>
+#include <support/support.h>
+#include <support/xsignal.h>
+#include <support/xthread.h>
+#include <support/xunistd.h>
+#include <sys/wait.h>
+
+/* How many malloc objects to keep arond.  */
+enum { malloc_objects = 1009 };
+
+/* The maximum size of an object.  */
+enum { malloc_maximum_size = 70000 };
+
+/* How many iterations the test performs before exiting.  */
+enum { iterations = 10000 };
+
+/* Barrier for synchronization with the threads sending SIGUSR1
+   signals, to make it more likely that the signals arrive during a
+   fork/free/malloc call.  */
+static pthread_barrier_t barrier;
+
+/* Set to 1 if SIGUSR1 is received.  Used to detect a signal during
+   fork/free/malloc.  */
+static volatile sig_atomic_t sigusr1_received;
+
+/* Periodically set to 1, to indicate that the thread is making
+   progress.  Checked by liveness_signal_handler.  */
+static volatile sig_atomic_t progress_indicator = 1;
+
+/* Set to 1 if an error occurs in the signal handler.  */
+static volatile sig_atomic_t error_indicator = 0;
+
+static void
+sigusr1_handler (int signo)
+{
+  sigusr1_received = 1;
+
+  /* Perform a fork with a trivial subprocess.  */
+  pid_t pid = _Fork ();
+  if (pid == -1)
+    {
+      write_message ("error: fork\n");
+      error_indicator = 1;
+      return;
+    }
+  if (pid == 0)
+    _exit (0);
+  int status;
+  int ret = TEMP_FAILURE_RETRY (waitpid (pid, &status, 0));
+  if (ret < 0)
+    {
+      write_message ("error: waitpid\n");
+      error_indicator = 1;
+      return;
+    }
+  if (status != 0)
+    {
+      write_message ("error: unexpected exit status from subprocess\n");
+      error_indicator = 1;
+      return;
+    }
+}
+
+static void
+liveness_signal_handler (int signo)
+{
+  if (progress_indicator)
+    progress_indicator = 0;
+  else
+    write_message ("warning: thread seems to be stuck\n");
+}
+
+struct signal_send_args
+{
+  pthread_t target;
+  int signo;
+  bool sleep;
+};
+#define SIGNAL_SEND_GET_ARG(arg, field) \
+  (((struct signal_send_args *)(arg))->field)
+
+/* Send SIGNO to the parent thread.  If SLEEP, wait a second between
+   signals, otherwise use barriers to delay sending signals.  */
+static void *
+signal_sender (void *args)
+{
+  int signo = SIGNAL_SEND_GET_ARG (args, signo);
+  bool sleep = SIGNAL_SEND_GET_ARG (args, sleep);
+
+  pthread_t target = SIGNAL_SEND_GET_ARG (args, target);
+  while (true)
+    {
+      if (!sleep)
+        xpthread_barrier_wait (&barrier);
+      xpthread_kill (target, signo);
+      if (sleep)
+        usleep (1 * 1000 * 1000);
+      else
+        xpthread_barrier_wait (&barrier);
+    }
+  return NULL;
+}
+
+static pthread_t sigusr1_sender[5];
+static pthread_t sigusr2_sender;
+
+static int
+do_test (void)
+{
+  xsignal (SIGUSR1, sigusr1_handler);
+  xsignal (SIGUSR2, liveness_signal_handler);
+
+  pthread_t self = pthread_self ();
+
+  struct signal_send_args sigusr2_args = { self, SIGUSR2, true };
+  sigusr2_sender = xpthread_create (NULL, signal_sender, &sigusr2_args);
+
+  /* Send SIGUSR1 signals from several threads.  Hopefully, one
+     signal will hit one of the ciritical functions.  Use a barrier to
+     avoid sending signals while not running fork/free/malloc.  */
+  struct signal_send_args sigusr1_args = { self, SIGUSR1, false };
+  xpthread_barrier_init (&barrier, NULL,
+                         array_length (sigusr1_sender) + 1);
+  for (size_t i = 0; i < array_length (sigusr1_sender); ++i)
+    sigusr1_sender[i] = xpthread_create (NULL, signal_sender, &sigusr1_args);
+
+  void *objects[malloc_objects] = {};
+  unsigned int fork_signals = 0;
+  unsigned int free_signals = 0;
+  unsigned int malloc_signals = 0;
+  unsigned int seed = 1;
+  for (int i = 0; i < iterations; ++i)
+    {
+      progress_indicator = 1;
+      int slot = rand_r (&seed) % malloc_objects;
+      size_t size = rand_r (&seed) % malloc_maximum_size;
+
+      /* Occasionally do a fork first, to catch deadlocks there as
+         well (see bug 24161).  */
+      bool do_fork = (rand_r (&seed) % 7) == 0;
+
+      xpthread_barrier_wait (&barrier);
+      if (do_fork)
+        {
+          sigusr1_received = 0;
+          pid_t pid = _Fork ();
+          TEST_VERIFY_EXIT (pid != -1);
+          if (sigusr1_received)
+            ++fork_signals;
+          if (pid == 0)
+            _exit (0);
+          int status;
+          int ret = TEMP_FAILURE_RETRY (waitpid (pid, &status, 0));
+          if (ret < 0)
+            FAIL_EXIT1 ("waitpid: %m");
+          TEST_COMPARE (status, 0);
+        }
+      sigusr1_received = 0;
+      free (objects[slot]);
+      if (sigusr1_received)
+        ++free_signals;
+      sigusr1_received = 0;
+      objects[slot] = malloc (size);
+      if (sigusr1_received)
+        ++malloc_signals;
+      xpthread_barrier_wait (&barrier);
+
+      if (objects[slot] == NULL || error_indicator != 0)
+        {
+          printf ("error: malloc: %m\n");
+          return 1;
+        }
+    }
+
+  /* Clean up allocations.  */
+  for (int slot = 0; slot < malloc_objects; ++slot)
+    free (objects[slot]);
+
+  printf ("info: signals received during fork: %u\n", fork_signals);
+  printf ("info: signals received during free: %u\n", free_signals);
+  printf ("info: signals received during malloc: %u\n", malloc_signals);
+
+  return 0;
+}
+
+#define TIMEOUT 100
+#include <support/test-driver.c>
diff --git a/manual/process.texi b/manual/process.texi
index 54e65f76c6..e17149ce60 100644
--- a/manual/process.texi
+++ b/manual/process.texi
@@ -138,8 +138,8 @@ creating a process and making it run another program.
 @cindex parent process
 @cindex subprocess
 A new processes is created when one of the functions
-@code{posix_spawn}, @code{fork}, or @code{vfork} is called.  (The
-@code{system} and @code{popen} also create new processes internally.)
+@code{posix_spawn}, @code{fork}, @code{_Fork} or @code{vfork} is called.
+(The @code{system} and @code{popen} also create new processes internally.)
 Due to the name of the @code{fork} function, the act of creating a new
 process is sometimes called @dfn{forking} a process.  Each new process
 (the @dfn{child process} or @dfn{subprocess}) is allocated a process
@@ -155,9 +155,10 @@ limited information about why the child terminated---for example, its
 exit status code.
 
 A newly forked child process continues to execute the same program as
-its parent process, at the point where the @code{fork} call returns.
-You can use the return value from @code{fork} to tell whether the program
-is running in the parent process or the child.
+its parent process, at the point where the @code{fork} or @code{_Fork}
+call returns.  You can use the return value from @code{fork} or
+@code{_Fork} to tell whether the program is running in the parent process
+or the child.
 
 @cindex process image
 Having several processes run the same program is only occasionally
@@ -249,16 +250,13 @@ It is declared in the header file @file{unistd.h}.
 @deftypefun pid_t fork (void)
 @standards{POSIX.1, unistd.h}
 @safety{@prelim{}@mtsafe{}@asunsafe{@ascuplugin{}}@acunsafe{@aculock{}}}
-@c The nptl/.../linux implementation safely collects fork_handlers into
-@c an alloca()ed linked list and increments ref counters; it uses atomic
-@c ops and retries, avoiding locking altogether.  It then takes the
-@c IO_list lock, resets the thread-local pid, and runs fork.  The parent
-@c restores the thread-local pid, releases the lock, and runs parent
-@c handlers, decrementing the ref count and signaling futex wait if
-@c requested by unregister_atfork.  The child bumps the fork generation,
-@c sets the thread-local pid, resets cpu clocks, initializes the robust
-@c mutex list, the stream locks, the IO_list lock, the dynamic loader
-@c lock, runs the child handlers, reseting ref counters to 1, and
+@c The posix/fork.c implementation iterates over the fork_handlers 
+@c using a lock.  It then takes the IO_list lock, resets the thread-local
+@c pid, and runs fork.  The parent releases the lock, and runs parent
+@c handlers, and unlocks the internal lock.  The child bumps the fork
+@c generation, sets the thread-local pid, resets cpu clocks, initializes
+@c the robust mutex list, the stream locks, the IO_list lock, the dynamic
+@c loader lock, runs the child handlers, reseting ref counters to 1, and
 @c initializes the fork lock.  These are all safe, unless atfork
 @c handlers themselves are unsafe.
 The @code{fork} function creates a new process.
@@ -322,6 +320,17 @@ process is cleared.  (The child process inherits its mask of blocked
 signals and signal actions from the parent process.)
 @end itemize
 
+@deftypefun pid_t _Fork (void)
+@standards{GNU, unistd.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+The @code{_Fork} function is similar to @code{fork} but does not issue
+any atfork callback registered with @code{pthread_atfork} neither reset
+any internal state or locks (such as the malloc one) and only setup a
+minimal state required to call async-signal-safe functions (such as raise
+or execve).
+
+It is an async-signal-safe replacement of @code{fork}.
+@end deftypefun
 
 @deftypefun pid_t vfork (void)
 @standards{BSD, unistd.h}
diff --git a/posix/Makefile b/posix/Makefile
index e0a7802012..25cd5bc456 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -114,7 +114,7 @@ test-srcs	:= globtest
 tests           += wordexp-test tst-exec tst-spawn tst-spawn2 tst-spawn3
 endif
 ifeq (yesyes,$(build-shared)$(have-thread-library))
-tests		+= tst-getopt-cancel
+tests		+= tst-getopt-cancel tst-_Fork
 endif
 tests-static	= tst-exec-static tst-spawn-static
 tests		+= $(tests-static)
@@ -283,6 +283,7 @@ $(objpfx)ptestcases.h: PTESTS PTESTS2C.sed
 $(objpfx)runptests.o: $(objpfx)ptestcases.h
 
 $(objpfx)tst-getopt-cancel: $(shared-thread-library)
+$(objpfx)tst-_Fork: $(shared-thread-library)
 
 test-xfail-annexc = yes
 $(objpfx)annexc.out: $(objpfx)annexc
diff --git a/posix/Versions b/posix/Versions
index cfd3819966..0ee433299e 100644
--- a/posix/Versions
+++ b/posix/Versions
@@ -147,6 +147,9 @@ libc {
   }
   GLIBC_2.30 {
   }
+  GLIBC_2.34 {
+    _Fork;
+  }
   GLIBC_PRIVATE {
     __libc_fork; __libc_pread; __libc_pwrite;
     __nanosleep_nocancel; __pause_nocancel;
diff --git a/posix/fork.c b/posix/fork.c
index 85c819c00f..1c4481f9c2 100644
--- a/posix/fork.c
+++ b/posix/fork.c
@@ -40,8 +40,10 @@ __libc_fork (void)
 {
   /* Determine if we are running multiple threads.  We skip some fork
      handlers in the single-thread case, to make fork safer to use in
-     signal handlers.  POSIX requires that fork is async-signal-safe,
-     but our current fork implementation is not.  */
+     signal handlers.  Although POSIX has dropped async-signal-safe
+     requirement for fork (Austin Group tracker issue #62) this is
+     best effort to make is async-signal-safe at least for single-thread
+     case.  */
   bool multiple_threads = __libc_single_threaded == 0;
 
   __run_fork_handlers (atfork_run_prepare, multiple_threads);
diff --git a/posix/tst-_Fork.c b/posix/tst-_Fork.c
new file mode 100644
index 0000000000..29a7ab6aaf
--- /dev/null
+++ b/posix/tst-_Fork.c
@@ -0,0 +1,218 @@
+/* Basic tests for _Fork.
+   Copyright (C) 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/>.  */
+
+#include <array_length.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include <stdbool.h>
+#include <support/check.h>
+#include <support/xsignal.h>
+#include <support/temp_file.h>
+#include <support/xunistd.h>
+#include <support/xthread.h>
+
+/* For single-thread, _Fork behaves like fork.  */
+static int
+singlethread_test (void)
+{
+  const char testdata1[] = "abcdefghijklmnopqrtuvwxz";
+  enum { testdatalen1 = array_length (testdata1) };
+  const char testdata2[] = "01234567890";
+  enum { testdatalen2 = array_length (testdata2) };
+
+  pid_t ppid = getpid ();
+
+  int tempfd = create_temp_file ("tst-_Fork", NULL);
+
+  /* Check if the opened file is shared between process by read and write
+     some data on parent and child processes.  */
+  xwrite (tempfd, testdata1, testdatalen1);
+  off_t off = xlseek (tempfd, 0, SEEK_CUR);
+  TEST_COMPARE (off, testdatalen1);
+
+  pid_t pid = _Fork ();
+  TEST_VERIFY_EXIT (pid != -1);
+  if (pid == 0)
+    {
+      TEST_VERIFY_EXIT (getpid () != ppid);
+      TEST_COMPARE (getppid(), ppid);
+
+      TEST_COMPARE (xlseek (tempfd, 0, SEEK_CUR), testdatalen1);
+
+      xlseek (tempfd, 0, SEEK_SET);
+      char buf[testdatalen1];
+      TEST_COMPARE (read (tempfd, buf, sizeof (buf)), testdatalen1);
+      TEST_COMPARE (memcmp (buf, testdata1, testdatalen1), 0);
+
+      xlseek (tempfd, 0, SEEK_SET);
+      xwrite (tempfd, testdata2, testdatalen2);
+
+      close (tempfd);
+
+      _exit (EXIT_SUCCESS);
+    }
+
+  int status;
+  xwaitpid (pid, &status, 0);
+  TEST_VERIFY (WIFEXITED (status));
+  TEST_COMPARE (WEXITSTATUS (status), EXIT_SUCCESS);
+
+  TEST_COMPARE (xlseek (tempfd, 0, SEEK_CUR), testdatalen2);
+
+  xlseek (tempfd, 0, SEEK_SET);
+  char buf[testdatalen2];
+  TEST_COMPARE (read (tempfd, buf, sizeof (buf)), testdatalen2);
+
+  TEST_COMPARE (memcmp (buf, testdata2, testdatalen2), 0);
+
+  return 0;
+}
+
+
+static volatile sig_atomic_t sigusr1_handler_ran;
+static pid_t sig_pid = -1;
+#define SIG_PID_EXIT_CODE 20
+
+static void
+sigusr1_handler (int signum)
+{
+  TEST_COMPARE (signum, SIGUSR1);
+
+  pid_t ppid = getpid ();
+
+  sig_pid = _Fork ();
+  TEST_VERIFY_EXIT (sig_pid != -1);
+  if (sig_pid == 0)
+    {
+      TEST_VERIFY_EXIT (getpid () != ppid);
+      TEST_COMPARE (getppid(), ppid);
+
+      _exit (SIG_PID_EXIT_CODE);
+    }
+
+  sigusr1_handler_ran = 1;
+}
+
+/* _Fork is async-signal-safe, so check if it can successfully issue
+    a new process in a signal handler.  */
+static int
+singlethread_signal_test (void)
+{
+  xsignal (SIGUSR1, &sigusr1_handler);
+  /* Assume synchronous signal handling.  */
+  xraise (SIGUSR1);
+  TEST_COMPARE (sigusr1_handler_ran, 1);
+
+  int status;
+  xwaitpid (sig_pid, &status, 0);
+  TEST_VERIFY (WIFEXITED (status));
+  TEST_COMPARE (WEXITSTATUS (status), SIG_PID_EXIT_CODE);
+
+  xsignal (SIGUSR1, SIG_DFL);
+
+  return 0;
+}
+
+
+static bool atfork_prepare_var;
+static bool atfork_parent_var;
+static bool atfork_child_var;
+
+static void
+atfork_prepare (void)
+{
+  atfork_prepare_var = true;
+}
+
+static void
+atfork_parent (void)
+{
+  atfork_parent_var = true;
+}
+
+static void
+atfork_child (void)
+{
+  atfork_child_var = true;
+}
+
+/* Different than fork, _Fork does not execute any pthread_atfork
+   handlers.  */
+static int
+singlethread_atfork_test (void)
+{
+  pthread_atfork (atfork_prepare, atfork_parent, atfork_child);
+  singlethread_test ();
+  TEST_COMPARE (atfork_prepare_var, false);
+  TEST_COMPARE (atfork_parent_var, false);
+  TEST_COMPARE (atfork_child_var, false);
+
+  return 0;
+}
+
+
+static void *
+mt_atfork_test (void *args)
+{
+  singlethread_atfork_test ();
+
+  return NULL;
+}
+
+static int
+multithread_atfork_test (void)
+{
+  pthread_t thr = xpthread_create (NULL, mt_atfork_test, NULL);
+  xpthread_join (thr);
+
+  return 0;
+}
+
+
+static void *
+mt_signal_test (void *args)
+{
+  singlethread_signal_test ();
+
+  return NULL;
+}
+
+static int
+multithread_signal_test (void)
+{
+  pthread_t thr = xpthread_create (NULL, mt_signal_test, NULL);
+  xpthread_join (thr);
+
+  return 0;
+}
+
+
+static int
+do_test (void)
+{
+  singlethread_atfork_test ();
+  singlethread_signal_test ();
+
+  multithread_atfork_test ();
+  multithread_signal_test ();
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/posix/unistd.h b/posix/unistd.h
index 3f22763379..670d471ac2 100644
--- a/posix/unistd.h
+++ b/posix/unistd.h
@@ -776,6 +776,13 @@ extern __pid_t fork (void) __THROWNL;
 extern __pid_t vfork (void) __THROW;
 #endif /* Use misc or XPG < 7. */
 
+#ifdef __USE_GNU
+/* This is similar to fork, however it does not run the atfork handlers
+   neither reinitialize any internal locks in multithread case.
+   Different than fork, _Fork is async-signal-safe.  */
+extern __pid_t _Fork (void) __THROWNL;
+#endif
+
 
 /* Return the pathname of the terminal FD is open on, or NULL on errors.
    The returned storage is good only until the next call to this function.  */
diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
index 509e9b7cb0..55834ca18b 100644
--- a/sysdeps/mach/hurd/i386/libc.abilist
+++ b/sysdeps/mach/hurd/i386/libc.abilist
@@ -2203,6 +2203,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index 4cc1c6a591..dc812707a2 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2171,3 +2171,4 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index 26ad9845e4..3b7e00c87b 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -2253,6 +2253,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist
index bb9dfd4daf..7a06fd731c 100644
--- a/sysdeps/unix/sysv/linux/arc/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arc/libc.abilist
@@ -1931,3 +1931,4 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
index 3b0a47e967..946568ac6a 100644
--- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
@@ -155,6 +155,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
 GLIBC_2.4 _IO_2_1_stdin_ D 0xa0
diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
index 9ab3924888..4d2d167974 100644
--- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
@@ -152,6 +152,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
 GLIBC_2.4 _IO_2_1_stdin_ D 0xa0
diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
index 14a84dac8f..d3092f5702 100644
--- a/sysdeps/unix/sysv/linux/csky/libc.abilist
+++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
@@ -2115,3 +2115,4 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index 5c8502f3d3..78a6fe365a 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -2074,6 +2074,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index ddc5837059..f21e646797 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -2241,6 +2241,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index e3b345b803..811da8c935 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -2106,6 +2106,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index 25f2d1c08f..1223fc32d7 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -156,6 +156,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0x98
 GLIBC_2.4 _IO_2_1_stdin_ D 0x98
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index c4891479d3..035d8d17fd 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -2186,6 +2186,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
index 143b0163b4..55d7144063 100644
--- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
@@ -2166,3 +2166,4 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
index 13d374a031..f4223a84cf 100644
--- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
@@ -2163,3 +2163,4 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index b2295f1937..1ccb65fe80 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -2157,6 +2157,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index 4c786070d0..27b7489778 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -2155,6 +2155,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index aa9c6a4dca..05b7afe7c8 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -2163,6 +2163,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index 5939588ad5..aa3845e160 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -2157,6 +2157,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index 92556c4237..efe35b8751 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2204,3 +2204,4 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index 26c93dff05..eda0349d39 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -2213,6 +2213,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index f04b167788..c51540783d 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -2246,6 +2246,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
index c2ca00709e..a508ef7e7a 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
@@ -2076,6 +2076,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
index 0ea50dc851..9366d54213 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
@@ -2366,3 +2366,4 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
index 0263e284d4..2a427fb493 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
@@ -1933,3 +1933,4 @@ GLIBC_2.33 wprintf F
 GLIBC_2.33 write F
 GLIBC_2.33 writev F
 GLIBC_2.33 wscanf F
+GLIBC_2.34 _Fork F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
index 1626c5351f..26dcd9ec47 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
@@ -2133,3 +2133,4 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index a66426eb4d..753b7a99fa 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -2211,6 +2211,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index ab351873ae..454f8d72ba 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -2112,6 +2112,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
index 22ceaa3d87..fe4d7b31ab 100644
--- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
@@ -2081,6 +2081,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
index d36f228192..7ef2df0f07 100644
--- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
@@ -2078,6 +2078,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index 59b4313280..380c51907a 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -2202,6 +2202,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index 266dcdfa08..3c3ad9188d 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -2129,6 +2129,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index 2744bba4af..aff31183eb 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -2088,6 +2088,7 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index ce2f4fb72b..fd6e98861c 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2185,3 +2185,4 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 _Fork F
-- 
2.25.1


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

* Re: [PATCH v2] posix: Add _Fork [BZ #4737]
  2021-02-11 15:26   ` [PATCH v2] " Adhemerval Zanella
@ 2021-02-11 16:21     ` Andreas Schwab
  2021-02-11 17:10       ` Adhemerval Zanella
  0 siblings, 1 reply; 38+ messages in thread
From: Andreas Schwab @ 2021-02-11 16:21 UTC (permalink / raw)
  To: Adhemerval Zanella via Libc-alpha

On Feb 11 2021, Adhemerval Zanella via Libc-alpha wrote:

> diff --git a/NEWS b/NEWS
> index 85e84fe536..b196dd2474 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -14,6 +14,14 @@ Major new features:
>    constant on Linux.  MINSIGSTKSZ is redefined to sysconf(_SC_MINSIGSTKSZ)
>    and SIGSTKSZ is redefined to sysconf (_SC_SIGSTKSZ).
>  
> +* The function _Fork has been added as a async-signal-safe fork
> +  replacement since Austin Group issue 62 droped the async-signal-safe
                                             dropped

> +  requirement for fork (and it will be included in the future POSIX

"a future" or "the next"?

> +  standard).  The new _Fork symbol does not issue any atfork handler neither
                               function does not run

> +  reset any internal state or lock (such as the malloc one) and only
     resets
> +  setup a minimal state required to call async-signal-safe functions (such
     sets up

> +  as raise or execve).  This function is currently a GNU extension.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."

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

* Re: [PATCH v2] posix: Add _Fork [BZ #4737]
  2021-02-11 16:21     ` Andreas Schwab
@ 2021-02-11 17:10       ` Adhemerval Zanella
  2021-02-11 17:33         ` Andreas Schwab
  0 siblings, 1 reply; 38+ messages in thread
From: Adhemerval Zanella @ 2021-02-11 17:10 UTC (permalink / raw)
  To: Andreas Schwab, Adhemerval Zanella via Libc-alpha



On 11/02/2021 13:21, Andreas Schwab wrote:
> On Feb 11 2021, Adhemerval Zanella via Libc-alpha wrote:
> 
>> diff --git a/NEWS b/NEWS
>> index 85e84fe536..b196dd2474 100644
>> --- a/NEWS
>> +++ b/NEWS
>> @@ -14,6 +14,14 @@ Major new features:
>>    constant on Linux.  MINSIGSTKSZ is redefined to sysconf(_SC_MINSIGSTKSZ)
>>    and SIGSTKSZ is redefined to sysconf (_SC_SIGSTKSZ).
>>  
>> +* The function _Fork has been added as a async-signal-safe fork
>> +  replacement since Austin Group issue 62 droped the async-signal-safe
>                                              dropped
> 
>> +  requirement for fork (and it will be included in the future POSIX
> 
> "a future" or "the next"?

Afaik in the next revision, I will fix it.

> 
>> +  standard).  The new _Fork symbol does not issue any atfork handler neither
>                                function does not run

I changed to 'The new _Fork symbol does not run any atfork function ...'.

> 
>> +  reset any internal state or lock (such as the malloc one) and only
>      resets

Ack.

>> +  setup a minimal state required to call async-signal-safe functions (such
>      sets up

Ack.

> 
>> +  as raise or execve).  This function is currently a GNU extension.
> 
> Andreas.
> 

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

* Re: [PATCH v2] posix: Add _Fork [BZ #4737]
  2021-02-11 17:10       ` Adhemerval Zanella
@ 2021-02-11 17:33         ` Andreas Schwab
  2021-02-11 17:36           ` Adhemerval Zanella
  0 siblings, 1 reply; 38+ messages in thread
From: Andreas Schwab @ 2021-02-11 17:33 UTC (permalink / raw)
  To: Adhemerval Zanella via Libc-alpha

On Feb 11 2021, Adhemerval Zanella via Libc-alpha wrote:

> I changed to 'The new _Fork symbol does not run any atfork function ...'.

A symbol doesn't run anything.  It's the function that the symbol
designates that does it.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."

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

* Re: [PATCH v2] posix: Add _Fork [BZ #4737]
  2021-02-11 17:33         ` Andreas Schwab
@ 2021-02-11 17:36           ` Adhemerval Zanella
  0 siblings, 0 replies; 38+ messages in thread
From: Adhemerval Zanella @ 2021-02-11 17:36 UTC (permalink / raw)
  To: Andreas Schwab, Adhemerval Zanella via Libc-alpha



On 11/02/2021 14:33, Andreas Schwab wrote:
> On Feb 11 2021, Adhemerval Zanella via Libc-alpha wrote:
> 
>> I changed to 'The new _Fork symbol does not run any atfork function ...'.
> 
> A symbol doesn't run anything.  It's the function that the symbol
> designates that does it.
> 

Ack, I replace symbol with function.

> Andreas.
> 

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

* Re: [PATCH 7/8] support: Add xpthread_kill
  2021-02-02 15:11 ` [PATCH 7/8] support: Add xpthread_kill Adhemerval Zanella
@ 2021-03-08 12:13   ` Florian Weimer
  0 siblings, 0 replies; 38+ messages in thread
From: Florian Weimer @ 2021-03-08 12:13 UTC (permalink / raw)
  To: Adhemerval Zanella via Libc-alpha

* Adhemerval Zanella via Libc-alpha:

> Checked on x86_64-linux-gnu.

This is okay, thanks.

Florian


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

* Re: [PATCH 1/8] posix: Consolidate register-atfork
  2021-02-02 15:11 [PATCH 1/8] posix: Consolidate register-atfork Adhemerval Zanella
                   ` (6 preceding siblings ...)
  2021-02-02 15:11 ` [PATCH 8/8] posix: Add _Fork [BZ #4737] Adhemerval Zanella
@ 2021-03-08 13:04 ` Florian Weimer
  7 siblings, 0 replies; 38+ messages in thread
From: Florian Weimer @ 2021-03-08 13:04 UTC (permalink / raw)
  To: Adhemerval Zanella via Libc-alpha

* Adhemerval Zanella via Libc-alpha:

> Both htl and nptl uses a different data structure to implement atfork
> handlers.  The nptl one was refactored by 27761a1042d to use a dynarray
> which simplifies the code.
>
> This patch moves the nptl one to be the generic implementation and
> replace Hurd linked one.  Different than previous NPTL, Hurd also uses
> a global lock, so performance should be similar.
>
> Checked on x86_64-linux-gnu, i686-linux-gnu, and with a build for
> i686-gnu.

This looks okay to me (but it would be nice if a Hurd developer could
review too).

Thanks,
Florian


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

* Re: [PATCH 4/8] nptl: Move fork into libc
  2021-02-02 15:11 ` [PATCH 4/8] nptl: Move fork into libc Adhemerval Zanella
@ 2021-03-08 13:42   ` Florian Weimer
  2021-03-10 17:08     ` Adhemerval Zanella
  0 siblings, 1 reply; 38+ messages in thread
From: Florian Weimer @ 2021-03-08 13:42 UTC (permalink / raw)
  To: Adhemerval Zanella via Libc-alpha

* Adhemerval Zanella via Libc-alpha:

> This is part of the libpthread removal project:
>
>    <https://sourceware.org/ml/libc-alpha/2019-10/msg00080.html>
>
> Checked on x86_64-linux-gnu.

I assume you used script/move-symbol-to-libc.py for this?  The patch
looks okay.

Thanks,
Florian


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

* Re: [PATCH 3/8] posix: Consolidate fork implementation
  2021-02-02 15:11 ` [PATCH 3/8] posix: Consolidate fork implementation Adhemerval Zanella
@ 2021-03-09 10:58   ` Florian Weimer
  2021-03-10 17:07     ` Adhemerval Zanella
  2021-03-11 13:56   ` Andreas Schwab
  1 sibling, 1 reply; 38+ messages in thread
From: Florian Weimer @ 2021-03-09 10:58 UTC (permalink / raw)
  To: Adhemerval Zanella via Libc-alpha

* Adhemerval Zanella via Libc-alpha:

> diff --git a/sysdeps/nptl/_Fork.c b/sysdeps/nptl/_Fork.c
> new file mode 100644
> index 0000000000..9c701bc3d7
> --- /dev/null
> +++ b/sysdeps/nptl/_Fork.c

> +pid_t
> +_Fork (void)
> +{
> +  pid_t pid = arch_fork (&THREAD_SELF->tid);
> +  if (pid == 0)
> +    {
> +      struct pthread *self = THREAD_SELF;
> +
> +      /* See __pthread_once.  */
> +      if (__fork_generation_pointer != NULL)
> +	*__fork_generation_pointer += __PTHREAD_ONCE_FORK_GEN_INCR;

This should not be part of _Fork, I think.  There is no need to do that
for a new interface.

I think this means that there has to be _Fork, the generic fork
implementation, and something between _Fork and fork that performs the
architecture-specific bits.

Hurd may also need this for its internal fork handlers if they are
supposed to run for fork, but not for _Fork.

Given that this affects the way functionality is split in the
consolidation, I have not reviewed this version of the patch further.

Thanks,
Florian


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

* Re: [PATCH 5/8] posix: Do not clobber errno by atfork handlers
  2021-02-02 15:11 ` [PATCH 5/8] posix: Do not clobber errno by atfork handlers Adhemerval Zanella
@ 2021-03-09 11:01   ` Florian Weimer
  2021-03-10 20:10     ` Adhemerval Zanella
  0 siblings, 1 reply; 38+ messages in thread
From: Florian Weimer @ 2021-03-09 11:01 UTC (permalink / raw)
  To: Adhemerval Zanella via Libc-alpha

* Adhemerval Zanella via Libc-alpha:

> Checked on x86_64-linux-gnu.
> ---
>  posix/fork.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/posix/fork.c b/posix/fork.c
> index 4c9e60f187..7f27fb8338 100644
> --- a/posix/fork.c
> +++ b/posix/fork.c
> @@ -68,7 +68,7 @@ __libc_fork (void)
>      }
>  
>    pid_t pid = _Fork ();
> -
> +  int save_errno = errno;
>    if (pid == 0)
>      {
>        /* Reset the lock state in the multi-threaded case.  */
> @@ -107,6 +107,8 @@ __libc_fork (void)
>    __run_fork_handlers (pid == 0 ? atfork_run_child : atfork_run_parent,
>  		       multiple_threads);
>  
> +  if (pid < 0)
> +    __set_errno (save_errno);
>    return pid;
>  }
>  weak_alias (__libc_fork, __fork)

Why is this condition correct?  Shouldn't it be pid >= 0?

I wonder if this should be part of __run_fork_handlers, so that fork
handlers always observe the original errno value.

Thanks,
Florian


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

* Re: [PATCH 6/8] Consolidate pthread_atfork
  2021-02-02 15:11 ` [PATCH 6/8] Consolidate pthread_atfork Adhemerval Zanella
@ 2021-03-09 11:09   ` Florian Weimer
  2021-03-10 20:15     ` Adhemerval Zanella
  0 siblings, 1 reply; 38+ messages in thread
From: Florian Weimer @ 2021-03-09 11:09 UTC (permalink / raw)
  To: Adhemerval Zanella via Libc-alpha

* Adhemerval Zanella via Libc-alpha:

> diff --git a/sysdeps/htl/pthread_atfork_compat.h b/sysdeps/htl/pthread_atfork_compat.h
> new file mode 100644
> index 0000000000..8943a148e8
> --- /dev/null
> +++ b/sysdeps/htl/pthread_atfork_compat.h
> @@ -0,0 +1,2 @@
> +#define PTHREAD_ATFORK_COMPAT_INTRODUCED  GLIBC_2_12
> +#define PTHREAD_ATFORK_COMPAT_OBSOLETED   GLIBC_2_23
> diff --git a/sysdeps/nptl/pthread_atfork_compat.h b/sysdeps/nptl/pthread_atfork_compat.h
> new file mode 100644
> index 0000000000..d3ab9373b3
> --- /dev/null
> +++ b/sysdeps/nptl/pthread_atfork_compat.h
> @@ -0,0 +1,2 @@
> +#define PTHREAD_ATFORK_COMPAT_INTRODUCED  GLIBC_2_0
> +#define PTHREAD_ATFORK_COMPAT_OBSOLETED   GLIBC_2_3

These files should have comments.

We need to move the pthread_atfork compatibility symbol eventually, but
that can wait.

Thanks,
Florian


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

* Re: [PATCH 3/8] posix: Consolidate fork implementation
  2021-03-09 10:58   ` Florian Weimer
@ 2021-03-10 17:07     ` Adhemerval Zanella
  0 siblings, 0 replies; 38+ messages in thread
From: Adhemerval Zanella @ 2021-03-10 17:07 UTC (permalink / raw)
  To: Florian Weimer, Adhemerval Zanella via Libc-alpha



On 09/03/2021 07:58, Florian Weimer wrote:
> * Adhemerval Zanella via Libc-alpha:
> 
>> diff --git a/sysdeps/nptl/_Fork.c b/sysdeps/nptl/_Fork.c
>> new file mode 100644
>> index 0000000000..9c701bc3d7
>> --- /dev/null
>> +++ b/sysdeps/nptl/_Fork.c
> 
>> +pid_t
>> +_Fork (void)
>> +{
>> +  pid_t pid = arch_fork (&THREAD_SELF->tid);
>> +  if (pid == 0)
>> +    {
>> +      struct pthread *self = THREAD_SELF;
>> +
>> +      /* See __pthread_once.  */
>> +      if (__fork_generation_pointer != NULL)
>> +	*__fork_generation_pointer += __PTHREAD_ONCE_FORK_GEN_INCR;
> 
> This should not be part of _Fork, I think.  There is no need to do that
> for a new interface.

I think you are right, this is used solely for pthread_once and it is not
marked as async-signal-safe (so there is no need to keep it on Linux
_Fork implementation).

> 
> I think this means that there has to be _Fork, the generic fork
> implementation, and something between _Fork and fork that performs the
> architecture-specific bits.

It should be simpler to add a inline hook on fork instead, so the 
sequence would be:

posix/fork.c
   [...]
   pid_t pid = _Fork ();
   if (pid == 0)
     {
       __fork_system_setup ();
       [...]
     }

And __fork_system_setup () is implemented on Linux to setup the required
fork generation for pthread_once (with an empty generic one).

> 
> Hurd may also need this for its internal fork handlers if they are
> supposed to run for fork, but not for _Fork.

I did not dig into Hurd implementation, but I tried to make its _Fork
to no run pthread_atfork as well.  It does use the old callback 
mechanism:

sysdeps/mach/hurd/_Fork.c

 41 /* Things that want to be called before we fork, to prepare the parent for
 42    task_create, when the new child task will inherit our address space.  */
 43 DEFINE_HOOK (_hurd_fork_prepare_hook, (void));
 44 
 45 /* Things that want to be called when we are forking, with the above all
 46    locked.  They are passed the task port of the child.  The child process
 47    is all set up except for doing proc_child, and has no threads yet.  */
 48 DEFINE_HOOK (_hurd_fork_setup_hook, (void));
 49 
 50 /* Things to be run in the child fork.  */
 51 DEFINE_HOOK (_hurd_fork_child_hook, (void));
 52 
 53 /* Things to be run in the parent fork.  */
 54 DEFINE_HOOK (_hurd_fork_parent_hook, (void));

sysdeps/mach/hurd/profil.c:213:text_set_element (_hurd_fork_prepare_hook, fork_profil_prepare);

sysdeps/mach/hurd/profil.c:255:text_set_element (_hurd_fork_child_hook, fork_profil_child);
sysdeps/mach/hurd/setitimer.c:377:text_set_element (_hurd_fork_child_hook, fork_itimer);

sysdeps/mach/hurd/profil.c:221:text_set_element (_hurd_fork_parent_hook, fork_profil_parent);

The hooks seems to be self-contained and there are only a handful of them,
so maybe Hurd developers could cleanup this up and run in directly
instead.

The __run_fork_handlers is only called from fork.c now.

> 
> Given that this affects the way functionality is split in the
> consolidation, I have not reviewed this version of the patch further.

Alright, I will update the patch.

 

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

* Re: [PATCH 4/8] nptl: Move fork into libc
  2021-03-08 13:42   ` Florian Weimer
@ 2021-03-10 17:08     ` Adhemerval Zanella
  0 siblings, 0 replies; 38+ messages in thread
From: Adhemerval Zanella @ 2021-03-10 17:08 UTC (permalink / raw)
  To: Florian Weimer, Adhemerval Zanella via Libc-alpha



On 08/03/2021 10:42, Florian Weimer wrote:
> * Adhemerval Zanella via Libc-alpha:
> 
>> This is part of the libpthread removal project:
>>
>>    <https://sourceware.org/ml/libc-alpha/2019-10/msg00080.html>
>>
>> Checked on x86_64-linux-gnu.
> 
> I assume you used script/move-symbol-to-libc.py for this?  The patch
> looks okay.

I will double-check, but if I recall correctly I did use the script.

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

* Re: [PATCH 5/8] posix: Do not clobber errno by atfork handlers
  2021-03-09 11:01   ` Florian Weimer
@ 2021-03-10 20:10     ` Adhemerval Zanella
  2021-03-11 13:25       ` Florian Weimer
  0 siblings, 1 reply; 38+ messages in thread
From: Adhemerval Zanella @ 2021-03-10 20:10 UTC (permalink / raw)
  To: Florian Weimer, Adhemerval Zanella via Libc-alpha



On 09/03/2021 08:01, Florian Weimer wrote:
> * Adhemerval Zanella via Libc-alpha:
> 
>> Checked on x86_64-linux-gnu.
>> ---
>>  posix/fork.c | 4 +++-
>>  1 file changed, 3 insertions(+), 1 deletion(-)
>>
>> diff --git a/posix/fork.c b/posix/fork.c
>> index 4c9e60f187..7f27fb8338 100644
>> --- a/posix/fork.c
>> +++ b/posix/fork.c
>> @@ -68,7 +68,7 @@ __libc_fork (void)
>>      }
>>  
>>    pid_t pid = _Fork ();
>> -
>> +  int save_errno = errno;
>>    if (pid == 0)
>>      {
>>        /* Reset the lock state in the multi-threaded case.  */
>> @@ -107,6 +107,8 @@ __libc_fork (void)
>>    __run_fork_handlers (pid == 0 ? atfork_run_child : atfork_run_parent,
>>  		       multiple_threads);
>>  
>> +  if (pid < 0)
>> +    __set_errno (save_errno);
>>    return pid;
>>  }
>>  weak_alias (__libc_fork, __fork)
> 
> Why is this condition correct?  Shouldn't it be pid >= 0?

But pid >= 0 is a valid call which should not set errno.  The idea is
to return the _Fork error value even if some atfork handler in the
parent does clobber it.

> 
> I wonder if this should be part of __run_fork_handlers, so that fork
> handlers always observe the original errno value.

I am not sure about it, checking the errno without actually calling a
function that might setting it is error-prone imho.

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

* Re: [PATCH 6/8] Consolidate pthread_atfork
  2021-03-09 11:09   ` Florian Weimer
@ 2021-03-10 20:15     ` Adhemerval Zanella
  0 siblings, 0 replies; 38+ messages in thread
From: Adhemerval Zanella @ 2021-03-10 20:15 UTC (permalink / raw)
  To: Florian Weimer, Adhemerval Zanella via Libc-alpha



On 09/03/2021 08:09, Florian Weimer wrote:
> * Adhemerval Zanella via Libc-alpha:
> 
>> diff --git a/sysdeps/htl/pthread_atfork_compat.h b/sysdeps/htl/pthread_atfork_compat.h
>> new file mode 100644
>> index 0000000000..8943a148e8
>> --- /dev/null
>> +++ b/sysdeps/htl/pthread_atfork_compat.h
>> @@ -0,0 +1,2 @@
>> +#define PTHREAD_ATFORK_COMPAT_INTRODUCED  GLIBC_2_12
>> +#define PTHREAD_ATFORK_COMPAT_OBSOLETED   GLIBC_2_23
>> diff --git a/sysdeps/nptl/pthread_atfork_compat.h b/sysdeps/nptl/pthread_atfork_compat.h
>> new file mode 100644
>> index 0000000000..d3ab9373b3
>> --- /dev/null
>> +++ b/sysdeps/nptl/pthread_atfork_compat.h
>> @@ -0,0 +1,2 @@
>> +#define PTHREAD_ATFORK_COMPAT_INTRODUCED  GLIBC_2_0
>> +#define PTHREAD_ATFORK_COMPAT_OBSOLETED   GLIBC_2_3
> 
> These files should have comments.

Ack.

> 
> We need to move the pthread_atfork compatibility symbol eventually, but
> that can wait.
> 
> Thanks,
> Florian
> 

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

* Re: [PATCH 5/8] posix: Do not clobber errno by atfork handlers
  2021-03-10 20:10     ` Adhemerval Zanella
@ 2021-03-11 13:25       ` Florian Weimer
  2021-03-11 14:07         ` Adhemerval Zanella
  0 siblings, 1 reply; 38+ messages in thread
From: Florian Weimer @ 2021-03-11 13:25 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: Adhemerval Zanella via Libc-alpha

* Adhemerval Zanella:

> On 09/03/2021 08:01, Florian Weimer wrote:
>> * Adhemerval Zanella via Libc-alpha:
>> 
>>> Checked on x86_64-linux-gnu.
>>> ---
>>>  posix/fork.c | 4 +++-
>>>  1 file changed, 3 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/posix/fork.c b/posix/fork.c
>>> index 4c9e60f187..7f27fb8338 100644
>>> --- a/posix/fork.c
>>> +++ b/posix/fork.c
>>> @@ -68,7 +68,7 @@ __libc_fork (void)
>>>      }
>>>  
>>>    pid_t pid = _Fork ();
>>> -
>>> +  int save_errno = errno;
>>>    if (pid == 0)
>>>      {
>>>        /* Reset the lock state in the multi-threaded case.  */
>>> @@ -107,6 +107,8 @@ __libc_fork (void)
>>>    __run_fork_handlers (pid == 0 ? atfork_run_child : atfork_run_parent,
>>>  		       multiple_threads);
>>>  
>>> +  if (pid < 0)
>>> +    __set_errno (save_errno);
>>>    return pid;
>>>  }
>>>  weak_alias (__libc_fork, __fork)
>> 
>> Why is this condition correct?  Shouldn't it be pid >= 0?
>
> But pid >= 0 is a valid call which should not set errno.  The idea is
> to return the _Fork error value even if some atfork handler in the
> parent does clobber it.

Then maybe move that into the else part for the parent (on fork error
there is no subprocess) and add a comment?

Thanks,
Florian


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

* Re: [PATCH 3/8] posix: Consolidate fork implementation
  2021-02-02 15:11 ` [PATCH 3/8] posix: Consolidate fork implementation Adhemerval Zanella
  2021-03-09 10:58   ` Florian Weimer
@ 2021-03-11 13:56   ` Andreas Schwab
  2021-03-11 13:59     ` Adhemerval Zanella
  1 sibling, 1 reply; 38+ messages in thread
From: Andreas Schwab @ 2021-03-11 13:56 UTC (permalink / raw)
  To: Adhemerval Zanella via Libc-alpha

On Feb 02 2021, Adhemerval Zanella via Libc-alpha wrote:

> +pid_t
> +__libc_fork (void)
>  {
> -  __set_errno (ENOSYS);
> -  return -1;
> +  /* Determine if we are running multiple threads.  We skip some fork
> +     handlers in the single-thread case, to make fork safer to use in
> +     signal handlers.  POSIX requires that fork is async-signal-safe,
> +     but our current fork implementation is not.  */

The last sentence is now obsolete, isn't it?

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."

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

* Re: [PATCH 3/8] posix: Consolidate fork implementation
  2021-03-11 13:56   ` Andreas Schwab
@ 2021-03-11 13:59     ` Adhemerval Zanella
  0 siblings, 0 replies; 38+ messages in thread
From: Adhemerval Zanella @ 2021-03-11 13:59 UTC (permalink / raw)
  To: Andreas Schwab, Adhemerval Zanella via Libc-alpha



On 11/03/2021 10:56, Andreas Schwab wrote:
> On Feb 02 2021, Adhemerval Zanella via Libc-alpha wrote:
> 
>> +pid_t
>> +__libc_fork (void)
>>  {
>> -  __set_errno (ENOSYS);
>> -  return -1;
>> +  /* Determine if we are running multiple threads.  We skip some fork
>> +     handlers in the single-thread case, to make fork safer to use in
>> +     signal handlers.  POSIX requires that fork is async-signal-safe,
>> +     but our current fork implementation is not.  */
> 
> The last sentence is now obsolete, isn't it?

It is, I will remove it.


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

* Re: [PATCH 5/8] posix: Do not clobber errno by atfork handlers
  2021-03-11 13:25       ` Florian Weimer
@ 2021-03-11 14:07         ` Adhemerval Zanella
  2021-03-11 14:22           ` Andreas Schwab
  0 siblings, 1 reply; 38+ messages in thread
From: Adhemerval Zanella @ 2021-03-11 14:07 UTC (permalink / raw)
  To: Florian Weimer; +Cc: Adhemerval Zanella via Libc-alpha



On 11/03/2021 10:25, Florian Weimer wrote:
> * Adhemerval Zanella:
> 
>> On 09/03/2021 08:01, Florian Weimer wrote:
>>> * Adhemerval Zanella via Libc-alpha:
>>>
>>>> Checked on x86_64-linux-gnu.
>>>> ---
>>>>  posix/fork.c | 4 +++-
>>>>  1 file changed, 3 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/posix/fork.c b/posix/fork.c
>>>> index 4c9e60f187..7f27fb8338 100644
>>>> --- a/posix/fork.c
>>>> +++ b/posix/fork.c
>>>> @@ -68,7 +68,7 @@ __libc_fork (void)
>>>>      }
>>>>  
>>>>    pid_t pid = _Fork ();
>>>> -
>>>> +  int save_errno = errno;
>>>>    if (pid == 0)
>>>>      {
>>>>        /* Reset the lock state in the multi-threaded case.  */
>>>> @@ -107,6 +107,8 @@ __libc_fork (void)
>>>>    __run_fork_handlers (pid == 0 ? atfork_run_child : atfork_run_parent,
>>>>  		       multiple_threads);
>>>>  
>>>> +  if (pid < 0)
>>>> +    __set_errno (save_errno);
>>>>    return pid;
>>>>  }
>>>>  weak_alias (__libc_fork, __fork)
>>>
>>> Why is this condition correct?  Shouldn't it be pid >= 0?
>>
>> But pid >= 0 is a valid call which should not set errno.  The idea is
>> to return the _Fork error value even if some atfork handler in the
>> parent does clobber it.
> 
> Then maybe move that into the else part for the parent (on fork error
> there is no subprocess) and add a comment?

But we need to restore it *after* __run_fork_handlers calls. I will
add the comment to make it explicit:

  /* Restore the errno value even if some atfork handler in the parent                                
     clobber it.  */
  if (pid < 0)
    __set_errno (save_errno)

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

* Re: [PATCH 5/8] posix: Do not clobber errno by atfork handlers
  2021-03-11 14:07         ` Adhemerval Zanella
@ 2021-03-11 14:22           ` Andreas Schwab
  2021-03-11 14:25             ` Florian Weimer
  0 siblings, 1 reply; 38+ messages in thread
From: Andreas Schwab @ 2021-03-11 14:22 UTC (permalink / raw)
  To: Adhemerval Zanella via Libc-alpha; +Cc: Florian Weimer, Adhemerval Zanella

On Mär 11 2021, Adhemerval Zanella via Libc-alpha wrote:

> But we need to restore it *after* __run_fork_handlers calls. I will
> add the comment to make it explicit:
>
>   /* Restore the errno value even if some atfork handler in the parent                                
>      clobber it.  */

Perhaps: "If _Fork failed, preserve its errno value."

>   if (pid < 0)
>     __set_errno (save_errno)

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."

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

* Re: [PATCH 5/8] posix: Do not clobber errno by atfork handlers
  2021-03-11 14:22           ` Andreas Schwab
@ 2021-03-11 14:25             ` Florian Weimer
  2021-03-11 15:29               ` Adhemerval Zanella
  0 siblings, 1 reply; 38+ messages in thread
From: Florian Weimer @ 2021-03-11 14:25 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Adhemerval Zanella via Libc-alpha, Adhemerval Zanella

* Andreas Schwab:

> On Mär 11 2021, Adhemerval Zanella via Libc-alpha wrote:
>
>> But we need to restore it *after* __run_fork_handlers calls. I will
>> add the comment to make it explicit:
>>
>>   /* Restore the errno value even if some atfork handler in the parent                                
>>      clobber it.  */
>
> Perhaps: "If _Fork failed, preserve its errno value."
>
>>   if (pid < 0)
>>     __set_errno (save_errno)

Agreed.  And then it's clear it should be moved to the parent branch of
the if statement above.

Thanks,
Florian


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

* Re: [PATCH 5/8] posix: Do not clobber errno by atfork handlers
  2021-03-11 14:25             ` Florian Weimer
@ 2021-03-11 15:29               ` Adhemerval Zanella
  2021-03-11 15:32                 ` Florian Weimer
  0 siblings, 1 reply; 38+ messages in thread
From: Adhemerval Zanella @ 2021-03-11 15:29 UTC (permalink / raw)
  To: Florian Weimer, Andreas Schwab; +Cc: Adhemerval Zanella via Libc-alpha



On 11/03/2021 11:25, Florian Weimer wrote:
> * Andreas Schwab:
> 
>> On Mär 11 2021, Adhemerval Zanella via Libc-alpha wrote:
>>
>>> But we need to restore it *after* __run_fork_handlers calls. I will
>>> add the comment to make it explicit:
>>>
>>>   /* Restore the errno value even if some atfork handler in the parent                                
>>>      clobber it.  */
>>
>> Perhaps: "If _Fork failed, preserve its errno value."

Ack.

>>
>>>   if (pid < 0)
>>>     __set_errno (save_errno)
> 
> Agreed.  And then it's clear it should be moved to the parent branch of
> the if statement above.
> 

But moving it before __run_fork_handlers in the the previous if (which
handles the pid != 0) will both 1. reset the errno even for success
(pid > 0) and 2. not fixing the issue since __run_fork_handlers will
be issue later. What I am missing in your suggestion? 

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

* Re: [PATCH 5/8] posix: Do not clobber errno by atfork handlers
  2021-03-11 15:29               ` Adhemerval Zanella
@ 2021-03-11 15:32                 ` Florian Weimer
  2021-03-11 17:25                   ` Adhemerval Zanella
  0 siblings, 1 reply; 38+ messages in thread
From: Florian Weimer @ 2021-03-11 15:32 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: Andreas Schwab, Adhemerval Zanella via Libc-alpha

* Adhemerval Zanella:

>>>>   if (pid < 0)
>>>>     __set_errno (save_errno)
>> 
>> Agreed.  And then it's clear it should be moved to the parent branch of
>> the if statement above.
>> 
>
> But moving it before __run_fork_handlers in the the previous if (which
> handles the pid != 0) will both 1. reset the errno even for success
> (pid > 0) and 2. not fixing the issue since __run_fork_handlers will
> be issue later. What I am missing in your suggestion? 

After the __run_fork_handlers call on the parent branch.

Thanks,
Florian


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

* Re: [PATCH 5/8] posix: Do not clobber errno by atfork handlers
  2021-03-11 15:32                 ` Florian Weimer
@ 2021-03-11 17:25                   ` Adhemerval Zanella
  2021-03-11 19:23                     ` Florian Weimer
  0 siblings, 1 reply; 38+ messages in thread
From: Adhemerval Zanella @ 2021-03-11 17:25 UTC (permalink / raw)
  To: Florian Weimer; +Cc: Andreas Schwab, Adhemerval Zanella via Libc-alpha



On 11/03/2021 12:32, Florian Weimer wrote:
> * Adhemerval Zanella:
> 
>>>>>   if (pid < 0)
>>>>>     __set_errno (save_errno)
>>>
>>> Agreed.  And then it's clear it should be moved to the parent branch of
>>> the if statement above.
>>>
>>
>> But moving it before __run_fork_handlers in the the previous if (which
>> handles the pid != 0) will both 1. reset the errno even for success
>> (pid > 0) and 2. not fixing the issue since __run_fork_handlers will
>> be issue later. What I am missing in your suggestion? 
> 
> After the __run_fork_handlers call on the parent branch.

Why is this an improvement over doing on fork.c, now that with
this change is the only caller of __run_fork_handlers and the
routine with the information (pid result) to restore the
errno?

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

* Re: [PATCH 5/8] posix: Do not clobber errno by atfork handlers
  2021-03-11 17:25                   ` Adhemerval Zanella
@ 2021-03-11 19:23                     ` Florian Weimer
  2021-03-11 19:30                       ` Adhemerval Zanella
  0 siblings, 1 reply; 38+ messages in thread
From: Florian Weimer @ 2021-03-11 19:23 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: Andreas Schwab, Adhemerval Zanella via Libc-alpha

* Adhemerval Zanella:

> On 11/03/2021 12:32, Florian Weimer wrote:
>> * Adhemerval Zanella:
>> 
>>>>>>   if (pid < 0)
>>>>>>     __set_errno (save_errno)
>>>>
>>>> Agreed.  And then it's clear it should be moved to the parent branch of
>>>> the if statement above.
>>>>
>>>
>>> But moving it before __run_fork_handlers in the the previous if (which
>>> handles the pid != 0) will both 1. reset the errno even for success
>>> (pid > 0) and 2. not fixing the issue since __run_fork_handlers will
>>> be issue later. What I am missing in your suggestion? 
>> 
>> After the __run_fork_handlers call on the parent branch.
>
> Why is this an improvement over doing on fork.c, now that with
> this change is the only caller of __run_fork_handlers and the
> routine with the information (pid result) to restore the
> errno?

I suggest to leave it in fork.c, but put it in the parent branch,
instead after the if statement.  The code only runs if fork fails, so
it's something the parent process needs to do.  It's not cleanup that
has to happen on both paths.  The compiler will likely optimize it to
identical machine code, but I think it's helpful to the reader to put it
on the parent execution path.

Thanks,
Florian


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

* Re: [PATCH 5/8] posix: Do not clobber errno by atfork handlers
  2021-03-11 19:23                     ` Florian Weimer
@ 2021-03-11 19:30                       ` Adhemerval Zanella
  0 siblings, 0 replies; 38+ messages in thread
From: Adhemerval Zanella @ 2021-03-11 19:30 UTC (permalink / raw)
  To: Florian Weimer; +Cc: Andreas Schwab, Adhemerval Zanella via Libc-alpha



On 11/03/2021 16:23, Florian Weimer wrote:
> * Adhemerval Zanella:
> 
>> On 11/03/2021 12:32, Florian Weimer wrote:
>>> * Adhemerval Zanella:
>>>
>>>>>>>   if (pid < 0)
>>>>>>>     __set_errno (save_errno)
>>>>>
>>>>> Agreed.  And then it's clear it should be moved to the parent branch of
>>>>> the if statement above.
>>>>>
>>>>
>>>> But moving it before __run_fork_handlers in the the previous if (which
>>>> handles the pid != 0) will both 1. reset the errno even for success
>>>> (pid > 0) and 2. not fixing the issue since __run_fork_handlers will
>>>> be issue later. What I am missing in your suggestion? 
>>>
>>> After the __run_fork_handlers call on the parent branch.
>>
>> Why is this an improvement over doing on fork.c, now that with
>> this change is the only caller of __run_fork_handlers and the
>> routine with the information (pid result) to restore the
>> errno?
> 
> I suggest to leave it in fork.c, but put it in the parent branch,
> instead after the if statement.  The code only runs if fork fails, so
> it's something the parent process needs to do.  It's not cleanup that
> has to happen on both paths.  The compiler will likely optimize it to
> identical machine code, but I think it's helpful to the reader to put it
> on the parent execution path.

Right, I got it now your suggestion.

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

end of thread, other threads:[~2021-03-11 19:30 UTC | newest]

Thread overview: 38+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-02 15:11 [PATCH 1/8] posix: Consolidate register-atfork Adhemerval Zanella
2021-02-02 15:11 ` [PATCH 2/8] linux: Use __libc_single_threaded on fork Adhemerval Zanella
2021-02-02 15:15   ` Andreas Schwab
2021-02-02 16:40     ` Adhemerval Zanella
2021-02-02 15:11 ` [PATCH 3/8] posix: Consolidate fork implementation Adhemerval Zanella
2021-03-09 10:58   ` Florian Weimer
2021-03-10 17:07     ` Adhemerval Zanella
2021-03-11 13:56   ` Andreas Schwab
2021-03-11 13:59     ` Adhemerval Zanella
2021-02-02 15:11 ` [PATCH 4/8] nptl: Move fork into libc Adhemerval Zanella
2021-03-08 13:42   ` Florian Weimer
2021-03-10 17:08     ` Adhemerval Zanella
2021-02-02 15:11 ` [PATCH 5/8] posix: Do not clobber errno by atfork handlers Adhemerval Zanella
2021-03-09 11:01   ` Florian Weimer
2021-03-10 20:10     ` Adhemerval Zanella
2021-03-11 13:25       ` Florian Weimer
2021-03-11 14:07         ` Adhemerval Zanella
2021-03-11 14:22           ` Andreas Schwab
2021-03-11 14:25             ` Florian Weimer
2021-03-11 15:29               ` Adhemerval Zanella
2021-03-11 15:32                 ` Florian Weimer
2021-03-11 17:25                   ` Adhemerval Zanella
2021-03-11 19:23                     ` Florian Weimer
2021-03-11 19:30                       ` Adhemerval Zanella
2021-02-02 15:11 ` [PATCH 6/8] Consolidate pthread_atfork Adhemerval Zanella
2021-03-09 11:09   ` Florian Weimer
2021-03-10 20:15     ` Adhemerval Zanella
2021-02-02 15:11 ` [PATCH 7/8] support: Add xpthread_kill Adhemerval Zanella
2021-03-08 12:13   ` Florian Weimer
2021-02-02 15:11 ` [PATCH 8/8] posix: Add _Fork [BZ #4737] Adhemerval Zanella
2021-02-02 15:48   ` Andreas Schwab
2021-02-02 18:22   ` Joseph Myers
2021-02-11 15:26   ` [PATCH v2] " Adhemerval Zanella
2021-02-11 16:21     ` Andreas Schwab
2021-02-11 17:10       ` Adhemerval Zanella
2021-02-11 17:33         ` Andreas Schwab
2021-02-11 17:36           ` Adhemerval Zanella
2021-03-08 13:04 ` [PATCH 1/8] posix: Consolidate register-atfork Florian Weimer

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).