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