[PATCH v4 4/4] posix: Add _Fork [BZ #4737]

Florian Weimer fweimer@redhat.com
Thu Jun 24 08:47:20 GMT 2021


* Adhemerval Zanella via Libc-alpha:

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

Maybe:

+The @code{_Fork} function is similar to @code{fork}, but it does not invoke
+any callbacks registered with @code{pthread_atfork}, nor does it reset
+any internal state or locks (such as the @code{malloc} locks).  In the
+new subprocess, only async-signal-safe functions may be called, such as
+@code{dup2} or @code{execve}.
+
+The @code{_Fork} function is an async-signal-safe replacement of @code{fork}.
+It is a GNU extension.

> diff --git a/posix/tst-_Fork.c b/posix/tst-_Fork.c
> new file mode 100644
> index 0000000000..f14da12d5a
> --- /dev/null
> +++ b/posix/tst-_Fork.c

> +/* _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);

This test tests using a synchronous signal, so it doesn't add much
value in my opinion.

> +/* 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);

Use TEST_VERIFY (!atfork_child_var) etc.?

> diff --git a/posix/unistd.h b/posix/unistd.h
> index d9d8929f71..fa06c890ba 100644
> --- a/posix/unistd.h
> +++ b/posix/unistd.h
> @@ -781,6 +781,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

Should this be _THROW (no callbacks)?  Do we have to specify the
returns_twice attribute?

Thanks,
Florian



More information about the Libc-alpha mailing list