Provided by: manpages-fr-dev_4.13-4_all bug

NOM

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

SYNOPSIS

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

       #define _GNU_SOURCE
       #include <sched.h>

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

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

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

       Remarque : il n'y pas encore d'enveloppe glibc pour clone3() ; voir les REMARQUES.

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 » correspond 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
       explicite en invoquant la fonction exit(2) ou après la réception d'un signal fatal.

       L'argument stack indique l'emplacement de la pile utilisée par le processus 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'utiliser 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  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  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 restant à 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'attributs
       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 suivante :

           struct clone_args {
               u64 flags;        /* Masque de bit d'attribut */
               u64 pidfd;        /* Où stocker le descripteur de fichier du PID
                                    (pid_t *) */
               u64 child_tid;    /* Où stocker le TID enfant,
                                    dans la mémoire de l'enfant's memory (pid_t *) */
               u64 parent_tid;   /* Où stocker le TID enfant,
                                    dans la mémoire du parent's memory (int *) */
               u64 exit_signal;  /* Signal à envoyer au parent quand
                                    l'efant 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  valoir  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 enfant).

       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 arguments 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
              pile                pile
              ---                 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 parent. 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  du  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écifiques 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
       positionné 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 intermédiaires doivent  être  indiqués,  positionnez  le
       tableau sur :

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

       Le  PID  dans un espace de noms de PID en dehors des deux espaces de noms intermédiaires 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 dans les 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'indiquer 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é,  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 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  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 se termine 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
              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
              un processus qui partage une table de descripteurs de fichier  appelle  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 fichier 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 appelant, 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
              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 positionné, le processus enfant travaille sur une copie des informations de
              l'appelant concernant le systè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 version 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'appelant 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 habituelles
              (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 enfant é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 beaucoup 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émentations 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  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_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 processus est créé dans le même espace de noms  cgroup  que  le  processus
              appelant.

              Pour plus d'informations sur les espaces de noms cgroup, consultez 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 appelant.

              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 le noyau 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, reportez 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
              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 montage que le parent.

              Pour  plus  d'informations  sur  les  espaces  de  noms  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é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 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é ajouté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 processus 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'espace de noms PID initial) et par  les  processus  initiaux
              dans les autres espaces de noms PID. Cette restriction empêche la création 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 (Linux 2.0 à 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 hacker le système, mais autrement il n'est plus utilisé. Depuis 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 Linux 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  renvoyant  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 descripteurs 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 architectures 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émentation de bibliothèques de gestion des threads.

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

              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 ensuite
              depuis un 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 initialement  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 appelant partagent la même liste de
              compteurs « undo » pour les sémaphores 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 « undo » 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 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 parent 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 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 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 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 depuis 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 affectera (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  arbitrairement
              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ériel, 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
              provoqué une exception matériel (comme un un accès invalide 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 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 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 enfant.

       CLONE_VFORK (depuis Linux 2.2)
              Si le bit CLONE_VFORK est actif, l'exécution du processus appelant 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 processus enfant 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é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_VM ne l'est pas,  toute  autre  pile  de
              signal mise en place par sigaltstack(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  contiendra
       le code d'erreur.

ERREURS

       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 descripteur 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ées 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 processus 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 architecture. Par exemple, sur arch64,
              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 du 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 126 bits.

       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 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'espaces de noms utilisateur imbriqués. Consultez pid_namespaces(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'espaces de noms utilisateur imbriqués. Consultez user_namespaces(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 nouvel 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 descripteur 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'identifiant 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 montage dans lequel il se trouve).

       EPERM (clone3() seulement)
              set_tid_size était supérieur à zéro et l'appelant n'a pas la possibilité CAP_SYS_ADMIN dans un  ou
              plusieurs   des   espaces   de  noms  utilisateur  qui  appartiennent  aux  espaces  de  noms  PID
              correspondants.

       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'espaces 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 Linux 5.3.

CONFORMITÉ

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

NOTES

       Une utilisation de ces appels systèmes 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.

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

       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écursive, 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 processus partagent des ressources,
       telles qu'une table de descripteurs de fichier, des opérations Annuler de 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  noyaux  2.4.x,  CLONE_THREAD  ne  fait en général pas du processus parent du nouveau thread un
       processus identique au parent du processus appelant. 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.0 et supérieurs).

       Sur i386, clone() ne devrait pas être appelé via 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'enfant 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 (si l'enfant partage la mémoire du parent  du  fait  d'une
       utilisation  de CLONE_VM, aucune duplication via la copie-en-écriture ne se produit et il peut s'ensuivre
       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 paramè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 parent_tid, tls, et child_tid.

BOGUES

       Les versions de la bibliothèque C GNU jusqu'à la 2.24 comprise contenaient 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 parent), 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 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);

       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 malloc(3) pour les raisons suivantes :

       –  mmap(2)  alloue  un  bloc  de mémoire commençant à la limite d'une page et 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érationnel sur Linux, mais il existe et a des effets sur d'autres
          systèmes, donc on doit l'inclure pour la portabilité.

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

       #define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \
                               } while (0)

       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 du
              processus enfant */

           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 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)
               errExit("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)
               errExit("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)
               errExit("uname");
           printf("uts.nodename dans le parent : %s\n", uts.nodename);

           if (waitpid(pid, NULL, 0) == -1)    /* Attendre le processus enfant */
               errExit("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)

COLOPHON

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

TRADUCTION

       La  traduction  française   de   cette   page   de   manuel   a   été   créée   par   Christophe   Blaess
       <https://www.blaess.fr/christophe/>,   Stéphan   Rafin   <stephan.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.coulon@wanadoo.fr>,   Julien   Cristau
       <jcristau@debian.org>,     Thomas     Huriaux      <thomas.huriaux@gmail.com>,      Nicolas      François
       <nicolas.francois@centraliens.net>,     Florentin     Duneau    <fduneau@gmail.com>,    Simon    Paillard
       <simon.paillard@resel.enst-bretagne.fr>,    Denis    Barbier    <barbier@debian.org>,    David     Prévot
       <david@tilapin.org>,     Cédric     Boutillier     <cedric.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 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.

Linux                                            1 novembre 2020                                        CLONE(2)