clone

CLONE(2)                   Linux-Programmierhandbuch                  CLONE(2)



BEZEICHNUNG
       clone, __clone2 - erzeugt einen Kindprozess

ÃBERSICHT
       /* Prototyp für die Glibc-Wrapper-Funktion */

       #define _GNU_SOURCE
       #include <sched.h>

       int clone(int (*fn)(void *), void *child_stack,
                 int flags, void *arg, â¦
                 /* pid_t *ptid, void *newtls, pid_t *ctid */ );

       /* Für den Prototyp des den rohen Systemaufrufs siehe ANMERKUNGEN */

BESCHREIBUNG
       clone() erzeugt auf eine ähnliche Weise wie fork(2) einen neuen
       Prozess.

       Diese Seite beschreibt sowohl die clone()-Wrapper-Funktion von Glibc
       als auch den darunterliegenden Systemaufruf, auf dem sie basiert. Der
       Haupttext erklärt die Wrapper-Funktion. Die Unterschiede zum rohen
       Systemaufruf werden gegen Ende dieser Seite erläutert.

       Im Gegensatz zu fork(2) erlaubt clone(), dass der Kindprozess Teile
       seines Kontextes mit dem aufrufenden Prozess teilt. Dazu zählen der
       virtuelle Adressraum, die Tabelle der Dateideskriptoren und die Tabelle
       der Signal-Handler. (Beachten Sie, dass »aufrufender Prozess« auf
       dieser Handbuchseite »Elternprozess« entspricht. Aber lesen Sie im
       Folgenden die Beschreibung von CLONE_PARENT.)

       clone() wird benutzt, um Threads zu implementieren: mehrere
       Steuerflüsse in einem Programm, die gleichzeitig in einem gemeinsamen
       Speicherbereich ausgeführt werden.

       Wird mit clone() ein Kindprozess erzeugt, beginnt es die Ausführung
       durch Aufruf der Funktion, auf die das Argument fn zeigt. (Dies ist ein
       Unterschied zu fork(2), wo die Ausführung im Kindprozess vom Punkt des
       fork(2)-Aufrufs fortfährt.) Das Argument arg wird als Argument der
       Funktion fn übergeben.

       Kehrt die Funktion fn(arg) zurück, so beendet sich der Kindprozess.
       Der Ganzzahlwert, der von fn zurückgeliefert wird, entspricht dem
       Exit-Status des Kindprozesses. Der Kindprozess kann auch durch den
       expliziten Aufruf von exit(2) oder durch den Empfang eines fatalen
       Signals beendet werden.

       Das Argument child_stack bestimmt den Ort des Stapelspeichers, der vom
       Kindprozess verwendet wird. Da der aufrufende und der Kindprozess sich
       Speicherbereiche teilen können, kann der Kindprozess nicht auf dem
       selben Stapelspeicher wie der aufrufende Prozess laufen. Der aufrufende
       Prozess muss daher einen Speicherbereich als Stapelspeicher für den
       Kindprozess bereithalten und per clone einen Zeiger darauf an den
       Kindprozess übergeben. Der Stapelspeicher wächst (mit Ausnahme der
       PA-Prozessoren von HP) auf allen von Linux unterstützten Prozessoren
       nach unten, so dass child_stack für gewöhnlich auf die oberste
       Adresse im bereitgehaltenen Speicherbereich zeigt.

       Das niederwertige Byte von flags enthält die Nummer des
       Beendigungssignals, das an den Elternprozess gesandt wird, wenn der
       Kindprozess endet. Falls dieses Signal als etwas anderes als SIGCHLD
       angegeben wurde, dann muss der Elternprozess die Optionen __WALL oder
       __WCLONE angeben, wenn er mit wait(2) auf den Kindprozess wartet. Falls
       kein Signal angegeben wurde, wird dem Elternprozess nicht signalisiert,
       wenn der Kindprozess endet.

       flags kann darüber hinaus noch durch bitweises »ODER« mit keiner
       oder mehreren der folgenden Konstanten verknüpft werden. Dadurch wird
       festgelegt, welche Ressourcen sich Eltern- und Kindprozess teilen:

       CLONE_CHILD_CLEARTID (seit Linux 2.5.49)
              Die Kind-Thread-Kennung an der Stelle ctid im Kindspeicher
              bereinigen (nullen), wenn das Kind existiert und beim Futex
              (»fast userspace mutual exclusion«/schneller gegenseitiger
              Ausschluss im Userspace) an dieser Adresse aufwachen lassen. Die
              betroffene Adresse könnte durch den Systemaufruf
              set_tid_address(2) geändert werden. Dies wird von
              Threading-Bibliotheken benutzt.

       CLONE_CHILD_SETTID (seit Linux 2.5.49)
              Speichert die Kind-Thread-Kennung an der Stelle ctid im
              Kindspeicher. Die Speicheraktion wird abgeschlossen, bevor
              clone() die Steuerung an den Benutzerraum im Kindprozess
              zurückgibt. (Beachten Sie, dass die Speicheraktion noch nicht
              abgeschlossen sein könnte, bevor clone() den Elternprozess
              zurückliefert, was relevant wird, wenn auch der Schalter
              CLONE_VM eingesetzt wird.)

       CLONE_FILES (since Linux 2.0)
              Ist CLONE_FILES gesetzt, teilen sich der aufrufende und der
              Kindprozess ihre Dateideskriptor-Tabellen. Jeder
              Dateideskriptor, der im aufrufenden Prozess oder vom Kindprozess
              erzeugt wird, ist auch im anderen Prozess gültig. Ebenso wirkt
              sich das SchlieÃen eines Dateideskriptors oder das Ãndern der
              zugehörigen Schalter (benutzen der F_SETFD-Operation von
              fcntl(2)) auf den anderen Prozess aus. Falls sich ein Prozess
              eine Dateideskriptor-Tabelle teilt und execve(2) aufruft, wird
              seine Dateideskriptor-Tabelle dupliziert (nicht länger
              geteilt).

              Ist CLONE_FILES nicht gesetzt, erbt der Kindprozess zur
              Ausführungszeit von clone() eine Kopie der aktuell geöffneten
              Dateideskriptoren. AnschlieÃende Aktionen, die Dateideskriptoren
              öffnen oder schlieÃen bzw. deren Schalter ändern, werden
              entweder vom aufrufenden Prozess oder dem Kindprozess
              durchgeführt und betreffen nicht den jeweils anderen Prozess.
              Beachten Sie aber, dass sich die duplizierten Dateideskriptoren
              im Kind auf die gleiche offene Dateideskription wie der
              korrespondierende Dateideskriptor im aufrufenden Prozess bezieht
              und sich daher den Dateiversatz und die Dateistatusschalter mit
              diesem teilt (siehe open(2)).

       CLONE_FS (seit Linux 2.0)
              Ist CLONE_FS gesetzt, teilen sich aufrufender Prozess und
              Kindprozess ihre Informationen über das Dateisystem. Dazu
              zählen der Ort des Wurzelverzeichnisses, das aktuelle
              Arbeitsverzeichnis und die Maske der Dateizugriffsrechte
              (umask). Jeder Aufruf von chroot(2), chdir(2) oder umask(2),
              entweder durch den aufrufenden Prozess oder den Kindprozess,
              beeinflusst auch den jeweils anderen Prozess.

              Ist CLONE_FS nicht gesetzt, arbeitet der Kindprozess von clone()
              mit einer Kopie der Dateisysteminformationen des aufrufenden
              Prozesses zur Zeit des clone()-Aufrufs. Spätere Aufrufe von
              chroot(2), chdir(2) oder umask(2) beeinflussen den anderen
              Prozess nicht.

       CLONE_IO (seit Linux 2.6.25)
              Ist CLONE_FS gesetzt, teilt sich der neue Prozess einen
              E/A-Kontext mit dem aufrufenden Prozess. Falls dieser Schalter
              nicht gesetzt ist (wie bei fork(2)), hat der neue Prozess seinen
              eigenen E/A-Kontext.

              Der E/A-Kontext entspricht dem E/A-Gültigkeitsbereich des
              Platten-Steuerprogramms, d.h. welches das E/A-Steuerprogramm zur
              Modellplanung für E/As des Prozesses benutzt. Falls sich
              Prozesse den gleichen E/A-Kontext teilen, werden sie vom
              E/A-Steuerprogramm als ein einziger betrachtet. Als Konsequenz
              daraus müssen sie sich die gleiche Plattenzeitzugriffzeit
              teilen. Einige E/A-Steuerprogramme ermöglichen zwei Prozessen,
              die einen E/A-Kontext teilen, ihren Plattenzugriff zu verzahnen.
              Falls mehrere Prozesse E/A im Auftrag des gleichen Prozesses
              durchführen (aio_read(3) zum Beispiel), sollten sie für eine
              bessere E/A-Leistung CLONE_IO verwenden.

              Falls der Kernel nicht mit der Option CONFIG_BLOCK konfiguriert
              wurde, bewirkt dieser Schalter nichts.

       CLONE_NEWCGROUP (seit Linux 4.6)
              Erstellt den Prozess in einem neuen cgroup-Namensraum. Falls
              dieser Schalter nicht gesetzt ist, dann wird (wie mit fork(2))
              der Prozess in den gleichen cgroup-Namensräumen wie der
              aufrufende Prozess erstellt. Der Schalter ist für die
              Implementierung von Containern gedacht.

              Weitere Informationen über cgroup-Namensräume finden Sie unter
              cgroup_namespaces(7).

              Nur ein privilegierter Prozess (CAP_SYS_ADMIN) kann
              CLONE_NEWCGROUP angeben.

       CLONE_NEWIPC (seit Linux 2.6.19)
              Ist CLONE_NEWIPC gesetzt, dann wird der Prozess in einem neuen
              IPC-Namensraum erstellt. Falls dieser Schalter nicht gesetzt
              ist, dann wird der Prozess (wie bei fork(2)) im gleichen
              IPC-Namensraum wie der aufrufende Prozess erstellt. Dieser
              Schalter ist für die Implementierung von Containern gedacht.

              Ein IPC-Namensraum stellt eine isolierte Ansicht von
              System-V-IPC-Objekten (siehe sysvipc(7)) und (seit 2.6.30)
              POSIX-Nachrichtenwarteschlangen (siehe mq_overview(7)) bereit.
              Das gemeinsame Merkmal dieser IPC-Mechanismen ist, dass
              IPC-Objekte durch andere Mechanismen als Dateisystempfadnamen
              identifiziert werden.

              Objekte, die in einem IPC-Namensraum erstellt wurden, sind für
              alle anderen Prozesse sichtbar, die Mitglieder des Namensraums
              sind. Die Objekte sind jedoch nicht für Prozesse in anderen
              Namensräumen sichtbar.

              Wenn ein IPC-Namensraum zerstört wird, d.h. wenn der letzte
              Prozess im Namensraum beendet wird, werden alle IPC-Objekte im
              Namensraum automatisch zerstört.

              Nur ein privilegierter Prozess (CAP_SYS_ADMIN) kann CLONE_NEWIPC
              angeben. Dieser Schalter darf nicht zusammen mit CLONE_SYSVSEM
              angegeben werden.

              Weitere Informationen zu IPC-Namensräumen finden Sie in
              namespaces(7).

       CLONE_NEWNET (seit Linux 2.6.24)
              (Die Implementierung dieses Schalters wurde erst ungefähr mit
              der Kernel-Version 2.6.29 abgeschlossen.)

              Wenn CLONE_NEWNET gesetzt ist, dann wird der Prozess in einem
              neuen Netzwerk-Namensraum erstellt. Falls dieser Schalter nicht
              gesetzt ist, dann wird der Prozess (wie mit fork(2)) im gleichen
              Netzwerk-Namensraum wie der aufrufende Prozess erstellt. Dieser
              Schalter ist für die Implementierung von Containern gedacht.

              Ein Netzwerk-Namensraum stellt eine isolierte Ansicht des
              Netzwerk-Stapelspeichers (Netzwerkgeräteschnittstellen, IPv4-
              und IPv6-Protokoll-Stapelspeicher, IP-Routing-Tabellen,
              Firewall-Regeln, die Verzeichnisbäume /proc/net und
              /sys/class/net, Sockets, etc.)  bereit. Ein physisches
              Netzwerkgerät kann in genau einem Netzwerknamensraum bestehen.
              Ein virtuelles Netzwerkgerätepaar (veth(4)) stellt eine einer
              Pipe ähnliche Abstraktion bereit, die benutzt werden kann, um
              Tunnel zwischen Netzwerk-Namensräumen aufzubauen und eine
              Brücke in ein physisches Netzwerkgerät in einem anderen
              Namensraum zu erstellen.

              Wenn ein Netzwerk-Namensraum freigegeben wird, d.h. wenn der
              letzte Prozess im Namensraum beendet wird, werden seine
              physischen Netzwerkgeräte zurück in den ursprünglichen
              Namensraum verschoben (nicht zum Elternprozess). Weitere
              Informationen zu Netzwerk-Namensräumen finden Sie in
              namespaces(7).

              Nur ein privilegierter Prozess (CAP_SYS_ADMIN) kann CLONE_NEWNET
              angeben.

       CLONE_NEWNS (seit Linux 2.4.19)
              Wenn der Schalter CLONE_NEWNS gesetzt ist, wird der geklonte
              Kindprozess in einem neuen, eingehängten Namensraum gestartet,
              der mit einer Kopie des Namensraums des Elternprozesses
              initialisiert wurde. Wenn CLONE_NEWNS nicht gesetzt ist, bleibt
              der Kindprozess im gleichen Namensraum wie der Elternprozess.

              Nur ein privilegierter Prozess (einer der die Fähigkeit
              CAP_SYS_ADMIN hat) kann den Schalter CLONE_NEWNS angeben. Es ist
              nicht erlaubt, sowohl CLONE_NEWNS als auch CLONE_FS im gleichen
              Aufruf von clone() anzugeben.

              Für weitere Informationen über Einhängenamensräume lesen Sie
              namespaces(7) und mount_namespaces(7)

       CLONE_NEWPID (seit Linux 2.6.24)
              Wenn CLONE_NEWPID gesetzt ist, dann wird der Prozess in einem
              neuen PID-Namensraum erstellt. Falls dieser Schalter nicht
              gesetzt ist (wie mit fork(2)), dann wird der Prozess in dem
              gleichen PID-Namensraum wie der aufrufende Prozess erstellt. Der
              Schalter ist für die Implementierung von Containern gedacht.

              Weitere Informationen zu PID-Namensräumen finden Sie in
              namespaces(7) und pid_namespaces(7).

              Nur ein privilegierter Prozess (CAP_SYS_ADMIN) kann CLONE_NEWPID
              angeben. Dieser Schalter darf nicht zusammen mit CLONE_THREAD
              oder CLONE_PARENT angegeben werden.

       CLONE_NEWUSER
              (Dieser Schalter hatte für clone() erstmals in Linux 2.6.23
              eine Bedeutung, die aktuelle clone()-Semantik wurde in Linux 3.5
              aufgenommen und die letzten Anteile, um Benutzernamensräume
              komplett nutzbar zu bekommen, wurden in Linux 3.8 aufgenommen.)

              Wenn CLONE_NEWUSER gesetzt ist, dann wird der Prozess in einem
              neuen Benutzer-Namensraum erstellt. Falls dieser Schalter nicht
              gesetzt ist, dann wird der Prozess (wie mit fork(2)) im gleichen
              Benutzer-Namensraum wie der aufrufende Prozess erstellt.

              Vor Linux 3.8 verlangte die Verwendung von CLONE_NEWUSER, dass
              der Aufrufende drei Capabilities hatte: CAP_SYS_ADMIN,
              CAP_SETUID und CAP_SETGID. Seit Linux 3.8 werden für die
              Erstellung eines Benutzernamensraums keine Privilegien
              benötigt.

              Dieser Schalter kann nicht zusammen mit CLONE_THREAD oder
              CLONE_PARENT angegeben werden. Aus Sicherheitsgründen darf
              CLONE_NEWUSER nicht zusammen mit CLONE_FS angegeben werden.

              Für weitere Informationen über Benutzernamensräume lesen Sie
              namespaces(7) und user_namespaces(7).

       CLONE_NEWUTS (seit Linux 2.6.19)
              Falls CLONE_NEWUTS gesetzt ist, erzeugt der Prozess einen neuen
              UTS-Namensraum, dessen Bezeichner durch Duplizieren der
              Bezeichner aus dem UTS-Namensraum des aufrufenden Prozesses
              initialisiert werden. Wenn dieser Schalter nicht gesetzt ist
              (wie mit fork(2)), dann wird der Prozess im gleichen
              UTS-Namensraum wie der aufrufende Prozess erzeugt. Dieser
              Schalter ist für die Implementierung von Containern gedacht.

              Ein UTS-Namensraum ist eine Zusammenstellung von Bezeichnern,
              die von uname(2) zurückgegeben werden; von denen können der
              Domain-Name und der Rechnername durch setdomainname(2)
              beziehungsweise sethostname(2) geändert werden. Ãnderungen, die
              an Bezeichnern in einem UTS-Namensraum vorgenommen werden, sind
              für alle anderen Prozesse im gleichen Namensraum sichtbar,
              nicht jedoch für Prozesse in anderen UTS-Namensräumen.

              Nur ein privilegierter Prozess (CAP_SYS_ADMIN) kann CLONE_NEWUTS
              angeben.

              Weitere Informationen zu UTS-Namensräumen finden Sie in
              namespaces(7).

       CLONE_PARENT (seit Linux 2.3.12)
              Falls CLONE_PARENT gesetzt ist, dann wird der Elternprozess des
              neuen Kindprozesses (wie er von getppid(2) zurückgegeben wird)
              der gleiche wie der aufrufende Prozess sein.

              Falls CLONE_PARENT nicht gesetzt ist (wie bei fork(2)), dann ist
              der Elternprozess des Kindprozesses der aufrufende Prozess.

              Beachten Sie, dass dem Elternprozess, wie er von getppid(2)
              zurückgegeben wird, signalisiert wird wenn der Kindprozess
              endet. Wenn also CLONE_PARENT gesetzt ist, wird dem
              Elternprozess des aufrufenden Prozesses anstatt dem aufrufenden
              Prozess selbst das Signal gesandt.

       CLONE_PARENT_SETTID (seit Linux 2.5.49)
              Die Kindprozess-Thread-Kennung an der Stelle ptid im
              Elternspeicher ablegen. (In Linux 2.5.32-2.5.48 gab es einen
              Schalter CLONE_SETTID, der das tat.) Die Speicheraktion wird
              abgeschlossen, bevor clone() die Steuerung an den Benutzerraum
              zurückgibt.

       CLONE_PID (Linux 2.0 bis 2.5.15)
              Falls CLONE_PID gesetzt ist, wird der Kindprozess mit der
              gleichen Prozesskennung wie der aufrufende Prozess erstellt.
              Dies ist gut, um das System zu hacken, aber andererseits zu
              nicht viel mehr zu gebrauchen. Seit Linux 2.3.21 konnte dieser
              Schalter nur durch den Boot-Prozess angegeben werden (PID 0).
              Dieser Schalter verschwand in Linux 2.5.16 komplett aus den
              Kernelquellen. Seitdem ignoriert der Kernel dieses Bit, falls es
              in flags festgelegt ist.

       CLONE_PIDFD (since Linux 5.2)
              If CLONE_PIDFD is set, clone()  stores a PID file descriptor
              referring to the child process at the location ptid in the
              parent's memory.  The close-on-exec flag is set on this new file
              descriptor.  PID file descriptors can be used for the purposes
              described in pidfd_open(2).

              Since the ptid argument is used to return the PID file
              descriptor, CLONE_PIDFD cannot be used with CLONE_PARENT_SETTID.

              It is currently not possible to use this flag together with
              CLONE_THREAD.  This means that the process identified by the PID
              file descriptor will always be a thread-group leader.

              For a while there was a CLONE_DETACHED flag.  This flag is
              usually ignored when passed along with other flags.  However,
              when passed alongside CLONE_PIDFD, an error is returned.  This
              ensures that this flag can be reused for further PID file
              descriptor features in the future.

       CLONE_PTRACE (seit Linux 2.2)
              Falls CLONE_PTRACE angegeben ist und der aufrufende Prozess
              verfolgt wird, dann wird der Kindprozess ebenfalls verfolgt
              (siehe ptrace(2)).

       CLONE_SETTLS (seit Linux 2.5.32)
              Der TLS (Thread Local Storage)-Deskriptor ist auf newtls
              gesetzt.

              Die Interpretation von newtls und der resultierende Effekt ist
              architekturabhängig. Auf X86 ist newtls als ein struct
              user_desc * interpretiert (siehe set_thread_area(2)). Auf X86-64
              ist es der neue für das Basisregister %fs zu setzende Wert
              (siehe das Argument ARCH_SET_FS von arch_prctl(2)). Auf
              Architekturen mit einem dedizierten TLS-Register ist es der neue
              Wert dieses Registers.

       CLONE_SIGHAND (seit Linux 2.0)
              Ist CLONE_SIGHAND gesetzt, teilen sich der aufrufende Prozess
              und der Kindprozess die Tabelle der Signal-Handler. Ruft einer
              der beiden Prozesse sigaction(2) auf, um das Antwortverhalten
              auf ein Signal zu verändern, so betrifft dies auch den anderen
              Prozess. Jedoch besitzen aufrufender Prozess und Kindprozess
              nach wie vor getrennte Signalmasken und getrennte Listen der
              noch ausstehenden Signale. Daher könnten Signale durch Aufruf
              von sigprocmask(2) für einen Prozess geblockt oder zugelassen
              werden ohne den anderen Prozess zu beeinflussen.

              Ist CLONE_SIGHAND nicht gesetzt, erbt der Kindprozess durch den
              clone-Aufruf eine Kopie des Signal-Handlers vom aufrufenden
              Prozess. Spätere Aufrufe von sigaction(2) durch einen der
              Prozesse hat dann keine Auswirkung auf den anderen Prozess.

              Seit Linux 2.6.0 müssen die flags auÃerdem CLONE_VM enthalten,
              falls CLONE_SIGHAND angegeben wurde.

       CLONE_STOPPED (seit Linux 2.6.0)
              Falls CLONE_STOPPED gesetzt ist, ist der Kindprozess anfangs
              gestoppt (als ob ein SIGSTOP-Signal gesendet worden wäre) und
              muss durch Senden eines SIGCONT-Signals wieder aufgenommen
              werden.

              Dieser Schalter war ab Linux 2.6.25 missbilligt und wurde in
              Linux 2.6.38 vollständig entfernt. Seitdem ignoriert der Kernel
              ihn ohne Fehler. Seit Linux 4.6 wird dasselbe Bit für den
              Schalter CLONE_NEWCGROUP wiederverwendet.

       CLONE_SYSVSEM (seit Linux 2.5.10)
              Wenn CLONE_SYSVSEM gesetzt ist, dann teilen sich der Kindprozess
              und der aufrufende Prozess eine einzige Liste von
              System-V-Semaphore-Anpassungswerten, (siehe semop(2)). In diesem
              Fall sammelt die gemeinsame Liste semadj Werte über alle
              Prozesse, die die Liste gemeinsam nutzen und
              Semaphore-Anpassungen werden nur durchgeführt, wenn der letzte
              Prozess, der die Liste gemeinsam nutzt, sich beendet (oder
              mittels unshare(2) aufhört, die Liste mitzunutzen). Falls
              dieser Schalter nicht gesetzt ist, besitzt der Kindprozess eine
              separate semadj-Liste, die anfangs leer ist.

       CLONE_THREAD (seit Linux 2.4.0)
              Falls CLONE_THREAD gesetzt ist, wird der Kindprozess in die
              gleiche Thread-Gruppe wie der aufrufende Prozess platziert. Um
              den Rest der Diskussion von CLONE_THREAD leserlicher zu machen,
              wird der Begriff »Thread« benutzt, um Bezug auf Prozesse
              innerhalb einer Thread-Gruppe zu nehmen.

              Thread-Gruppen waren ein Leistungsmerkmal, das in Linux 2.4
              hinzugefügt wurde, um den POSIX-Thread-Gedanken von einer
              Thread-Zusammenstellung zu unterstützen, die sich eine einzelne
              PID teilt. Intern ist diese gemeinsame PID ein sogenannter
              Thread-Gruppen-Bezeichner (TGID) für die Thread-Gruppe. Seit
              Linux 2.4 geben Aufrufe von getpid(2) die TGID des Aufrufers
              zurück.

              Die Threads innerhalb einer Gruppe können durch ihre
              (systemweit) einheitliche Thread-Kennung (TID) unterschieden
              werden. Die TID eines neuen Threads ist als Funktionsergebnis
              verfügbar, das an den Aufrufenden von clone() zurückgegeben
              wird. Ein Thread kann durch Benutzen von gettid(2) seine eigene
              TID erhalten.

              Wenn clone() ohne Angabe von CLONE_THREAD aufgerufen wurde, dann
              wird der resultierende Thread in eine neue Thread-Gruppe
              platziert, deren TGID der TID des Threads entspricht. Dieser
              Thread ist der Führer der neuen Thread-Gruppe.

              Ein neuer mit CLONE_THREAD erzeugter Thread hat den gleichen
              Elternprozess wie der, der clone() aufruft (d.h. wie
              CLONE_PARENT), so dass Aufrufe von getppid(2) den gleichen Wert
              für alle Threads in der Thread-Gruppe zurückliefern. Wenn ein
              CLONE_THREAD-Thread endet, wird dem Thread, der ihn per clone()
              erstellt hat, weder ein SIGCHLD-Signal (oder ein anderes
              Ende-Signal) gesandt, noch kann der Status eines solchen Threads
              per wait(2) abgefragt werden. (Der Thread wird als losgelöst
              bezeichnet.)

              Nachdem alle Threads in einer Thread-Gruppe beendet sind, wird
              dem Elternprozess ein SIGCHLD-Signal (oder ein anderes
              Ende-Signal) gesandt.

              Falls einige der Threads in einer Thread-Gruppe ein execve(2)
              durchführen, dann werden alle Threads auÃer dem Thread-Führer
              beendet und das neue Programm wird im Thread-Gruppenführer
              ausgeführt.

              Falls einer der Threads in einer Thread-Gruppe per fork(2) einen
              Kindprozess erzeugt, dann kann jeder Thread in der Gruppe
              wait(2) für diesen Kindprozess ausführen.

              Seit Linux 2.5.35 müssen die flags auch CLONE_SIGHAND
              enthalten, wenn CLONE_THREAD angegeben wurde. Beachten Sie auch,
              dass seit Linux 2.6.0 CLONE_SIGHAND auch CLONE_VM enthalten
              muss.

              Signalzuordnungen und -aktionen sind prozessweit: Falls ein
              nicht abgefangenes Signal an den Thread geschickt wird, dann
              wird es alle Mitglieder in der Thread-Gruppe beeinflussen
              (beenden, stoppen, fortfahren, darin ignoriert werden).

              Jeder Thread hat seine eigene Signalmaske, wie von
              sigprocmask(2) gesetzt.

              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 kill(2)  or 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 tgkill(2)  or
              pthread_sigqueue(3), or because the thread executed a machine
              language instruction that triggered a hardware exception (e.g.,
              invalid memory access triggering SIGSEGV or a floating-point
              exception triggering SIGFPE).

              Ein Aufruf von sigpending(2) liefert eine Signalmenge zurück,
              die die Vereinigung der anhängigen Prozess-orientierten Signale
              und der Signale, die für den aufrufenden Thread anhängig sind,
              ist.

              Falls ein Prozess-orientiertes Signal an eine Thread-Gruppe
              ausgeliefert wird und die Thread-Gruppe einen Handler für
              dieses Signal installiert hat, dann dann wird der Handler in
              exakt einem willkürlich ausgewählten Mitglied der
              Thread-Gruppe aufrufen, das das Signal nicht blockiert hat.
              Falls mehrere Threads in einer Gruppe darauf warten das gleiche
              Signal per sigwaitinfo(2) zu akzeptieren, wird der Kernel einen
              dieser Threads willkürlich auswählen, um das Signal zu
              empfangen.

       CLONE_UNTRACED (seit Linux 2.5.46)
              Falls CLONE_UNTRACED angegeben ist, kann ein verfolgender
              Prozess kein CLONE_PTRACE auf diesem Kindprozess erzwingen.

       CLONE_VFORK (seit Linux 2.2)
              Falls CLONE_VFORK gesetzt ist, wird die Ausführung des
              aufrufenden Prozesses aufgeschoben bis der Kindprozess seine
              virtuellen Speicherressourcen durch Aufrufen von execve(2) oder
              _exit(2) (wie bei vfork(2)) freigibt.

              Falls CLONE_VFORK nicht gesetzt ist, dann werden sowohl der
              aufrufende Prozess, als auch der Kindprozess nach dem Aufruf
              planbar und eine Anwendung sollte sich nicht darauf verlassen,
              dass die Ausführung in einer speziellen Reihenfolge erfolgt.

       CLONE_VM (seit Linux 2.0)
              Ist CLONE_VM gesetzt, laufen aufrufender Prozess und Kindprozess
              im selben Speicherbereich. Insbesondere sind Schreibzugriffe des
              aufrufenden Prozesses oder des Kindprozesses in den gemeinsamen
              Speicher auch vom anderen Prozess aus sichtbar. Zudem
              beeinflusst jede Veränderung der Speicher-Mappings mit mmap(2)
              oder munmap(2) durch den Kindprozess oder den aufrufenden
              Prozess auch den jeweils anderen Prozess.

              Ist CLONE_VM nicht gesetzt, erhält der Kindprozess eine eigene
              Kopie des Speicherbereichs des aufrufenden Prozesses zur Zeit
              des clone()-Aufrufs. Führt ein Prozess Schreibzugriffe auf den
              Speicher oder Ãnderungen am Dateispeicher-Mapping aus,
              beeinflussen diese Operationen nicht den jeweils anderen, wie
              bei fork(2).

