Provided by:
manpages-fr-dev_2.64.1-1_all 
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 pour les macros de test de fonctionnalité de la glibc (consultez
feature_test_macros(7)) :
waitid() : _SVID_SOURCE || _XOPEN_SOURCE
DESCRIPTION
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é prêt (waitable).
wait() et waitpid()
L’appel système wait() suspend l’exécution du processus courant 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 courant
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.)
Les options WUNTRACED et WCONTINUED n’ont d’effet que si le drapeau
SA_NOCLDSTOP n’a pas été levé pour le signal SIGCHLD (voir
sigaction(2)).
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_STOPPED (le fils a été arrêté
par un signal), 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é ; en cas d’erreur, -1 est renvoyé. Si WNOHANG
est utilisé et aucun fils n’a changé d’état, la valeur de retour est 0.
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.
Ces fonctions remplissent errno avec le code d’erreur en cas d’échec.
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.
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.) 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(2).
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(2), 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
$
#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)
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> ».