diff options
Diffstat (limited to 'lib/libsys/fork.2')
-rw-r--r-- | lib/libsys/fork.2 | 278 |
1 files changed, 278 insertions, 0 deletions
diff --git a/lib/libsys/fork.2 b/lib/libsys/fork.2 new file mode 100644 index 000000000000..e59b208a9ff5 --- /dev/null +++ b/lib/libsys/fork.2 @@ -0,0 +1,278 @@ +.\" Copyright (c) 1980, 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" 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, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. +.\" +.Dd May 17, 2024 +.Dt FORK 2 +.Os +.Sh NAME +.Nm fork +.Nd create a new process +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft pid_t +.Fn fork void +.Ft pid_t +.Fn _Fork void +.Sh DESCRIPTION +The +.Fn fork +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 +.It +The child process has a unique process ID. +.It +The child process has a different parent +process ID (i.e., the process ID of the parent process). +.It +The child process has its own copy of the parent's descriptors, +except for descriptors returned by +.Xr kqueue 2 , +which are not inherited from the parent process. +These descriptors reference the same underlying objects, so that, +for instance, file pointers in file objects are shared between +the child and the parent, so that an +.Xr lseek 2 +on a descriptor in the child process can affect a subsequent +.Xr read 2 +or +.Xr write 2 +by the parent. +This descriptor copying is also used by the shell to +establish standard input and output for newly created processes +as well as to set up pipes. +Any file descriptors that were marked with the close-on-fork flag, +.Dv FD_CLOFORK +.Po see +.Fn fcntl 2 +and +.Dv O_CLOFORK +in +.Fn open 2 +.Pc , +will not be present in the child process, but remain open in the parent. +.It +The child process' resource utilizations +are set to 0; see +.Xr setrlimit 2 . +.It +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, +locks and other resources held by the other threads are not released +and therefore only async-signal-safe functions +(see +.Xr sigaction 2 ) +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 +and +.Fn _Fork +return a value +of 0 to the child process and return the process ID of the child +process to the parent process. +Otherwise, a value of -1 is returned +to the parent process, no child process is created, and the global +variable +.Va errno +is set to indicate the error. +.Sh EXAMPLES +The following example shows a common pattern of how +.Fn fork +is used in practice. +.Bd -literal -offset indent +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +int +main(void) +{ + pid_t pid; + + /* + * If child is expected to use stdio(3), state of + * the reused io streams must be synchronized between + * parent and child, to avoid double output and other + * possible issues. + */ + fflush(stdout); + + switch (pid = fork()) { + case -1: + err(1, "Failed to fork"); + case 0: + printf("Hello from child process!\en"); + + /* + * Since we wrote into stdout, child needs to use + * exit(3) and not _exit(2). This causes handlers + * registered with atexit(3) to be called twice, + * once in parent, and once in the child. If such + * behavior is undesirable, consider + * terminating child with _exit(2) or _Exit(3). + */ + exit(0); + default: + break; + } + + printf("Hello from parent process (child's PID: %d)!\en", pid); + + return (0); +} +.Ed +.Pp +The output of such a program is along the lines of: +.Bd -literal -offset indent +Hello from parent process (child's PID: 27804)! +Hello from child process! +.Ed +.Sh ERRORS +The +.Fn fork +system call will fail and no child process will be created if: +.Bl -tag -width Er +.It Bq Er EAGAIN +The system-imposed limit on the total +number of processes under execution would be exceeded. +The limit is given by the +.Xr sysctl 3 +MIB variable +.Dv KERN_MAXPROC . +(The limit is actually ten less than this +except for the super user). +.It Bq Er EAGAIN +The user is not the super user, and +the system-imposed limit +on the total number of +processes under execution by a single user would be exceeded. +The limit is given by the +.Xr sysctl 3 +MIB variable +.Dv KERN_MAXPROCPERUID . +.It Bq Er EAGAIN +The user is not the super user, and +the soft resource limit corresponding to the +.Fa resource +argument +.Dv RLIMIT_NPROC +would be exceeded (see +.Xr getrlimit 2 ) . +.It Bq Er ENOMEM +There is insufficient swap space for the new process. +.El +.Sh SEE ALSO +.Xr execve 2 , +.Xr rfork 2 , +.Xr setitimer 2 , +.Xr setrlimit 2 , +.Xr sigaction 2 , +.Xr vfork 2 , +.Xr wait 2 , +.Xr pthread_atfork 3 +.Sh STANDARDS +The +.Fn fork +and +.Fn _Fork +functions conform to +.St -p1003.1-2024 . +.Sh HISTORY +The +.Fn fork +function appeared in +.At v1 . +The +.Fn _Fork +function appeared in +.Fx 13.1 . |