Je suis un cours de programmation système récemment et je suis passé par les appels système exec () et execve () . Jusqu'à présent, je ne trouve aucune différence entre ces deux sources. Même Wikipedia ne fournit pas d'explication claire. Il existe donc une différence entre exec () et execve () .
Et quelqu'un, s'il vous plaît, pourrait donner une brève description des appels système de la famille exec, tels que execl () , execv () , execle () , execvp () .
Utilisez man exec
et lisez:
The execv(), execvp(), and execvpe() functions provide an array of pointers to
null-terminated strings that represent the argument list available to the new program.
The first argument, by convention, should point to the filename associated with the file
being executed. The array of pointers must be terminated by a NULL pointer.
execv
int execv(const char *path, char *const argv[]);
Donc, vous passez un tableau en tant que paramètres
int execle(const char *path, const char *arg,
..., char * const envp[]);
Presque identique, mais pas sous forme de tableau, mais plutôt sous forme de liste de valeurs (chaînes), suivie d'un tableau qui désigne l'environnement.
Ici:
int execvp(const char *file, char *const argv[]);
Vous appelez un fichier, sans chemin d'accès, et attend donc que vous soyez déjà dans la bonne variable path
avant d'appeler.
Enfin et surtout:
int execve(const char *filename, char *const argv[],
char *const envp[]);
Semblable au précédent, mais vous avez maintenant deux tableaux, pour les arguments et les variables d’environnement.
Il n'y a pas d'appel système exec
- il est généralement utilisé pour désigner tous les appels execXX
en tant que groupe. Ils font tous essentiellement la même chose: charger un nouveau programme dans le processus actuel et lui fournir des arguments et des variables d’environnement. Les différences concernent la manière dont le programme est trouvé, les arguments spécifiés et l'origine de l'environnement.
Les appels avec v
dans le nom prennent un paramètre de tableau pour spécifier le tableau argv[]
du nouveau programme.
Les appels avec l
dans le nom prennent les arguments du nouveau programme en tant que liste d'arguments de longueur variable à la fonction elle-même.
Les appels avec e
dans le nom prennent un argument supplémentaire pour fournir l'environnement du nouveau programme; sinon, le programme hérite de l'environnement du processus actuel.
Les appels avec p
dans le nom recherchent la variable d’environnement PATH
pour rechercher le programme s’il ne contient aucun répertoire (c’est-à-dire qu’il ne contient pas de caractère /
). Sinon, le nom du programme est toujours traité comme un chemin d'accès à l'exécutable.
Puisque toutes ces fonctions appartiennent à la famille exec (), laissez-moi differentiate
en fonction de extra characters
avec les significations,
1.exec ve ():
p: not present => le nom du programme à exécuter sera tiré de pathname
v: present => l'argument sera passé sous la forme array
e: present => environnement sera pris de envp argument
2.exec le ():
p: not present => le nom du programme à exécuter sera tiré de pathname
l: present => l'argument sera passé en tant que list
e: present => environnement sera pris de envp argument
3.exec lp ():
p: present => le nom du programme à exécuter sera tiré de la variable filename
spécifiée ou du système search for program file
dans la variable PATH
.
l: present => l'argument sera passé en tant que list
e: not present => environnement sera pris de caller's environ
4.exec vp ():
p: present => le nom du programme à exécuter sera tiré de la variable filename
spécifiée ou du système search for program file
dans la variable PATH
.
v: present => l'argument sera passé sous la forme array
e: not present => environnement sera pris de caller's environ
5.exec v ():
p: not present => le nom du programme à exécuter sera tiré de pathname
v: present => l'argument sera passé sous la forme array
e: not present => environnement sera pris de caller's environ
6.exec l ():
p: not present => le nom du programme à exécuter sera tiré de pathname
l: present => l'argument sera passé en tant que list
e: not present => environnement sera pris de caller's environ
Les arguments sont différents pour ces fonctions.
Les fonctions execl, execlp et execle exigent que chacun des arguments de ligne de commande du nouveau programme soit spécifié en tant qu'arguments séparés.
Les execv, execvp et execve, nous devons construire un tableau de pointeurs sur les arguments, et l’adresse de ce tableau est l’argument de ces trois fonctions.
Les fonctions execve, execle nous permettent de passer le pointeur à un tableau de pointeurs vers les chaînes de l'environnement. Les quatre autres fonctions utilisent la variable environ
dans le processus appelant pour copier l'environnement existant dans le programme.
p
signifie que la fonction prend un argument de nom de fichier et utilise la variable d’environnement PATH pour rechercher le fichier exécutable.l
signifie que la fonction prend une liste d'arguments et s'exclut mutuellement avec la lettre v
, ce qui signifie qu'elle utilise un vecteur argv [].La lettre e
signifie que la fonction utilise un tableau envp[]
au lieu d'utiliser l'environnement actuel.
Le nouveau programme hérite des fonctionnalités supplémentaires suivantes du processus appelant.
Process ID and the Parent Process ID
Real user ID and Real Group ID
Supplementary group IDs
Process group ID
Session ID
Controlling terminal
Time left until alarm clock
Current working directory
Root directory
File mode creation mask
File locks
Process signal mask
Pending signals
Resource limits
Values for tms_utime, tms_stime, tms_cutime, and tms_cstime.
la famille de fonctions exec () remplace l’image de processus existante par une nouvelle image de processus. Il s'agit d'une différence marquée par rapport à l'appel système fork () dans lequel les processus parent et enfant coexistent dans la mémoire.
int execv (const char *filename, char *const argv[])
Le nom de fichier est le fichier de la nouvelle image de processus.
argv représente un tableau de chaînes terminées par un caractère null. Le dernier élément de ce tableau doit être un pointeur null.
int execl (const char *filename, const char *arg0, …)
Identique à execv mais les arguments sont fournis sous forme de chaîne individuelle (séparée par des virgules) au lieu d'un tableau/vecteur.
int execve (const char *filename, char *const argv[], char *const env[])
Identique à execv mais cela permet de spécifier des variables d’environnement pour une nouvelle image de processus.
int execle (const char *filename, const char *arg0, …, char *const env[])
Identique à execl mais cela permet de spécifier des variables d'environnement pour la nouvelle image de processus.
int execvp (const char *filename, char *const argv[])
Identique à la fonction execv mais la variable d’environnement standard PATH est recherchée pour trouver le nom de fichier si celui-ci ne contient pas de barre oblique.
Voici une liste de variable d'environnement standard:
https://www.gnu.org/software/libc/manual/html_node/Standard-Environment.html#Standard-Environment
int execlp (const char *filename, const char *arg0, …)
Identique à execl sauf que if effectue la recherche de nom de fichier comme fonction execvp.
Dans un système Linux, si vous tapez env
ou printenv
sur le shell ou le terminal, vous obtiendrez une liste des variables d’environnement standard.
Dans la famille exec, il existe des fonctions qui varient légèrement dans leurs capacités et comment elles sont appelées:
Les fonctions contenant la lettre p dans leurs noms (execvp
et execlp
) acceptent un nom de programme et recherchent un programme portant ce nom dans le chemin d'exécution actuel; les fonctions qui ne contiennent pas le p doivent avoir le chemin complet du programme à exécuter.
Les fonctions contenant la lettre v dans leurs noms (execv
, execvp
et execve) acceptent la liste d'arguments du nouveau programme sous la forme d'un tableau de pointeurs vers des chaînes terminé par NULL. Les fonctions contenant la lettre l (execl
, execlp
et Execle) acceptent la liste d’arguments en utilisant le mécanisme varargs
du langage C.
Les fonctions qui contiennent la lettre e dans leurs noms (execve
et execle
) acceptent un argument supplémentaire, un tableau de variables d’environnement. L’argument doit être Chaque chaîne de caractères .__ devrait être de la forme VARIABLE=value
.
Pour répondre à la première partie de votre question, dans le contexte de Linux en particulier, il n'y a qu'un seul appel système et il s'agit de execve (pas exec ). Le reste de la soi-disant "famille exec" ( execl , execle , execv , execve , execvp , etc.) sont tous des enveloppeurs GLIBC pour l'appel système du noyau, c'est-à-dire execve .