Provided by: manpages-fr-dev_4.23.1-1_all bug

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() ; appelez-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 » 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 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'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
                                    (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 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
           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 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 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é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 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'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 binaire 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
              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 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 (et
              non définis à SIG_IGN) 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  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  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 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    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 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 Linux 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  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é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  employé  en   association   avec
              CLONE_THREAD.

       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 (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 bidouiller 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 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 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  une
              même  liste  de  valeurs  d’ajustement de 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 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 Linux 2.4 pour gérer 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 threads 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 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 processus 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 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 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 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é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 provoqué 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  signal,  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 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_VFORK 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 sera positionné 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 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é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 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  et  CLONE_THREAD  ou CLONE_PARENT, seuls ou ensemble,ont été indiqués
              dans le masque flags.

       EINVAL CLONE_NEWUSER et CLONE_THREAD ont été indiqués 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 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 (clone3() seulement)
              CLONE_THREAD ou CLONE_PARENT ont été spécifiés dans le masque flags, mais un signal
              a été spécifié dans exit_signal.

       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 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 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 capacité CAP_SYS_ADMIN
              dans  un  ou plusieurs des espaces de noms utilisateur qui possèdent les 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

       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.

       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'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 à l’aide de 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.

STANDARDS

       Linux.

HISTORIQUE

       clone3()
              Linux 5.3.

   Linux 2.4 et antérieurs
       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'attribut CLONE_THREAD impliquait CLONE_PARENT (de même que
       dans Linux 2.6.0 et supérieurs).

       Sous Linux 2.4 et plus anciens, clone() ne prend pas les paramètres  parent_tid,  tls,  et
       child_tid.

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.

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

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 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é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 <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/types.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 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  ⟨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⟩.