execvp(3)
Fonction de la bibliothèque C
Remplace le programme du processus courant par une commande cherchée dans le PATH, avec ses arguments dans un tableau terminé par NULL.
#include <unistd.h>
int execvp(const char *file, char *const argv[]);Description
execvp charge un autre programme dans le processus courant et l'exécute depuis son début. Le code, les données et la pile de l'ancien programme sont remplacés ; le PID ne change pas, et les descripteurs de fichiers ouverts restent ouverts (sauf ceux marqués « close-on-exec »). On l'appelle presque toujours dans un enfant créé par fork, pour que le parent continue.
Le p du nom signifie que file est cherché dans les dossiers de la variable PATH, comme le fait le shell, sauf s'il contient un / : il est alors pris tel quel. Le v signifie que les arguments arrivent dans un tableau (vector). Par convention, argv[0] est le nom de la commande, et la dernière case doit valoir NULL. Le nouveau programme reçoit l'environnement du processus courant.
Les autres membres de la famille changent une lettre : execlp prend les arguments un par un, terminés par (char *) NULL, execv ne cherche pas dans le PATH, et l'appel système sous-jacent, execve, veut un chemin exact et un environnement explicite.
Valeur de retour
En cas de succès, execvp ne revient jamais : il n'y a plus de programme appelant pour recevoir une valeur. S'il revient, c'est un échec, la valeur est -1 et errno en donne la cause : ENOENT quand la commande est introuvable, EACCES quand le fichier n'est pas exécutable.
Pièges
Tout ce qui suit
execvpne s'exécute qu'en cas d'échec. Écris-y unperrorpuis unexit, sinon l'enfant continue le code du parent.Un tableau d'arguments sans
NULLfinal fait lireexecvpau-delà du tableau.Le tampon de
printfest perdu dans le remplacement. Vide-le avecfflush(stdout)avant l'appel.No such file or directorypeut aussi venir d'un script dont l'interpréteur n'existe pas, comme un#!/bin/shsuivi d'un retour chariot Windows.
Exemple
#include <stdio.h>#include <unistd.h>
int main(int argc, char **argv){ if (argc < 2) { fprintf(stderr, "usage : %s commande [arguments]\n", argv[0]); return 2; } execvp(argv[1], argv + 1); perror(argv[1]); return 127;}$ gcc -Wall -Wextra lance.c -o lance$ ./lance echo bonjour depuis execvpbonjour depuis execvp$ ./lance commande-inconnuecommande-inconnue: No such file or directory$ echo $?127argv + 1 est déjà un tableau au bon format : il commence au nom de la commande et se termine par le NULL que la norme C garantit en argv[argc].
pipe_chain
Écris pipe_chain, qui lance chaque commande d'une liste dans son propre enfant avec execvp et branche la sortie de chacune sur l'entrée de la suivante.