dwww Home | Manual pages | Find package

wait(2)                       System Calls Manual                      wait(2)

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  appe-
       lant  change  d'état et permettent d'obtenir des informations sur l'en-
       fant 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 pro-
       cessus 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 sigac-
       tion(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  comporte-
       ment  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'iden-
              tifiant de groupe du processus est égal à celui du processus ap-
              pelant 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'en-
       fant  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  argu-
       ment,  et  pas un pointeur vers celui-ci, comme le font wait() et wait-
       pid() !) :

       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 dis-
              ponible 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  si-
              gnal.  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 cor-
              respond à 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 pro-
              cessus correspond à id. depuis Linux 5.4, si id vaut  zéro,  at-
              tendre 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'en-
              fant.

       Si  l'appel  réussit, waitid() remplit les champs suivants de la struc-
       ture 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  re-
              lance de l'enfant. Le champ si_code permet de savoir comment in-
              terpré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, wai-
       tid() renvoie 0 immédiatement et l'état de la structure siginfo_t poin-
       té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 dif-
       fé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, ren-
       voie -1.

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

ERREURS
       EAGAIN Le  descripteur  de  fichier PID spécifié dans id n'est pas blo-
              quant et le processus auquel il fait référence ne s'est pas ter-
              miné.

       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 (wait-
              pid())  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 éga-
              lement 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  « zom-
       bie ».  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'obte-
       nir 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  pro-
       cessus suppresseur (subreaper) le plus proche tel que défini par l'uti-
       lisation 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  sigac-
       tion(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 dis-
       position par défaut de SIGCHLD est « ignore », la configuration  expli-
       cite  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,  Li-
       nux 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 fonction-
       nalité,  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  en-
       fants 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  unique-
              ment  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'en-
       veloppe 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),  si-
       gnal(2),  wait4(2),  pthread_create(3),  core(5),  credentials(7),  si-
       gnal(7)

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

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

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