Man page - vfork(2)

Packages contains this manual

Available languages:

en fr it ja ru ro

Manual

vfork

NOM
BIBLIOTHÈQUE
SYNOPSIS
DESCRIPTION
Description des normes
Description de l’implĂ©mentation Linux
Description historique
VERSIONS
Notes pour Linux
STANDARDS
HISTORIQUE
AVERTISSEMENTS
BOGUES
VOIR AUSSI
TRADUCTION

NOM

vfork - Créer un processus enfant et bloquer le parent

BIBLIOTHÈQUE

BibliothĂšque C standard ( libc , -lc )

SYNOPSIS

#include <unistd.h>

pid_t vfork(void);

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

vfork () :
Depuis la glibc 2.12 :
(_XOPEN_SOURCE >= 500) && ! (_POSIX_C_SOURCE >= 200809L)
|| /* Depuis la glibc 2.19 : */ _DEFAULT_SOURCE
|| /* glibc <= 2.19 : */ _BSD_SOURCE
Avant la glibc 2.12 :
_BSD_SOURCE || _XOPEN_SOURCE >= 500

DESCRIPTION

Description des normes

(D’aprĂšs POSIX.1). La routine vfork () a le mĂȘme effet que fork (2), sauf que le comportement est indĂ©fini si le processus créé par vfork () effectue l’une des actions suivantes avant d’appeler avec succĂšs _exit (2) ou une routine de la famille exec (3) : modification d’une donnĂ©e autre que la variable de type pid_t stockant le retour de vfork (), revenir de la fonction dans laquelle vfork () a Ă©tĂ© invoquĂ©, appel d’une autre fonction.

Description de l’implĂ©mentation Linux

vfork (), tout comme fork (2), crée un processus enfant à partir du processus appelant. Pour plus de détails sur les valeurs renvoyées et les erreurs possibles, consultez fork (2).

vfork () est conçu comme un cas particulier de clone (2). Il sert Ă  crĂ©er un nouveau processus sans effectuer de copie de la table des pages mĂ©moire du processus parent. Cela peut ĂȘtre utile dans des applications nĂ©cessitant une grande rapiditĂ© d’exĂ©cution, si l’enfant doit invoquer immĂ©diatement un appel execve (2).

vfork () diffĂšre de fork (2) en ce que le thread appelant reste suspendu jusqu’à ce que l’enfant se termine (soit normalement, en appelant _exit (2), soit de façon anormale aprĂšs l’envoi d’un signal fatal) ou qu’il appelle execve (2). Jusqu’à ce point, l’enfant partage toute la mĂ©moire avec son parent, y compris la pile. Le processus enfant ne doit pas revenir de la fonction en cours, ni appeler exit (3) (ce qui aurait pour effet d’appeler les gestionnaires de sortie Ă©tablis par le processus parent et de vider les tampons stdio (3) du parent), mais appeler Ă  _exit (2).

Comme avec fork (2), le processus enfant créé par vfork () hĂ©rite des copies de plusieurs attributs du processus appelant (par exemple les descripteurs de fichiers, les dispositions des signaux et le rĂ©pertoire de travail actuel) ; l’appel vfork () diffĂšre seulement par le traitement de l’espace d’adressage virtuel, comme dĂ©crit ci-dessus.

Les signaux pour le processus parent sont dĂ©livrĂ©s aprĂšs que l’enfant libĂšre la mĂ©moire du parent (c’est-Ă -dire aprĂšs que l’enfant se termine ou qu’il appelle execve (2)).

Description historique

