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

NOM

       wait, waitpid, waitid - Attendre la fin d'un processus

BIBLIOTHÈQUE

       Bibliothèque C standard (libc, -lc)

SYNOPSIS

       #include <sys/wait.h>

       pid_t wait(int *_Nullable wstatus);
       pid_t waitpid(pid_t pid, int *_Nullable wstatus, int options);

       int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options);
                       /* Il s'agit de l'interface de glibc et POSIX ; consultez les
                          NOTES pour des informations sur les appels système bruts. */

   Exigences    de    macros    de   test   de   fonctionnalités   pour   la   glibc   (consulter
   feature_test_macros(7)) :

       waitid() :
           Depuis la glibc 2.26 :
               _XOPEN_SOURCE >= 500 || _POSIX_C_SOURCE >= 200809L
           Pour la glibc antérieure et égale à 2.25 :
               _XOPEN_SOURCE
                   || /* Depuis la glibc 2.12: */ _POSIX_C_SOURCE >= 200809L
                   || /* glibc <= 2.19: */ _BSD_SOURCE

DESCRIPTION

       Tous ces appels système attendent qu'un des enfants du processus appelant change d'état et
       permettent d'obtenir des informations sur l'enfant en question. Un processus est considéré
       comme changeant d'état s'il termine, s'il est stoppé par un signal ou s'il est relancé par
       un signal. Dans le cas d'un enfant qui se termine, l'attendre permet au système de libérer
       les ressources qui lui étaient allouées ; si le processus n'est pas attendu, il  reste  en
       état de « zombie » (voir les NOTES plus bas).

       Si un enfant a déjà changé d'état, ces appels système retournent immédiatement. Sinon, ils
       bloquent jusqu'à ce qu'un enfant change d'état ou qu'un gestionnaire de signal  interrompe
       l'appel  (sauf si les appels système sont relancés automatiquement par l'option SA_RESTART
       de sigaction(2)). Dans la suite de cette page, un enfant qui a changé d'état  et  qui  n'a
       pas été attendu est appelé prêt (waitable).

   wait() et waitpid()
       L'appel  système  wait()  suspend l'exécution du processus appelant jusqu'à ce que l'un de
       ses enfants se termine. L'appel wait(&status) est équivalent à :

           waitpid(-1, &wstatus, 0);

       L'appel système waitpid() suspend l'exécution  du  processus  appelant  jusqu'à  ce  qu'un
       enfant  spécifié  par l'argument pid change d'état. Par défaut, waitpid() n'attend que les
       enfants terminés, mais ce comportement peut être modifié par  l'argument  options,  de  la
       façon décrite ci-dessous.

       La valeur de pid peut être l'une des suivantes :

       < -1   Attendre  la  fin  de  n'importe  quel  processus  enfant  appartenant au groupe de
              processus d'ID -pid.

       -1     Attendre n'importe lequel des processus enfant.

       0      Attendre la fin de n'importe quel processus enfant dont l'identifiant de groupe  du
              processus est égal à celui du processus appelant au moment de l'appel à waitpid().

       > 0    Attendre la fin d'un enfant dont l'identifiant du processus est égal à la valeur du
              processus numéro pid.

       La valeur de l'argument option options est un OU binaire entre zéro ou plus des constantes
       suivantes :

       WNOHANG
              Ne pas bloquer si aucun enfant ne s'est terminé.

       WUNTRACED
              Recevoir  l'information  concernant  également les enfants bloqués (mais non suivis
              par ptrace(2)). L'état des enfants suivis qui se sont terminés est fourni même sans
              cette option.

       WCONTINUED (Depuis Linux 2.6.10)
              Renvoyer  également  si  un  processus  enfant  stoppé  a été relancé par le signal
              SIGCONT.

       (Pour les options spécifiques à Linux, voir plus bas.)

       Si wstatus n'est pas NULL, wait()  et  waitpid()  stockent  l'état  de  l'enfant  dans  la
       variable  de  type int pointée. Cet entier peut être évalué avec les macros suivantes (qui
       prennent l'entier lui-même comme argument, et pas un pointeur vers celui-ci, comme le font
       wait() et waitpid() !) :

       WIFEXITED(wstatus)
              Vrai  si l'enfant s'est terminé normalement, c'est-à-dire par un appel à exit(3) ou
              _exit(2) ou par un return depuis main().

       WEXITSTATUS(wstatus)
              Donne le code de retour, consistant en les 8 bits  de  poids  faible  du  paramètre
              status  fourni  à exit(3) ou _exit(2) ou dans le return de la routine main(). Cette
              macro ne peut être évaluée que si WIFEXITED a renvoyé vrai.

       WIFSIGNALED(wstatus)
              Vrai si l'enfant s'est terminé à cause d'un signal.

       WTERMSIG(wstatus)
              Donne le numéro du signal qui a causé la fin de l'enfant. Cette macro ne peut  être
              évaluée que si WIFSIGNALED a renvoyé vrai.

       WCOREDUMP(wstatus)
              Vrai  si  le  processus  enfant  a  produit une image mémoire (« core dump ») (voir
              core(5)). Cette macro ne doit être évaluée que si WIFSIGNALED a renvoyé vrai.

              Cette macro n'est  pas  décrite  par  POSIX.1-2001  et  n'est  pas  disponible  sur
              certaines implémentations d'UNIX (par exemple AIX ou SunOS). N'utilisez cette macro
              qu'entourée de #ifdef WCOREDUMP ... #endif.

       WIFSTOPPED(wstatus)
              Vrai si le processus enfant a été  arrêté  par  l'envoi  d'un  signal.  Cela  n'est
              possible  que si l'on a effectué l'appel avec l'option WUNTRACED ou si l'enfant est
              suivi (voir ptrace(2)).

       WSTOPSIG(wstatus)
              Donne le numéro du signal qui a causé l'arrêt de l'enfant. Cette macro ne peut être
              évaluée que si WIFSTOPPED renvoie vrai.

       WIFCONTINUED(wstatus)
              (Depuis Linux 2.6.10) Vrai si le processus enfant a été relancé par SIGCONT.

   waitid()
       L'appel  système  waitid(), disponible depuis Linux 2.6.9, fournit des moyens plus fins de
       contrôler quels changements d'états attendre.

       Les arguments idtype et id sélectionnent le(s) enfant(s) à attendre, comme suit :

       idtype == P_PID
              Attendre la fin de l'enfant dont l'identifiant du processus correspond à id.

       idtype == P_PIDFD (depuis Linux 5.4)
              Attendre la fin de l'enfant auquel fait référence le  descripteur  de  fichier  PID
              spécifié  dans  id  (voir  pidfd_open(2)  pour  plus  d'informations  à  propos des
              descripteurs de fichier PID).

       idtype == P_PGID
              Attendre la fin de l'enfant dont l'identifiant de groupe du processus correspond  à
              id.  depuis Linux 5.4, si id vaut zéro, attendre pour n'importe quel enfant qui est
              dans le même groupe de processus que le groupe de processus de l'appelant au moment
              de l'appel.

       idtype == P_ALL
              Attendre n'importe quel enfant ; l'argument id est ignoré.

       Les  changements  d'état à attendre sont indiqués par un OU binaire des attributs suivants
       dans le paramètre options :

       WEXITED
              Attendre les enfants qui se sont terminés.

       WSTOPPED
              Attendre les enfants qui ont été arrêtés par un signal.

       WCONTINUED
              Attendre les enfants précédemment arrêtés  qui  ont  été  relancés  par  le  signal
              SIGCONT.

       Les attributs suivants peuvent également être utilisés dans options :

       WNOHANG
              Comme pour waitpid().

       WNOWAIT
              Laisser  l'enfant dans un état prêt ; un appel ultérieur à wait() pourra de nouveau
              fournir des informations sur l'état de l'enfant.

       Si l'appel réussit, waitid() remplit les champs suivants de la structure siginfo_t pointée
       par infop :

       si_pid L'identifiant de processus de l'enfant.

       si_uid L'UID  réel  de  l'enfant.  Ce  champ  n'est  pas  rempli par la plupart des autres
              implémentations.

       si_signo
              Toujours SIGCHLD.

       si_status
              Soit le code de retour de l'enfant donné à _exit(2)  ou  exit(3),  soit  le  signal
              ayant  provoqué la terminaison, l'arrêt ou la relance de l'enfant. Le champ si_code
              permet de savoir comment interpréter ce champ.

       si_code
              L'un de CLD_EXITED (l'enfant a appelé _exit(2)), CLD_KILLED (l'enfant a été tué par
              un  signal),  CLD_DUMPED  (l'enfant  a été tué par un signal et a produit une image
              mémoire  (core  dump)),  CLD_STOPPED  (l'enfant  a  été  arrêté  par  un   signal),
              CLD_TRAPPED (l'enfant suivi a été capturé) ou CLD_CONTINUED (l'enfant a été relancé
              par SIGCONT).

       Si WNOHANG est utilisé dans options et si aucun enfant  n'est  prêt,  waitid()  renvoie  0
       immédiatement   et   l'état  de  la  structure  siginfo_t  pointée  par  infop  dépend  de
       l'implémentation. Pour différencier (de façon portable) ce cas de celui où un des  enfants
       était prêt, définissez à zéro le champ si_pid avant l'appel, et vérifiez que sa valeur est
       différente de zéro après le renvoi de l'appel.

       Le premier rectificatif technique POSIX.1-2008 (2013) ajoute l'exigence que quand  WNOHANG
       est  spécifié dans options et si aucun enfant n'est prêt, waitid() doit définir à zéro les
       champs si_pid et si_signo de la structure. Dans  Linux  et  d'autres  implémentations  qui
       respectent cette exigence, il n'est pas nécessaire de définir à zéro le champ si_pid avant
       l'appel à waitid(). Néanmoins, toutes les implémentations ne suivent pas la  spécification
       de POSIX.1 sur ce point.

VALEUR RENVOYÉE

       wait() :  en  cas  de réussite, l'identifiant du processus enfant terminé est renvoyé ; en
       cas d'échec, la valeur de retour est -1.

       waitpid() : s'il réussit, l'appel renvoie l'identifiant du processus enfant dont l'état  a
       changé ;  si  WNOHANG  est utilisé et si un enfant (ou plus) spécifié par pid existe, mais
       n'a pas encore changé d'état, la valeur renvoyée est 0. En cas d'échec, -1 est renvoyé.

       waitid() : renvoie 0 s'il réussit ou si WNOHANG est utilisé  et  siaucun  enfant  spécifié
       dans id n'a encore changé d'état. En cas d'échec, renvoie -1.

       En cas d'échec, chacun de ces appels définit errno pour préciser l'erreur.

ERREURS

       EAGAIN Le  descripteur  de fichier PID spécifié dans id n'est pas bloquant et le processus
              auquel il fait référence ne s'est pas terminé.

       ECHILD (pour wait()) Le processus appelant n'a pas d'enfants qui n'ont pas été attendus.

       ECHILD (pour waitpid() ou waitid()) Le processus indiqué par pid (waitpid()) ou idtype  et
              id (waitid()) n'existe pas ou n'est pas un enfant du processus appelant. (Cela peut
              arriver pour son propre enfant si l'action de SIGCHLD est définie à SIG_IGN ;  voir
              également le passage de la section Notes sur Linux concernant les threads.)

       EINTR  WNOHANG  n'est  pas  indiqué  et  un  signal  à intercepter ou SIGCHLD a été reçu ;
              consultez signal(7).

       EINVAL L'argument options n'est pas valable.

       ESRCH  (pour wait() ou waitpid()) pid est équivalent à INT_MIN.

VERSIONS

   Différences entre bibliothèque C et noyau
       wait() est en fait une fonction de bibliothèque implémentée (dans glibc) en tant  qu'appel
       système à wait4().

       sur  certaines  architectures,  il n'y a pas d'appel système waitpid() ; à la place, cette
       interface est implémentée au moyen d'une fonction d'enveloppe  de  la  bibliothèque C  qui
       appelle wait4(2).

       L'appel système brut waitid() prend un cinquième paramètre, de type struct rusage *. Si ce
       paramètre n'est pas NULL, il est utilisé pour renvoyer les informations d'utilisation  des
       ressources  au  sujet  du  thread  enfant,  de  la  même  façon  que  wait4(2).  Consultez
       getrusage(2) pour plus de détails.

STANDARDS

       POSIX.1-2008.

HISTORIQUE

       SVr4, 4.3BSD, POSIX.1-2001.

NOTES

       Un enfant qui se termine mais n'a pas été attendu devient un « zombie ». Le noyau conserve
       des  informations  minimales  sur  le  processus  zombie  (identifiant,  code  de  retour,
       informations d'utilisation des ressources) pour permettre au  parent  de  l'attendre  plus
       tard  et  d'obtenir  des informations sur l'enfant. Tant que le zombie n'est pas effacé du
       système par une attente, il prendra un emplacement dans la table des processus  du  noyau,
       et  si  cette  table est remplie, il sera impossible de créer de nouveaux processus. Si un
       processus parent se termine, ses enfants zombies (s'il y en a) sont  adoptés  par  init(1)
       (ou  par  le  processus  suppresseur  (subreaper)  le  plus  proche  tel  que  défini  par
       l'utilisation de l'opération PR_SET_CHILD_SUBREAPER  de  prctl(2)) ;  init(1)  les  attend
       automatiquement pour supprimer les zombies.

       POSIX.1-2001  indique  que si l'action pour SIGCHLD est définie à SIG_IGN ou si l'attribut
       SA_NOCLDWAIT est indiqué pour SIGCHLD (voir sigaction(2)), les enfants qui se terminent ne
       deviennent  pas des zombies et un appel à wait() ou waitpid() sera bloquant jusqu'à ce que
       tous les enfants soient terminés, et échouera ensuite en positionnant errno à ECHILD.  (La
       norme  POSIX  originale  ne  décrivait  pas le comportement si l'action pour SIGCHLD était
       SIG_IGN. Veuillez noter que même si la disposition par défaut de SIGCHLD  est  « ignore »,
       la  configuration  explicite de la disposition de SIG_IGN entraîne un traitement différent
       des processus enfants zombies.)

       Linux 2.6 est conforme aux préconisations de POSIX. Cependant, Linux 2.4 et  les  versions
       antérieures  ne  l'étaient  pas.  Lorsqu'un  appel  wait()  ou  waitpid() était exécuté en
       ignorant SIGCHLD, les appels se comportaient comme si SIGCHLD était pris en compte,  c'est
       à  dire  que  l'appel  restait  bloqué  en attendant que l'enfant suivant se termine, puis
       renvoyait l'identifiant de processus et l'état de cet enfant.

   Notes pour Linux
       Dans le noyau Linux, un thread ordonnancé par le noyau n'est  pas  différent  d'un  simple
       processus. En fait, un thread est juste un processus qui est créé à l'aide de la routine —
       spécifique à Linux — clone(2).  Les  routines  portables,  comme  pthread_create(3),  sont
       implémentées  en  appelant  clone(2).  Avant  Linux 2.4, un thread était simplement un cas
       particulier de processus, et en conséquence un thread ne pouvait pas attendre les  enfants
       d'un  autre  thread,  même si ce dernier appartenait au même groupe de threads. Toutefois,
       POSIX réclame une telle fonctionnalité, et depuis Linux 2.4 un thread  peut,  par  défaut,
       attendre les enfants des autres threads du même groupe.

       Les  options  suivantes  sont  spécifiques  à Linux et servent pour les enfants créés avec
       clone(2) ; elles peuvent aussi, depuis Linux 4.7, être utilisées avec waitid() :

       __WCLONE
              Attendre uniquement des enfants clones.  Sinon,  attendre  uniquement  les  enfants
              non-clones  (un  enfant  « clone »  est  un enfant qui n'envoie pas de signal ou un
              autre signal que SIGCHLD à son père à sa terminaison). Cette option est ignorée  si
              __WALL est aussi indiqué.

       __WALL (depuis Linux 2.4)
              Attendre tous les enfants, quel que soit leur type (clone ou non-clone).

       __WNOTHREAD (Depuis Linux 2.4)
              Ne  pas  attendre  les  enfants  des autres threads du même groupe de threads. Cela
              était le cas par défaut avant Linux 2.4.

       Depuis Linux 4.7, l'attribut __WALL est automatiquement impliqué si l'enfant est suivi.

BOGUES

       Selon la norme POSIX.1-2008, une application appelant  waitid() doit  garantir  que  infop
       pointe  sur  une  structure  siginfo_t  (c'est-à-dire qu'elle ne pointe pas sur NULL). Sur
       Linux, si infop est NULL, waitid()  réussit,  et  renvoie  l'identificateur  du  processus
       enfant  attendu.  Dans  la  mesure  du  possible,  les applications doivent éviter d'avoir
       recours à cette fonctionnalité incohérente, non standard et superflue.

EXEMPLES

       Le programme suivant montre l'utilisation de fork(2) et de waitpid(). Le programme crée un
       processus  enfant.  Si aucun argument n'est fourni dans la ligne de commande du programme,
       l'enfant suspend son exécution avec pause(2), pour que l'utilisateur  puisse  lui  envoyer
       des  signaux. Sinon, l'enfant se termine immédiatement en utilisant l'entier fourni sur la
       ligne de commande comme code de retour. Le processus père boucle en surveillant l'état  de
       l'enfant  avec  waitpid()  et  utilise les macros W*() décrites ci-dessus pour analyser le
       code d'état de l'enfant.

       La session interactive suivante montre l'utilisation de ce programme :

           $ ./a.out &
           Le PID de l'enfant est 32360
           [1] 32359
           $ kill -STOP 32360
           arrêté par le signal 19
           $ kill -CONT 32360
           relancé
           $ kill -TERM 32360
           tué par le signal 15
           [1]+  Done                    ./a.out
           $

   Source du programme

       #include <stdint.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <sys/types.h>
       #include <sys/wait.h>
       #include <unistd.h>

       int
       main(int argc, char *argv[])
       {
           int    wstatus;
           pid_t  cpid, w;

           cpid = fork();
           if (cpid == -1) {
               perror("fork");
               exit(EXIT_FAILURE);
           }

           if (cpid == 0) {            /* Code exécuté par l'enfant */
               printf("Child PID is %jd\n", (intmax_t) getpid());
               if (argc == 1)
                   pause();                    /* Attendre un signal */
               _exit(atoi(argv[1]));

           } else {                    /* Code exécuté par le parent */
               do {
                   w = waitpid(cpid, &wstatus, WUNTRACED | WCONTINUED);
                   if (w == -1) {
                       perror("waitpid");
                       exit(EXIT_FAILURE);
                   }

                   if (WIFEXITED(wstatus)) {
                       printf("terminé, code=%d\n", WEXITSTATUS(wstatus));
                   } else if (WIFSIGNALED(wstatus)) {
                       printf("tué par le signal %d\n", WTERMSIG(wstatus));
                   } else if (WIFSTOPPED(wstatus)) {
                       printf("arrêté par le signal %d\n", WSTOPSIG(wstatus));
                   } else if (WIFCONTINUED(wstatus)) {
                       printf("relancé\n");
                   }
               } while (!WIFEXITED(wstatus) && !WIFSIGNALED(wstatus));
               exit(EXIT_SUCCESS);
           }
       }

VOIR AUSSI

       _exit(2),  clone(2),  fork(2),  kill(2),  ptrace(2),  sigaction(2),  signal(2),  wait4(2),
       pthread_create(3), core(5), credentials(7), signal(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-Pierre
       Giraud <jean-pierregiraud@neuf.fr>

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