clone

CLONE(2)                    Linux-Programmierhandbuch                   CLONE(2)



BEZEICHNUNG
       clone, __clone2, clone3 - erzeugt einen Kindprozess

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

       #define _GNU_SOURCE
       #include <sched.h>

       int clone(int (*fn)(void *), void *stack, int flags, void *arg, …
                 /* pid_t *parent_tid, void *tls, pid_t *child_tid */ );

       /* Für den Prototyp des den rohen clone()-Systemaufrufs siehe ANMERKUNGEN */

       long clone3(struct clone_args *cl_args, size_t size);

       Hinweis: Es gibt noch keinen Glibc-Wrapper für clone3(); siehe
       ANMERKUNGEN.

BESCHREIBUNG
       Diese Systemaufrufe erzeugen auf eine ähnliche Weise wie fork(2) einen
       neuen Prozess (»Kind«).

       Im Gegensatz zu fork(2) bieten diese Systemaufrufe eine genauere
       Kontrolle darüber, welche Teile des Ausführungskontextes vom aufrufenden
       und vom Kindprozess gemeinsam benutzt werden. Beispielsweise kann der
       Aufrufende mittels dieser Systemaufrufe steuern, ob die zwei Prozesse den
       virtuellen Adressraum, die Tabelle der Dateideskriptoren und die Tabelle
       der Signal-Handler gemeinsam benutzen. Diese Systemaufrufe ermöglichen es
       auch, den neuen Kindprozess in einen separaten Namensraum (siehe
       namespaces(7)) abzulegen.

       Beachten Sie, dass in dieser Handbuchseite der »aufrufende Prozess«
       normalerweise der »Elternprozess« ist. Siehe aber auch die nachfolgende
       Beschreibung von CLONE_PARENT und CLONE_THREAD.

       Diese Seite beschreibt die folgenden Schnittstellen:

       *  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.

       *  Der neuere Systemaufruf clone3().

       Im Rest der Seite wird die Terminologie »der Clone-Aufruf« verwandt, wenn
       Details erklärt werden, die auf alle diese Schnittstellen zutreffen.

   Die clone()-Wrapper-Funktion
       Wird mit der clone()-Wrapper-Funktion 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 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
       stack für gewöhnlich auf die oberste Adresse im bereitgehaltenen
       Speicherbereich zeigt. Beachten Sie, dass clone() keine Möglichkeit
       bereitstellt, mit der der Aufrufende den Kernel über die Größe des
       Stack-Bereichs informieren könnte.

       Die verbliebenen Argumente für clone() werden unten behandelt.

   clone3()
       Der Systemaufruf clone3() stellt eine Obermenge der Funktionalität der
       älteren Schnittstelle clone() bereit. Er stellt auch eine Reihe von
       API-Verbesserungen bereit, einschließlich: Platz für zusätzliche
       Schalter-Bits; deutlichere Trennung beim Einsatz der verschiedenen
       Argumente, die Möglichkeit, die Größe des Stack-Bereichs des
       Kindprozesses festzulegen.

       Wie bei fork(2) kehrt clone3() sowohl im Eltern- als auch im Kindprozess
       zurück. Er liefert 0 im Kindprozess und die PID des Kindprozesses im
       Elternprozess zurück.

       Das Argument cl_args von clone3() ist eine Struktur der folgenden Form:

           struct clone_args {
               u64 flags;        /* Schalter-Bit-Maske */
               u64 pidfd;        /* Wo der PID-Dateideskriptor gespeichert
                                    werden soll (pid_t *) */
               u64 child_tid;    /* Wo die Kind-TID gespeichert werden soll,
                                    im Speicher des Kindes (pid_t *) */
               u64 parent_tid;   /* Wo die Kind-TID gespeichert werden soll,
                                    im Speicher des Elternprozesses (int *) */
               u64 exit_signal;  /* Beim Beenden des Kindprozesses an den Elternprozess
                                    zu sendendes Signal */
               u64 stack;        /* Zeiger auf das niedrigste Byte des Stacks */
               u64 stack_size;   /* Größe des Stacks */
               u64 tls;          /* Ort eines neuen TLS */
               u64 set_tid;      /* Zeiger auf ein pid_t-Feld
                                    (seit Linux 5.5) */
               u64 set_tid_size; /* Anzahl von Elementen in set_tid
                                    (seit Linux 5.5) */
               u64 cgroup;       /* Dateideskriptor für Ziel-Cgroup
                                    eines Kindes (seit Linux 5.7) */
           };

       Das an clone3() übergebene Argument size sollte auf die Größe dieser
       Struktur initialisiert werden. (Die Existenz des Arguments size
       ermöglicht zukünftige Erweiterungen der clone_args-Struktur.)

       Der Stack für den Kindprozess wird in cl_args.stack, der auf das
       niedrigste Byte des Stack-Bereichs zeigt, und cl_args.stack_size, der die
       Größe des Stack-Bereichs in Byte festlegt, festgelegt. Falls der Schalter
       CLONE_VM (siehe unten) festgelegt ist, muss ein Stack explizit reserviert
       und festgelegt werden. Andernfalls können diese Felder als NULL und 0
       festgelegt werden, wodurch der Kindprozess den gleichen Stack-Bereich wie
       der Elternprozess verwendet (im eigenen virtuellen Adressraum des
       Kindprozesses).

       Die verbliebenen Felder im Argument cl_args werden unten behandelt.

   Äquivalenz zwischen den Argumenten von clone() und clone3()
       Anders als die ältere clone()-Schnittstelle, bei der die Argumente
       individuell übergeben werden, werden die Argumente bei der neueren
       clone3()-Schnittstelle in die oben gezeigte Struktur clone_args gepackt.
       Diese Struktur erlaubt es, dass eine Obermenge an Informationen über die
       clone()-Argumente übergeben wird.

       Die folgende Tabelle zeigt die Äquivalenz zwischen den Argumenten von
       clone() und den Feldern in den an clone3() übergebenen clone_args:

              clone()            clone3()       Hinweise
                                 Feld cl_args
              Schalter & ~0xff   Schalter       Für die meisten Schalter; Details unten
              parent_tid         pidfd          Siehe CLONE_PIDFD
              child_tid          child_tid      Siehe CLONE_CHILD_SETTID
              parent_tid         parent_tid     Siehe CLONE_PARENT_SETTID
              Schalter & 0xff    exit_signal
              stack              stack
              ---                stack_size
              tls                tls            Siehe CLONE_SETTLS
              ---                set_tid        Siehe weiter unten für Details.
              ---                set_tid_size
              ---                cgroup         Siehe CLONE_INTO_CGROUP

   Das Kind-Beendigungssignal
       Wenn sich der Kindprozess beendet, kann ein Signal an den Elternprozess
       gesandt werden. Das Beendigungssignal wird in den niedrigen Bytes von
       flags (clone()) oder in cl_args.exit_signal (clone3()) festgelegt. Falls
       dieses Signal als etwas anderes als SIGCHLD festgelegt wurde, dann muss
       der Elternprozess die Optionen __WALL oder __WCLONE angeben, wenn er mit
       wait(2) auf den Kindprozess wartet. Falls kein Signal (d.h. Null)
       festgelegt wurde, wird dem Elternprozess nicht signalisiert, wenn der
       Kindprozess endet.

   Das Feld set_tid
       Standardmäßig wählt der Kernel die nächste sequenzielle PID für den neuen
       Prozess in jedem der PID-Namensräume, in denen er vorhanden ist. Beim
       Erstellen eines Prozesses mit clone3() kann das (seit Linux 5.5
       verfügbare) Feld set_tid zur Auswahl bestimmter PIDs für den Prozess in
       einem oder allen der PID-Namensräume, in denen er vorhanden ist,
       eingesetzt werden. Falls die PID des neu erstellten Prozesses nur im
       aktuellen PID-Namensraum oder in dem neu erstellten PID-Namensraum (falls
       flags CLONE_NEWPID enthält) gesetzt werden soll, dann muss das erste
       Element in dem Feld set_tid auf die gewünschte PID gesetzt werden und
       set_tid_size muss 1 sein.

       Falls die PID des neu erstellten Prozesses einen bestimmten Wert in
       mehreren PID-Namensräumen haben soll, dann kann dass Feld set_tid über
       mehrere Einträge verfügen. Der erste Eintrag definiert die PID im am
       tiefsten verschachtelten PID-Namensraum und jeder der nachfolgenden
       Einträge enthält die PID in dem entsprechenden Vorfahren-PID-Namensraum.
       Die Anzahl der PID-Namensräume in denen eine PID gesetzt werden soll,
       wird mit set_tid_size gesetzt; dieser Wert kann nicht größer als die
       Anzahl der derzeit verschachtelten PID-Namensräume sein.

       Um einen Prozess zu erzeugen, der die nachfolgenden PIDs in einem
       PID-Namensraum hat:

              PID-NS-Stufe   Angeforderte PID   Hinweise
              0              31496              Äußerster PID-Namensraum
              1              42
              2              7                  Innerster PID-Namensraum

       Setzen Sie das Feld auf:

           set_tid[0] = 7;
           set_tid[1] = 42;
           set_tid[2] = 31496;
           set_tid_size = 3;

       Falls nur die PIDs in den zwei innersten PID-Namensräumen festgelegt
       werden müssen, setzen Sie das Feld auf:

           set_tid[0] = 7;
           set_tid[1] = 42;
           set_tid_size = 2;

       Die PID in den PID-Namensräumen außerhalb der zwei innersten
       PID-Namensräume wird genauso wie jede andere PID ausgewählt.

       Die Funktionalität set_tid benötigt CAP_SYS_ADMIN in allen
       Benutzernamensräumen, die dem des Ziel-PID-Namensraumes gehören.

       Aufrufende dürfen in einem gegebenen PID-Namensraum nur eine PID größer
       als 1 auswählen, falls ein init-Prozess (d.h. ein Prozess mit der PID 1)
       in diesem Namensraum bereits existiert. Andernfalls muss der PID-Eintrag
       für diesen PID-Namensraum 1 sein.

   Die Schaltermaske
       Sowohl clone() als auch clone3() erlauben eine Schalter-Bit-Maske, die
       das Verhalten verändert und dem Aufrufenden festzulegen erlaubt, was von
       dem aufrufenden Prozess und dem Kindprozess gemeinsam benutzt wird. Diese
       Bitmaske—das Argument flags von clone() oder das an clone3() übergebene
       Feld cl_args.flags—wird im Rest dieser Handbuchseite als die flags-Maske
       bezeichnet.

       Die flags-Maske wird als bitweises ODER von Null oder mehreren der oben
       aufgeführten Konstanten festgelegt. Falls nicht unten anders angegeben,
       sind diese Schalter sowohl in clone() als auch clone3() verfügbar (und
       haben die gleiche Wirkung).

       CLONE_CHILD_CLEARTID (seit Linux 2.5.49)
              Die Kind-Thread-Kennung an der durch child_tid gezeigten Stelle
              (clone()) oder cl_args.child_tid (clone3()) 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, auf die child_tid
              (clone()) oder cl_args.child_tid (clone3()) zeigt, im
              Kindspeicher. Die Speicheraktion wird abgeschlossen, bevor der
              Clone-Aufruf die Steuerung an den Benutzerraum im Kindprozess
              zurückgibt. (Beachten Sie, dass die Speicheraktion noch nicht
              abgeschlossen sein könnte, bevor der Clone-Aufruf den
              Elternprozess zurückliefert, was relevant wird, wenn auch der
              Schalter CLONE_VM eingesetzt wird.)

       CLONE_CLEAR_SIGHAND (seit Linux 5.5)
              Standardmäßig sind die Signal-Zuordnungen im Kind-Thread identisch
              zu denen im Eltern-Prozess. Falls dieser Schalter angegeben ist,
              dann werden alle Signale, die im Eltern-Prozess gehandhabt werden,
              im Kind-Thread auf ihre Standardzuordnung (SIG_DFL) zurückgesetzt.

              Es ergibt keinen Sinn, diesen Schalter zusammen mit CLONE_SIGHAND
              anzugeben; daher ist diese Kombination nicht erlaubt.

       CLONE_DETACHED (historisch)
              Eine Zeit lang (während der Linux-2.5-Entwicklungsserie) gab es
              einen Schalter CLONE_DETACHED, der dazu führte, dass der
              Elternprozess kein Signal empfing, wenn sich das Kind beendete.
              Schließlich wurde die Auswirkung dieses Schalters in dem Schalter
              CLONE_THREAD mit aufgenommen und zum Zeitpunkt der
              Veröffentlichung von Linux 2.6.0 hatte dieser Schalter keine
              Auswirkung. Beginnend mit Linux 2.6.2 verschwand die
              Notwendigkeit, diesen Schalter mit CLONE_THREAD zusammen
              anzugeben.

              Dieser Schalter ist noch definiert, wird aber beim Aufruf von
              clone() normalerweise ignoriert. Siehe allerdings die Beschreibung
              von CLONE_PIDFD für einige Ausnahmen.

       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 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_INTO_CGROUP (seit Linux 5.7)
              Standardmäßig wird ein Kindprozess in die gleiche Version-2-Cgroup
              wie sein Elternprozess abgelegt. Der Schalter CLONE_INTO_CGROUP
              ermöglicht es, den Kindprozess in einer anderen Version-2-Cgroup
              zu erstellen. (Beachten Sie, dass CLONE_INTO_CGROUP nur für
              Version-2-Cgroups wirksam wird.)

              Um den Kindprozess in eine andere Cgroup abzulegen, legt der
              Aufrufende CLONE_INTO_CGROUP in cl_args.flags fest und übergibt im
              Feld cl_args.cgroup einen Dateideskriptor, der sich auf eine
              Version-2-Cgroup bezieht. (Dieser Dateideskriptor kann erhalten
              werden, indem ein Cgroup-v2-Verzeichnis mittels des Schalters
              O_RDONLY oder O_PATH geöffnet wird.) Beachten Sie, dass sämtliche
              übliche Einschränkungen (beschrieben in cgroups(7)) über das
              Ablegen eines Prozesses in einer Version-2-Cgroup gültig bleiben.

              Folgende Anwendungsfälle für CLONE_INTO_CGROUP sind unter anderen
              möglich:

              *  Das Erzeugen eines Prozesses in einer Cgroup, die sich von der
                 des Elternprozesses unterscheidet, ermöglicht es einem
                 Diensteverwalter, neue Dienste direkt in dedizierte Cgroups zu
                 erzeugen. Dies beseitigt das Flackern bei der Buchführung, das
                 erzeugt würde, falls der Kindprozess erst in der gleichen
                 Cgroup wie der Elternprozess erzeugt und dann in die
                 Ziel-Cgroup verschoben würde. Desweiteren ist die Erzeugung des
                 Kindprozesses direkt in der Ziel-Cgroup deutlich billiger als
                 das Verschieben des Kindprozesses in die Ziel-Cgroup, nachdem
                 er erstellt wurde.

              *  Der Schalter CLONE_INTO_CGROUP erlaubt auch die Erstellung
                 eingefrorener Kindprozesse durch Erzeugung dieser in einer
                 eingefrorenen Cgroup. (Siehe cgroups(7) für eine Beschreibung
                 des Einfrier-Controllers.)

              *  Für Anwendungen mit Threads (oder sogar
                 Thread-Implementierungen, die Cgroups verwenden, um einzelne
                 Threads zu begrenzen) ist es möglich, ein festes Cgroup-Layout
                 zu errichten, bevor jeder Thread direkt in seine Ziel-Cgroup
                 erzeugt wird.

       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-Schedulers, d.h. welches der E/A-Scheduler zur
              Modellplanung für E/As des Prozesses benutzt. Falls sich Prozesse
              den gleichen E/A-Kontext teilen, werden sie vom E/A-Scheduler als
              ein einziger betrachtet. Als Konsequenz daraus müssen sie sich die
              gleiche Plattenzeitzugriffzeit teilen. Einige E/A-Scheduler
              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)
              Der Prozess wird in einem neuen cgroup-Namensraum erstellt. Falls
              dieser Schalter nicht gesetzt ist, dann wird der Prozess (wie mit
              fork(2)) im gleichen cgroup-Namensraum wie der aufrufende Prozess
              erstellt.

              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)
              Wenn CLONE_NEWIPC gesetzt ist, dann wird der Prozess in einem
              neuen IPC-Namensraum erstellt. Falls dieser Schalter nicht gesetzt
              ist, dann wird der Prozess (wie mit fork(2)) im gleichen
              IPC-Namensraum wie der aufrufende Prozess erstellt.

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

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

       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.

              Weitere Informationen zu Netzwerk-Namensräumen finden Sie in
              network_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.

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

              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.

       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, dann wird der Prozess (wie mit fork(2)) im gleichen
              PID-Namensraum wie der aufrufende Prozess erstellt.

              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 festgelegt 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.

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

              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 festgelegt werden. Aus Sicherheitsgründen darf
              CLONE_NEWUSER nicht zusammen mit CLONE_FS festgelegt werden.

       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.

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

              Nur ein privilegierter Prozess (CAP_SYS_ADMIN) kann CLONE_NEWUTS
              angeben.

       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.

              Der Schalter CLONE_PARENT kann in Clone-Aufrufen durch den
              globalen Init-Prozess (PID 1 im anfänglichen PID-Namensraum) und
              in Init-Prozessen in anderen PID-Namensräumen nicht verwandt
              werden. Diese Einschränkung verhindert die Erstellung von
              Prozessbäumen mit mehreren Wurzeln sowie die Erstellung von nicht
              zerstörbaren Zombies im anfänglichen PID-Namensraum.

       CLONE_PARENT_SETTID (seit Linux 2.5.49)
              Die Kindprozess-Thread-Kennung an der Stelle im Elternspeicher
              ablegen, auf die parent_tid (clone()) oder cl_args.parent_tid
              (clone3()) zeigt. (In Linux 2.5.32-2.5.48 gab es einen Schalter
              CLONE_SETTID, der das tat.) Die Speicheraktion wird abgeschlossen,
              bevor der Clone-Aufruf 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 festgelegt werden (PID 0). Dieser Schalter verschwand
              in Linux 2.5.16 komplett aus den Kernelquellen. In der Folge
              ignorierte der Kernel dieses Bit, falls es in der flags-Maske
              festgelegt wurde. Viel später wurde das Bit für die Verwendung als
              Schalter CLONE_PIDFD recyclet.

       CLONE_PIDFD (seit Linux 5.2)
              Falls dieser Schalter festgelegt ist, wird ein
              PID-Dateideskriptor, der sich auf einen Kindprozess bezieht,
              reserviert und an dem festgelegten Ort im Speicher des
              Elternprozesses abgelegt. Der Schalter »close-on-exec« wird bei
              diesem neuen Dateideskriptor gesetzt. PID-Dateideskriptoren können
              für die in pidfd_open(2) beschriebenen Zwecke verwandt werden.

              *  Bei der Verwendung von clone3() wird der PID-Dateideskriptor an
                 dem durch cl_args.pidfd angezeigten Ort abgelegt.

              *  Bei der Verwendung von clone() wird der PID-Dateideskriptor an
                 dem Ort abgelegt, auf den parent_tid zeigt. Da das Argument
                 parent_tid zur Rückgabe des PID-Dateideskriptors verwandt wird,
                 kann CLONE_PIDFD beim Aufruf von clone() nicht mit
                 CLONE_PARENT_SETTID benutzt werden.

              Es ist derzeit nicht möglich, diesen Schalter zusammen mit
              CLONE_THREAD zu verwenden. Das bedeutet, dass ein durch den
              PID-Dateideskriptor identifizierter Prozess immer der
              Prozessgruppenleiter sein wird.

              Falls der veraltete Schalter CLONE_DETACHED beim Aufruf von
              clone() zusammen mit CLONE_PIDFD festgelegt wird, wird ein Fehler
              zurückgeliefert. Falls CLONE_DETACHED beim Aufruf von clone3()
              festgelegt wird, wird auch ein Fehler zurückgeliefert. Dieses
              Fehlerverhalten stellt sicher, dass das CLONE_DETACHED
              entsprechende Bit für weitere
              PID-Dateideskriptorenfunktionalitäten in der Zukunft recyclet
              werden kann.

       CLONE_PTRACE (seit Linux 2.2)
              Falls CLONE_PTRACE festgelegt 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 tls gesetzt.

              Die Interpretation von tls und der resultierende Effekt ist
              architekturabhängig. Auf X86 ist tls 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.

              Der Einsatz dieses Schalters verlangt detaillierte Kenntnisse und
              sollte im Allgemeinen nicht erfolgen, außer in einigen
              Bibliotheken, die Threading implementieren.

       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 zum
              Zeitpunkt des Clone-Aufrufs 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 muss die flags-Maske außerdem CLONE_VM enthalten,
              falls CLONE_SIGHAND festgelegt 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 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 aufrufen hat (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 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 muss die flags-Maske auch CLONE_SIGHAND
              enthalten, wenn CLONE_THREAD festgelegt 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.

              Ein Signal kann Prozess-orientiert oder Thread-orientiert sein.
              Ein Prozess-orientiertes Signal kann auf eine Thread-Gruppe (d.h.
              einer TGID) abzielen und wird an einen beliebig ausgewählten
              Thread innerhalb dieser, der das Signal nicht blockiert,
              ausgeliefert. Ein Signal kann Prozess-orientiert sein, da es vom
              Kernel aus anderen Gründen (neben Hardware-Ausnahmebehandlungen)
              erstellt wurde oder da mittels kill(2) oder sigqueue(3) gesandt
              wurde. Ein Thread-orientiertes Signal zielt auf ein bestimmten
              Thread (d.h. wird an ihn ausgeliefert). Ein Signal kann
              Thread-orientiert sein, da es mittels tgkill(2) oder
              pthread_sigqueue(3) gesandt wurde oder da der Thread einen
              Maschinensprachenbefehl ausführte, der eine
              Hardware-Ausnahmebehandlung auslöste (z.B. löst ein ungültiger
              Speicherzugriff SIGSEGV oder eine Fließkommaausnahmebehandlung
              SIGFPE aus).

              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 festgelegt 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 zum Zeitpunkt
              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).

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).

       EBUSY (nur clone3())
              CLONE_INTO_CGROUP wurde in cl_args.flags angegeben, aber der in
              cl_args.cgroup angegebene Dateideskriptor bezieht sich auf eine
              Version-2-Cgroup, in der ein Domain-Controller aktiviert wurde.

       EEXIST (nur clone3())
              Eine (oder mehrere) der in set_tid festgelegten PIDs existiert im
              entsprechenden PID-Namensraum bereits.

       EINVAL In der flags-Maske wurden sowohl CLONE_SIGHAND als auch
              CLONE_CLEAR_SIGHAND festgelegt.

       EINVAL CLONE_SIGHAND wurde in der flags-Maske festgelegt, aber nicht
              CLONE_VM. (Seit Linux 2.6.0.)

       EINVAL CLONE_THREAD wurde in der flags-Maske festgelegt, aber nicht
              CLONE_SIGHAND. (Seit Linux 2.5.35.)

       EINVAL CLONE_THREAD wurde in der flags-Maske 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 der flags-Maske wurden sowohl CLONE_FS als auch CLONE_NEWNS
              festgelegt.

       EINVAL (seit Linux 3.9)
              In der flags-Maske wurden sowohl CLONE_NEWUSER als auch CLONE_FS
              festgelegt.

       EINVAL In der flags-Maske wurden sowohl CLONE_NEWIPC als auch
              CLONE_SYSVSEM festgelegt.

       EINVAL Eines (oder beides) von CLONE_NEWPID oder CLONE_NEWUSER und eines
              (oder beides) von CLONE_THREAD oder CLONE_PARENT wurde in der
              flags-Maske festgelegt.

       EINVAL (seit Linux 2.6.32)
              CLONE_PARENT wurde festgelegt und der Aufrufende ist ein
              Init-Prozess.

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

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

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

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

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

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

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

       EINVAL (nur clone3())
              In der flags-Maske wurden CLONE_DETACHED festgelegt.

       EINVAL (nur clone())
              CLONE_PIDFD wurde zusammen mit CLONE_DETACHED in der flags-Maske
              festgelegt.

       EINVAL CLONE_PIDFD wurde zusammen mit CLONE_THREAD in der flags-Maske
              festgelegt.

       EINVAL (nur clone())
              CLONE_PIDFD wurde zusammen mit CLONE_PARENT_SETTID in der
              flags-Maske festgelegt.

       EINVAL (nur clone3())
              set_tid_size ist größer als die Anzahl der geschachtelten
              PID-Namensräume.

       EINVAL (nur clone3())
              Eine der in set_tid festgelegten PIDs war ungültige.

       EINVAL (nur AArch64, Linux 4.6 und älter)
              stack war nicht an einer 126-Bit-Grenze ausgerichtet.

       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 der flags-Maske festgelegt, 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 der flags-Maske 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 der flags-Maske 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).

       EOPNOTSUPP (nur clone3())
              CLONE_INTO_CGROUP wurde in cl_args.flags angegeben, aber der in
              cl_args.cgroup angegebene Dateideskriptor bezieht sich auf eine
              Version-2-Cgroup, die im Zustand Domain ungültig ist.

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

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

       EPERM  CLONE_NEWUSER wurde in der flags-Maske 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 der flags-Maske 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).

       EPERM (nur clone3())
              set_tid_size war größer als Null und dem Aufrufenden fehlt in
              einem oder mehreren Benutzernamensräumen, dem die entsprechenden
              PID-Namensräume gehören, die Capability CAP_SYS_ADMIN.

       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 der flags-Maske festgelegt und die
              Begrenzung für die Anzahl von verschachtelten Benutzernamensräumen
              würde überschritten. Siehe die Diskussion des Fehlers ENOSPC oben.

