Date: Tue, 3 Aug 2021 18:19:42 GMT From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 49ad342cc10c - main - Add _Fork() Message-ID: <202108031819.173IJgPB060470@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=49ad342cc10cba14b3a40ba26cf8bb2150e2925a commit 49ad342cc10cba14b3a40ba26cf8bb2150e2925a Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2021-08-02 09:50:32 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2021-08-03 18:19:32 +0000 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 --- include/unistd.h | 1 + lib/libc/sys/Makefile.inc | 1 + lib/libc/sys/Symbol.map | 4 +++ lib/libc/sys/_Fork.c | 45 +++++++++++++++++++++++++++ lib/libc/sys/fork.2 | 78 ++++++++++++++++++++++++++++++++++++++++++++--- 5 files changed, 125 insertions(+), 4 deletions(-) diff --git a/include/unistd.h b/include/unistd.h index 9fa9bebbc4c0..5f358ad72d9a 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -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 diff --git a/lib/libc/sys/Makefile.inc b/lib/libc/sys/Makefile.inc index 9a417f4a7c74..a1eb9567a380 100644 --- a/lib/libc/sys/Makefile.inc +++ b/lib/libc/sys/Makefile.inc @@ -49,6 +49,7 @@ SRCS+= closefrom.c SRCS+= pipe.c SRCS+= shm_open.c SRCS+= vadvise.c +SRCS+= _Fork.c SRCS+= compat-stub.c diff --git a/lib/libc/sys/Symbol.map b/lib/libc/sys/Symbol.map index 0044c06fd639..80bb2c236191 100644 --- a/lib/libc/sys/Symbol.map +++ b/lib/libc/sys/Symbol.map @@ -417,6 +417,10 @@ FBSD_1.6 { shm_rename; }; +FBSD_1.7 { + _Fork; +}; + FBSDprivate_1.0 { ___acl_aclcheck_fd; __sys___acl_aclcheck_fd; diff --git a/lib/libc/sys/_Fork.c b/lib/libc/sys/_Fork.c new file mode 100644 index 000000000000..a7aaf82429bb --- /dev/null +++ b/lib/libc/sys/_Fork.c @@ -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()); +} diff --git a/lib/libc/sys/fork.2 b/lib/libc/sys/fork.2 index 9ea0a6afb96f..bf934d166b03 100644 --- a/lib/libc/sys/fork.2 +++ b/lib/libc/sys/fork.2 @@ -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 .
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202108031819.173IJgPB060470>