Provided by: manpages-de-dev_1.11-1_all bug

BEZEICHNUNG

       clone, __clone2 - erzeugt einen Kindprozess

ÜBERSICHT

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

       #include <sched.h>

       int clone(int (*fn)(void *), void *child_stack,
                 int flags, void *arg, 
                 /* pid_t *ptid, struct user_desc *tls,
                 pid_t *ctid */ );

       /* Prototyp für den rohen Systemaufruf */

       long clone(unsigned long flags, void *child_stack,
                  void *ptid, void *ctid,
                  struct pt_regs *regs);

   Mit der Glibc-Wrapper-Funktion erforderliche Makros (siehe feature_test_macros(7)):

       clone():
           Seit Glibc 2.14:
               _GNU_SOURCE
           Vor Glibc 2.14:
               _BSD_SOURCE || _SVID_SOURCE
                   /* _GNU_SOURCE genügt ebenfalls */

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  Speicherplatz,  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  Steuer-Threads  in  einem
       Programm, die gleichzeitig in einem gemeinsamen Speicherbereich ausgeführt werden.

       Wird mit clone() ein Kindprozess erzeugt, führt er die Funktion fn(arg) aus. (Dies ist ein
       Unterschied zu fork(2), wo die Ausführung im Kindprozess  vom  Punkt  des  fork(2)-Aufrufs
       fortfährt.)  Das  Argument  fn  ist  ein  Zeiger auf eine Funktion, die vom Kindprozess zu
       Beginn seiner Ausführung  abgearbeitet  wird.  arg  wird  der  Funktion  fn  als  Argument
       übergeben.

       Kehrt  die Funktion fn(arg) zurück, so beendet sich der Kindprozess. Der Ganzzahlwert, der
       von fn zurückgeliefert wird, entspricht dem Exit-Code 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-ID  an  der  Stelle  ctid  im  Kindspeicher löschen, 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-ID an der Stelle ctid im Kindspeicher

       CLONE_FILES (since Linux 2.0)
              If  CLONE_FILES  is  set,  the calling process and the child process share the same
              file descriptor table. Any file descriptor created by the calling process or by the
              child  process  is  also  valid  in  the  other  process.  Similarly, if one of the
              processes closes a file descriptor, or changes  its  associated  flags  (using  the
              fcntl(2)   F_SETFD  operation),  the  other  process is also affected. If a process
              sharing a file descriptor table calls  execve(2),  its  file  descriptor  table  is
              duplicated (unshared).

              Ist CLONE_FILES nicht gesetzt, erbt der Kindprozess zur Ausführungszeit von clone()
              eine   Kopie   der   aktuell   geöffneten   Dateideskriptoren.    (Die    kopierten
              Dateideskriptoren   im   Kindprozess   beziehen   sich  auf  die  gleichen  offenen
              Dateideskriptoren (siehe  open(2))  wie  die  entsprechenden  Dateideskriptoren  im
              aufrufenden  Prozess.) Anschließende Operationen, 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.

       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) und 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_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
              svipc(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«)
              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.

              Weitere Informationen über Einhänge-Namensräume finden Sie unter 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 (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.

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

              Weitere Informationen über Benutzer-Namensräume finden Sie unter 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-ID  an der Stelle ptid im Elternspeicher ablegen. (In Linux
              2.5.32-2.5.48 gab es einen Schalter CLONE_SETTID, der das tat.)

       CLONE_PID (veraltet)
              If CLONE_PID is set, the child process is created with the same process ID  as  the
              calling  process.  This  is  good for hacking the system, but otherwise of not much
              use. Since 2.3.21 this flag can be specified only by the system boot  process  (PID
              0).  It  disappeared  in  Linux  2.5.16. Since then, the kernel silently ignores it
              without error.

       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)
              Das  Argument newtls ist der neue TLS-Desktiptor (Thread Local Storage). (Lesen Sie
              set_thread_area(2).)

       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.  Einzelne  Signale
              könnten  daher  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-test6  müssen  die  flags  außerdem  CLONE_VM  enthalten,  falls
              CLONE_SIGHAND angegeben wurde.

       CLONE_STOPPED (seit Linux 2.6.0-test2)
              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.

              This  flag  was  deprecated from Linux 2.6.25 onward, and was removed altogether in
              Linux 2.6.38. Since then, the kernel silently ignores it without error.

       CLONE_SYSVSEM (seit Linux 2.5.10)
              If CLONE_SYSVSEM is set, then the child and the calling process share a single list
              of System V semaphore adjustment (semadj)  values (see semop(2)). In this case, the
              shared list accumulates semadj values across all processes sharing  the  list,  and
              semaphore  adjustments are performed only when the last process that is sharing the
              list terminates (or ceases sharing the list using unshare(2)). If this flag is  not
              set, then the child has a separate semadj list that is initially empty.

       CLONE_THREAD (seit Linux 2.4.0-test8)
              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-ID  (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-test6 CLONE_SIGHAND auch
              CLONE_VM enthalten muss.

              Signale können an eine Thread-Gruppe als Ganzes geschickt werden (d.h. einer  TGID)
              unter  Benutzung  von  kill(2)  oder an einen bestimmten Thread unter Benutzung von
              tgkill(2).

              Signalanordnungen 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 sie von sigprocmask(2) gesetzt wird,
              Signale  können  aber  entweder  für  den  ganzen  Prozess  anstehen (d.h. an jedes
              Mitglied der Thread-Gruppe zu liefern sein), wenn sie mit  kill(2)  gesandt  wurden
              oder  für einen einzelnen Thread, wenn sie mit tgkill(2) gesandt wurden. Ein Aufruf
              von sigpending(2) gibt eine  Signalzusammenstellung  zurück,  die  eine  Verbindung
              ausstehender  Signale  für  den  ganzen  Prozess  und  der Signale ist, die für den
              aufrufenden Prozess anstehen.

              Falls kill(2) benutzt wird, um ein Signal an eine Thread-Gruppe zu senden  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 per kill(2) gesandt 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).

   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.  Zudem wird die Reihenfolge der Argumente
       geändert.  Die  rohe  Schnittstelle  für  Systemaufrufe  auf  x86   und   vielen   anderen
       Architekturen sieht ungefähr so aus:

           long clone(unsigned long flags, void *child_stack,
                      void *ptid, void *ctid,
                      struct pt_regs *regs);

       Ein  weiterer  Unterschied  für  den  rohen  Systemaufruf besteht darin, dass das Argument
       child_stack  Null  sein  könnte,  so  dass   in   diesem   Fall   »copy-on-write«-Semantik
       sicherstellt, 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.

       Für  einige  Architekturen  unterscheidet  sich  die  Reihenfolge  der  Argumente  für den
       Systemaufruf von der  oben  gezeigten.  In  der  Masse  der  MicroBlaze-,  ARM-,  ARM-64-,
       PA-RISC-,  Arc-, Power PC-, Xtensa- und MIPS-Architekturen ist die Reihenfolge des vierten
       und fünften Arguments vertauscht. Auf den Cris- und S390-Architekturen ist die Reihenfolge
       des ersten und zweiten Arguments vertauscht.

   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.   Die    rohe
       Systemaufrufschnittstelle  hat  kein  fn- oder arg-Argument und ändert die Reihenfolge der
       Argumente, so dass flags das erste und tls das letzte Argument ist.

       __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 früher
       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-ID  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-test6.)

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

       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  clone()  zurückgegeben, wenn ein Wert von Null für child_stack angegeben
              wurde.

       EINVAL In flags wurde CLONE_NEWIPC angegeben,  der  Kernel  wurde  jedoch  nicht  mit  den
              Optionen CONFIG_SYSVIPC und CONFIG_IPC_NS konfiguriert.

       EINVAL In flags wurde CLONE_NEWNET angegeben, der Kernel wurde jedoch nicht mit der Option
              CONFIG_NET_NS konfiguriert.

       EINVAL In flags wurde CLONE_NEWPID angegeben, der Kernel wurde jedoch nicht mit der Option
              CONFIG_PID_NS konfiguriert.

       EINVAL In flags wurde CLONE_NEWUTS angegeben, der Kernel wurde jedoch nicht mit der Option
              CONFIG_UTS konfiguriert.

       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.

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

       EPERM  CLONE_NEWUSER was specified in flags, but either  the  effective  user  ID  or  the
              effective  group  ID  of the caller does not have a mapping in the parent namespace
              (see user_namespaces(7)).

       EPERM (seit Linux 3.9)
              CLONE_NEWUSER was specified in flags and the caller  is  in  a  chroot  environment
              (i.e.,  the  caller's root directory does not match the root directory of the mount
              namespace in which it resides).

       EUSERS (seit Linux 3.11)
              CLONE_NEWUSER was specified in flags, and the call would cause  the  limit  on  the
              number of nested user namespaces to be exceeded. See user_namespaces(7).

