Provided by: manpages-fr-dev_4.21.0-2_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.

STANDARDS

       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.

   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.

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/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("Le PID de l'enfant est %jd\n", (intmax_t) getpid());
               if (argc == 1)
                   pause();                    /* Attendre un signal */
               _exit(atoi(argv[1]));

           } else {                    /* Code exécuté par le parant */
               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(status)) {
                       printf("arrêté par le signal %d\en", 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⟩.