aboutsummaryrefslogtreecommitdiff
path: root/lib/libsys/fork.2
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libsys/fork.2')
-rw-r--r--lib/libsys/fork.2278
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 .