.\" 2008-11-19, mtk, document CLONE_NEWIPC
.\" 2008-11-19, Jens Axboe, mtk, document CLONE_IO
.\"
-.TH CLONE 2 2017-09-15 "Linux" "Linux Programmer's Manual"
+.TH CLONE 2 2019-03-06 "Linux" "Linux Programmer's Manual"
.SH NAME
clone, __clone2 \- create a child process
.SH SYNOPSIS
performed by either the calling
process or the child process do not affect the other process.
Note, however,
-that the duplicated file descriptors in the child refer to the same open file
-descriptions as the corresponding file descriptors in the calling process,
+that the duplicated file descriptors in the child refer to the same
+open file descriptions as the corresponding file descriptors
+in the calling process,
and thus share file offsets and file status flags (see
.BR open (2)).
.TP
directory trees, sockets, etc.).
A physical network device can live in exactly one
network namespace.
-A virtual network device ("veth") pair provides a pipe-like abstraction
-.\" FIXME . Add pointer to veth(4) page when it is eventually completed
+A virtual network
+.RB ( veth (4))
+device pair provides a pipe-like abstraction
that can be used to create tunnels between network namespaces,
and can be used to create a bridge to a physical network device
in another namespace.
performed later by one of the processes have no effect on the other
process.
.IP
-Since Linux 2.6.0-test6,
+Since Linux 2.6.0,
+.\" Precisely: Linux 2.6.0-test6
.I flags
must also include
.B CLONE_VM
.B CLONE_SIGHAND
is specified
.TP
-.BR CLONE_STOPPED " (since Linux 2.6.0-test2)"
+.BR CLONE_STOPPED " (since Linux 2.6.0)"
+.\" Precisely: Linux 2.6.0-test2
If
.B CLONE_STOPPED
is set, then the child is initially stopped (as though it was sent a
.I semadj
list that is initially empty.
.TP
-.BR CLONE_THREAD " (since Linux 2.4.0-test8)"
+.BR CLONE_THREAD " (since Linux 2.4.0)"
+.\" Precisely: Linux 2.6.0-test8
If
.B CLONE_THREAD
is set, the child is placed in the same thread group as the calling process.
if
.B CLONE_THREAD
is specified
-(and note that, since Linux 2.6.0-test6,
+(and note that, since Linux 2.6.0,
+.\" Precisely: Linux 2.6.0-test6
.BR CLONE_SIGHAND
also requires
.BR CLONE_VM
to be included).
.IP
-Signals may be sent to a thread group as a whole (i.e., a TGID) using
-.BR kill (2),
-or to a specific thread (i.e., TID) using
-.BR tgkill (2).
-.IP
Signal dispositions and actions are process-wide:
if an unhandled signal is delivered to a thread, then
it will affect (terminate, stop, continue, be ignored in)
all members of the thread group.
.IP
Each thread has its own signal mask, as set by
-.BR sigprocmask (2),
-but signals can be pending either: for the whole process
-(i.e., deliverable to any member of the thread group),
-when sent with
-.BR kill (2);
-or for an individual thread, when sent with
-.BR tgkill (2).
+.BR sigprocmask (2).
+.IP
+A signal may be process-directed or thread-directed.
+A process-directed signal is targeted at a thread group (i.e., a TGID),
+and is delivered to an arbitrarily selected thread from among those
+that are not blocking the signal.
+A signal may be process directed because it was generated by the kernel
+for reasons other than a hardware exception, or because it was sent using
+.BR kill (2)
+or
+.BR sigqueue (3).
+A thread-directed signal is targeted at (i.e., delivered to)
+a specific thread.
+A signal may be thread directed because it was sent using
+.BR tgkill (2)
+or
+.BR pthread_sigqueue (3),
+or because the thread executed a machine language instruction that triggered
+a hardware exception
+(e.g., invalid memory access triggering
+.BR SIGSEGV
+or a floating-point exception triggering
+.BR SIGFPE ).
+.IP
A call to
.BR sigpending (2)
-returns a signal set that is the union of the signals pending for the
-whole process and the signals that are pending for the calling thread.
+returns a signal set that is the union of the pending process-directed
+signals and the signals that are pending for the calling thread.
.IP
-If
-.BR kill (2)
-is used to send a signal to a thread group,
+If a process-directed signal is delivered to a thread group,
and the thread group has installed a handler for the signal, then
the handler will be invoked in exactly one, arbitrarily selected
member of the thread group that has not blocked the signal.
If multiple threads in a group are waiting to accept the same signal using
.BR sigwaitinfo (2),
the kernel will arbitrarily select one of these threads
-to receive a signal sent using
-.BR kill (2).
+to receive the signal.
.TP
.BR CLONE_UNTRACED " (since Linux 2.5.46)"
If
.BR clone ()
system call is that the
.I child_stack
-argument may be zero,
+argument may be NULL,
in which case the child uses a duplicate of the parent's stack.
(Copy-on-write semantics ensure that the child gets separate copies
of stack pages when either process modifies the stack.)
as detailed in the following paragraphs.
.PP
The raw system call interface on x86-64 and some other architectures
-(including sh, tile, and alpha) is roughly:
+(including sh, tile, ia-64, and alpha) is:
.PP
.in +4
.EX
.SS ia64
On ia64, a different interface is used:
.PP
-.nf
+.in +4
+.EX
.BI "int __clone2(int (*" "fn" ")(void *), "
.BI " void *" child_stack_base ", size_t " stack_size ,
.BI " int " flags ", void *" "arg" ", ... "
.BI " /* pid_t *" ptid ", struct user_desc *" tls \
", pid_t *" ctid " */ );"
-.fi
+.EE
+.in
.PP
The prototype shown above is for the glibc wrapper function;
-the raw system call interface has no
-.I fn
-or
-.I arg
-argument, and changes the order of the arguments so that
-.I flags
-is the first argument, and
-.I tls
-is the last argument.
+for the system call itself,
+the prototype can be described as follows (it is identical to the
+.BR clone ()
+prototype on microblaze):
+.PP
+.in +4
+.EX
+.BI "long clone2(unsigned long " flags ", void *" child_stack_base ,
+.BI " int " stack_size , "\fR /* Size of stack */"
+.BI " int *" ptid ", int *" ctid ,
+.BI " unsigned long " tls );
+.EE
+.in
.PP
.BR __clone2 ()
operates in the same way as
was specified, but
.B CLONE_VM
was not.
-(Since Linux 2.6.0-test6.)
+(Since Linux 2.6.0.)
+.\" Precisely: Linux 2.6.0-test6
.TP
.B EINVAL
.B CLONE_THREAD
.\" (Since Linux 2.6.0-test6.)
.TP
.B EINVAL
+.B CLONE_THREAD
+was specified, but the current process previously called
+.BR unshare (2)
+with the
+.B CLONE_NEWPID
+flag or used
+.BR setns (2)
+to reassociate itself with a PID namespace.
+.TP
+.B EINVAL
.\" commit e66eded8309ebf679d3d3c1f5820d1f2ca332c71
Both
.B CLONE_FS
option.
.TP
.B EINVAL
+.BR CLONE_NEWUSER
+was specified in
+.IR flags ,
+but the kernel was not configured with the
+.B CONFIG_USER_NS
+option.
+.TP
+.B EINVAL
.BR CLONE_NEWUTS
was specified in
.IR flags ,
but the kernel was not configured with the
-.B CONFIG_UTS
+.B CONFIG_UTS_NS
option.
.TP
.B EINVAL
#include <stdlib.h>
#include <unistd.h>
-#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \\
+#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \e
} while (0)
static int /* Start function for cloned child */
if (uname(&uts) == \-1)
errExit("uname");
- printf("uts.nodename in child: %s\\n", uts.nodename);
+ printf("uts.nodename in child: %s\en", uts.nodename);
/* Keep the namespace open for a while, by sleeping.
This allows some experimentation\-\-for example, another
struct utsname uts;
if (argc < 2) {
- fprintf(stderr, "Usage: %s <child\-hostname>\\n", argv[0]);
+ fprintf(stderr, "Usage: %s <child\-hostname>\en", argv[0]);
exit(EXIT_SUCCESS);
}
pid = clone(childFunc, stackTop, CLONE_NEWUTS | SIGCHLD, argv[1]);
if (pid == \-1)
errExit("clone");
- printf("clone() returned %ld\\n", (long) pid);
+ printf("clone() returned %ld\en", (long) pid);
/* Parent falls through to here */
if (uname(&uts) == \-1)
errExit("uname");
- printf("uts.nodename in parent: %s\\n", uts.nodename);
+ printf("uts.nodename in parent: %s\en", uts.nodename);
if (waitpid(pid, NULL, 0) == \-1) /* Wait for child */
errExit("waitpid");
- printf("child has terminated\\n");
+ printf("child has terminated\en");
exit(EXIT_SUCCESS);
}