vfork(2) System Calls Manual vfork(2) NOM vfork - Creer un processus enfant et bloquer le parent BIBLIOTHEQUE Bibliotheque C standard (libc, -lc) SYNOPSIS #include pid_t vfork(void); Exigences de macros de test de fonctionnalites 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'apres POSIX.1). La routine vfork() a le meme effet que fork(2), sauf que le comportement est indefini si le processus cree par vfork() effectue l'une des actions suivantes avant d'appeler avec succes _exit(2) ou une routine de la famille exec(3) : modification d'une donnee autre que la variable de type pid_t stockant le retour de vfork(), revenir de la fonction dans laquelle vfork() a ete invoque, appel d'une autre fonction. Description de l'implementation Linux vfork(), tout comme fork(2), cree un processus enfant a partir du processus appelant. Pour plus de details sur les valeurs renvoyees et les erreurs possibles, consultez fork(2). vfork() est concu comme un cas particulier de clone(2). Il sert a creer un nouveau processus sans effectuer de copie de la table des pages memoire du processus parent. Cela peut etre utile dans des applications necessitant une grande rapidite d'execution, si l'enfant doit invoquer immediatement un appel execve(2). vfork() differe de fork(2) en ce que le thread appelant reste suspendu jusqu'a ce que l'enfant se termine (soit normalement, en appelant _exit(2), soit de facon anormale apres l'envoi d'un signal fatal) ou qu'il appelle execve(2). Jusqu'a ce point, l'enfant partage toute la memoire 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 etablis par le processus parent et de vider les tampons stdio(3) du parent), mais appeler a _exit(2). Comme avec fork(2), le processus enfant cree par vfork() herite des copies de plusieurs attributs du processus appelant (par exemple les descripteurs de fichiers, les dispositions des signaux et le repertoire de travail actuel) ; l'appel vfork() differe seulement par le traitement de l'espace d'adressage virtuel, comme decrit ci-dessus. Les signaux pour le processus parent sont delivres apres que l'enfant libere la memoire du parent (c'est-a-dire apres que l'enfant se termine ou qu'il appelle execve(2)). Description historique Sous Linux, fork(2) est implemente en utilisant un mecanisme de copie en ecriture, ainsi ses seuls couts sont le temps et la memoire necessaire pour dupliquer la table des pages memoire du processus parent, et creer une seulestructure de tache pour l'enfant. Toutefois, jadis fork(2) necessitait malheureusement une copie complete de l'espace de donnees du parent, souvent inutilement, car un appel exec(3) est souvent realise immediatement par l'enfant. Pour ameliorer les performances, BSD a introduit un appel systeme vfork() qui ne copie pas l'espace d'adressage du parent, mais emprunte au parent son espace d'adressage et son fil de controle jusqu'a un appel a execve(2) ou qu'une sortie survienne. Le processus parent etait suspendu tant que l'enfant utilisait les ressources. L'utilisation de vfork() etait loin d'etre facile, car, pour eviter de modifier les donnees du processus parent, il fallait etre capable de determiner quelles variables se trouvaient dans des registres du processeur. VERSIONS Les exigences que les normes apportent sur vfork() sont plus relachees que celles sur fork(2), ainsi il est possible d'avoir une implementation conforme ou les deux appels sont synonymes. En particulier, un programmeur ne doit pas s'appuyer sur le fait que le parent reste bloque jusqu'a ce que l'enfant se termine ou appelle execve(2), ni sur le comportement par rapport a la memoire partagee. Certaines personnes considerent la semantique de vfork() comme une verrue architecturale, et la page de manuel de 4.2BSD indique que << cet appel systeme sera supprime quand des mecanismes de partage appropries seront implementes. Il ne faut pas essayer de tirer profit du partage memoire induit par vfork, car dans ce cas il serait rendu synonyme de fork(2) >>. Cependant, meme si le materiel de gestion memoire moderne a diminue la difference de performances entre fork(2) et vfork(), il existe diverses raisons pour lesquelles Linux et d'autres systemes ont conserve vfork() : - Certaines applications de haute performance ont besoin du petit gain apporte par vfork(). - vfork() can be implemented on systems that lack a memory-management unit (MMU), but fork(2) can't be implemented on such systems. (POSIX.1-2008 removed vfork() from the standard; the POSIX rationale for the posix_spawn(3) function notes that that function, which provides functionality equivalent to fork(2)+ exec(3), is designed to be implementable on systems that lack an MMU.) - Sur les systemes ou la memoire est restreinte, vfork evite le besoin d'allouer de la memoire temporairement (voir la description de /proc/sys/vm/overcommit_memory dans proc(5)) afin d'executer un nouveau programme. Cela peut etre particulierement benefique lorsqu'un grand processus parent souhaite executer un petit programme d'assistance dans un processus enfant. Par contraste, l'utilisation de fork(2) dans ce scenario necessite soit l'allocation d'une quantite de memoire egale a la taille du processus parent (si la gestion stricte du depassement est en cours) soit un depassement de memoire avec le risque qu'un processus soit termine par la mise a mort sur memoire saturee (OOM killer). Notes pour Linux Les gestionnaires enregistres avec pthread_atfork(3) ne sont pas appeles lorsqu'un programme multithreade utilisant la bibliotheque de threads NPTL appelle vfork(). En revanche ces gestionnaires sont appeles si le programme utilise la bibliotheque LinuxThreads. (Consultez pthreads(7) pour une description des bibliotheques de threads pour Linux.) Un appel a vfork() est equivalent a appeler clone(2) avec flags valant : CLONE_VM | CLONE_VFORK | SIGCHLD STANDARDS Aucun. HISTORIQUE 4.3BSD, POSIX.1-2001 (mais la declare obsolete). POSIX.1-2008 supprime la specification de vfork(). L'appel systeme vfork() est apparu dans 3.0BSD. Dans 4.4BSD, il est devenu synonyme de fork(2), mais NetBSD l'a reintroduit a nouveau (consultez ). Sous Linux, il a ete l'equivalent de fork(2) jusqu'a 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 systeme independant. La prise en charge a ete introduite dans la glibc 2.0.112. AVERTISSEMENTS Le processus enfant devrait veiller a ne pas modifier la memoire d'une maniere inattendue, dans la mesure ou les modifications seront vues par le processus parent une fois que l'enfant s'est acheve ou execute un autre programme. A cet egard, les gestionnaires de signaux peuvent etre particulierement problematiques : si un gestionnaire de signal qui est invoque dans l'enfant d'un vfork() modifie la memoire, ces modifications peuvent aboutir a une inconsistance de l'etat du processus du point de vue du processus parent (par exemple, les modifications de la memoire pourraient etre visibles dans le parent, mais pas les modifications de l'etat des descripteurs de fichiers ouverts). Lorsque vfork() est appele dans un processus multithreade, seul le thread appelant est suspendu jusqu'a ce que l'enfant s'acheve ou execute un nouveau programme. Cela signifie que l'enfant partage un espace d'adresses avec un autre code en cours d'execution. Cela peut etre dangereux si un autre thread dans le processus parent modifie son identifiant (avec setuid(2) ou une autre commande similaire), dans la mesure ou il y a alors deux processus avec differents niveaux de privileges executes dans le meme espace d'adresses. Comme exemple de risque, imaginez qu'un programme multithreade execute en tant que superutilisateur cree un enfant avec vfork(). Apres le vfork(), un thread dans le processus parent transfere le processus a un utilisateur non privilegie afin d'executer du code non sur (par exemple, peut-etre au moyen d'un greffon ouvert avec dlopen(3)). Dans ce cas, des attaques sont possibles ou le processus parent utilise mmap(2) pour projeter en memoire du code qui sera execute par le processus enfant privilegie. BOGUES Les details de la gestion des signaux sont compliques et varient suivant les systemes. La page de manuel BSD indique : << Pour eviter une possible situation d'interblocage, les processus qui sont des enfants au milieu d'un vfork() ne recoivent jamais le signal SIGTTOU ou SIGTTIN ; des sorties et des ioctl sont autorises, 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 francaise de cette page de manuel a ete creee par Christophe Blaess , Stephan Rafin , Thierry Vignaud , Francois Micaux, Alain Portal , Jean-Philippe Guerard , Jean-Luc Coulon (f5ibh) , Julien Cristau , Thomas Huriaux , Nicolas Francois , Florentin Duneau , Simon Paillard , Denis Barbier , David Prevot et Jean-Pierre Giraud Cette traduction est une documentation libre ; veuillez vous reporter a la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITE LEGALE. Si vous decouvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message a . Pages du manuel de Linux 6.06 31 octobre 2023 vfork(2)