VERSIONEN

       Es  gibt  keinen Eintrag für clone() in der libc5. Die Glibc2 stellt clone() wie in dieser
       Handbuchseite beschrieben bereit.

KONFORM ZU

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

ANMERKUNGEN

       In den 2.4.x-Kerneln 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).

       Für  eine  Weile  gab es CLONE_DETACHED (eingeführt in 2.5.32): Elternprozesse wollen kein
       Ende-Signal des Kindprozesses. In 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

       Versionen  der  GNU-C-Bibiliothek,  die die NPTL-Threading-Bibliothek enthalten, enthalten
       eine Wrapper-Funktion für getpid(2), die  die  Zwischenspeicherung  der  PIDs  verrichtet.
       Diese  Zwischenspeicherung  beruht auf der Unterstützung für clone() im Glibc-Wrapper, der
       Zwischenspeicher könnte aber der derzeitigen Implementierung unter Umständen nicht aktuell
       sein.  Insbesondere  wenn  ein  Signal  sofort  nach dem clone()-Aufruf an den Kindprozess
       gesandt wird, könnte 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, könnte es nötig sein Kode
       wie den folgenden zu verwenden:

           #include <syscall.h>

           pid_t mypid;

           mypid = syscall(SYS_getpid);

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(msg)    do { perror(msg); 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), 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  4.04  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 http://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> 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>.