Provided by: manpages-fr-dev_3.65d1p1-1_all bug

NOM

       clone, __clone2 - Créer un processus fils (child)

SYNOPSIS

       /* Prototype de la fonction d'appel d'enrobage de glibc */

       #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 */ );

       /* Prototype de l'appel système brut */

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

   Conditions  requises  par  la  macro de test de fonctionnalités pour la fonction d'enrobage de
   glibc (consultez feature_test_macros(7)) :

       clone() :
           À partir de glibc 2.14 :
               _GNU_SOURCE
           Avant glibc 2.14 :
               _BSD_SOURCE || _SVID_SOURCE
                   /* _GNU_SOURCE est également suffisant */

DESCRIPTION

       clone() crée un nouveau processus, de façon analogue à fork(2).

       Cette page présente à la fois la fonction d'enrobage clone() de glibc et  l'appel  système
       sous-jacent  sur  lequel elle s'appuie. Le texte principal décrit la fonction d'enrobage ;
       les différences avec l'appel système brut sont précisées plus bas dans l'article.

       Contrairement à fork(2), clone() permet le partage d'une partie  du  contexte  d'exécution
       entre le processus fils et le processus appelant. Le partage peut s'appliquer sur l'espace
       mémoire, sur la table des descripteurs de  fichiers  ou  la  table  des  gestionnaires  de
       signaux.  (Notez  que  sur  cette  page  de  manuel,  le « processus appelant » correspond
       normalement au « processus père », mais voyez quand même la  description  de  CLONE_PARENT
       plus bas).

       L'appel  système  clone()  est  principalement utilisé pour permettre l'implémentation des
       threads :  un  programme  est  scindé  en  plusieurs  lignes  de   contrôle,   s'exécutant
       simultanément dans un espace mémoire partagée.

       Quand  le  processus  fils  est créé par clone(), il exécute la fonction fn(arg). Ceci est
       différent de fork(2),  pour lequel l'exécution continue dans le processus fils à partir du
       moment  de  l'appel de fork(2). L'argument fn est un pointeur vers la fonction appelée par
       le processus fils lors de son démarrage. L'argument arg est transmis à la fonction fn lors
       de son invocation.

       Quand  la  fonction  fn(arg)  revient,  le  processus  fils  se termine. La valeur entière
       renvoyée par fn est utilisée comme code de retour  du  processus  fils.  Ce  dernier  peut
       également  se  terminer  de manière explicite en invoquant la fonction exit(2) ou après la
       réception d'un signal fatal.

       L'argument child_stack indique l'emplacement de la pile utilisée par  le  processus  fils.
       Comme les processus fils et appelant peuvent partager de la mémoire, il n'est généralement
       pas possible pour le fils d'utiliser la même pile que son père. Le processus appelant doit
       donc  préparer  un espace mémoire pour stocker la pile de son fils, et transmettre à clone
       un pointeur sur cet emplacement. Les piles croissent vers le bas sur tous les  processeurs
       implémentant  Linux  (sauf  le  HP  PA),  donc  child_stack doit pointer sur la plus haute
       adresse de l'espace mémoire prévu pour la pile du processus fils.

       L'octet de poids faible de flags contient le numéro du signal  qui  sera  envoyé  au  père
       lorsque  le  processus  fils  se  terminera.  Si  ce  signal  est différent de SIGCHLD, le
       processus parent doit également spécifier les options __WALL ou __WCLONE lorsqu'il  attend
       la  fin  du  fils avec wait(2). Si aucun signal n'est indiqué, le processus parent ne sera
       pas notifié de la terminaison du fils.

       flags permet également de préciser ce qui sera partagé  entre  le  père  et  le  fils,  en
       effectuant un OU binaire entre une ou plusieurs des constantes suivantes :

       CLONE_CHILD_CLEARTID (depuis Linux 2.5.49)
              Effacer  l'ID du thread enfant à ctid dans la mémoire du fils lorsqu'il se termine,
              et réveiller le futex à cette adresse. L'adresse concernée peut être  modifiée  par
              l'appel  système  set_tid_address(2).  Cela  est  utilisé dans les bibliothèques de
              gestion de threads.

       CLONE_CHILD_SETTID (depuis Linux 2.5.49)
              Enregistrer l'ID du thread enfant à ctid dans la mémoire du fils.

       CLONE_FILES (depuis Linux 2.0)
              Si l'attribut CLONE_FILES est positionné, le processus  appelant  et  le  processus
              fils partagent la même table des descripteurs de fichier. Tout descripteur créé par
              un processus est également valide pour l'autre processus. De même si  un  processus
              ferme  un  descripteur, ou modifie ses attributs (en utilisant l'opération fcntl(2)
              F_SETFD), l'autre processus en est aussi affecté.

              Si CLONE_FILES n'est pas positionné, le  processus  fils  hérite  d'une  copie  des
              descripteurs  de  fichier ouverts par l'appelant au moment de l'appel clone(). (Les
              copies  des  descripteurs  de  fichier  dans  le  fils  sont  associées  aux  mêmes
              descriptions  de  fichiers  ouverts  (consultez  open(2))  que  les descripteurs de
              fichier correspondants dans  le  processus  appelant.)  Les  opérations  effectuées
              ensuite sur un descripteur par un des processus n'affectent pas l'autre processus.

       CLONE_FS (depuis Linux 2.0)
              Si  l'attribut  CLONE_FS est positionné, le processus appelant et le processus fils
              partagent les mêmes informations concernant le système de fichiers. Ceci inclut  la
              racine  du  système de fichiers, le répertoire de travail, et l'umask. Tout appel à
              chroot(2), chdir(2) ou umask(2) effectué par un processus aura également  influence
              sur l'autre processus.

              Si CLONE_FS n'est pas choisi, le processus travaille sur une copie des informations
              de l'appelant concernant le système de fichiers. Cette copie est effectuée lors  de
              l'invocation  de  clone(). Les appels à chroot(2), chdir(2), umask(2) effectués par
              un processus n'affectent pas l'autre processus.

       CLONE_IO (depuis Linux 2.6.25)
              Si  CLONE_IO  est  défini,  alors  le  nouveau  processus   partage   un   contexte
              d'entrées-sorties  avec  le  processus  appelant. Si cet attribut n'est pas défini,
              alors  (comme  pour  fork(2))  le  nouveau  processus   a   son   propre   contexte
              d'entrées-sorties.

              Le  contexte  d'entrées-sorties  correspond  à  la visibilité que l'ordonnanceur de
              disques a des entrées-sorties (c'est-à-dire, ce que l'ordonnanceur d'entrée-sorties
              utilise pour modéliser l'ordonnancement des entrées-sorties d'un processus). Si des
              processus partagent le même contexte d'entrées-sorties, ils sont traités  comme  un
              seul  par  l'ordonnanceur  d'entrées-sorties. Par conséquent, ils partagent le même
              temps d'accès aux disques. Pour certains ordonnanceurs d'entrées-sorties,  si  deux
              processus   partagent   un  contexte  d'entrées-sorties,  ils  seront  autorisés  à
              intercaler leurs accès disque. Si plusieurs threads utilisent  des  entrées-sorties
              pour  le même processus (aio_read(3), par exemple), ils devraient utiliser CLONE_IO
              pour obtenir de meilleurs performances d'entrées-sorties.

              Si le noyau n'a pas été configuré avec  l'option  CONFIG_BLOCK,  cet  attribut  n'a
              aucun effet.

       CLONE_NEWIPC (depuis Linux 2.6.19)
              Si  CLONE_NEWIPC est défini, alors créer le processus dans un nouvel espace de noms
              IPC. Si cet attribut n'est pas défini, alors (comme pour fork(2)) le processus  est
              créé  dans  le  même espace de noms IPC que le processus appelant. Cet attribut est
              sensé être utilisé pour l'implémentation de conteneurs.

              Un espace de noms IPC fournit une vue isolée des objets IPC en System V  (consultez
              svipc(7))  et  (à  partir  de  Linux  2.6.30) des files d'attente de messages POSIX
              (consultez mq_overview(7)). Le point commun entre ces mécanismes IPC  est  que  les
              objets  IPC  y sont identifiés par d'autres moyens que des chemins d'accès dans des
              systèmes de fichiers.

              Les objets créés dans un espace de noms IPC sont visibles pour tous  les  processus
              qui  sont  membres  de  cet  espace  de  noms,  mais  ne sont pas visibles pour les
              processus des autres espaces de noms IPC.

              Quand un espace de noms est  détruit  (c'est-à-dire,  quand  le  dernier  processus
              membre de cet espace de noms se termine), tous les objets IPC de cet espace de noms
              sont automatiquement détruits.

              Utiliser  cet  attribut  nécessite :  un   noyau   configuré   avec   les   options
              CONFIG_SYSVIPC   et   CONFIG_IPC_NS   et   que   le   processus   soit   privilégié
              (CAP_SYS_ADMIN).  Cet  attribut  ne  peut  pas  être  utilisé  en  même  temps  que
              CLONE_SYSVSEM.

       CLONE_NEWNET (depuis Linux 2.6.24)
              (L'implémentation de cet attribut n'est complète que depuis le noyau 2.6.29.)

              Si  CLONE_NEWNET est défini, alors créer le processus dans un nouvel espace de noms
              réseau. Si cet attribut n'est pas défini, alors (comme pour fork(2))  le  processus
              est créé dans le même espace de noms réseau que le processus appelant. Cet attribut
              est sensé être utilisé pour l'implémentation de conteneurs.

              Un espace de noms réseau fournit une vue isolée de la pile réseau  (interfaces  des
              périphériques  réseau, piles des protocoles IPv4 et IPv6, tables de routage, règles
              de pare-feu, les arbres de répertoire /proc/net  et  /sys/class/net,  les  sockets,
              etc.). Un périphérique réseau physique ne peut être que dans un seul espace de noms
              réseau. Une paire d'interface réseau virtuelle (« veth ») fournit  une  abstraction
              similaire à pipe qui peut être utilisé pour créer un pont vers une interface réseau
              physique d'un autre espace de noms réseau.

              Quand un espace de noms réseau est libéré (c'est-à-dire, quand le dernier processus
              de l'espace de noms se termine), ses périphériques réseau physiques sont remis dans
              l'espace de noms réseau initial (pas celui du processus père).

              Utiliser cet attribut nécessite : un noyau configuré avec l'option CONFIG_NET_NS et
              que le processus soit privilégié (CAP_SYS_ADMIN).

       CLONE_NEWNS (depuis Linux 2.4.19)
              Démarrer le processus dans un nouvel espace de noms de montage.

              Chaque processus se trouve dans un espace de noms de montage. Cet espace de noms du
              processus regroupe les données décrivant la hiérarchie  des  fichiers  vus  par  le
              processus  (l'ensemble  des  montages). Après un fork(2) ou clone() sans l'attribut
              CLONE_NEWNS le fils se déroule dans le même espace de noms de montage que son père.
              Les  appels  système mount(2) et umount(2) modifient l'espace de noms de montage du
              processus appelant, et affectent ainsi tous les processus se déroulant dans le même
              espace  de  noms,  sans affecter les processus se trouvant dans d'autres espaces de
              noms de montage.

              Après un clone() avec l'attribut CLONE_NEWNS le fils cloné démarre dans  un  nouvel
              espace de noms de montage, initialisé avec une copie de l'espace de noms du père.

              Seul  un  processus  privilégié (un processus ayant la capacité CAP_SYS_ADMIN) peut
              spécifier l'attribut CLONE_NEWNS. Il n'est pas possible  de  spécifier  à  la  fois
              CLONE_NEWNS et CLONE_FS pour le même appel clone().

       CLONE_NEWPID (depuis Linux 2.6.24)
              Si  CLONE_NEWPID est défini, alors créer le processus dans un nouvel espace de noms
              de PID. Si cet attribut n'est pas défini, alors (comme pour fork(2))  le  processus
              est créé dans le même espace de noms de PID que le processus appelant. Cet attribut
              est sensé être utilisé pour l'implémentation de conteneurs.

              Un espace de noms de PID fournit un environnement isolés pour  les  PID :  les  PID
              d'un  nouvel espace de noms de PID commence à 1, comme pour un système seul, et les
              appels à fork(2), vfork(2) et clone() produiront des processus avec des PID uniques
              dans l'espace de noms.

              Le premier processus créé dans un nouvel espace de noms (c'est-à-dire, le processus
              créé en utilisant l'attribut CLONE_NEWPID) a un  PID  de  1  et  est  le  processus
              « init »  pour  l'espace de noms. Les fils qui deviennent orphelins dans cet espace
              de noms seront adoptés par ce processus plutôt que  par  init(8).  Contrairement  à
              l'init  traditionnel,  le  processus  « init »  d'un  espace de noms de PID peut se
              terminer et, s'il le fait, tous les processus dans  l'espace  de  noms  sont  alors
              terminés.

              Les  espaces  de noms de PID forment une hiérarchie. Quand un espace de noms de PID
              est créé, les processus de cet espace de noms sont visibles depuis l'espace de noms
              de  PID  du  processus  qui  a créé le nouvel espace de noms ; de la même façon, si
              l'espace de noms parent est lui-même le fils d'un autre  espace  de  noms  de  PID,
              alors  les  processus  du  fils et du père seront tous visibles de l'espace de noms
              grand-père. À l'inverse, les processus de l'espace de noms de PID  fils  ne  voient
              pas  les  processus  de  l'espace  de  noms  parent.  L'existence  d'une hiérarchie
              d'espaces de noms signifie que chaque  processus  peut  désormais  avoir  plusieurs
              PID :  un  par  espace  de  noms dans lequel il est visible ; chacun de ces PID est
              unique dans les espaces de noms  correspondants.  (Un  appel  à  getpid(2)  renvoie
              toujours le PID associé à l'espace de noms dans lequel le processus se trouve.)

              Après avoir créé un nouvel espace de noms, il est utile pour le fils de changer son
              répertoire racine et monter une nouvelle instance de procfs  dans  /proc  de  telle
              sorte  que  des  outils  comme ps(1) fonctionnent correctement. (Si CLONE_NEWNS est
              également présent  dans  flags,  alors  il  n'est  pas  nécessaire  de  changer  de
              répertorie  racine :  une  nouvelle  instance de procfs peut être monté directement
              dans /proc.)

              L'utilisation  de  cet  attribut  nécessite :  un  noyau  configuré  avec  l'option
              CONFIG_PID_NS  et que le processus soit privilégié (CAP_SYS_ADMIN). Cet attribut ne
              peut pas être utilisé en même temps que CLONE_THREAD.

       CLONE_NEWUTS (depuis Linux 2.6.19)
              Si CLONE_NEWUTS est défini, alors créer le processus dans un nouvel espace de  noms
              de  UTS,  dont  les identifiants sont initialisés en dupliquant les identifiants de
              l'espace de noms UTS du processus appelant. Si cet attribut n'est pas défini, alors
              (comme  pour  fork(2)) le processus est créé dans le même espace de noms UTS que le
              processus appelant. Cet attribut est sensé être utilisé  pour  l'implémentation  de
              conteneurs.

              Un espace de noms UTS est l'ensemble des identifiants renvoyés par uname(2) ; parmi
              lesquels le nom de domaine et le nom d'hôte peuvent être modifiés respectivement  à
              l'aide  de  setdomainname(2)  et  sethostname(2).  Les modifications apportés à ces
              identifiants dans un espace de noms UTS sont visibles par  tous  les  processus  du
              même  espace de noms, mais ne sont pas visibles des processus des autres espaces de
              noms UTS.

              L'utilisation  de  cet  attribut  nécessite :  un  noyau  configuré  avec  l'option
              CONFIG_UTS_NS et que le processus soit privilégié (CAP_SYS_ADMIN).

       CLONE_PARENT (depuis Linux 2.3.12)
              Si  CLONE_PARENT  est  présent,  le  père du nouveau fils (comme il est indiqué par
              getppid(2)) sera le même que celui du processus appelant.

              Si CLONE_PARENT n'est pas fourni, alors (comme pour fork(2)) le père  du  processus
              fils sera le processus appelant.

              Remarquez  que  c'est  le  processus  père,  tel qu'indiqué par getppid(2), qui est
              notifié lors de la fin du fils. Ainsi, si CLONE_PARENT est présent, alors c'est  le
              père du processus appelant, et non ce dernier, qui sera notifié.

       CLONE_PARENT_SETTID (depuis Linux 2.5.49)
              Enregistrer  l'ID du thread enfant à ptid dans la mémoire du père et du fils. (Dans
              Linux 2.5.32-2.5.48 il y a un attribut CLONE_SETTID qui fait cela.)

       CLONE_PID (obsolète)
              Si l'attribut CLONE_PID est positionné, les processus appelant et fils ont le  même
              numéro  de  processus.  C'est  bien pour hacker le système, mais autrement il n'est
              plus utilisé. Depuis 2.3.21, cet attribut ne peut être utilisé que par le processus
              de démarrage du système (PID 0). Il a disparu dans Linux 2.5.16.

       CLONE_PTRACE (depuis Linux 2.2)
              Si  l'attribut  CLONE_PTRACE  est  positionné  et  si  l'appelant  est suivi par un
              débogueur, alors le fils sera également suivi (consultez ptrace(2)).

       CLONE_SETTLS (depuis Linux 2.5.32)
              Le paramètre  newtls  est  le  nouveau  descripteur  TLS  (Thread  Local  Storage).
              (Consultez set_thread_area(2).)

       CLONE_SIGHAND (depuis Linux 2.0)
              Si  l'attribut  CLONE_SIGHAND est positionné, le processus appelant et le processus
              fils partagent la même table des gestionnaires de signaux.  Si  l'appelant,  ou  le
              fils,  appelle  sigaction(2)  pour modifier le comportement associé à un signal, ce
              comportement est également changé pour l'autre processus. Néanmoins, l'appelant  et
              le  fils  ont  toujours  des  masques  de  signaux distincts, et leurs ensembles de
              signaux bloqués sont indépendants. L'un des processus peut donc bloquer  un  signal
              en utilisant sigprocmask(2) sans affecter l'autre processus.

              Si  CLONE_SIGHAND  n'est  pas  utilisé,  le  processus  fils hérite d'une copie des
              gestionnaires de signaux de l'appelant lors de l'invocation de clone(). Les  appels
              à sigaction(2) effectués ensuite depuis un processus n'ont pas d'effets sur l'autre
              processus.

              Depuis Linux 2.6.0-test6, l'attribut CLONE_VM doit  également  être  spécifié  dans
              flags si CLONE_SIGHAND l'est.

       CLONE_STOPPED (depuis Linux 2.6.0-test2)
              Si  l'attribut CLONE_STOPPED est positionné, le fils est initialement stoppé (comme
              s'il avait reçu le signal SIGSTOP), et doit être relancé en lui envoyant le  signal
              SIGCONT.

              Cet  attribut  est marqué comme obsolète depuis Linux 2.6.25, et a été complètement
              supprimé dans Linux 2.6.38.

       CLONE_SYSVSEM (depuis Linux 2.5.10)
              Si CLONE_SYSVSEM est positionné, le fils et le processus appelant partagent la même
              liste  de  compteurs « undo » pour les sémaphores System V (consultez semop(2)). Si
              cet attribut n'est pas utilisé, le fils a une liste « undo » séparée,  initialement
              vide.

       CLONE_THREAD (depuis Linux 2.4.0-test8)
              Si  CLONE_THREAD  est présent, le fils est placé dans le même groupe de threads que
              le processus appelant. Afin de rendre l'explication de CLONE_THREAD  plus  lisible,
              le  terme  « thread »  est utilisé pour parler des processus dans un même groupe de
              threads.

              Les groupes de threads  sont  une  fonctionnalité  ajoutées  dans  Linux  2.4  pour
              supporter la notion POSIX d'ensemble de threads partageant un même PID. En interne,
              ce PID partagé est appelé identifiant de groupe de threads (TGID).Depuis Linux 2.4,
              l'appel getpid(2) renvoie l'identifiant du groupe de thread de l'appelant.

              Les  threads  dans un groupe peuvent être distingués par leur identifiant de thread
              (TID, unique sur le système). Le TID d'un nouveau thread est renvoyé par clone() au
              processus  appelant,  et  un  thread  peut  obtenir  son  propre  TID  en utilisant
              gettid(2).

              Quand clone() est appelé sans positionner CLONE_THREAD, le nouveau thread est placé
              dans  un  nouveau  groupe  de  thread  dont le TGID est identique au TID du nouveau
              thread. Ce thread est le leader du nouveau groupe.

              Un nouveau thread créé en utilisant CLONE_THREAD  a  le  même  processus  père  que
              l'appelant de clone() (de même qu'avec CLONE_PARENT), ainsi les appels à getppid(2)
              renvoient la même valeur à tous les threads dans un même groupe.  Lorsqu'un  thread
              créé  avec  CLONE_THREAD  termine,  le thread qui a appelé clone() pour le créer ne
              reçoit pas le signal SIGCHLD (ou autre  notification  de  terminaison) ;  de  même,
              l'état d'un tel thread ne peut être obtenu par wait(2). Le thread est dit détaché.

              Lorsque  tous  les threads d'un groupe de threads terminent, le processus parent du
              groupe reçoit un signal SIGCHLD (ou autre indicateur de terminaison).

              Si l'un des threads dans un groupe de threads appelle execve(2), tous  les  threads
              sauf  le  leader  sont  tués, et le nouveau programme est exécuté dans le leader du
              groupe de threads.

              Si l'un des threads dans un groupe crée un fils avec fork(2), n'importe lequel  des
              threads du groupe peut utiliser wait(2) sur ce fils.

              Depuis  Linux  2.5.35,  l'attribut  CLONE_SIGHAND  de flags doit être positionné si
              CLONE_THREAD l'est. Depuis Linux 2.6.0-test6, CLONE_SIGHAND a également  besoin  de
              CLONE_THREAD.

              Un signal peut être envoyé à un groupe de threads dans son ensemble (c'est‐à‐dire à
              un TGID) avec kill(2), ou  bien  à  un  thread  en  particulier  (à  un  TID)  avec
              tgkill(2).

              Les  gestions  de signaux sont définies au niveau des processus : si un signal sans
              gestionnaire est reçu par un thread, il affectera (tuera, stoppera,  relancera,  ou
              sera ignoré par) tous les membres du groupe de threads.

              Chaque  thread  a son propre masque de signaux, défini par sigprocmask(2), mais les
              signaux peuvent être en attente soit pour le processus dans son ensemble (donc peut
              être  reçu par n'importe lequel des threads du groupe), quand ils sont envoyés avec
              kill(2), soit pour un thread particulier, lorsqu'ils sont envoyés par tgkill(2). Un
              appel  à sigpending(2) renvoie un ensemble de signaux qui est l'union des processus
              en attente pour le processus et ceux en attente pour le thread appelant.

              Si kill(2) est utilisé pour envoyer un signal à un groupe  de  threads,  et  si  le
              groupe  a  installé  un  gestionnaire  pour  ce  signal, alors le gestionnaire sera
              exécuté dans exactement un des membres  du  groupe  de  threads,  choisi  de  façon
              arbitraire  parmi ceux qui n'ont pas bloqué ce signal. Si plusieurs threads dans un
              groupe attendent le même signal en  utilisant  sigwaitinfo(2),  le  noyau  choisira
              arbitrairement l'un d'entre eux pour délivrer le signal envoyé par kill(2).

       CLONE_UNTRACED (depuis Linux 2.5.46)
              Si  l'attribut CLONE_UNTRACED est positionné, alors un processus traçant le père ne
              peut pas forcer CLONE_PTRACE pour ce fils.

       CLONE_VFORK (depuis Linux 2.2)
              Si le bit CLONE_VFORK est actif, l'exécution du processus  appelant  est  suspendue
              jusqu'à  ce  que  le  fils  libère ses ressources de mémoire virtuelle par un appel
              execve(2) ou _exit(2) (comme avec vfork(2)).

              Si CLONE_VFORK n'est pas indiqué, alors  les  deux  processus  sont  ordonnancés  à
              partir  de  la  fin de l'appel, et l'application ne doit pas considérer que l'ordre
              d'exécution soit déterminé.

       CLONE_VM (depuis Linux 2.0)
              Si le  bit  CLONE_VM  est  actif,  le  processus  appelant  et  le  processus  fils
              s'exécutent  dans  le même espace mémoire. En particulier, les écritures en mémoire
              effectuées par l'un  des  processus  sont  visibles  par  l'autre.  De  même  toute
              projection  en mémoire, ou toute suppression de projection, effectuées avec mmap(2)
              ou munmap(2) par l'un des processus affectera également l'autre processus.

              Si CLONE_VM n'est pas actif, le processus fils utilisera  une  copie  distincte  de
              l'espace  mémoire  de  l'appelant.  Le  cliché  est réalisé lors de l'invocation de
              clone(). Les écritures ou les projections de fichiers en mémoire effectuées par  un
              processus n'affectent pas l'autre processus, comme cela se passe avec fork(2).

   L'interface de l'appel système brut
       L'appel  système clone ressemble plus à fork(2), en ceci que l'exécution dans le processus
       fils continue à partir du point d'appel. À ce  titre,  les  arguments  fn  et  arg  de  la
       fonction  d'enrobage  de  clone()  sont  omis.  De  plus,  l'ordre  des  arguments change.
       L'interface de l'appel système brut sur x86 et sur plusieurs autres  architectures  est  à
       peu près :

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

       Une  autre  différence :  pour l'appel système brut, l'argument child_stack peut être nul,
       puisque  la  sémantique  de  copie-en-écriture  assure  que  le  fils  recevra  une  copie
       indépendante des pages de la pile dès qu'un des deux processus la modifiera. Pour que cela
       fonctionne, il faut naturellement que CLONE_VM ne soit pas présent.

       Pour certaines architectures, l'ordre des arguments de l'appel système diffère de  ce  qui
       est  décrit ci-dessus. Sur les architectures score, microblaze, ARM, ARM 64, PA-RISC, arc,
       Power PC, xtensa, et MIPS, l'ordre des quatrième et cinquième arguments est  inversé.  Sur
       les architectures cris et s390, l'ordre des premier et deuxième arguments est inversé.

   blackfin, m68k, et sparc
       Les  conventions  de passage des arguments sur blackfin, m68k et sparc sont différentes de
       celles décrites précédemment. Pour plus de détails, se référer aux sources du noyau (et de
       glibc).

   ia64
       Sur ia64, une interface différente est utilisée :

       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 */ );

       Le  prototype  présenté  plus  haut  correspond  à  la  fonction  intermédiaire de glibc ;
       l'interface de l'appel système brut ne reconnaît pas les arguments fn ou arg,  et  modifie
       l'ordre des arguments, de sorte que  flags devient le premier argument, et tls le dernier.

       __clone2()  fonctionne  comme  clone(),  aux différences suivantes près : child_stack_base
       pointe sur la plus petite adresse de la pile du fils, et stack_size indique la  taille  de
       la pile sur laquelle pointe child_stack_base.

   Linux 2.4 et antérieurs
       Sous Linux 2.4 et plus anciens, clone() ne prend pas les arguments ptid, tls et ctid.

VALEUR RENVOYÉE

       En  cas  de  réussite,  le TID du processus fils est renvoyé dans le thread d'exécution de
       l'appelant. En cas d'échec, -1 est renvoyé dans le  contexte  de  l'appelant,  aucun  fils
       n'est créé, et errno contiendra le code d'erreur.

ERREURS

       EAGAIN Trop de processus en cours d'exécution.

       EINVAL CLONE_SIGHAND a été spécifié mais pas CLONE_VM (depuis Linux 2.6.0-test6).

       EINVAL CLONE_THREAD a été spécifié mais pas CLONE_SIGHAND  (depuis Linux 2.5.35).

       EINVAL Les attributs CLONE_NEWNS et CLONE_FS ont été indiqués simultanément dans flags.

       EINVAL Les  attributs  CLONE_NEWIPC  et  CLONE_SYSVSEM ont été indiqués simultanément dans
              flags.

       EINVAL Les attributs CLONE_NEWPID et CLONE_THREAD  ont  été  indiqués  simultanément  dans
              flags.

       EINVAL Renvoyée  par  clone()  quand  une  valeur  nulle  a été indiquée pour le paramètre
              child_stack.

       EINVAL CLONE_NEWIPC a été indiqué dans flags, mais le noyau n'a pas été configuré avec les
              options CONFIG_SYSVIPC et CONFIG_IPC_NS.

       EINVAL CLONE_NEWNET  a  été  indiqué  dans flags, mais le noyau n'a pas été configuré avec
              l'option CONFIG_NET_NS.

       EINVAL CLONE_NEWPID a été indiqué dans flags, mais le noyau n'a  pas  été  configuré  avec
              l'option CONFIG_PID_NS.

       EINVAL CLONE_NEWUTS  a  été  indiqué  dans flags, mais le noyau n'a pas été configuré avec
              l'option CONFIG_UTS.

       ENOMEM Pas assez de mémoire pour copier les parties du contexte du processus appelant  qui
              doivent  être  dupliquées, ou pour allouer une structure de tâche pour le processus
              fils.

       EPERM  CLONE_NEWIPC,  CLONE_NEWNET,  CLONE_NEWNS,  CLONE_NEWPID  ou  CLONE_NEWUTS  a   été
              spécifié par un processus non privilégié (processus sans CAP_SYS_ADMIN).

       EPERM  CLONE_PID a été réclamé par un processus autre que le processus 0.

VERSIONS

       Il  n'y  a  pas de définition pour clone() dans la libc5. glibc2 fournit une définition de
       clone() comme décrit ici.

CONFORMITÉ

       clone() est spécifique à Linux et ne doit pas être utilisé dans des programmes conçus pour
       être portables.

NOTES

       Dans les noyaux 2.4.x, CLONE_THREAD ne rend pas en général le processus père de l'appelant
       père du nouveau thread. Cependant, pour les versions 2.4.7 à 2.4.18 du  noyau,  l'attribut
       CLONE_THREAD impliquait CLONE_PARENT (de même qu'avec les noyaux 2.6).

       CLONE_DETACHED  a existé pendant un moment (introduit dans 2.5.32): le père ne veut pas de
       signal à la  mort  du  fils.  Dans  2.6.2,  la  nécessité  d'utiliser  ce  paramètre  avec
       CLONE_THREAD a été supprimée. Cet attribut est toujours défini, mais n'a plus aucun effet.

       Sur  i386,  clone() ne devrait pas être appelé via vsyscall, mais directement en utilisant
       int $0x80.

BOGUES

       Les versions de la bibliothèque C GNU qui gèrent la bibliothèque de  gestion  des  threads
       NPTL  contiennent  une fonction enveloppe pour getpid(2) qui effectue un cache des PID. Ce
       cache nécessite une prise en charge par l'enveloppe de clone() de  la  glibc,  mais  telle
       qu'il  est  actuellement  implémenté,  le  cache  peut  ne  pas être à jour sous certaines
       circonstances. En particulier, si un signal est distribué à un fils juste après l'appel  à
       clone(),  alors  un  appel  à  getpid(2)  dans  le  gestionnaire de signaux du signal peut
       renvoyer le PID du processus appelant (le père), si l'enveloppe de clone n'a toujours  pas
       eu le temps de mettre le cache de PID à jour pour le fils. (Cette discussion ignore le cas
       où le fils a été créé en utilisant CLONE_THREAD, quand getpid(2)  doit  renvoyer  la  même
       valeur  pour  le  fils et pour le processus qui a appelé clone(), puisque l'appelant et le
       fils se trouvent dans le même groupe de threads. Ce problème de cache n'apparaît  pas  non
       plus  si  le paramètre flags contient CLONE_VM.) Pour obtenir la véritable valeur, il peut
       être nécessaire d'utiliser quelque chose comme ceci :

           #include <syscall.h>

           pid_t mypid;

           mypid = syscall(SYS_getpid);

EXEMPLE

       Le programme suivant décrit l'usage de clone() dans le but de créer un processus fils  qui
       s'exécute  dans  un  espace  de  noms UTS distinct. Le processus fils change le nom d'hôte
       (hostname) dans son propre espace UTS. Les processus père et fils affichent chacun le  nom
       d'hôte  qui  leur correspond, permettant ainsi de constater la différence des noms d'hôtes
       dans leurs espaces de noms UTS respectifs.

   Code du programme
       #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              /* Commencer la fonction pour le fils cloné */
       childFunc(void *arg)
       {
           struct utsname uts;

           /* Modifier le nom d'hôte dans l'espace de noms UTS du
              processus fils */

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

           /* Récupérer et afficher le nom d'hôte */

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

           /* Rester en sommeil (fonction sleep) pour conserver l'espace
              de noms ouvert pendant un moment. Cela permet de réaliser
              quelques expérimentations — par exemple, un autre processus
              pourrait rejoindre l'espace de noms. */

           sleep(200);

           return 0;           /* Le processus fils se termine à ce moment */
       }

       #define STACK_SIZE (1024 * 1024)    /* Taille de la pile pour le
                                              fils cloné */

       int
       main(int argc, char *argv[])
       {
           char *stack;                    /* Début du tampon de la pile */
           char *stackTop;                 /* Fin du tampon de la pile */
           pid_t pid;
           struct utsname uts;

           if (argc < 2) {
               fprintf(stderr, "Utilisation : %s <nom_d_hôte-fils>\n", argv[0]);
               exit(EXIT_SUCCESS);
           }

           /* Allouer la pile pour le processus fils */

           stack = malloc(STACK_SIZE);
           if (stack == NULL)
               errExit("malloc");
           stackTop = stack + STACK_SIZE;  /* Pile supposée s'étendre vers
                                              le bas */

           /* Créer un processus fils disposant de son propre
              espace de noms UTS ; le processus fils débute
              son exécution dans childFunc() */

           pid = clone(childFunc, stackTop, CLONE_NEWUTS | SIGCHLD, argv[1]);
           if (pid == -1)
               errExit("clone");
           printf("clone() a renvoyé %ld\n", (long) pid);

           /* C'est ici que le processus père échoue */

           sleep(1);           /* Laisser le temps au processus fils de
                                  changer son nom d'hôte */

           /* Afficher le nom d'hôte pour l'espace de noms UTS du processus père.
              Celui-ci sera différent du nom d'hôte pour l'espace de noms UTS du
              processus fils. */

           if (uname(&uts) == -1)
               errExit("uname");
           printf("uts.nodename dans le père : %s\n", uts.nodename);

           if (waitpid(pid, NULL, 0) == -1)    /* Attendre le processus fils */
               errExit("waitpid");
           printf("Fin du processus fils\n");

           exit(EXIT_SUCCESS);
       }

VOIR AUSSI

       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), pthreads(7)

COLOPHON

       Cette  page  fait partie de la publication 3.65 du projet man-pages Linux. Une description
       du projet et des  instructions  pour  signaler  des  anomalies  peuvent  être  trouvées  à
       l'adresse http://www.kernel.org/doc/man-pages/.

TRADUCTION

       Depuis    2010,    cette   traduction   est   maintenue   à   l'aide   de   l'outil   po4a
       <http://po4a.alioth.debian.org/> par l'équipe de traduction francophone au sein du  projet
       perkamon <http://perkamon.alioth.debian.org/>.

       Christophe    Blaess    <http://www.blaess.fr/christophe/>   (1996-2003),   Alain   Portal
       <http://manpagesfr.free.fr/>  (2003-2006).  Julien  Cristau  et  l'équipe  francophone  de
       traduction de Debian (2006-2009).

       Veuillez     signaler     toute     erreur     de     traduction     en     écrivant     à
       <debian-l10n-french@lists.debian.org>  ou  par  un  rapport  de  bogue   sur   le   paquet
       manpages-fr.

       Vous  pouvez  toujours  avoir  accès  à la version anglaise de ce document en utilisant la
       commande « man -L C <section> <page_de_man> ».