VERSIONEN
       Der Systemaufruf clone3() erschien erstmalig in Linux 5.3.

KONFORM ZU
       Diese Systemaufrufe sind Linux-spezifisch und sollten nicht in
       portierbaren Programmen benutzt werden.

ANMERKUNGEN
       Diese Systemaufrufe werden benutzt, um Threads zu implementieren: mehrere
       Steuerflüsse in einem Programm, die gleichzeitig in einem gemeinsamen
       Speicherbereich ausgeführt werden.

       Glibc stellt keinen Wrapper für clone3() bereit; rufen Sie ihn mittels
       syscall(2) auf.

       Beachten Sie, dass die Glibc-Wrapperfunktion clone() einige Änderungen am
       Speicher, auf den 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.

       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 Clone-Aufrufs 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).

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

   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.

       Im Gegensatz zum Glibc-Wrapper akzeptiert der rohe Systemaufruf clone()
       NULL als stack-Argument (und clone3() erlaubt entsprechend cl_args.stack
       NULL zu sein). In diesem Fall verwendet das Kind eine Dublette des Stacks
       des Elternprozesses. (»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 festgelegt 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 und Alpha) sieht so aus:

           long clone(unsigned long flags, void *stack,
                      int *parent_tid, int *child_tid,
                      unsigned long tls);

       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 *stack,
                     int *parent_tid, unsigned long tls,
                     int *child_tid);

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

           long clone(void *stack, unsigned long flags,
                      int *parent_tid, int *child_tid,
                      unsigned long tls);

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

           long clone(unsigned long flags, void *stack,
                      int stack_size,         /* Größe des Stacks */
                      int *parent_tid, int *child_tid,
                      unsigned long tls);

   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 *stack_base, size_t stack_size,
                        int flags, void *arg, …
                     /* pid_t *parent_tid, struct user_desc *tls,
                        pid_t *child_tid */ );

       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 *stack_base,
                       int stack_size,         /* Größe des Stacks */
                       int *parent_tid, int *child_tid,
                       unsigned long tls);

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

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

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.

BEISPIELE
       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).

       Innerhalb des Beispielprogramms reservieren wir Speicher, der für den
       Stack des Kindprogramms verwandt werden soll. Dabei verwenden wir aus den
       folgenden Gründen mmap(2) statt malloc(3):

       *  mmap(2) reserviert einen Speicherblock, der an einer Seitengrenze
          beginnt und ein Vielfaches der Seitengröße groß ist. Dies ist
          nützlich, um am Ende des Stacks mittels mprotect(2) eine Wächterseite
          (eine Seite mit dem Schutz PROT_NONE) einzurichten.

       *  Wir können den Schalter MAP_STACK festlegen, um ein für den Stack
          geeignetes Mapping festzulegen. Derzeit führt dieser Schalter unter
          Linux zu keiner Aktion, aber er existiert und hat auf anderen Systemen
          Auswirkungen, daher sollten wir ihn zwecks Portabilität aufnehmen.

   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>
       #include <sys/mman.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);
           }

           /* Speicher für den Stack des Kindprozess reservieren */

           stack = mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE,
                        MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
           if (stack == MAP_FAILED)
               errExit("mmap");

       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), mmap(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.08 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                             9. Juni 2020                          CLONE(2)