ANMERKUNGEN
       Beachten Sie, dass die Glibc-Wrapperfunktion clone() einige Ãnderungen
       am Speicher, auf den child_stack zeigt, vornimmt (Ãnderungen, um den
       Stack korrekt für das Kind einzurichten), bevor der Systemaufruf
       clone() ausgelöst wird. Verwenden Sie daher in Fällen, in denen
       clone() zur rekursiven Erstellung von Kindern verwandt wird, nicht den
       Puffer, der für den Stack der Eltern eingesetzt wird, als Stack der
       Kinder.

   Unterschiede C-Bibliothek/Kernel
       Der rohe sys_clone-Systemaufruf entspricht eher fork(2), da er mit der
       Ausführung des Kindprozesses am Zeitpunkt des Aufrufs fortfährt. Von
       daher werden die Argumente fn und arg der clone()-Wrapper-Funktion
       weggelassen.

       Ein weiterer Unterschied für den rohen Systemaufruf clone() besteht
       darin, dass das Argument child_stack NULL sein könnte, so dass in
       diesem Fall das Kind eine Dublette des Stacks des Elternprozesses
       verwendet. (»Copy-on-write«-Semantik stellt sicher, dass der
       Kindprozess getrennte Kopien des Stapelspeichers erhält, wenn einer
       der beiden Prozesse den Stapelspeicher verändert.) In diesem Fall
       sollte die Option CLONE_VM nicht angegeben werden, damit es korrekt
       funktioniert. (Falls das Kind sich aufgrund des Schalters CLONE_VM mit
       dem Elternprozess den Speicher teilt, dann tritt keine
       copy-on-write-Duplizierung auf und wahrscheinlich tritt Chaos ein.

       Die Reihenfolge der Argumente unterscheidet sich auch im rohen
       Systemaufruf und es gibt über die Architekturen hinweg Variationen in
       den Argumenten, wie dies in den folgenden Absätzen dargestellt wird.

       Die rohe Schnittstelle für Systemaufrufe auf x86-64 und einigen
       anderen Architekturen (darunter Sh, Tile, Ia-64 und Alpha) sieht so
       aus:

           long clone(unsigned long flags, void *child_stack,
                      int *ptid, int *ctid,
                      unsigned long newtls);

       Auf x86-32 und mehreren anderen häufigen Architekturen (darunter
       Score, ARM, ARM 64, PA-RISC, Arc, Power PC, Xtensa und MIPS) ist die
       Reihenfolge der letzten zwei Argumente gedreht:

           long clone(unsigned long flags, void *child_stack,
                     int *ptid, unsigned long newtls,
                     int *ctid);

       Auf der Cris- und S30-Architektur ist die Reihenfolge der ersten zwei
       Argumente gedreht:

           long clone(void *child_stack, unsigned long flags,
                      int *ptid, int *ctid,
                      unsigned long newtls);

       Auf der Microblaze-Architektur wird ein zusätzliches Argument
       übergeben:

           long clone(unsigned long flags, void *child_stack,
                      int stack_size,         /* GröÃe des Stacks */
                      int *ptid, int *ctid,
                      unsigned long newtls);

   Blackfin, M68k und Sparc
       Die Konventionen der Argumentübergabe weichen auf Blackfin, M68k und
       Sparc von der obigen Beschreibung ab. Einzelheiten finden Sie in der
       Kernel- (und Glibc-) Quelle.

   Ia64
       Auf ia64 wird eine andere Schnittstelle benutzt:

           int __clone2(int (*fn)(void *),
                        void *child_stack_base, size_t stack_size,
                        int flags, void *arg, â¦
                     /* pid_t *ptid, struct user_desc *tls,
                        pid_t *ctid */ );

       Der oben gezeigte Prototyp ist für die Glibc-Wrapper-Funktion; für
       den Systemaufruf selbst wird der Prototyp wie folgt beschrieben (er ist
       identisch zum clone()-Prototyp auf Microblaze):

           long clone2(unsigned long flags, void *child_stack_base,
                       int stack_size,         /* GröÃe des Stacks */
                       int *ptid, int *ctid,
                       unsigned long tls);

       __clone2() arbeitet auf die gleiche Weise wie clone(), auÃer dass
       child_stack_base auf die niedrigste Adresse im Stapelspeicherbereich
       des Kindprozesses zeigt und stack_size die GröÃe des Stapelspeichers
       angibt, auf die child_stack_base zeigt.

   Linux 2.4 und älter
       Unter Linux 2.4 und früher gab es die Argumente ptid, tls und ctid
       noch nicht.

RÃCKGABEWERT
       Bei Erfolg wird im ausgeführten Thread des Aufrufenden die
       Thread-Kennung des Kindprozesses zurückgegeben. Im Fehlerfall wird im
       Kontext des Aufrufenden -1 zurückgegeben, kein Kindprozess erzeugt und
       errno entsprechend gesetzt.

FEHLER
       EAGAIN Es laufen bereits zu viele Prozesse; siehe fork(2).

       EINVAL CLONE_SIGHAND wurde angegeben, aber nicht CLONE_VM. (Seit Linux
              2.6.0.)

       EINVAL CLONE_THREAD wurde angegeben, aber nicht CLONE_SIGHAND. (Seit
              Linux 2.5.35.)

       EINVAL CLONE_THREAD wurde festgelegt, aber der aktuelle Prozess hatte
              vorher unshare(2) mit dem Schalter CLONE_NEWPID aufgerufen oder
              setns(2) verwandt, um sich wieder einem PID-Namensraum
              zuzuordnen.

       EINVAL In flags wurden sowohl CLONE_FS als auch CLONE_NEWNS angegeben.

       EINVAL (seit Linux 3.9)
              In flags wurden sowohl CLONE_NEWUSER als auch CLONE_FS
              angegeben.

       EINVAL In flags wurden sowohl CLONE_NEWIPC als auch CLONE_SYSVSEM
              angegeben.

       EINVAL Eines (oder beides) von CLONE_NEWPID oder CLONE_NEWUSER und
              eines (oder beides) von CLONE_THREAD oder CLONE_PARENT wurde in
              flags angegeben.

       EINVAL Wird von der Glibc-Wrapper-Funktion clone() zurückgegeben, wenn
              ein Wert von Null für fn oder child_stack angegeben wurde.

       EINVAL CLONE_NEWIPC wurde in flags festgelegt, aber der Kernel ist
              nicht mit den Optionen CONFIG_SYSVIPC und CONFIG_IPC_NS
              konfiguriert.

       EINVAL CLONE_NEWNET wurde in flags festgelegt, aber der Kernel ist
              nicht mit der Option CONFIG_NET_NS konfiguriert.

       EINVAL CLONE_NEWPID wurde in flags angegeben, aber der Kernel ist nicht
              mit der Option CONFIG_PID_NS konfiguriert.

       EINVAL CLONE_NEWUSER wurde in flags festgelegt, aber der Kernel ist
              nicht mit der Option CONFIG_USER_NS konfiguriert.

       EINVAL CLONE_NEWUTS wurde in flags festgelegt, aber der Kernel ist
              nicht mit der Option CONFIG_UTS_NS konfiguriert.

       EINVAL child_stack ist nicht an einer geeigneten Grenze für diese
              Architektur ausgerichtet. Beispielsweise muss child_stack auf
              Aarch64 ein Vielfaches von 16 sein.

       EINVAL CLONE_PIDFD was specified together with CLONE_DETACHED.

       EINVAL CLONE_PIDFD was specified together with CLONE_PARENT_SETTID.

       EINVAL CLONE_PIDFD was specified together with CLONE_THREAD.

       ENOMEM Es kann nicht ausreichend Speicher für eine Aufgabenstruktur
              des Kindprozesses reserviert werden oder um benötigte Teile vom
              Kontext des Aufrufenden zu kopieren.

       ENOSPC (seit Linux 3.7)
              CLONE_NEWPID wurde in den Schalter angegeben, aber die
              Begrenzung der Verschachtelungstiefe von PID-Namensräumen
              würde überschritten; siehe pid_namespaces(7).

       ENOSPC (seit Linux 4.9; vorher EUSERS)
              CLONE_NEWUSER wurde in flags festgelegt und der Aufruf würde zu
              einer Ãberschreitung der Begrenzung für die Anzahl von
              verschachtelten Benutzernamensräumen führen. Siehe
              user_namespaces(7).

              Von Linux 3.11 bis Linux 4.8 war der in diesem Fall
              diagnostizierte Fehler EUSERS.

       ENOSPC (seit Linux 4.9)
              Einer der Werte in flags legte die Erstellung eines neuen
              Benutzer-Namensraums fest, dadurch würde aber die in der
              enstprechenden Datei in /proc/sys/user festgelegte Begrenzung
              überschritten. Für weitere Details siehe namespaces(7).

       EPERM  CLONE_NEWCGROUP, CLONE_NEWIPC, CLONE_NEWNET, CLONE_NEWNS,
              CLONE_NEWPID oder CLONE_NEWUTS wurde von einem nicht
              privilegierten Prozess angegeben (Prozess ohne CAP_SYS_ADMIN).

       EPERM  CLONE_PID wurde von einem anderen Prozess als Prozess 0
              angegeben. (Dieser Fehler tritt nur unter Linux 2.5.15 und
              früheren Versionen auf.)

       EPERM  CLONE_NEWUSER wurde in flags festgelegt, aber weder die
              effektive Benutzerkennung noch die effektive Gruppenkennung des
              Aufrufenden hat eine Abbildung in den Namensraum der Eltern
              (siehe user_namespaces(7)).

       EPERM (seit Linux 3.9)
              CLONE_NEWUSER wurde in flags festgelegt und der Aufrufende ist
              in einer Chroot-Umgebung (d.h. das Wurzelverzeichnis des
              Aufrufenden passt nicht zum Wurzelverzeichnis des
              Einhängenamensraums, in dem er sich befindet).

       ERESTARTNOINTR (seit Linux 2.6.17)
              Ein Systemaufruf wurde durch ein Signal unterbrochen und wird
              neu gestartet. (Dies wird nur während einer Verfolgung sichtbar
              sein.)

       EUSERS (Linux 3.11 bis Linux 4.8)
              CLONE_NEWUSER wurde in flags festgelegt und die Begrenzung für
              die Anzahl von verschachtelten Benutzernamensräumen würde
              überschritten. Siehe die Diskussion des Fehlers ENOSPC oben.

KONFORM ZU
       clone() ist Linux-spezifisch und sollte nicht in portierbaren
       Programmen benutzt werden.

ANMERKUNGEN
       Der Systemaufruf kcmp(2) kann zum Testen, ob zwei Prozesse sich
       verschiedene Ressourcen, wie die Dateideskriptortabelle, die
       Rücksetz-Aktionen der System-V-Semaphoren oder einen virtuellen
       Adressraum, teilen, verwandt werden.

       Handler, die mittels pthread_atfork(3) registriert sind, werden
       während eines Aufrufs von clone() nicht ausgeführt.

       In der Linux 2.4.x-Serie gibt CLONE_THREAD generell dem neuen Prozess
       nicht den gleichen Elternprozess, wie dem aufrufenden Prozess. Für die
       Kernel-Versionen 2.4.7 bis 2.4.18 implizierte der Schalter CLONE_THREAD
       jedoch den Schalter CLONE_PARENT (wie in Kernel 2.6.0 und neuer).

       Für eine Weile gab es CLONE_DETACHED (eingeführt in 2.5.32):
       Elternprozesse wollen kein Ende-Signal des Kindprozesses. In Linux
       2.6.2 verschwand die Notwendigkeit, dies zusammen mit CLONE_THREAD zu
       übergeben. Dieser Schalter ist immer noch definiert, hat aber keine
       Auswirkungen.

       Auf i386-Architekturen sollte clone() nicht durch vsyscall aufgerufen
       werden, sondern direkt durch int $0x80.

FEHLER
       GNU-C-Bibliotheksversionen 2.3.4 bis einschlieÃlich 2.24 enthielten
       eine Wrapper-Funktion für getpid(2), die Zwischenspeichern von PIDs
       vornahm. Dieses Zwischenspeichern beruhte auf der Unterstützung in dem
       Glibc-Wrapper von clone(), aber Einschränkungen in der Implementierung
       bedeuteten, dass unter einigen Umständen der Zwischenspeicher nicht
       aktuell war. Insbesondere wenn ein Signal sofort nach dem
       clone()-Aufruf an den Kindprozess gesandt wurde, konnte ein Aufruf von
       getpid(2) in einem Signal-Handler die PID des aufrufenden Prozesses
       (des »Elternprozesses«) zurückgeben, falls der Clone-Wrapper noch
       keine Chance hatte den PID-Zwischenspeicher im Kindprozess zu
       aktualisieren. (Diese Diskussion ignoriert den Fall, dass der
       Kindprozess mit CLONE_THREAD erstellt wurde, in dem getpid(2) den
       gleichen Wert im Kindprozess zurückgeben sollte und im Prozess, der
       clone() aufrief, wie sich der Aufrufende und der Kindprozess in der
       gleichen Thread-Gruppe befinden. Das Problem des nicht mehr frischen
       Zwischenspeichers tritt auch auf, wenn das Argument flags CLONE_VM
       enthält.) Um die Wahrheit zu erfahren, war es manchmal notwendig
       gewesen, Code wie den folgenden zu verwenden:

           #include <syscall.h>

           pid_t mypid;

           mypid = syscall(SYS_getpid);

       Aufgrund des Problems mit dem nicht mehr frischem Zwischenspeicher
       sowie anderen in getpid(2) bemerkten Problemen, wurde die
       Funktionalität des PID-Zwischenspeicherns in Glibc 2.25 entfernt.

BEISPIEL
       Das folgende Programm demonstriert die Benutzung von clone() zum
       Erzeugen eines Kindprozesses, der in einem separaten UTS-Namensraum
       ausgeführt wird. Der Kindprozess ändert in seinem UTS-Namensraum den
       Rechnernamen. Dann zeigen sowohl Eltern- als auch Kindprozess den
       Rechnernamen des Systems an, wodurch sichtbar wird, dass der
       Rechnername sich im UTS-Namensraum von Eltern- und Kindprozess
       unterscheidet. Ein Beispiel für die Verwendung dieses Programms finden
       Sie in setns(2).

   Programmquelltext
       #define _GNU_SOURCE
       #include <sys/wait.h>
       #include <sys/utsname.h>
       #include <sched.h>
       #include <string.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <unistd.h>

       #define errExit(Nachricht)    do { perror(Nachricht); exit(EXIT_FAILURE); \
                               } while (0)

       static int              /* Startfunktion für geklonten Kindprozess */
       childFunc(void *arg)
       {
           struct utsname uts;

           /* Rechnername im UTS-Namensraum des Kindprozesses ändern */

           if (sethostname(arg, strlen(arg)) == -1)
               errExit("sethostname");

           /* Rechnernamen abfragen und anzeigen */

           if (uname(&uts) == -1)
               errExit("uname");
           printf("uts.nodename im Kindprozess:  %s\n", uts.nodename);

           /* Der Namensraum wird für eine Weile durch Schlafen offen gehalten.
              Dies ermöglicht etwas zu experimentieren â  zum Beispiel
              kann ein weiterer Prozess dem Namensraum beitreten. */

           sleep(200);

           return 0;           /* Kindprozess wird nun beendet */
       }

       #define STACK_SIZE (1024 * 1024)    /* StapelspeichergröÃe für geklonten
                                              Kindprozess */

       int
       main(int argc, char *argv[])
       {
           char *stack;                    /* Start des Stapelspeicherpuffers */
           char *stackTop;                 /* Ende des Stapelspeicherpuffers */
           pid_t pid;
           struct utsname uts;

           if (argc < 2) {
               fprintf(stderr, "Aufruf: %s <Kindprozess-Rechnername>\n", argv[0]);
               exit(EXIT_SUCCESS);
           }

           /* Stapelspeicher für Kindprozess reservieren */

           stack = malloc(STACK_SIZE);
           if (stack == NULL)
               errExit("malloc");
           stackTop = stack + STACK_SIZE;  /* Annahme, dass Stapelspeicher nach
                                              unten wächst */

           /* Es wird ein Kindprozess erzeugt, der seinen eigenen Namensraum hat.
              Der Kindprozess beginnt die Ausführung in childFunc() */

           pid = clone(childFunc, stackTop, CLONE_NEWUTS | SIGCHLD, argv[1]);
           if (pid == -1)
               errExit("clone");
           printf("clone() gab %ld zurück\n", (long) pid);

           /* Elternprozess fällt bis hierher durch */

           sleep(1);   /* gibt dem Kindprozess Zeit zum Ãndern des Rechnernamens */

           /* Den Rechnernamen im UTS-Namensraum des Elternprozesses anzeigen.
              Dieser wird sich vom Rechnernamen im UTS-Namensraum des Kindprozesses
              unterscheiden. */

           if (uname(&uts) == -1)
               errExit("uname");
           printf("uts.nodename im Elternprozess: %s\n", uts.nodename);

           if (waitpid(pid, NULL, 0) == -1)    /* Warten auf Kindprozess */
               errExit("waitpid");
           printf("Kindprozess wurde beendet\n");

           exit(EXIT_SUCCESS);
       }