Sous Linux, fork (2) est implĂ©mentĂ© en utilisant un mĂ©canisme de copie en Ă©criture, ainsi ses seuls coĂ»ts sont le temps et la mĂ©moire nĂ©cessaire pour dupliquer la table des pages mĂ©moire du processus parent, et crĂ©er une seulestructure de tĂąche pour l’enfant. Toutefois, jadis fork (2) nĂ©cessitait malheureusement une copie complĂšte de l’espace de donnĂ©es du parent, souvent inutilement, car un appel exec (3) est souvent rĂ©alisĂ© immĂ©diatement par l’enfant. Pour amĂ©liorer les performances, BSD a introduit un appel systĂšme vfork () qui ne copie pas l’espace d’adressage du parent, mais emprunte au parent son espace d’adressage et son fil de contrĂŽle jusqu’à un appel Ă  execve (2) ou qu’une sortie survienne. Le processus parent Ă©tait suspendu tant que l’enfant utilisait les ressources. L’utilisation de vfork () Ă©tait loin d’ĂȘtre facile, car, pour Ă©viter de modifier les donnĂ©es du processus parent, il fallait ĂȘtre capable de dĂ©terminer quelles variables se trouvaient dans des registres du processeur.

VERSIONS

Les exigences que les normes apportent sur vfork () sont plus relĂąchĂ©es que celles sur fork (2), ainsi il est possible d’avoir une implĂ©mentation conforme oĂč les deux appels sont synonymes. En particulier, un programmeur ne doit pas s’appuyer sur le fait que le parent reste bloquĂ© jusqu’à ce que l’enfant se termine ou appelle execve (2), ni sur le comportement par rapport Ă  la mĂ©moire partagĂ©e.

Certaines personnes considĂšrent la sĂ©mantique de vfork () comme une verrue architecturale, et la page de manuel de 4.2BSD indique que « cet appel systĂšme sera supprimĂ© quand des mĂ©canismes de partage appropriĂ©s seront implĂ©mentĂ©s. Il ne faut pas essayer de tirer profit du partage mĂ©moire induit par vfork , car dans ce cas il serait rendu synonyme de fork (2) ». Cependant, mĂȘme si le matĂ©riel de gestion mĂ©moire moderne a diminuĂ© la diffĂ©rence de performances entre fork (2) et vfork (), il existe diverses raisons pour lesquelles Linux et d’autres systĂšmes ont conservĂ© vfork () :

-

Certaines applications de haute performance ont besoin du petit gain apporté par vfork ().

-

vfork () peut ĂȘtre implĂ©mentĂ© sur des systĂšmes sans unitĂ© de gestion mĂ©moire (MMU, pour « memory-management unit »), mais fork (2) ne peut pas ĂȘtre implĂ©mentĂ© sur de tels systĂšmes (POSIX.1-2008 a supprimĂ© vfork () de la norme ; la raison invoquĂ©e par POSIX pour la fonction posix_spawn (3) note que cette fonction, qui fournit une fonctionnalitĂ© Ă©quivalente Ă  fork (2)+ exec (3), est conçue pour ĂȘtre implĂ©mentable sur des systĂšmes sans MMU).

-

Sur les systĂšmes oĂč la mĂ©moire est restreinte, vfork Ă©vite le besoin d’allouer de la mĂ©moire temporairement (voir la description de /proc/sys/vm/overcommit_memory dans proc (5)) afin d’exĂ©cuter un nouveau programme. Cela peut ĂȘtre particuliĂšrement bĂ©nĂ©fique lorsqu’un grand processus parent souhaite exĂ©cuter un petit programme d’assistance dans un processus enfant. Par contraste, l’utilisation de fork (2) dans ce scĂ©nario nĂ©cessite soit l’allocation d’une quantitĂ© de mĂ©moire Ă©gale Ă  la taille du processus parent (si la gestion stricte du dĂ©passement est en cours) soit un dĂ©passement de mĂ©moire avec le risque qu’un processus soit terminĂ© par la mise Ă  mort sur mĂ©moire saturĂ©e (OOM killer).

Notes pour Linux

