Provided by: manpages-fr-dev_3.57d1p1-1_all bug

NOM

       execve - Exécuter un programme

SYNOPSIS

       #include <unistd.h>

       int execve(const char *filename, char *const argv[],
        char *const envp[]);

DESCRIPTION

       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 signaux pour lesquels le processus avait placé un gestionnaire sont réinitialisés à
          leur valeur par défaut (consultez signal(7)).

       *  L'éventuelle  pile  spécifique  pour  les  gestionnaires de signaux n'est pas conservée
          (sigaltstack(2)).

       *  Les projections en mémoire ne sont pas conservées (mmap(2)).

       *  Les segments de mémoire partagée System V sont détachés (shmat(2)).

       *  Les objets de mémoire partagée POSIX sont supprimés (shm_open(3)).

       *  Les descripteurs de files de messages POSIX ouverts sont fermés (mq_overview(7)).

       *  Les sémaphores nommés POSIX ouverts sont fermés (sem_overview(7)).

       *  Les temporisations POSIX ne sont pas conservées (timer_create(2)).

       *  Les flux de répertoires ouverts sont fermés (opendir(3)).

       *  Les verrouillages de mémoire ne sont pas préservés (mlock(2), mlockall(2)).

       *  Les gestionnaires de terminaison ne sont pas préservés (atexit(3), on_exit(3)).

       *  L'environnement de travail en virgule flottante est remis à zéro (consultez fenv(3)).

       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() :

       *  L'attribut PR_SET_DUMPABLE de prctl(2) est activé,  sauf  si  un  programme  setuid  ou
          setgid est exécuté, auquel cas il est désactivé.

       *  L'attribut PR_SET_KEEPCAPS de prctl(2) est effacé.

       *  (Depuis  Linux 2.4.36 ou 2.6.23) Si un programme setuid ou setgid est exécuté, alors le
          signal de mort de son père défini  par  l'attribut  PR_SET_PDEATHSIG  de  prctl(2)  est
          effacé.

       *  Le  nom du processus, positionné par prctl(2) PR_SET_NAME (et affiché avec ps -o comm),
          est réinitialisé avec le nom du nouvel exécutable.

       *  L'attribut   securebits   SECBIT_KEEP_CAPS   de   prctl()   est    effacé.    Consultez
          capabilities(7).

       *  Le signal de terminaison est réinitialisé à SIGCHLD (consultez clone(2)).

       Notez également les points suivants :

       *  Tous  les threads autre que l'appelant sont détruits lors d'un execve(). Les mutex, les
          variables de condition, et les autres objets de pthreads sont détruits.

       *  L'équivalent de setlocale(LC_ALL, "C") est exécuté au démarrage du programme.

       *  POSIX.1-2001 indique que les actions pour les signaux ignorés ou placés à la valeur par
          défaut ne sont pas modifiées. Une exception est néanmoins spécifiée dans POSIX.1-2001 :
          si SIGCHLD est ignoré, l'implémentation peut laisser l'action inchangée ou la  replacer
          à la valeur par défaut ; Linux ne modifie pas l'action.

       *  Toutes   les   opérations  d'E/S  asynchrones  en  cours  sont  annulées  (aio_read(3),
          aio_write(3)).

       *  Pour le traitement des capacités lors d'un execve(), consultez capabilities(7).

       *  Par défaut, les descripteurs de fichier restent ouverts au travers d'un  execve().  Les
          descripteurs marqués close‐on‐exec sont fermés ; consultez la description de FD_CLOEXEC
          dans fcntl(2). (Si un descripteur de fichier est fermé, cela  cause  la  libération  de
          tous  les  verrous  d'enregistrement  obtenus  sur  le  fichier  correspondant  par  ce
          processus. Consultez fcntl(2) pour  les  détails.)  POSIX.1-2001  indique  que  si  les
          descripteurs de fichiers 0, 1 et 2 devaient être fermés après un execve() réussi, et le
          processus devient privilégié en raison d'un bit  set-user-ID  ou  set-group-ID  sur  le
          fichier  exécuté,  le  système  peut  ouvrir  un fichier non indiqué pour chacun de ces
          descripteurs. En général, un programme portable, privilégié ou pas, peut considérer que
          ces trois descripteurs resteront fermés après un execve().

   Scripts
       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.

   Limites sur la taille des paramètres et environnement
       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.