SIEHE AUCH
       fork(2), futex(2), getpid(2), gettid(2), kcmp(2), pidfd_open(2),
       set_thread_area(2), set_tid_address(2), setns(2), tkill(2), unshare(2),
       wait(2), capabilities(7), namespaces(7), pthreads(7)

KOLOPHON
       Diese Seite ist Teil der Veröffentlichung 5.03 des Projekts
       Linux-man-pages. Eine Beschreibung des Projekts, Informationen, wie
       Fehler gemeldet werden können sowie die aktuelle Version dieser Seite
       finden sich unter https://www.kernel.org/doc/man-pages/.


ÃBERSETZUNG
       Die deutsche Ãbersetzung dieser Handbuchseite wurde von Daniel Kobras
       <kobras@linux.de>, Chris Leick <c.leick@vollbio.de>, Mario Blättermann
       <mario.blaettermann@gmail.com>, Dr. Tobias Quathamer <toddy@debian.org>
       und Helge Kreutzmann <debian@helgefjell.de> erstellt.

       Diese Ãbersetzung ist Freie Dokumentation; lesen Sie die GNU General
       Public License Version 3 oder neuer bezüglich der Copyright-
       Bedingungen. Es wird KEINE HAFTUNG übernommen.

       Wenn Sie Fehler in der Ãbersetzung dieser Handbuchseite finden,
       schicken Sie bitte eine E-Mail an <debian-l10n-
       german@lists.debian.org>.



Linux                           2. August 2019                        CLONE(2)