Loading

NOM

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

SYNOPSIS

       #include <sys/types.h>
       #include <sys/wait.h>

       pid_t wait(int *status);

       pid_t waitpid(pid_t pid, int *status, int options);

       int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options);

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

       waitid() : _SVID_SOURCE || _XOPEN_SOURCE

       Tous ces appels système attendent qu’un des fils du processus  appelant
       change  d’état, et permettent d’obtenir des informations sur le fils 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 fils 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  fils  a  déjà  changé  d’état,  ces  appels  système retournent
       immédiatement. Sinon, ils bloquent jusqu’à ce qu’un fils 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 fils qui a changé d’état
       et qui n’a pas été attendu est appelé prt (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, &status, 0);

       L’appel système waitpid() suspend  l’exécution  du  processus  appelant
       jusqu’à  ce  qu’un  fils spécifié par l’argument pid change d’état. Par
       défaut, waitpid() n’attend que les fils 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 fils appartenant  au
              groupe de processus d’ID -pid.

       -1     Attendre n’importe lequel des processus fils.

       0      Attendre  la fin de n’importe quel processus fils du même groupe
              que l’appelant.

       > 0    Attendre la fin du processus numéro pid.

       La valeur de l’argument option options est  un  OU  binaire  entre  les
       constantes suivantes :

       WNOHANG     Ne pas bloquer si aucun fils ne s’est terminé.

       WUNTRACED   Recevoir   l’information   concernant  également  les  fils
                   bloqués (mais non suivis par ptrace(2)) si on  ne  l’a  pas
                   encore  reçue.  L’état des fils suivis est fourni même sans
                   cette option.

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

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

       Si  status  n’est pas NULL, wait() et waitpid() stockent l’état du fils
       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(status)
              Vrai si le fils s’est terminé normalement, c’est-à-dire  par  un
              appel à exit(3) ou _exit(2), ou par un return depuis main().

       WEXITSTATUS(status)
              Donne  le  code  de  retour,  consistant  en les 8 bits de poids
              faibles 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 est non nul.

       WIFSIGNALED(status)
              Vrai  si  le  fils  s’est  terminé  à  cause  d’un  signal   non
              intercepté.

       WTERMSIG(status)
              Donne  le  numéro  du  signal  qui a causé la fin du fils. Cette
              macro ne peut être évaluée que si WIFSIGNALED est non nul.

       WCOREDUMP(status)
              Vrai si le processus fils a produit une  image  mémoire  (« core
              dump»).  Cette  macro  ne doit être évaluée que si WIFSIGNALED a
              renvoyé une valeur non nulle. Cette macro n’est pas décrite  par
              POSIX.1-2001  et  n’est  pas  disponible sur certaines variantes
              d’Unix (par  exemple  AIX  ou  SunOS).  N’utilisez  cette  macro
              qu’entourée de #ifdef WCOREDUMP ... #endif.

       WIFSTOPPED(status)
              Vrai si le fils est actuellement arrêté. Cela n’est possible que
              si l’on a effectué l’appel avec l’option WUNTRACED ou si le fils
              est suivi (voir ptrace(2)).

       WSTOPSIG(status)
              Donne  le  numéro  du  signal qui a causé l’arrêt du fils. Cette
              macro ne peut être évaluée que si WIFSTOPPED est non nul.

       WIFCONTINUED(status)
              (Depuis Linux 2.6.10) Vrai si le processus fils  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) fils à  attendre,  comme
       suit :

       idtype == P_PID
              Attendre la fin du processus numéro id.

       idtype == P_PGID
              Attendre  la  fin de n’importe quel processus fils appartenant à
              un groupe de processus d’ID id.

       idtype == P_ALL
              Attendre n’importe quel fils ; 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 fils 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 le fils dans un état prêt ; un  appel  ultérieur  à
                   wait()  pourra  de  nouveau  fournir  des  informations sur
                   l’état du fils.

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

       si_uid      L’UID  réel  du  fils.  Ce  champ  n’est  pas rempli par la
                   plupart des autres implémentations.

       si_signo    Toujours SIGCHLD.

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

       si_code     L’un  de CLD_EXITED (le fils a appelé _exit(2)), CLD_KILLED
                   (le fils a été tué par un signal), CLD_DUMPED  (le  fils  a
                   été tué par un signal, et a produit une image (core dump)),
                   CLD_STOPPED  (le  fils  a  été  arrêté  par   un   signal),
                   CLD_TRAPPED (le fils suivi a été rattrapé) ou CLD_CONTINUED
                   (le fils a été relancé par SIGCONT).

       Si WNOHANG est utilisé dans options et aucun fils n’est prêt,  waitid()
       renvoie 0 immédiatement et l’état de la structure siginfo_t pointée par
       infop n’est pas précisé. Pour différencier ce cas de celui  où  un  des
       fils  était  prêt,  fixez le champ si_pid avant l’appel, et vérifiez sa
       valeur après le retour.

