execve
Exécuter un programme
- Provided by: manpages-fr-dev (Version: 3.65d1p1-1)
- Source: manpages-fr
- Report a bug
Exécuter un programme
#include <unistd.h>
int execve(const char *filename, char *const
argv[],
char *const envp[]);
execve() exécute le programme correspondant au fichier filename. Celui‐ci doit être un exécutable binaire ou bien un script commençant par une ligne du type :
#! interpréteur [argument-optionnel]
Pour des détails sur ce dernier cas, consultez « Scripts » ci‐dessous.
argv est un tableau de chaînes d'arguments passées au nouveau programme. Par convention, la première de ces chaînes devrait contenir le nom de fichier associé au fichier étant exécuté. envp est un tableau de chaînes, ayant par convention la forme clé=valeur, qui sont passées au nouveau programme comme environnement. argv ainsi que envp doivent se terminer par un pointeur NULL. Les arguments et l'environnement sont accessibles par le nouveau programme dans sa fonction principale, lorsqu'elle est définie comme :
int main(int argc, char *argv[], char *envp[])
En cas de réussite, execve() ne revient pas à l'appelant, et les segments de texte, de données (« data » et « bss »), ainsi que la pile du processus appelant sont remplacés par ceux du programme chargé.
Si l'on effectuait un ptrace(2) sur le programme appelant, un signal SIGTRAP est envoyé après la réussite de execve().
Si le bit Set-UID est positionné sur le fichier filename, si le système de fichiers sous‐jacent n'est pas monté nosuid (l'attribut MS_NOSUID de mount(2)), et si le programme n'est pas tracé, l'UID effectif du processus appelant est modifié pour prendre celui du propriétaire du fichier. De même, lorsque le bit Set‐GID est positionné, le GID effectif est modifié pour correspondre à celui du groupe du fichier.
L'UID effectif du processus est copié dans le Set-UID sauvé ; de la même manière, le GID effectif est copié dans le Set-GID sauvé. Ces copies ont lieu après toute modification d'ID effectif à cause des bits de permission Set-UID et Set-GID.
Si l'exécutable est un fichier binaire a.out lié dynamiquement, et contenant des appels aux bibliothèques partagées, le linker dynamique de Linux ld.so(8) est appelé avant l'exécution, afin de charger les bibliothèques partagées nécessaires en mémoire et d'effectuer l'édition des liens de l'exécutable.
Si l'exécutable est au format ELF lié dynamiquement, l'interpréteur indiqué dans le segment PT_INTERP sera invoqué pour charger les bibliothèques partagées. Cet interpréteur est généralement /lib/ld-linux.so.2 pour les fichiers binaires liés avec la glibc 2 (pour les fichiers binaires liés avec l'ancienne libc Linux 5, l'interpréteur était typiquement /lib/ld-linux.so.1).
Tous les attributs du processus sont préservés lors d'un execve(), à l'exception des suivants :
Les attributs de processus listés ci‐dessus sont spécifiés dans POSIX.1-2001. Les attributs de processus spécifiques à Linux suivants sont également réinitialisés lors d'un execve() :
Notez également les points suivants :
Un script est un fichier dont le bit d'exécution est activé et dont la première ligne est de la forme :
#! interpréteur [argument-optionnel]
L'interpréteur doit être un nom de fichier valide pour un exécutable qui n'est pas un script lui‐même. Si l'argument filename de execve() indique un script, l'interpréteur sera appelé avec les arguments suivants :
interpréteur [argument-optionnel] filename arg...
où arg... est la liste de mots pointée par l'argument argv de execve(), commençant par argv[1].
Pour être portable, argument-optionnel doit soit être absent, soit être un seul mot (c'est‐à‐dire ne pas contenir d'espace) ; consultez les NOTES ci‐dessous.
La plupart des implémentations UNIX imposent des limites sur la taille totale des chaînes des paramètres des lignes de commande (argv) et de l'environnement (envp) qui peuvent être passées à un nouveau programme. POSIX.1 permet à une implémentation d'annoncer cette limite en utilisant la constante ARG_MAX (soit définie dans <limits.h>, soit disponible à l'exécution en utilisant l'appel sysconf(_SC_ARG_MAX)).
Sur les noyaux Linux antérieurs à 2.6.23, la mémoire utilisée pour stocker les chaînes d'environnement et d'arguments était limitée à 32 pages (défini par la constante noyau MAX_ARG_PAGES). Sur les architectures dont la taille de page est 4 Ko, cela donne un maximum de 128 Ko.
Sur les noyaux 2.6.23 et ultérieurs, la plupart des architectures ont une limite de taille dérivée de la limite de ressources souple RLIMIT_STACK (consultez getrlimit(2)) qui est en vigueur au moment de l'appel à execve() (ce n'est pas le cas pour les architectures sans unité de gestion mémoire : elles conservent la limite des noyaux antérieurs à 2.6.23). Ce changement permet aux programmes d'avoir une liste de paramètre ou un environnement beaucoup plus grand. Pour ces architectures, la taille totale est limitées à 1/4 de la taille de pile permise (imposer une limite de 1/4 permet d'assurer que le nouveau programme garde de l'espace pour la pile). Depuis Linux 2.6.25, le noyau place une limite inférieure de 32 pages à cette limite de taille, de telle sorte que même si RLIMIT_STACK est très faible, il est garantit aux applications qu'elles auront au moins autant de place pour les paramètres et leur environnement que ce qui était fournit par Linux 2.6.23 et les précédents (cette garantie n'était pas présente dans les noyaux 2.6.23 et 2.6.24). De plus, la limite par chaîne est de 32 pages (la constante noyau MAX_ARG_STRLEN), et le nombre maximal de chaînes est de 0x7FFFFFFF.
En cas de réussite, execve() ne revient pas, en cas d'échec il renvoie -1 et errno contient le code d'erreur.
SVr4, BSD 4.3, POSIX.1-2001. POSIX.1-2001 ne documente pas le comportement avec « #! » mais est néanmoins compatible.
Les processus Set-UID et Set-GID ne peuvent pas être suivis par ptrace(2).
Linux ignore les bits Set-UID et Set-GID sur les scripts.
Le résultat d'un montage de système de fichiers avec l'attribut nosuid peut varier suivant les versions du noyau Linux : certaines refuseront l'exécution des fichiers Set-UID et Set-GID lorsque cela donnerait à l'appelant des privilèges qu'il n'a pas (et renverront l'erreur EPERM), d'autres ignoreront simplement les bits Set-UID et Set-GID mais accepteront d'effectuer l'appel exec().
La première ligne d'un shell script exécutable (#!) a une longueur maximale de 127 caractères.
La sémantique de l'argument-optionnel d'un script diffère selon les implémentations. Sous Linux, la chaîne qui suit le nom de l'interpréteur est passée à l'interpréteur comme un seul mot, et cette chaîne peut contenir des espaces. Cependant, le comportement est différent sur d'autres systèmes. Certains utilisent la première espace comme fin de l'argument-optionnel. Sur certains systèmes, un script peut avoir plusieurs arguments, délimités par des espaces dans argument-optionnel.
Sous Linux, argv et envp peuvent être NULL, ce qui a le même effet que d’indiquer ces paramètres comme un pointeur vers une liste contenant un pointeur NULL unique. Ne vous servez pas de cette caractéristique ! Elle n'est ni standard ni portable : sur la plupart des systèmes UNIX, faire cela causera une erreur.
POSIX.1-2001 indique que les valeurs renvoyées par sysconf(3) ne doivent pas changer pendant la vie d'un processus. Cependant, depuis Linux 2.6.23, si la limite de ressources RLIMIT_STACK change, alors la valeur renvoyée par _SC_ARG_MAX changera également, pour refléter le fait que la limite de l'espace qui reçoit les paramètres de la ligne de commande et les variables d'environnement a changé.
Avec UNIX V6, la liste des arguments d'un appel exec() se terminait par 0, alors que la liste des arguments de main se terminait par -1. Aussi, cette liste d'arguments n'était pas utilisable directement dans un appel exec() supplémentaire. Depuis UNIX V7, les deux terminateurs sont NULL.
Le programme suivant est conçu pour être exécuté par le second programme ci‐dessous. Il se contente d'afficher les paramètres de sa ligne de commande, un par ligne.
/* myecho.c */
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char *argv[])
{
int j;
for (j = 0; j < argc; j++)
printf("argv[%d]: %s\n", j, argv[j]);
exit(EXIT_SUCCESS);
}
Ce programme peut être utilisé pour exécuter
le programme donné comme argument de ligne de commande :
/* execve.c */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int
main(int argc, char *argv[])
{
char *newargv[] = { NULL, "hello", "world", NULL };
char *newenviron[] = { NULL };
if (argc != 2) {
fprintf(stderr, "Usage: %s <file-to-exec>\n", argv[0]);
exit(EXIT_FAILURE);
}
newargv[0] = argv[1];
execve(argv[1], newargv, newenviron);
perror("execve"); /* execve() ne retourne qu'en cas d'erreur */
exit(EXIT_FAILURE);
}
On peut utiliser le second programme pour exécuter le premier de la façon suivante :
$ cc myecho.c -o myecho $ cc execve.c -o execve $ ./execve ./myecho argv[0]: ./myecho argv[1]: hello argv[2]: world
On peut aussi utiliser ces programmes pour montrer l'utilisation d'un interpréteur de scripts. Pour ce faire, on crée un script dont l'« interpréteur » est notre programme myecho :
$ cat > script.sh #! ./myecho script-arg ^D $ chmod +x script.sh
On peut alors utiliser notre programme pour exécuter le script :
$ ./execve ./script.sh argv[0]: ./myecho argv[1]: script-arg argv[2]: ./script.sh argv[3]: hello argv[4]: world
chmod(2), fork(2), ptrace(2), execl(3), fexecve(3), getopt(3), credentials(7), environ(7), path_resolution(7), ld.so(8)
Cette page fait partie de la publication 3.65 du projet man-pages Linux. Une description du projet et des instructions pour signaler des anomalies peuvent être trouvées à l'adresse http://www.kernel.org/doc/man-pages/.
Depuis 2010, cette traduction est maintenue à l'aide de l'outil po4a <http://po4a.alioth.debian.org/> par l'équipe de traduction francophone au sein du projet perkamon <http://perkamon.alioth.debian.org/>.
Christophe Blaess <http://www.blaess.fr/christophe/> (1996-2003), Alain Portal <http://manpagesfr.free.fr/> (2003-2006). Julien Cristau et l'équipe francophone de traduction de Debian (2006-2009).
Veuillez signaler toute erreur de traduction en écrivant à <debian-l10n-french@lists.debian.org> ou par un rapport de bogue sur le paquet manpages-fr.
Vous pouvez toujours avoir accès à la version anglaise de ce document en utilisant la commande « man -L C <section> <page_de_man> ».