Les gestionnaires enregistrĂ©s avec pthread_atfork (3) ne sont pas appelĂ©s lorsqu’un programme multithreadĂ© utilisant la bibliothĂšque de threads NPTL appelle vfork (). En revanche ces gestionnaires sont appelĂ©s si le programme utilise la bibliothĂšque LinuxThreads. (Consultez pthreads (7) pour une description des bibliothĂšques de threads pour Linux.)

Un appel à vfork () est équivalent à appeler clone (2) avec flags valant :

CLONE_VM | CLONE_VFORK | SIGCHLD

STANDARDS

Aucun.

HISTORIQUE

4.3BSD, POSIX.1-2001 (mais la déclare obsolÚte). POSIX.1-2008 supprime la spécification de vfork ().

L’appel systĂšme vfork () est apparu dans 3.0BSD. Dans 4.4BSD, il est devenu synonyme de fork (2), mais NetBSD l’a rĂ©introduit Ă  nouveau (consultez http://www.netbsd.org/Documentation/kernel/vfork.html ). Sous Linux, il a Ă©tĂ© l’équivalent de fork (2) jusqu’à Linux 2.2.0-pre-6. Depuis Linux 2.2.0-pre-9 (sur i386, un peu plus tard sur d’autres architectures), il s’agit d’un appel systĂšme indĂ©pendant. La prise en charge a Ă©tĂ© introduite dans la glibc 2.0.112.

AVERTISSEMENTS

Le processus enfant devrait veiller Ă  ne pas modifier la mĂ©moire d’une maniĂšre inattendue, dans la mesure oĂč les modifications seront vues par le processus parent une fois que l’enfant s’est achevĂ© ou exĂ©cute un autre programme. À cet Ă©gard, les gestionnaires de signaux peuvent ĂȘtre particuliĂšrement problĂ©matiques : si un gestionnaire de signal qui est invoquĂ© dans l’enfant d’un vfork () modifie la mĂ©moire, ces modifications peuvent aboutir Ă  une inconsistance de l’état du processus du point de vue du processus parent (par exemple, les modifications de la mĂ©moire pourraient ĂȘtre visibles dans le parent, mais pas les modifications de l’état des descripteurs de fichiers ouverts).

Lorsque vfork () est appelĂ© dans un processus multithreadĂ©, seul le thread appelant est suspendu jusqu’à ce que l’enfant s’achĂšve ou exĂ©cute un nouveau programme. Cela signifie que l’enfant partage un espace d’adresses avec un autre code en cours d’exĂ©cution. Cela peut ĂȘtre dangereux si un autre thread dans le processus parent modifie son identifiant (avec setuid (2) ou une autre commande similaire), dans la mesure oĂč il y a alors deux processus avec diffĂ©rents niveaux de privilĂšges exĂ©cutĂ©s dans le mĂȘme espace d’adresses. Comme exemple de risque, imaginez qu’un programme multithreadĂ© exĂ©cutĂ© en tant que superutilisateur crĂ©e un enfant avec vfork (). AprĂšs le vfork (), un thread dans le processus parent transfĂšre le processus Ă  un utilisateur non privilĂ©giĂ© afin d’exĂ©cuter du code non sĂ»r (par exemple, peut-ĂȘtre au moyen d’un greffon ouvert avec dlopen (3)). Dans ce cas, des attaques sont possibles oĂč le processus parent utilise mmap (2) pour projeter en mĂ©moire du code qui sera exĂ©cutĂ© par le processus enfant privilĂ©giĂ©.

BOGUES

Les dĂ©tails de la gestion des signaux sont compliquĂ©s et varient suivant les systĂšmes. La page de manuel BSD indique : « Pour Ă©viter une possible situation d’interblocage, les processus qui sont des enfants au milieu d’un vfork () ne reçoivent jamais le signal SIGTTOU ou SIGTTIN ; des sorties et des ioctl sont autorisĂ©s, mais des tentatives de lecture donneront une indication de fin de fichier. »

VOIR AUSSI

clone (2), execve (2), _exit (2), fork (2), unshare (2), wait (2)

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