dwww Home | Manual pages | Find package

clone(2)                      System Calls Manual                     clone(2)

NOM
       clone, __clone2, clone3 - Créer un processus enfant (child)

BIBLIOTHÈQUE
       Bibliothèque C standard (libc, -lc)

SYNOPSIS
       /* Prototype de la fonction enveloppe de la glibc */

       #define _GNU_SOURCE
       #include <sched.h>

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

       /* Pour le prototype de l'appel système clone() brut, voir REMARQUES */

       #include <linux/sched.h>    /* Définition de struct clone_args */
       #include <sched.h>          /* Définition des constantes CLONE_* */
       #include <sys/syscall.h>    /* Définition des constantes SYS_* */
       #include <unistd.h>

       long syscall(SYS_clone3, struct clone_args *cl_args, size_t size);

       Remarque :  La  glibc  ne fournit pas d'enveloppe pour clone3() ; appe-
       lez-la en utilisant syscall(2).

DESCRIPTION
       Ces appels système créent un nouveau  processus  « enfant »,  de  façon
       analogue à fork(2).

       Contrairement  à  fork(2),  ces appels système offrent un contrôle plus
       précis du contexte d'exécution partagé entre le processus  appelant  et
       son  enfant.  Par  exemple, en utilisant ces appels système, l'appelant
       peut  contrôler  si  les  deux  processus  partagent  ou  non  l'espace
       d'adresse  virtuel,  la  table des descripteurs de fichier et celle des
       gestionnaires de signal. Ces appels  système  permettent  également  au
       nouveau processus enfant d'aller dans un namespaces(7) à part.

       Remarquez que dans cette page de manuel, le « processus appelant » cor-
       respond en principe au « processus parent ». Mais voir les descriptions
       de CLONE_PARENT et de CLONE_THREAD ci-dessous.

       Cette page décrit les interfaces suivantes :

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

       •  Le nouvel appel système clone3().

       Dans la suite de cette page, le terme « appel clone » est utilisé  pour
       évoquer les détails applicables à toutes ces interfaces,

   La fonction enveloppe clone()
       Quand  le  processus enfant est créé par la fonction enveloppe clone(),
       il débute son exécution par un appel à la fonction vers laquelle pointe
       l'argument  fn  (cela est différent de fork(2), pour lequel l'exécution
       continue dans le processus enfant à partir  du  moment  de  l'appel  de
       fork(2)). L'argument arg est passé comme argument de la fonction fn.

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

       L'argument  stack indique l'emplacement de la pile utilisée par le pro-
       cessus enfant. Comme les processus enfant et appelant peuvent  partager
       de  la mémoire, il n'est généralement pas possible pour l'enfant d'uti-
       liser la même pile que son parent. Le processus appelant doit donc pré-
       parer  un  espace mémoire pour stocker la pile de son enfant, et trans-
       mettre à clone un pointeur sur cet  emplacement.  Les  piles  croissent
       vers  le  bas  sur  tous les processeurs implémentant Linux (sauf le HP
       PA), donc stack doit pointer sur la plus haute adresse de l'espace  mé-
       moire  prévu pour la pile du processus enfant. Remarquez que clone() ne
       fournit aucun moyen pour que l'appelant puisse informer le noyau de  la
       taille de la zone de la pile.

       Les paramètres restants de clone() sont décrits ci-dessous.

   clone3()
       L'appel  système  clone3() fournit un sur-ensemble de la fonctionnalité
       de l'ancienne interface de  clone().  Il  offre  également  un  certain
       nombre d'améliorations de l'API dont : un espace pour des bits d'attri-
       buts supplémentaires, une séparation plus propre dans l'utilisation  de
       plusieurs  paramètres et la possibilité d'indiquer la taille de la zone
       de la pile de l'enfant.

       Comme avec fork(2), clone3() renvoie à la fois au parent et à l'enfant.
       Il  renvoie 0 dans le processus enfant et il renvoie le PID de l'enfant
       dans le parent.

       Le paramètre cl_args de clone3() est une structure ayant la forme  sui-
       vante :

           struct clone_args {
               u64 flags;        /* Masque de bit d'attribut */
               u64 pidfd;        /* Où stocker le descripteur de fichier du PID
                                    (int *) */
               u64 child_tid;    /* Où stocker le TID enfant,
                                    dans la mémoire de l'enfant (pid_t *) */
               u64 parent_tid;   /* Où stocker le TID enfant,
                                    dans la mémoire du parent (pid_t *) */
               u64 exit_signal;  /* Signal à envoyer au parent quand
                                    l'enfant se termine */
               u64 stack;        /* Pointeur vers l'octet le plus faible de la pile */
               u64 stack_size;   /* Taille de la pile */
               u64 tls;          /* Emplacement du nouveau TLS */
               u64 set_tid;      /* Pointeur vers un tableau pid_t
                                    (depuis Linux 5.5) */
               u64 set_tid_size; /* Nombre d'éléments dans set_tid
                                    (depuis Linux 5.5) */
               u64 cgroup;       /* Descripteur de fichier du cgroup cible
                                    de l'enfant (depuis Linux 5.7) */
           };

       Le paramètre size fourni à clone3() doit être initialisé à la taille de
       cette structure (l'existence du paramètre size autorise des  extensions
       futures de la structure clone_args).

       La pile du processus enfant est indiquée avec cl_args.stack, qui pointe
       vers  l'octet  le  plus  faible  de  la  zone  de  la  pile,  et   avec
       cl_args.stack_size,  qui  indique  la  taille  de la pile en octets. Si
       l'attribut CLONE_VM est indiqué (voir ci-dessous), une pile  doit  être
       explicitement  allouée  et indiquée. Sinon, ces deux champs peuvent va-
       loir NULL et 0, ce qui amène l'enfant à utiliser la même zone  de  pile
       que  son  parent  (dans  l'espace d'adressage virtuel de son propre en-
       fant).

       Les autres champs du paramètre cl_args sont abordés ci-dessous.

   Équivalence entre les paramètres de clone() et de clone3()
       Contrairement à l'ancienne interface clone(), où  les  paramètres  sont
       passés  individuellement,  ceux  de la nouvelle interface clone3() sont
       empaquetés dans la  structure  clone_args  présentée  ci-dessus.  Cette
       structure  permet de passer un ensemble d'informations à l’aide des ar-
       guments de clone().

       Le tableau suivant montre l'équivalence entre les paramètres de clone()
       et les champs du paramètre clone_args fournis à clone3() :

           clone()             clone3()        Notes
                               Champ cl_args
           attributs & ~0xff   attributs       Pour  la  plupart des attributs,
                                               détails ci-dessous
           parent_tid          pidfd           Voir CLONE_PIDFD
           child_tid           child_tid       Voir CLONE_CHILD_SETTID
           parent_tid          parent_tid      Voir CLONE_PARENT_SETTID
           attributs & 0xff    exit_signal
           stack               stack
           ---                 stack_size
           tls                 tls             Voir CLONE_SETTLS
           ---                 set_tid         Voir ci-dessous pour des détails
           ---                 set_tid_size
           ---                 cgroup          Voir CLONE_INTO_CGROUP

   Signal de fin de l'enfant
       Quand le processus enfant se termine, un signal peut être envoyé au pa-
       rent.  Le  signal  de  fin  est indiqué dans l'octet de poids faible de
       flags (clone()) ou dans cl_args.exit_signal (clone3()).  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 de l'enfant avec
       wait(2). Si aucun signal n'est indiqué (donc zéro), le processus parent
       ne sera pas notifié de la terminaison de l'enfant.

   Le tableau set_tid
       Par défaut, le noyau choisit le PID séquentiel suivant pour le  nouveau
       processus  dans  chacun  des  espaces de noms de PID où il est présent.
       Lors de la création d'un processus avec clone3(),  le  tableau  set_tid
       (depuis  Linux 5.5)  peut être utilisé pour sélectionner des PID spéci-
       fiques pour le processus dans tout ou partie des espaces de noms où  il
       est  présent. Si le PID du processus nouvellement créé ne doit être po-
       sitionné que dans l'espace de noms du processus actuel ou dans celui du
       PID nouvellement créé (si flags contient CLONE_NEWPID), le premier élé-
       ment du tableau set_tid doit être le PID souhaité et set_tid_size  doit
       valoir 1.

       Si le PID du processus nouvellement créé doit avoir une certaine valeur
       dans plusieurs espaces de noms de PID, le tableau  set_tid  peut  avoir
       plusieurs  entrées.  La  première  entrée définit le PID de l'espace de
       noms le plus imbriqué, puis chacune des entrées suivantes  contient  le
       PID de l'espace de noms supérieur correspondant. Le nombre d'espaces de
       noms de PID où un PID doit être positionné est défini par set_tid_size,
       qui  ne peut pas être plus grand que le nombre d'espaces de noms de PID
       imbriqués.

       Pour créer un processus dont les PID suivants s'inscrivent dans la hié-
       rarchie de l'espace de noms de PID :

           Niveau esp. noms du PID   PID demandé   Notes
           0                         31496         Espace de noms du PID le plus à l'extérieur
           1                         42
           2                         7             Espace de noms du PID le plus à l'intérieur

       Positionner le tableau sur :

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

       Si seuls les PID des deux espaces de noms de PID les plus à l’intérieur
       doivent être indiqués, positionnez le tableau sur :

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

       Le PID dans les espaces de noms de PID en dehors des  deux  espaces  de
       noms  les  plus à l’intérieur sera sélectionné de la même manière qu'on
       sélectionne n'importe quel autre PID.

       La fonctionnalité set_tid exige CAP_SYS_ADMIN  ou  (depuis  Linux  5.9)
       CAP_CHECKPOINT_RESTORE  dans  tous  les  espaces  de noms appartenant à
       l'utilisateur des espaces de noms du processus cible.

       Les appelants ne peuvent choisir qu'un PID supérieur à 1 dans un espace
       de  noms  de PID donné si un processus init (à savoir un processus dont
       le PID est 1) existe déjà dans cet espace de noms. Sinon,  l'entrée  du
       PID dans cet espace de noms de PID doit valoir 1.

   Le masque flags
       Tant  clone() que clone3() permettent d'utiliser un masque de bit flags
       pour modifier leur comportement, et elles permettent à l'appelant d'in-
       diquer ce qui est partagé entre le processus appelant et son enfant. Ce
       masque de bit – le paramètre flags de clone() ou le champ cl_args.flags
       passé  à  clone3() – est désigné comme le masque flags dans le reste de
       cette page.

       Le masque flags est indiqué comme un OU bit à bit de zéro ou  plus  des
       constantes  ci-dessous. Sauf explicitement indiqués, ces attributs sont
       disponibles (et ont le même effet) dans clone() et dans clone3().

       CLONE_CHILD_CLEARTID (depuis Linux 2.5.49)
              Effacer  (zéro)  l'ID  du  thread  enfant  situé  là  où  pointe
              child_tid  (clone()) ou cl_args.child_tid (clone3()) dans la mé-
              moire de l'enfant lorsqu'il se termine, et provoquer  le  réveil
              avec le futex à cette adresse. L'adresse concernée peut être mo-
              difié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 de l'enfant là où pointe child_tid
              ((clone()) ou cl_args.child_tid (clone3()) dans  la  mémoire  de
              l'enfant.  L'opération  d'enregistrement  se  termine  avant que
              l'appel clone ne redonne le contrôle à l'espace utilisateur dans
              le  processus enfant (remarquez que l'opération d'enregistrement
              peut ne pas être terminée avant que l'appel clone ne renvoie  au
              processus  parent,  ce qui sera pertinent si l'attribut CLONE_VM
              est également utilisé).

       CLONE_CLEAR_SIGHAND (depuis Linux 5.5)
              Par défaut, l'état des signaux du thread de l'enfant est le même
              que  celui  du  parent. Si cet attribut est positionné, tous les
              signaux gérés par le parent sont réinitialisés à leur  état  par
              défaut (SIG_DFL) dans l'enfant.

              Indiquer  cet  attribut  avec  CLONE_SIGHAND  n'a pas de sens et
              n'est pas autorisé.

       CLONE_DETACHED (historique)
              Pendant un moment (pendant la série de versions au cours du  dé-
              veloppement de Linux 2.5), il y a eu un attribut CLONE_DETACHED,
              avec lequel le parent ne recevait pas de signal  quand  l'enfant
              se terminait. Au final, l'effet de cet attribut a été inhibé par
              l'attribut CLONE_THREAD et quand Linux 2.6.0 a été  publié,  cet
              attribut  n'avait  pas  d'effet. À partir de Linux 2.6.2, il n'a
              plus été nécessaire de fournir cet attribut avec CLONE_THREAD.

              Cet attribut est  toujours  défini,  mais  il  est  généralement
              ignoré  lors  d'un appel clone(). Toutefois, voir la description
              de CLONE_PIDFD pour certaines exceptions.

       CLONE_FILES (depuis Linux 2.0)
              Si l'attribut CLONE_FILES est positionné, le processus  appelant
              et  le  processus enfant partagent la même table de descripteurs
              de fichier. Tout descripteur créé par un processus est également
              valable 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 un
              processus qui partage une table de descripteurs de  fichier  ap-
              pelle execve(2), sa table est dupliquée (non partagée).

              Si  CLONE_FILES n'est pas positionné, le processus enfant hérite
              d'une copie des descripteurs de fichier ouverts  par  l'appelant
              au  moment  de l'appel clone(). Les opérations d'ouverture et de
              fermeture ou de modification d'attributs du descripteur  de  fi-
              chier  subséquentes, effectuées par le processus appelant ou son
              enfant, ne concernent pas l'autre processus. Remarquez toutefois
              que  les  copies  des descripteurs de fichier dans l'enfant sont
              associées aux mêmes descriptions de  fichiers  ouverts  que  les
              descripteurs  de  fichier correspondants dans le processus appe-
              lant, partageant ainsi les attributs de position et  d’états  du
              fichier (consultez open(2)).

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

              Si CLONE_FS n'est pas positionné, le processus enfant  travaille
              sur  une copie des informations de l'appelant concernant le sys-
              tème de fichiers au  moment  de  l'appel  clone.  Les  appels  à
              chroot(2), chdir(2), umask(2) effectués ensuite par un processus
              n'affectent pas l'autre processus.

       CLONE_INTO_CGROUP (depuis Linux 5.7)
              Par défaut, un processus enfant est mis dans le même cgroup ver-
              sion 2  que  son  parent. L'attribut CLONE_INTO_CGROUP permet au
              processus enfant d'être créé dans un cgroup version 2  différent
              (remarquez  que CLONE_INTO_CGROUP n'a d'effet que sur les cgroup
              version 2).

              Pour mettre le processus enfant dans un cgroup différent,  l'ap-
              pelant  indique CLONE_INTO_CGROUP dans cl_args.flags et passe un
              descripteur de fichier qui se rapporte à un cgroup version 2  du
              champ cl_args.cgroup (le descripteur de fichier peut être obtenu
              en ouvrant un répertoire  cgroup  v2,  en  utilisant  l'attribut
              O_RDONLY ou O_PATH). Remarquez que toutes les restrictions habi-
              tuelles (décrites dans cgroups(7)) quant au positionnement  d'un
              processus dans un cgroup version 2 s'appliquent.

              Voici    certains    des    cas   d'utilisation   possibles   de
              CLONE_INTO_CGROUP :

              •  Créer un processus dans un autre cgroup que celui  du  parent
                 permet  au  gestionnaire  de service de placer directement de
                 nouveaux services dans des cgroup dédiés.  Cela  élimine  les
                 contraintes  comptables  qui existeraient si le processus en-
                 fant était créé d'abord dans le même  cgroup  que  le  parent
                 puis  déplacé dans un cgroup cible. De plus, la création d'un
                 processus enfant directement dans un cgroup cible coûte beau-
                 coup  moins  cher que de déplacer le processus enfant dans le
                 cgroup cible après l'avoir créé.

              •  L'attribut CLONE_INTO_CGROUP permet également la création  de
                 processus  enfants  gelés  en  les créant dans un cgroup gelé
                 (voir cgroups(7) pour  une  description  des  contrôleurs  de
                 gel).

              •  Pour  les  applications threadées (voire même les implémenta-
                 tions de thread qui utilisent des  cgroup  pour  limiter  les
                 threads individuels), il est possible d'établir une couche de
                 cgroup fixe avant de créer chaque thread directement dans son
                 cgroup cible.

       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ées-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
              meilleures 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_NEWCGROUP (depuis Linux 4.6)
              Créer  le processus dans un nouvel espace de noms cgroup. Si cet
              attribut n'est pas invoqué, alors (comme pour fork(2))  le  pro-
              cessus  est  créé dans le même espace de noms cgroup que le pro-
              cessus appelant.

              Pour plus d'informations sur les espaces de noms cgroup, consul-
              tez cgroup_namespaces(7).

              Seul  un  processus disposant de privilèges (CAP_SYS_ADMIN) peut
              utiliser CLONE_NEWCGROUP.

       CLONE_NEWIPC (depuis Linux 2.6.19)
              Si CLONE_NEWIPC est invoqué, alors le processus est créé dans un
              nouvel espace de noms utilisateur IPC. Si cet attribut n'est pas
              invoqué, alors (comme pour fork(2)) le processus est  créé  dans
              le  même  espace  de noms utilisateur IPC que le processus appe-
              lant.

              Pour plus d'informations sur les espaces de noms  IPC,  reportez
              vous à ipc_namespaces(7).

              Seul  un  processus disposant de privilèges (CAP_SYS_ADMIN) peut
              utiliser CLONE_NEWIPC. Cet attribut ne peut pas être employé  en
              association avec CLONE_SYSVSEM.

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

              Si CLONE_NEWNET est invoqué, alors le processus est créé dans un
              nouvel espace de noms réseau. Si cet attribut n'est pas invoqué,
              alors (comme pour fork(2)) le processus est créé  dans  le  même
              espace de noms réseau que le processus appelant.

              Pour  plus d'informations sur les espaces de noms réseau, repor-
              tez vous à network_namespaces(7).

              Seul un processus disposant de privilèges  (CAP_SYS_ADMIN)  peut
              appeler CLONE_NEWNET.

       CLONE_NEWNS (depuis Linux 2.4.19)
              Si  l'attribut  CLONE_NEWNS  est invoqué, l'enfant cloné démarre
              dans un nouvel espace de noms de montage,  initialisé  avec  une
              copie  de  l'espace  de noms du parent. Si CLONE_NEWNS n'est pas
              invoqué, alors l'enfant existe dans le même espace  de  noms  de
              montage que le parent.

              Pour  plus  d'informations  sur  les espaces de noms de montage,
              consultez namespaces(7) et mount_namespaces(7).

              Seul un processus disposant de privilèges  (CAP_SYS_ADMIN)  peut
              utiliser l'attribut CLONE_NEWNS. Il n'est pas possible de spéci-
              fier à la fois CLONE_NEWNS et CLONE_FS pour le même appel clone.

       CLONE_NEWPID (depuis Linux 2.6.24)
              Si CLONE_NEWPID est invoqué, alors le processus est créé dans un
              nouvel  espace  de  noms PID. Si cet attribut n'est pas invoqué,
              alors (comme pour fork(2)) le processus est créé  dans  le  même
              espace de noms PID que le processus appelant.

              Pour  plus d'informations sur les espaces de noms PID, consultez
              namespaces(7) et pid_namespaces(7).

              Seul un processus disposant de privilèges  (CAP_SYS_ADMIN)  peut
              utiliser  CLONE_NEWPID. Cet attribut ne peut pas être utilisé en
              association avec CLONE_THREAD ou avec CLONE_PARENT.

       CLONE_NEWUSER
              (Cet attribut est apparu dans clone() pour la première fois dans
              Linux 2.6.23, les sémantiques actuelles de clone() ont été ajou-
              tées dans Linux 3.5, et les derniers modules rendant les espaces
              de noms utilisateur complètement opérationnels sont apparus dans
              Linux 3.8.)

              Si CLONE_NEWUSER est invoqué, alors le processus est  créé  dans
              un  nouvel espace de noms utilisateur. Si cet attribut n'est pas
              invoqué, alors (comme pour fork(2)) le processus est  créé  dans
              le même espace de noms utilisateur que le processus appelant.

              Pour  plus  d'informations  sur les espaces de noms utilisateur,
              consultez namespaces(7) et user_namespaces(7).

              Avant Linux 3.8, les processus  appelant  devaient  disposer  de
              trois  capacités  pour  utiliser CLONE_NEWUSER :  CAP_SYS_ADMIN,
              CAP_SETUID et CAP_SETGID. À partir de Linux 3.8, il  n'est  plus
              nécessaire  de  disposer de privilèges pour créer des espaces de
              noms utilisateur.

              Cet attribut ne  peut  pas  être  utilisé  en  association  avec
              CLONE_THREAD ou avec CLONE_PARENT. Pour des raisons de sécurité,
              CLONE_NEWUSER ne peut  pas  être  utilisé  en  association  avec
              CLONE_FS.

       CLONE_NEWUTS (depuis Linux 2.6.19)
              Si  CLONE_NEWUTS  est  défini, créez le processus dans un nouvel
              espace de noms 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.

              Pour obtenir plus d'informations sur les espaces  de  noms  UTS,
              consultez namespaces(7).

              Seul  un  processus disposant de privilèges (CAP_SYS_ADMIN) peut
              utiliser CLONE_NEWUTS.

       CLONE_PARENT (depuis Linux 2.3.12)
              Si CLONE_PARENT est présent, le parent du nouvel  enfant  (comme
              il est indiqué par getppid(2)) sera le même que celui du proces-
              sus appelant.

              Si CLONE_PARENT n'est pas fourni, alors (comme pour fork(2))  le
              parent du processus enfant sera le processus appelant.

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

              L'attribut CLONE_PARENT ne peut pas être utilisé dans des appels
              clone par le processus d'initialisation global (PID 1 dans l'es-
              pace de noms PID initial) et par les processus initiaux dans les
              autres  espaces  de noms PID. Cette restriction empêche la créa-
              tion d'arbres de processus à plusieurs racines ou de zombies non
              récupérables dans l'espace de noms PID initial.

       CLONE_PARENT_SETTID (depuis Linux 2.5.49)
              Enregistrer l'ID du thread enfant à l'endroit vers lequel pointe
              parent_tid (clone()) ou cl_args.parent_tid  (clone3())  dans  la
              mémoire  du  parent (dans Linux 2.5.32-2.5.48 il y a un attribut
              CLONE_SETTID  qui  fait  cela).   L'opération   d'enregistrement
              s'achève  avant  que  l'opération  clone  ne donne le contrôle à
              l'espace utilisateur.

       CLONE_PID (de Linux 2.0 à Linux 2.5.15)
              Si l'attribut CLONE_PID est positionné, les  processus  appelant
              et  enfant  ont le même numéro de processus. C'est bien pour bi-
              douiller le système, mais autrement il n'est plus  utilisé.  De-
              puis  Linux 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 Li-
              nux 2.5.16. Si bien que le noyau ignorait silencieusement le bit
              s'il était indiqué dans le masque flags. Bien plus tard, le même
              bit   a   été  recyclé  pour  être  utilisé  comme  attribut  de
              CLONE_PIDFD.

       CLONE_PIDFD (depuis Linux 5.2)
              Si cet attribut est indiqué, un descripteur de fichier PID  ren-
              voyant  au  processus  enfant  est  alloué et placé à un endroit
              donné dans la mémoire du parent.  L'attribut  close-on-exec  est
              positionné  sur  ce nouveau descripteur de fichier. Les descrip-
              teurs de fichier PID peuvent être utilisés  pour  des  objectifs
              décrits dans pidfd_open(2).

              •  Quand  on utilise clone3(), le descripteur de fichier PID est
                 placé à un endroit vers lequel pointe cl_args.pidfd.

              •  Quand on utilise clone(), le descripteur de fichier  PID  est
                 placé  à  un  endroit vers lequel pointe parent_tid. Comme le
                 paramètre parent_tid est utilisé pour renvoyer le descripteur
                 de  fichier  PID,  CLONE_PIDFD  ne peut pas être utilisé avec
                 CLONE_PARENT_SETTID lors d'un appel clone().

              Il n'est pas possible actuellement d'utiliser cet attribut  avec
              CLONE_THREAD.  Cela  veut dire que le processus identifié par le
              descripteur de fichier PID  sera  toujours  un  leader  dans  le
              groupe de threads.

              Si   l'attribut   obsolète   CLONE_DETACHED   est  indiqué  avec
              CLONE_PIDFD lors d'un appel à clone(), une erreur est  renvoyée.
              Une  erreur se produit aussi si CLONE_DETACHED est spécifié lors
              d'un appel à clone3(). Ce comportement garantit que le  bit  qui
              correspond  à CLONE_DETACHED pourra être utilisé à l'avenir pour
              des fonctionnalités supplémentaires du  descripteur  de  fichier
              PID.

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

       CLONE_SETTLS (depuis Linux 2.5.32)
              Le  descripteur  TLS  (Thread  Local Storage) est positionné sur
              tls.

              L'interprétation de tls et les effets qui en découlent dépendent
              de  l'architecture. Sur x86, tls est interprété comme une struct
              user_desc * (voir set_thread_area(2)). Sur x86-64, il s'agit  de
              la  nouvelle  valeur  à positionner pour le registre de base %fs
              (voir le paramètre ARCH_SET_FS de arch_prctl(2)). Sur les archi-
              tectures  ayant  un registre TLS dédié, il s'agit de la nouvelle
              valeur de ce registre.

              L'utilisation de cet attribut exige une  connaissance  détaillée
              et  n'est  généralement pas souhaitable, sauf dans l'implémenta-
              tion de bibliothèques de gestion des threads.

       CLONE_SIGHAND (depuis Linux 2.0)
              Si l'attribut CLONE_SIGHAND est positionné, le  processus  appe-
              lant  et le processus enfant partagent la même table de gestion-
              naires de signaux. Si l'appelant, ou  l'enfant,  appelle  sigac-
              tion(2)  pour  modifier  le comportement associé à un signal, ce
              comportement est également changé pour l'autre processus.  Néan-
              moins,  l'appelant  et  l'enfant ont toujours des masques de si-
              gnaux distincts, et leurs ensembles de signaux bloqués sont  in-
              dépendants. L'un des processus peut donc bloquer ou débloquer un
              signal en utilisant sigprocmask(2) sans affecter l'autre proces-
              sus.

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

              Depuis  Linux 2.6.0, le masque flags doit aussi inclure CLONE_VM
              si CLONE_SIGHAND est spécifié

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

              Cet attribut a été rendu obsolète par Linux 2.6.25,  puis  il  a
              été  supprimé  dans Linux 2.6.38. Depuis lors, le noyau l'ignore
              silencieusement sans erreur. À partir de Linux 4.6, le même  bit
              a été réutilisé comme attribut de CLONE_NEWCGROUP.

       CLONE_SYSVSEM (depuis Linux 2.5.10)
              Si  CLONE_SYSVSEM est positionné, l'enfant et le processus appe-
              lant partagent une même liste de valeurs d’ajustement  de  séma-
              phores  System V  (consultez semop(2)). Dans ce cas, cette liste
              regroupe toutes les  valeurs  semadj  des  processus  partageant
              cette liste, et les modifications des sémaphores sont effectuées
              seulement lorsque le dernier processus de la  liste  se  termine
              (ou  cesse de partager la liste en invoquant unshare(2)). Si cet
              attribut n'est pas utilisé, l'enfant a une liste semadj séparée,
              initialement vide.

       CLONE_THREAD (depuis Linux 2.4.0)
              Si  CLONE_THREAD  est  présent,  l'enfant 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ée dans Li-
              nux 2.4 pour gérer la notion POSIX d'ensemble de threads  parta-
              geant un même PID. En interne, ce PID partagé est appelé identi-
              fiant de groupe de threads  (TGID).  Depuis  Linux 2.4,  l'appel
              getpid(2)  renvoie l'identifiant du groupe de threads de l'appe-
              lant.

              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 disponible sous la forme  du  résultat  d'une
              fonction  renvoyé  à  l'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 threads 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 pro-
              cessus parent que le processus réalisant l'appel 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 l’a créé ne
              reçoit pas le signal SIGCHLD (ou autre notification de terminai-
              son) ;  de  même, l'état d'un tel thread ne peut pas ê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 un 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 pro-
              gramme est exécuté dans le leader du groupe de threads.

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

              Depuis  Linux 2.5.35,  le  masque  flags  doit   aussi   inclure
              CLONE_SIGHAND si CLONE_THREAD est spécifié (et remarquez que de-
              puis Linux 2.6.0, CLONE_SIGHAND a également besoin de CLONE_VM).

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

              Chaque  thread a son propre masque de signal, tel que défini par
              sigprocmask(2).

              Un signal peut être adressé à un processus ou à un thread.  S'il
              s'adresse  à  un  processus,  il  cible  un  groupe  de  threads
              (c'est-à-dire un TGID), et il est envoyé à un thread choisi  ar-
              bitrairement  parmi  ceux ne bloquant pas les signaux. Un signal
              peut s'adresser à un processus car il est généré  par  le  noyau
              pour  d'autres  raisons  qu'une  exception  matérielle, ou parce
              qu'il a été envoyé en utilisant kill(2) ou  sigqueue(3).  Si  un
              signal  s'adresse  à  un thread, il cible (donc est envoyé) à un
              thread spécifique. Un signal peut s'adresser à un thread du fait
              d'un envoi par tgkill(2) ou pthread_sigqueue(3), ou parce que le
              thread a exécuté une instruction en langage machine qui a provo-
              qué  une exception matérielle (comme un accès non valable en mé-
              moire, provoquant SIGSEGV, ou une exception de virgule flottante
              provoquant un SIGFPE).

              Un  appel  à  sigpending(2) renvoie un jeu de signaux qui réunit
              les signaux en attente adressés au processus et ceux en  attente
              pour le thread appelant.

              Si  un  signal  adressé à un processus est envoyé à un groupe de
              threads, et si le groupe a installé un gestionnaire pour ce  si-
              gnal,  alors le gestionnaire sera exécuté exactement dans 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 recevoir
              le signal.

       CLONE_UNTRACED (depuis Linux 2.5.46)
              Si l'attribut CLONE_UNTRACED est positionné, alors un  processus
              traçant  le  parent ne peut pas forcer CLONE_PTRACE pour cet en-
              fant.

       CLONE_VFORK (depuis Linux 2.2)
              Si le bit CLONE_VFORK est actif, l'exécution du processus  appe-
              lant est suspendue jusqu'à ce que l'enfant 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
              devrait  pas  considérer  que  l'ordre d'exécution est déterminé
              dans un ordre particulier.

       CLONE_VM (depuis Linux 2.0)
              Si le bit CLONE_VM est actif, le processus appelant et  le  pro-
              cessus enfant s'exécutent dans le même espace mémoire. En parti-
              culier, les écritures en mémoire effectuées par l'un des proces-
              sus  sont  visibles par l'autre. De même toute projection en mé-
              moire,  ou  toute  suppression  de  projection,  effectuée  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 enfant  utilisera  une
              copie  distincte  de l'espace mémoire de l'appelant au moment de
              l'appel clone. Les écritures ou les associations/désassociations
              de  fichiers  en mémoire effectuées par un processus n'affectent
              pas l'autre processus, comme cela se passe avec fork(2).

              Si l'attribut CLONE_VM est indiqué et si l'attribut  CLONE_VFORK
              ne  l'est  pas, toute autre pile de signal mise en place par si-
              galtstack(2) sera vidée dans le processus enfant.

VALEUR RENVOYÉE
       En cas de réussite, le TID du processus  enfant  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 enfant n'est créé, et errno sera posi-
       tionné pour indiquer l'erreur.

ERREURS
       EACCES (clone3() seulement)
              CLONE_INTO_CGROUP  était  indiqué  dans  cl_args.flags, mais les
              restrictions à la mise en place d'un processus  enfant  dans  un
              cgroup version 2  auquel  se  rapporte  cl_args.cgroup (décrites
              dans cgroups(7)) ne sont pas respectées.

       EAGAIN Trop de processus en cours d'exécution. Consultez fork(2).

       EBUSY (clone3() seulement)
              CLONE_INTO_CGROUP était indiqué dans cl_args.flags, mais le des-
              cripteur de fichier indiqué dans cl_args.cgroup se rapporte à un
              cgroup version 2 où un contrôleur de domaine est activé.

       EEXIST (clone3() seulement)
              Un (ou plusieurs) PID indiqué dans le set_tid existe  déjà  dans
              l'espace de noms PID correspondant.

       EINVAL Tant CLONE_SIGHAND que CLONE_CLEAR_SIGHAND ont été indiqués dans
              le masque flags.

       EINVAL CLONE_SIGHAND a été spécifié dans  le  masque  flags,  mais  pas
              CLONE_VM (depuis Linux 2.6.0).

       EINVAL CLONE_THREAD  a  été  spécifié  dans  le  masque flags, mais pas
              CLONE_SIGHAND  (depuis Linux 2.5.35).

       EINVAL CLONE_THREAD a été indiqué dans le masque flags mais le  proces-
              sus  actuel avait appelé unshare(2) avec l'attribut CLONE_NEWPID
              ou il utilisait setns(2) pour se réassocier à l'espace  de  noms
              PID.

       EINVAL Tant  CLONE_FS  que  CLONE_NEWNS ont été indiqués dans le masque
              flags.

       EINVAL (depuis Linux 3.9)
              Tant CLONE_NEWUSER que CLONE_FS ont été indiqués dans le  masque
              flags.

       EINVAL Tant  CLONE_NEWIPC  que  CLONE_SYSVSEM  ont été indiqués dans le
              masque flags.

       EINVAL CLONE_NEWPID ou CLONE_NEWUSER, et CLONE_THREAD ou  CLONE_PARENT,
              ont été indiqués, seuls ou ensemble, dans le masque flags.

       EINVAL (depuis Linux 2.6.32)
              CLONE_PARENT  a  été  spécifié  et  l'appelant  est un processus
              d'initialisation.

       EINVAL Renvoyée par l'enveloppe glibc de  clone()  quand  fn  ou  stack
              valent NULL.

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

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

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

       EINVAL CLONE_NEWUSER a été spécifié dans le masque flags, mais le noyau
              n'a pas été configuré avec l'option CONFIG_USER_NS.

       EINVAL CLONE_NEWUTS a été spécifié dans le masque flags, mais le  noyau
              n'a pas été configuré avec l'option CONFIG_UTS_NS.

       EINVAL stack n'est pas alignée sur une limite adaptée à cette architec-
              ture. Par exemple, sur aarch64, stack doit être un  multiple  de
              16.

       EINVAL (clone3() seulement)
              CLONE_DETACHED a été spécifié dans le masque flags.

       EINVAL (clone() seulement)
              CLONE_PIDFD  a  été  indiqué  avec CLONE_DETACHED dans le masque
              flags.

       EINVAL CLONE_PIDFD a été  indiqué  avec  CLONE_THREAD  dans  le  masque
              flags.

       EINVAL (clone() seulement)
              CLONE_PIDFD  a  été  indiqué  avec  CLONE_PARENT_SETTID  dans le
              masque flags.

       EINVAL (clone3() seulement)
              set_tid_size est supérieur au nombre de niveaux dans l'espace de
              noms PID.

       EINVAL (clone3() seulement)
              Un des PID indiqué dans set_tid n'était pas valable.

       EINVAL (AArch64 seulement, Linux 4.6 et antérieur)
              stack n'était pas aligné sur une limite de 128 bits.

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

       ENOSPC (depuis Linux 3.7)
              CLONE_NEWPID  a  été  spécifié  dans le masque flags, et l'appel
              provoquerait un dépassement de la limite du nombre maximal d'es-
              paces   de  noms  utilisateur  imbriqués.  Consultez  pid_names-
              paces(7).

       ENOSPC (depuis Linux 4.9 ; auparavant EUSERS)
              CLONE_NEWUSER a été spécifié dans le masque  flags,  et  l'appel
              provoquerait un dépassement de la limite du nombre maximal d'es-
              paces  de  noms  utilisateur  imbriqués.  Consultez  user_names-
              paces(7).

              De  Linux  3.11 à Linux 4.8, l'erreur indiquée dans ce cas était
              EUSERS.

       ENOSPC (depuis Linux 4.9)
              Une des valeurs dans le masque flags indiquait de créer un  nou-
              vel espace de noms utilisateur, mais cela aurait provoqué un dé-
              passement de la limite définie par le fichier correspondant dans
              /proc/sys/user. Pour plus de détails, voir namespaces(7).

       EOPNOTSUPP (clone3() seulement)
              CLONE_INTO_CGROUP était indiqué dans cl_args.flags, mais le des-
              cripteur de fichier indiqué dans cl_args.cgroup se rapporte à un
              cgroup version 2 dont l'état est domain invalid.

       EPERM  CLONE_NEWCGROUP,    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é spécifié par un processus autre que le processus
              0 (cette erreur n'arrive que sur Linux 2.5.15 et antérieurs).

       EPERM  CLONE_NEWUSER a été spécifié dans le masque flags, mais  l'iden-
              tifiant utilisateur effectif ou l'identifiant de groupe effectif
              de l'appelant n'a pas de correspondance dans  l'espace  de  noms
              parent (consultez user_namespaces(7)).

       EPERM (depuis Linux 3.9)
              CLONE_NEWUSER  a été spécifié dans le masque flags et l'appelant
              se trouve dans un environnement chroot (c'est-à-dire que le  ré-
              pertoire  racine  de  l'appelant ne correspond pas au répertoire
              racine de l'espace de noms de montage dans lequel il se trouve).

       EPERM (clone3() seulement)
              set_tid_size était supérieur à zéro et l'appelant n'a pas la ca-
              pacité  CAP_SYS_ADMIN  dans  un ou plusieurs des espaces de noms
              utilisateur qui possèdent les espaces  de  noms  PID  correspon-
              dants.

       ERESTARTNOINTR (depuis Linux 2.6.17)
              L'appel  système a été interrompu par un signal et va être redé-
              marré (cela n'est visible qu'à l'occasion d'un trace()).

       EUSERS (Linux 3.11 à Linux 4.8)
              CLONE_NEWUSER a été spécifié dans le masque  flags,  et  l'appel
              provoquerait un dépassement de la limite du nombre maximal d'es-
              paces de noms utilisateur imbriqués. Voir le point sur  l'erreur
              ENOSPC ci-dessus.

VERSIONS
       L'appel  système  clone3()  est  apparu  pour la première fois dans Li-
       nux 5.3.

STANDARDS
       Ces appels système sont spécifiques à Linux et ne doivent pas être uti-
       lisés dans des programmes conçus pour être portables.

NOTES
       Une  utilisation  de  ces  appels  système  consiste  à implémenter des
       threads : un programme est scindé  en  plusieurs  lignes  de  contrôle,
       s'exécutant simultanément dans un espace mémoire partagée.

       Remarquez  que  la  fonction enveloppe clone() de la glibc effectue des
       changements dans la mémoire vers laquelle pointe  stack  (ce  sont  des
       changements  nécessaires  pour  positionner  correctement  la pile pour
       l'enfant) avant de  recourir  à  l'appel  système  clone().  Dès  lors,
       lorsque  clone()  est  utilisé pour créer des enfants de manière récur-
       sive, n'utilisez pas le tampon servant à la pile du parent en tant  que
       pile de l'enfant.

       L'appel  système   kcmp(2) peut être utilisé pour vérifier si deux pro-
       cessus partagent des ressources, telles qu'une table de descripteurs de
       fichier, des opérations Annuler le sémaphore sur System V, ou un espace
       d'adressage virtuel.

       Les gestionnaires enregistrés en utilisant  pthread_atfork(3)  ne  sont
       pas exécutés pendant un appel clone.

       Dans  les séries 2.4.x de Linux, CLONE_THREAD ne fait en général pas du
       processus parent du nouveau thread un processus identique au parent  du
       processus  appelant. Cependant, de Linux 2.4.7 à Linux 2.4.18, l'attri-
       but CLONE_THREAD impliquait CLONE_PARENT (de même que dans  Linux 2.6.0
       et supérieurs).

       Sur i386, clone() ne devrait pas être appelé à l’aide de vsyscall, mais
       directement en utilisant int $0x80.

   différences entre bibliothèque C et noyau
       L'appel système clone brut ressemble plus à fork(2), en ceci que l'exé-
       cution  dans  le processus enfant continue à partir du point d'appel. À
       ce titre, les arguments fn et arg de la fonction enveloppe  de  clone()
       sont omis.

       Contrairement  à  l'enveloppe de la glibc, l'appel système brut clone()
       accepte NULL en paramètre de stack  (et  de  même,  clone3()  permet  à
       cl_args.stack  d'être  NULL). Dans ce cas l'enfant utilise une copie de
       la pile du parent (la sémantique de copie-en-écriture assure que  l'en-
       fant  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  natu-
       rellement  que CLONE_VM ne soit pas présent (si l'enfant partage la mé-
       moire du parent du fait d'une utilisation de CLONE_VM, aucune  duplica-
       tion  à  l’aide  de la copie-en-écriture ne se produit et il peut s'en-
       suivre probablement un grand chaos).

       L'ordre des paramètres change aussi dans l'appel système  brut  et  des
       variations  existent dans les paramètres en fonction des architectures,
       comme indiqué dans les paragraphes suivants.

       L'interface de l'appel système brut sur  des  architectures  x86-64  et
       quelques autres (dont sh, tile et alpha), est :

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

       Sur  x86-32  et d'autres architectures classiques (dont score, ARM, ARM
       64, PA-RISC, arc, Power PC, xtensa et MIPS), l'ordre des deux  derniers
       paramètres est inversé :

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

       Sur  les  architectures  cris  et  s390,  l'ordre des deux premiers pa-
       ramètres est inversé :

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

       Sur l'architecture microblaze, il existe un paramètre supplémentaire :

           long clone(unsigned long flags, void *stack,
                      int stack_size,         /* Taille de la pile */
                      int *parent_tid, int *child_tid,
                      unsigned long tls);

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

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

           int __clone2(int (*fn)(void *),
                        void *stack_base, size_t stack_size,
                        int flags, void *arg, ...
                     /* pid_t *parent_tid, struct user_desc *tls,
                        pid_t *child_tid */ );

       Le prototype présenté ci-dessus vaut pour la fonction enveloppe  de  la
       glibc ;  pour  l'appel système lui-même, il peut être décrit comme suit
       (il est identique au prototype clone() sur microblaze) :

           long clone2(unsigned long flags, void *stack_base,
                       int stack_size,         /* Taille de la pile */
                       int *parent_tid, int *child_tid,
                       unsigned long tls);

       __clone2() fonctionne comme clone(), sauf que stack_base pointe sur  la
       plus petite adresse de la pile de l'enfant et que stack_size indique la
       taille de la pile sur laquelle pointe stack_base.

   Linux 2.4 et antérieurs
       Sous Linux 2.4 et plus anciens, clone() ne prend pas les paramètres pa-
       rent_tid, tls, et child_tid.

BOGUES
       Les  versions  de la bibliothèque C GNU jusqu'à la 2.24 comprise conte-
       naient une fonction enveloppe pour getpid(2) qui  effectuait  un  cache
       des  PID.  Ce  cache nécessitait une prise en charge par l'enveloppe de
       clone() de la glibc, mais des limites dans  l'implémentation  faisaient
       que  le  cache pouvait ne pas être à jour sous certaines circonstances.
       En particulier, si un signal était distribué à un  enfant  juste  après
       l'appel  à  clone(), alors un appel à getpid(2) dans le gestionnaire de
       signaux du signal pouvait renvoyer le PID du processus appelant (le pa-
       rent),  si  l'enveloppe  de  clone  n'avait toujours pas eu le temps de
       mettre le cache de PID à jour pour l'enfant. (Ce point ignore le cas où
       l'enfant  a  été  créé  en utilisant CLONE_THREAD, quand getpid(2) doit
       renvoyer la même valeur pour l'enfant et pour le processus qui a appelé
       clone(), puisque l'appelant et l'enfant se trouvent dans le même groupe
       de threads. Ce problème de cache n'apparaît pas  non  plus  si  le  pa-
       ramè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);

       Suite à un problème de cache  ancien,  ainsi  qu'à  d'autres  problèmes
       traités dans getpid(2), la fonctionnalité de mise en cache du PID a été
       supprimée de la glibc 2.25.

EXEMPLES
       Le programme suivant décrit l'usage de clone() dans le but de créer  un
       processus  enfant qui s'exécute dans un espace de noms UTS distinct. Le
       processus enfant change le nom d'hôte (hostname) dans son propre espace
       UTS.  Les processus parent et enfant 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. Pour un exemple
       d’utilisation de ce programme, consultez setns(2).

       Dans le programme d'exemple, nous allouons la  mémoire  qui  doit  être
       utilisée  pour la pile de l'enfant en utilisant mmap(2) au lieu de mal-
       loc(3) pour les raisons suivantes :

       •  mmap(2) alloue un bloc de mémoire commençant à la limite d'une  page
          et qui est un multiple de la taille de la page. Cela est utile si on
          veut établir une page de protection (avec PROT_NONE) à la fin de  la
          pile en utilisant mprotect(2).

       •  On  peut indiquer l'attribut MAP_STACK pour demander une association
          adaptée à une pile. Pour le moment, cet attribut  n'est  pas  opéra-
          tionnel  sur Linux, mais il existe et a des effets sur d'autres sys-
          tèmes, donc on doit l'inclure pour la portabilité.

   Source du programme
       #define _GNU_SOURCE
       #include <err.h>
       #include <sched.h>
       #include <signal.h>
       #include <stdint.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <string.h>
       #include <sys/mman.h>
       #include <sys/utsname.h>
       #include <sys/wait.h>
       #include <unistd.h>

       static int              /* Commencer la fonction pour l'enfant cloné */
       childFunc(void *arg)
       {
           struct utsname uts;

           /* Modifier le nom d'hôte dans l'espace de noms UTS de l'enfant. */

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

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

           if (uname(&uts) == -1)
               err(EXIT_FAILURE, "uname");
           printf("uts.nodename dans l'enfant :  %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 enfant se termine à ce moment */
       }

       #define STACK_SIZE (1024 * 1024)    /* Taille de la pile pour
                                              l'enfant 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-enfant>\n", argv[0]);
               exit(EXIT_SUCCESS);
           }

          /* Allouer la mémoire à utiliser pour la pile du processus enfant. */

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

           stackTop = stack + STACK_SIZE;  /* On suppose que la pile grandit vers
                                              le bas */

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

           pid = clone(childFunc, stackTop, CLONE_NEWUTS | SIGCHLD, argv[1]);
           if (pid == -1)
               err(EXIT_FAILURE, "clone");
           printf("clone() a renvoyé %jd\n", (intmax_t) pid);

           /* Le parent se retrouve ici */

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

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

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

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

           exit(EXIT_SUCCESS);
       }

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

TRADUCTION
       La  traduction française de cette page de manuel a été créée par Chris-
       tophe Blaess <https://www.blaess.fr/christophe/>, Stéphan  Rafin  <ste-
       phan.rafin@laposte.net>, Thierry Vignaud <tvignaud@mandriva.com>, Fran-
       çois Micaux, Alain Portal <aportal@univ-montp2.fr>, Jean-Philippe  Gué-
       rard  <fevrier@tigreraye.org>,  Jean-Luc  Coulon (f5ibh) <jean-luc.cou-
       lon@wanadoo.fr>, Julien Cristau <jcristau@debian.org>,  Thomas  Huriaux
       <thomas.huriaux@gmail.com>,  Nicolas François <nicolas.francois@centra-
       liens.net>, Florentin Duneau <fduneau@gmail.com>, Simon  Paillard  <si-
       mon.paillard@resel.enst-bretagne.fr>,    Denis   Barbier   <barbier@de-
       bian.org>, David Prévot  <david@tilapin.org>,  Cédric  Boutillier  <ce-
       dric.boutillier@gmail.com>,  Frédéric Hantrais <fhantrais@gmail.com> et
       Jean-Philippe MENGUAL <jpmengual@debian.org>

       Cette traduction est une documentation libre ; veuillez vous reporter à
       la        GNU        General       Public       License       version 3
       ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩ concernant  les  conditions
       de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.

       Si  vous découvrez un bogue dans la traduction de cette page de manuel,
       veuillez envoyer un message à ⟨debian-l10n-french@lists.debian.org⟩.

Pages du manuel de Linux 6.03   5 février 2023                        clone(2)

Generated by dwww version 1.15 on Sat Jun 29 01:32:43 CEST 2024.