Précédent Remonter Suivant

7  Changement de code d'un processus

La primitive
    #include <unistd.h>
    int execve (char *filename, char *argv[], char *envp[]) ;
transforme le processus appelant en un nouveau processus. Attention, il n'y a pas création d'un nouveau processus, mais recouvrement de l'ancien processus par le nouveau.

Le nouveau processus est construit à partir d'un fichier ordinaire exécutable dont le nom est pointé par filename.

Le paramètre argv pointe sur un tableau de pointeurs de chaînes de caractères terminé par un pointeur NULL. Ces chaînes constituent la liste d'arguments du nouveau processus. Par convention, argv[0] est toujours présent et doit être le nom du programme à exécuter.

Le paramètre envp est aussi un pointeur sur un tableau de pointeurs de chaînes de caractères terminé par un pointeur NULL. Elles identifient les variables d'environnement qui seront accessibles depuis le nouveau processus. Ces chaînes sont construites suivant le format :
||<|nom de la variable||>|   =   ||<|valeur de la variable||>|

Les descripteurs ouverts dans le processus appelant restent ouverts dans le nouveau processus.

Quand le programme exécuté commence, il est appelé de la façon suivante : (les paramètres argc, argv et envp de main () sont optionnels)
    main (int argc, char *argv[], char *envp[])
execve() retourne dans le processus appelant uniquement en cas d'erreur et renvoie alors -1.

Exemple
% cat exec1.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>

char *path = "./exec2" ;
char *argval[] = {"exec2", "foo", "bar", NULL} ;

int main (int argc, char *argv[], char *envp[])
{
 pid_t pid ;

 switch (retour = fork()) {
   case -1 : 
     perror ("fork") ; 
     exit (1) ;
   case 0 : 
     printf ("processus fils va executer exec\n") ;
     execve (path, argval, envp) ;
     perror ("execve") ; 
     exit (1) ; 
   default :
     printf ("pere: a cree processus %d\n", retour) ;
     wait(0) ;
     printf ("pere: a recu terminaison fils\n") ;
 }
}

% cat exec2.c
#include <stdio.h>

int main (int argc, char *argv[])
{
 int i ;

 printf ("execution de exec2\n") ;
 printf ("exec2: %d arguments\n", argc) ;
 for (i=0 ; i<argc ; i++)
   printf ("exec2 argument %d: %s\n", i, argv[i]) ;

 exit (0) ;
}

% ./exec1
processus fils va executer exec
pere: a cree processus 14625
execution de exec2
exec2: 3 arguments
exec2 argument 0: exec2
exec2 argument 0: foo
exec2 argument 0: bar
pere: a recu terminaison fils
D'autres primitives sont disponibles ; elles sont écrites à l'aide de execve(). Il 'agit de execl(), execlp(), execle(), execv(), et execvp() dont les prototypes sont les suivants :
#include <unistd.h>

int execl (const char *filename, const char *arg, ...) ;
int execlp (const char *cmdname, const char *arg, ...) ;
int execle (const char *filename char *arg , ..., char* const envp[]) ;
int execv (const char *filename, char *const argv[]) ;
int execvp (const char *cmdname, char *const argv[]) ;
Elles permettent de spécifier les arguments du nouveau processus sous la forme d'une liste d'arguments (paramètres arg) et non d'un tableau de chaînes de caractères (paramètres argv), et/ou de rechercher le programme à exécuter parmi les chemins de recherches (variable d'environnement $PATH, paramètres cmdname) et non de spécifier complètement son chemin (paramètres filename), etc.


Précédent Remonter Suivant