Man page - waitid(2)

Packages contains this manual

Available languages:

en fr it pl nl ja ru

Manual

wait

NOM
BIBLIOTHÈQUE
SYNOPSIS
DESCRIPTION
wait() et waitpid()
waitid()
VALEUR RENVOYÉE
ERREURS
VERSIONS
Différences entre bibliothÚque C et noyau
STANDARDS
HISTORIQUE
NOTES
Notes pour Linux
BOGUES
EXEMPLES
Source du programme
VOIR AUSSI
TRADUCTION

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