Add _Fork()

Current POSIX standard requires fork() to be async-signal safe.  Neither
our implementation, nor implementations in other operating systems are,
and practically it is impossible to make fork() async-signal safe without
too much efforts.  Also, that would put undue requirement that all atfork
handlers should be async-signal safe as well, which contradicts its main
use.

As result, Austin Group dropped the requirement, and added a new function
_Fork() that should be async-signal safe, but it does not call atfork
handlers.  Basically, _Fork() can be implemented as a raw syscall.

Release of glibc 2.34 added _Fork(), do the same for FreeBSD.
Clarify threading behavior for fork() in the manpage.

Reviewed by:	markj
Sponsored by:	The FreeBSD Foundation
MFC after:	2 weeks
Differential revision:	https://reviews.freebsd.org/D31378
This commit is contained in:
Konstantin Belousov 2021-08-02 12:50:32 +03:00
parent 2d319ebe5c
commit 49ad342cc1
5 changed files with 125 additions and 4 deletions

View File

@ -586,6 +586,7 @@ int undelete(const char *);
int unwhiteout(const char *);
void *valloc(size_t); /* obsoleted by malloc() */
int funlinkat(int, const char *, int, int);
pid_t _Fork(void);
#ifndef _OPTRESET_DECLARED
#define _OPTRESET_DECLARED

View File

@ -49,6 +49,7 @@ SRCS+= closefrom.c
SRCS+= pipe.c
SRCS+= shm_open.c
SRCS+= vadvise.c
SRCS+= _Fork.c
SRCS+= compat-stub.c

View File

@ -417,6 +417,10 @@ FBSD_1.6 {
shm_rename;
};
FBSD_1.7 {
_Fork;
};
FBSDprivate_1.0 {
___acl_aclcheck_fd;
__sys___acl_aclcheck_fd;

45
lib/libc/sys/_Fork.c Normal file
View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 2021 The FreeBSD Foundation.
* All rights reserved.
*
* Portions of this software were developed by Konstantin Belousov
* under sponsorship from the FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice(s), this list of conditions and the following disclaimer as
* the first lines of this file unmodified other than the possible
* addition of one or more copyright notices.
* 2. Redistributions in binary form must reproduce the above copyright
* notice(s), this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <unistd.h>
#include "libc_private.h"
#pragma weak _Fork
pid_t
_Fork(void)
{
return (__sys_fork());
}

View File

@ -28,7 +28,7 @@
.\" @(#)fork.2 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
.Dd April 20, 2021
.Dd August 2, 2021
.Dt FORK 2
.Os
.Sh NAME
@ -40,10 +40,12 @@
.In unistd.h
.Ft pid_t
.Fn fork void
.Ft pid_t
.Fn _Fork void
.Sh DESCRIPTION
The
.Fn fork
system call causes creation of a new process.
function causes creation of a new process.
The new process (child process) is an exact copy of the
calling process (parent process) except for the following:
.Bl -bullet -offset indent
@ -77,6 +79,15 @@ are set to 0; see
All interval timers are cleared; see
.Xr setitimer 2 .
.It
The robust mutexes list (see
.Xr pthread_mutexattr_setrobust 3 )
is cleared for the child.
.It
The atfork handlers established with the
.Xr pthread_atfork 3
function are called as appropriate before fork in the parent process,
and after the child is created, in parent and child.
.It
The child process has only one thread,
corresponding to the calling thread in the parent process.
If the process has more than one thread,
@ -87,11 +98,58 @@ and therefore only async-signal-safe functions
are guaranteed to work in the child process until a call to
.Xr execve 2
or a similar function.
The
.Fx
implementation of
.Fn fork
provides a usable
.Xr malloc 3 ,
and
.Xr rtld 1
services in the child process.
.El
.Pp
The
.Fn fork
function is not async-signal safe and creates a cancellation point
in the parent process.
It cannot be safely used from signal handlers, and the atfork handlers
established by
.Xr pthread_atfork 3
do not need to be async-signal safe either.
.Pp
The
.Fn _Fork
function creates a new process, similarly to
.Fn fork ,
but it is async-signal safe.
.Fn _Fork
does not call atfork handlers, and does not create a cancellation point.
It can be used safely from signal handlers, but then no userspace
services (
.Xr malloc 3
or
.Xr rtld 1 )
are available in the child if forked from multi-threaded parent.
In particular, if using dynamic linking, all dynamic symbols used by the
child after
.Fn _Fork
must be pre-resolved.
Note: resolving can be done globally by specifying the
.Ev LD_BIND_NOW
environment variable to the dynamic linker, or per-binary by passing the
.Fl z Ar now
option to the static linker
.Xr ld 1 ,
or by using each symbol before the
.Fn _Fork
call to force the binding.
.Sh RETURN VALUES
Upon successful completion,
.Fn fork
returns a value
and
.Fn _Fork
return a value
of 0 to the child process and returns the process ID of the child
process to the parent process.
Otherwise, a value of -1 is returned
@ -176,9 +234,21 @@ There is insufficient swap space for the new process.
.Xr setrlimit 2 ,
.Xr sigaction 2 ,
.Xr vfork 2 ,
.Xr wait 2
.Xr wait 2 ,
.Xr pthread_atfork 3
.Sh HISTORY
The
.Fn fork
function appeared in
.At v1 .
.Pp
The
.Fn _Fork
function was defined by Austin Group together with the removal
of a requirement that the
.Fn fork
implementation must be async-signal safe.
The
.Fn _Fork
function appeared in
.Fx 14.0 .