VALEUR RENVOYÉE

       En cas de réussite, execve() ne revient pas,  en  cas  d'échec  il  renvoie  -1  et  errno
       contient le code d'erreur.

ERREURS

       E2BIG  Le nombre total d'octets dans l'environnement (envp) et la liste d'arguments (argv)
              est trop grand.

       EACCES La permission de parcours est refusée pour un des composants du chemin filename  ou
              du nom d'un interpréteur de script. (Consultez aussi path_resolution(7).)

       EACCES Le fichier ou l'interpréteur de script n'est pas un fichier régulier.

       EACCES L'autorisation  d'exécution  est  refusée  pour  le  fichier, ou un interpréteur de
              script, ou un interpréteur ELF.

       EACCES Le système de fichiers est monté avec l'option noexec.

       EFAULT Le paramètre filename ou l'un des pointeurs du  vecteur  argv  ou  envp  pointe  en
              dehors de l'espace d'adressage accessible.

       EINVAL Un exécutable ELF a plusieurs segments PT_INTERP (indique plusieurs interpréteurs).

       EIO    Une erreur d'entrée-sortie s'est produite.

       EISDIR L'interpréteur ELF cité est un répertoire.

       ELIBBAD
              L'interpréteur ELF mentionné n'est pas dans un format connu.

       ELOOP  Le  chemin  d'accès  au  fichier  filename, ou à un interpréteur de script, ou à un
              interpréteur ELF, contient une référence circulaire (à travers un lien symbolique)

       EMFILE Le nombre maximal de fichiers ouverts par processus est atteint.

       ENAMETOOLONG
              La chaîne de caractères filename est trop longue.

       ENFILE La limite du nombre total de fichiers ouverts sur le système a été atteinte.

       ENOENT Le fichier filename ou un script ou  un  interpréteur  ELF  n'existe  pas,  ou  une
              bibliothèque  partagée  nécessaire  pour  le  fichier  ou  l'interpréteur n'est pas
              disponible.

       ENOEXEC
              Le fichier exécutable n'est pas dans le bon format, ou  est  destiné  à  une  autre
              architecture.

       ENOMEM Pas assez de mémoire pour le noyau.

       ENOTDIR
              Un  élément du chemin d'accès au fichier filename, à un script ou à un interpréteur
              ELF, n'est pas un répertoire.

       EPERM  Le système de fichiers est monté avec l'attribut nosuid et  le  fichier  a  un  bit
              Set-UID ou Set-GID positionné.

       EPERM  Le processus est suivi avec ptrace(2), l'utilisateur n'est pas le superutilisateur,
              et le fichier a un bit Set-UID ou Set-GID positionné.

       ETXTBSY
              Un exécutable a été ouvert en écriture par un ou plusieurs processus.

CONFORMITÉ

       SVr4, BSD 4.3, POSIX.1-2001. POSIX.1-2001 ne documente pas  le  comportement  avec  « #! »
       mais est néanmoins compatible.

NOTES

       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é.

   Historique
       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.

EXEMPLE

       Le programme suivant est conçu pour être exécuté par le second programme ci‐dessous. Il se
       contente d'afficher sa ligne de commande, un argument 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

VOIR AUSSI

       chmod(2), fork(2), ptrace(2), execl(3), fexecve(3), getopt(3), credentials(7), environ(7),
       path_resolution(7), ld.so(8)

COLOPHON

       Cette page fait partie de la publication 3.57 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/.

TRADUCTION

       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> ».