VALEUR RENVOYÉE

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

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

       waitid() : renvoie 0 s’il réussit ou si WNOHANG est  utilisé  et  aucun
       fils  n’a  changé d’état. En cas d’erreur, il renvoie -1. Chacun de ces
       appels système positionne errno à la valeur appropriée en cas d’erreur.

ERREURS

       ECHILD (pour  wait())  Le  processus appelant n’a pas de fils 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 fils du processus appelant. (Ceci peut arriver  pour  son
              propre  fils  si l’action de SIGCHLD est placé sur 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 ; voir signal(7).

       EINVAL L’argument options est invalide.

CONFORMITÉ

       SVr4, BSD 4.3, POSIX.1-2001.

NOTES

       Un fils 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 le fils. 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 fils zombies sont adoptés  par  init(8),  qui  les  attend
       automatiquement pour les supprimer.

       POSIX.1-2001  indique  que si l’action pour SIGCHLD est fixée à 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  fils  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 fils zombies.) Linux 2.6 se conforme
       à  cette  norme.  Cependant,  ce  n’est  pas  le  cas  de  Linux 2.4 et
       précédents : si un appel à wait()  ou  waitpid()  est  fait  alors  que
       SIGCHLD  est  ignoré,  l’appel se comporte comme si SIGCHLD n’était pas
       ignoré, ce qui veut dire qu’il attend jusqu’à ce que le  prochain  fils
       se termine, et renvoie l’identifiant et le code de retour de ce fils.

   Notes sur 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 ne peuvent pas ê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. Ceci était le cas par défaut avant Linux 2.4.

EXEMPLE

       Le programme suivant montre l’utilisation de fork(2) et  de  waitpid().
       Le  programme  crée  un  processus fils. Si aucun argument n’est fourni
       dans la ligne de commande du programme, le fils suspend  son  exécution
       avec  pause(2),  pour que l’utilisateur puisse lui envoyer des signaux.
       Sinon, le fils 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 du fils avec waitpid(),  et  utilise  les  macros
       W*() décrites ci-dessus pour analyser le code d’état du fils.

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

           $ ./a.out &
           Le PID du fils 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 <sys/wait.h>
       #include <stdlib.h>
       #include <unistd.h>
       #include <stdio.h>

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

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

           if (cpid == 0) {            /* Code exécuté par le fils */
               printf("Le PID du fils est %ld\n", (long) getpid());
               if (argc == 1)
                   pause();                    /* Attendre un signal */
               _exit(atoi(argv[1]));

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

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

VOIR AUSSI

       _exit(2),   clone(2),   fork(2),   kill(2),   ptrace(2),  sigaction(2),
       signal(2), wait4(2), pthread_create(3), credentials(7), signal(7)

COLOPHON

       Cette page fait partie de  la  publication  3.23  du  projet  man-pages
       Linux.  Une description du projet et des instructions pour signaler des
       anomalies      peuvent      être       trouvées       à       l’adresse
       http://www.kernel.org/doc/man-pages/.

TRADUCTION

       Cette  page  de  manuel  a  été  traduite et mise à jour par Christophe
       Blaess <http://www.blaess.fr/christophe/> entre 1996 et 2003, puis  par
       Alain  Portal  <aportal AT univ-montp2 DOT fr> jusqu’en 2006, et mise à
       disposition sur http://manpagesfr.free.fr/.

       Les mises à jour et corrections de la version présente dans Debian sont
       directement gérées par Julien Cristau <jcristau@debian.org> et l’équipe
       francophone de traduction de Debian.

       Veuillez  signaler  toute  erreur   de   traduction   en   écrivant   à
       <debian-l10n-french@lists.debian.org> ou par un rapport de bogue sur le
       paquet manpages-fr.

       Vous pouvez toujours avoir accès à la version anglaise de  ce  document
       en utilisant la commande « man -L C <section> <page_de_man> ».