Provided by: manpages-de-dev_4.13-4_all bug

BEZEICHNUNG

       execve - Programm ausführen

ÜBERSICHT

       #include <unistd.h>

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

BESCHREIBUNG

       execve()  führt das Programm aus, auf das sich Pfadname bezieht. Dies führt dazu, dass das
       Programm, das derzeit vom aufrufenden Prozess ausgeführt wird, durch ein  neues  Programm,
       mit  einem  frisch initialisierten Stack, Heap und (initialisierten und uninitialisierten)
       Datensegmenten ersetzt wird.

       Pfadname muss entweder ein binäres ausführbares Programm oder ein  Skript  sein,  das  mit
       einer Zeile der folgenden Form beginnt:

           #!Interpreter [Optionale-Arg]

       Einzelheiten zu letzterem Fall finden Sie in »Interpreter-Skripte« weiter unten.

       argv  ist  ein  Feld  von  Zeigern  auf Zeichenketten, die an das neue Programm als dessen
       Befehlszeilenargumente  übergeben  werden.  Per  Konvention  sollte   die   erste   dieser
       Zeichenketten  (d.h.  argv[0])  den  Dateinnamen,  der  zu  der ausgeführten Datei gehört,
       enthalten. Das Feld argv muss durch einen NULL-Zeiger beendet werden. (Daher wird  in  dem
       neuen Programm argv[argc] NULL sein.)

       envp  ist  ein Feld von Zeigern auf Zeichenketten, gewöhnlich von der Form Schlüssel=Wert,
       die an die Umgebung des neuen Programms übergeben werden. Das Feld envp muss  durch  einen
       NULL-Zeiger beendet werden.

       Auf  den  Argumentzeiger  und  die Umgebung kann von der Main-Funktion des neuen Programms
       zugegriffen werden, wenn sie wie folgt definiert ist:

           int main(int argc, char *argv[], char *envp[])

       Beachten Sie allerdings, dass die Verwendung eines dritten Arguments bei der Funktion main
       nicht  in  POSIX.1 spezifiziert ist; laut POSIX.1 sollte auf die Umgebung über die externe
       Variable environ(7) zugegriffen werden.

       execve() kehrt bei Erfolg nicht zurück und Text,  initialisierte  Daten,  uninitialisierte
       Daten  (bss)  und  Stack des aufrufenden Prozesses werden entsprechend des Inhalts des neu
       geladenen Programms überschrieben.

       Falls das aktuelle Programm mit  ptrace  verfolgt  wird,  wird  nach  einem  erfolgreichen
       execve() ein Signal SIGTRAP an es gesandt.

       Falls  bei  der  Programmdatei, auf die sich Pfadname bezieht, das Bit set-user-ID gesetzt
       ist, dann wird  die  effektive  Benutzerkennung  des  aufrufenden  Programms  zu  der  des
       Eigentümers  der  Programmdatei  geändert.  Ähnlich  wird die effektive Gruppenkennung des
       aufrufenden Prozesses auf die Gruppe der Programmdatei gesetzt, wenn das Bit  set-group-ID
       auf der Programmdatei gesetzt ist.

       Die vorgenannten Umwandlungen der effektiven Kennungen werden nicht durchgeführt (d.h. die
       Bits set-user-ID und set-group-ID werden ignoriert), falls  eine  der  folgenden  Aussagen
       wahr ist:

       *  Das Attribut no_new_privs wird für den aufrufenden Thread gesetzt (siehe prctl(2)).

       *  Das  unterliegende  Dateisystem  ist  nosuid  eingehängt  (der  Schalter  MS_NOSUID für
          mount(2)).

       *  Der aufrufende Prozess wird mit ptrace verfolgt.

       Die Capabilities der Programmdatei (siehe capabilities(7))  werden  auch  ignoriert,  wenn
       eine der obigen Bedingungen zutrifft.

       Die  effektive Benutzerkennung des Prozesses wird in die gespeicherte set-user-ID kopiert.
       Ähnlich wird die effektive Gruppenkennung in die gespeicherte set-group-ID kopiert. Dieses
       Kopieren  findet  nach  allen  effektiven  ID-Änderungen statt, die aufgrund der Modusbits
       set-user-ID und set-group-ID erfolgen.

       Die reale UID und reale GID des Prozesses sowie die zusätzlichen  Gruppenkennungen  ändern
       sich beim Aufruf von execve() nicht.

       Falls  das  Programm  eine  dynamisch  gelinkte  Programmdatei  im  a.out-Format  ist, die
       dynamische Bibliotheken-Stubs enthält, dann wird der dynamische Linker ld.so(8) von  Linux
       am  Anfang der Ausführung aufgerufen, um die benötigten Laufzeitobjekte in den Speicher zu
       bringen und das Programm mit ihnen zu verlinken.

       Falls das Programm ein dynamisch gelinktes ELF-Programm  ist,  wird  der  in  dem  Segment
       PT_INTERP  benannte  Interpreter  zum  Laden  der  gemeinsamen  Objekte  verwandt.  Dieser
       Interpreter ist typischerweise /lib/ld-linux.so.2 für Programme, die mit der Glibc gelinkt
       sind (siehe ld-linux.so(8)).

   Auswirkung auf Prozessattribute
       Alle  außer  den  nachfolgend  aufgeführten  Prozessattributen  werden  durch ein execve()
       erhalten:

       *  Die Zuordnung aller gefangenen Signale wird auf die Vorgabe zurückgesetzt (signal(7)).

       *  Alle alternativen Signal-Stacks werden nicht erhalten (sigaltstack(2)).

       *  Speicher-Mappings werden nicht erhalten (mmap(2)).

       *  Gemeinsam benutzte Speichersegmente vom Typ »System V« werden abgetrennt (shmat(2)).

       *  Mappings gemeinsamer Speicherbereiche gemäß POSIX werden aufgehoben (shm_open(3)).

       *  Offene POSIX-Nachrichtenwarteschlangendeskriptoren werden geschlossen (mq_overview(7)).

       *  Alle offenen benannten POSIX-Semaphoren werden geschlossen (sem_overview(7)).

       *  POSIX-Timer werden nicht erhalten (timer_create(2)).

       *  Alle offenen Verzeichnis-Streams werden geschlossen (opendir(3)).

       *  Speichersperren werden nicht erhalten (mlock(2), mlockall(2)).

       *  Exit-Handler werden nicht erhalten (atexit(3), on_exit(3)).

       *  Die Gleitkomma-Umgebung wird auf den Standardwert zurückgesetzt (siehe fenv(3)).

       Die Prozessattribute in der vorstehenden Liste sind  alle  in  POSIX.1  spezifiziert.  Die
       folgenden  Linux-spezifischen  Prozessattribute  werden  auch während eines execve() nicht
       erhalten:

       *  Das Attribut »dumpable« ist auf den Wert 1 gesetzt, außer ein set-user-ID-Programm, ein
          set-group-ID-Programm  oder  ein  Programm  mit Capabilitys wird ausgeführt, in welchem
          Fall der »dumpable«-Schalter stattdessen  unter  den  in  PR_SET_DUMPABLE  in  prctl(2)
          beschriebenen Umständen auf den Wert in /proc/sys/fs/suid_dumpable zurückgesetzt werden
          kann.  Beachten  Sie,  dass  Änderungen  am  Attribut  »dumpable«  zu  Änderungen   der
          Eigentümerschaft  von  Dateien  im  Verzeichnis /proc/[PID] des Prozesses auf root:root
          führen können, wie dies in proc(5) beschrieben ist.

       *  Der prctl(2)-Schalter PR_SET_KEEPCAPS wird auf 0 gesetzt.

       *  (Seit  Linux  2.4.36  /  2.6.23)  Falls  ein  set-user-ID-  oder  set-group-ID-Programm
          ausgeführt  wird,  dann  wird das durch den Schalter prctl(2) PR_SET_PDEATHSIG gesetzte
          Todessignal des Elternprozesses auf 0 gesetzt.

       *  Der Prozessname, wie  er  von  prctl(2)  PR_SET_NAME  gesetzt  (und  durch  ps -o  comm
          angezeigt) wird, wird auf den Namen des ausführbaren Programms zurückgesetzt.

       *  Der SECBIT_KEEP_CAPS Schalter securebits wird auf 0 gesetzt. Siehe capabilities(7).

       *  Das Terminierungssignal wird auf SIGCHLD zurückgesetzt (siehe clone(2)).

       *  Die  Dateideskriptortabelle  wird  getrennt,  der  Effekt des Schalters CLONE_FILES von
          clone(2) wird rückgängig gemacht.

       Beachten Sie die folgenden weiteren Punkte:

       *  Alle Threads außer dem aufrufenden werden  während  eines  execve()  zerstört.  Mutexe,
          Bedingungsvariablen und andere Pthread-Objekte werden nicht erhalten.

       *  Das Äquivalent von setlocale(LC_ALL, "C") wird beim Programmstart ausgeführt.

       *  POSIX.1  legt  fest,  dass  Zuordnungen  aller  ignorierten  oder  auf die Vorgabewerte
          gesetzten Signale unverändert bleiben. POSIX.1 legt eine Ausnahme fest:  Falls  SIGCHLD
          ignoriert  wird,  dann  darf eine Implementierung die Zuordnung unverändert lassen oder
          sie auf die Vorgabe zurücksetzen; Linux macht Ersteres.

       *  Alle  ausstehenden  asynchronen  E/A-Operationen   werden   abgebrochen   (aio_read(3),
          aio_write(3)).

       *  Für den Umgang mit Capabilities während execve(), siehe capabilities(7).

       *  Standardmäßig    bleiben    Dateideskriptoren   über   ein   execve()   hinweg   offen.
          Dateideskriptoren, die mit close-on-exec markiert sind, werden geschlossen;  siehe  die
          Beschreibung  von  FD_CLOEXEC in fcntl(2). (Falls ein Dateideskriptor geschlossen wird,
          führt dies zur Freigabe aller von der unterliegenden Datei durch den Prozess erhaltenen
          Datensatzsperren.  Siehe fcntl(2) für Details.) Laut POSIX.1 darf das System eine nicht
          festgelegte Datei für jeden der Dateideskriptoren  0,  1  und  2  öffnen,  falls  diese
          andernfalls  nach einem erfolgreichen execve() geschlossen und der Prozess aufgrund der
          Modus-Bits set-user-ID oder set-group-ID Privilegien erhalten  würde.  Als  allgemeines
          Prinzip  darf  kein portables Programm, egal ob privilegiert oder nicht, annehmen, dass
          diese drei Dateideskriptoren über ein execve() geschlossen bleiben.

   Interpreter-Skripte
       Ein Interpreter-Skript ist eine Textdatei, die über Ausführrechte verfügt und dessen erste
       Zeile die folgende Form annimmt:

           #!Interpreter [Optionale-Arg]

       Der Interpreter muss ein gültiger Pfadname zu einer ausführbaren Datei sein.

       Falls  das  Argument  Pfadname  von  execve()  ein  Interpreterskript  festlegt, dann wird
       interpreter mit den folgenden Argumenten aufgerufen.

           Interpreter [Optionale-Arg] Pfadname Arg …

       Hierbei ist Pfadname der absolute Pfadname der Datei, die als erstes Argument von execve()
       festgelegt  ist,  und  arg…  die Serie von Wörtern, auf die vom Argument argv von execve()
       gezeigt wird, beginnen mit argv[1]. Beachten Sie, dass es keine Möglichkeit gibt, argv[0],
       der dem Aufruf execve() übergeben wurde, zu erhalten.

       Für  den  portablen Einsatz sollte Optionale-Arg entweder abwesend oder als einzelnes Wort
       angegeben werden (d.h. es  sollte  keine  Leerraumzeichen  enthalten);  siehe  ANMERKUNGEN
       unten.

       Seit  Linux 2.6.28 erlaubt es der Kernel, dass der Interpreter eines Skripts selbst wieder
       ein Skript ist. Diese Erlaubnis ist rekursiv bis zu einer Rekursionstiefe von 4,  so  dass
       der  Interpreter  ein  Skript  sein  darf,  das von einem Skript interpretiert wird und so
       weiter.

   Begrenzungen der Größe der Argumente und der Umgebung
       Die meisten UNIX-Implementierungen verhängen  eine  Begrenzung  für  die  Gesamtgröße  der
       Zeichenketten  der Befehlszeilenargumente (argv) und der Umgebung (envp), die an ein neues
       Programm übergeben werden darf. POSIX.1 erlaubt es einer Implementierung, diese Begrenzung
       mit  der  Konstante  ARG_MAX  bekanntzugeben  (entweder  definiert  in <limits.h> oder zur
       Laufzeit mit dem Aufruf sysconf(_SC_ARG_MAX) verfügbar).

       Vor Kernel 2.6.23 unter Linux war  der  Speicher,  der  zum  Ablegen  der  Umgebungs-  und
       Argumentzeichenketten  verwandt  wurde,  auf  32  Seiten  begrenzt  (definiert  durch  die
       Kernelkonstante MAX_ARG_PAGES). Auf Architekturen mit einer 4-kB-Seitengröße führt dies zu
       einer Maximalgröße von 128 kB.

       Auf  den  meisten  Architekturen wird unter Kernel 2.6.23 und neuer eine Größenbegrenzung,
       die von der Ressourcenbegrenzung RLIMIT_STACK (siehe getrlimit(2)) abgeleitet ist, die zum
       Zeitpunkt   des   Aufrufs   execve()   in  Kraft  war,  unterstützt.  (Architekturen  ohne
       Speicherverwaltungseinheit sind die Ausnahme: bei ihnen bleibt die Begrenzung, die vor dem
       Kernel  2.6.23  in  Kraft  war.)  Diese  Änderung erlaubt es Programmen, eine viel größere
       Argumenten- und/oder Umgebungsliste zu haben. Für diese Architekturen ist die  Gesamtgröße
       auf  1/4  der  erlaubten  Stack-Größe  begrenzt. (Die Erzwingung der 1/4-Begrenzung stellt
       sicher, dass neue Programme  immer  über  Stack-Bereich  verfügen.)  Zusätzlich  wird  die
       Gesamtgröße  auf 3/4 des Wertes der Kernelkonstanten _STK_LIM (8 Mibibytes) begrenzt. Seit
       Linux 2.6.25 stellt auch der Kernel eine  Untergrenze  von  32  Seiten  dieser  Begrenzung
       bereit,  so  dass  selbst  wenn  RLIMIT_STACK sehr gering ist, Anwendungen garantiert über
       mindestens so viel Argument- und Umgebungsbereich verfügen, wie dies  unter  Linux  2.6.23
       und  älter  der  Fall  war.  (Diese  Garantie  wurde  nicht  unter Linux 2.6.23 und 2.6.24
       erfüllt.) Zusätzlich ist die Begrenzung pro Zeichenkette 32 Seiten  (der  Kernelkonstanten
       MAX_ARG_STRLEN) und die maximale Anzahl von Zeichenketten ist 0x7FFFFFFF.

RÜCKGABEWERT

       Im  Erfolgsfall  kehrt  execve()  nicht  zurück, im Fehlerfall wird -1 zurückgeliefert und
       errno entsprechend gesetzt.

FEHLER

       E2BIG  Die Gesamtanzahl von Bytes in der Umgebungs- (envp) und der Argumentenliste  (argv)
              ist zu groß.

       EACCES Für einen Teil des Pfadpräfixes von Pfadname oder dem Namen des Skript-Interpreters
              wird die Suchberechtigung verweigert. (Siehe auch path_resolution(7).)

       EACCES Die Datei oder der Skriptinterpreter ist keine reguläre Datei.

       EACCES Für die Datei oder ein Skript oder  ELF-Interpreter  wird  die  Ausführberechtigung
              verweigert.

       EACCES Das Dateisystem ist nicht noexec eingehängt.

       EAGAIN (seit Linux 3.1)
              Nach  Änderung  der  realen  UID  mittels einer der Aufrufe set*uid() war – und ist
              immer noch – der Aufrufende über  seine  Ressourcenbegrenzung  RLIMIT_NPROC  (siehe
              setrlimit(2)).   Für   eine   detailliertere   Erläuterung   dieses  Fehlers  siehe
              ANMERKUNGEN.

       EFAULT Pfadname oder einer der Zeiger in den Vektoren argv oder envp zeigt aus dem für Sie
              zugänglichen Adressraum heraus.

       EINVAL Ein  ELF-Programm hat mehr als ein PT_INTERP-Segment (d.h. versuchte mehr als einen
              Interpreter anzugeben).

       EIO    Es ist ein E/A-Fehler (engl. I/O) aufgetreten.

       EISDIR Ein ELF-Interpreter war ein Verzeichnis.

       ELIBBAD
              Ein ELF-Interpreter war in einem unbekannten Format.

       ELOOP  Beim Auflösen von Pfadname oder  dem  Namen  eines  Skripts  oder  ELF-Interpreters
              wurden zu viele symbolische Links ermittelt.

       ELOOP  Während  der  rekursiven  Skript-Interpretation  (siehe »Interpreter-Skripte« oben)
              wurde die maximale Rekursionsbegrenzung erreicht. Vor Linux  3.8  wurde  in  diesem
              Fall der Fehler ENOEXEC erstellt.

       EMFILE Die Beschränkung pro Prozess der Anzahl offener Datei-Deskriptoren wurde erreicht.

       ENAMETOOLONG
              Pfadname ist zu lang.

       ENFILE Die systemweite Beschränkung für die Gesamtzahl offener Dateien wurde erreicht.

       ENOENT Die Datei Pfadname oder ein Skript oder ELF-Interpreter existiert nicht.

       ENOEXEC
              Ein Programm ist nicht in einem erkennbaren Format, ist für die falsche Architektur
              oder hat einen anderen Formatfehler, wodurch es nicht ausgeführt werden kann.

       ENOMEM Es war nicht genügend Kernelspeicher verfügbar.

       ENOTDIR
              Ein Teil des Pfadpräfixes von Pfadname oder ein  Skript  oder  ELF-Interpreter  ist
              kein Verzeichnis.

       EPERM  Das Dateisystem ist nosuid eingehängt, der Benutzer ist nicht der Superuser und die
              Datei hat das Bit set-user-ID oder set-group-ID gesetzt.

       EPERM  Der Prozess wird verfolgt, der Benutzer ist nicht der Superuser und die  Datei  hat
              das Bit set-user-ID oder set-group-ID gesetzt.

       EPERM  Eine   »Capability-unfähige«   Anwendung  würde  nicht  die  ganze  Menge  der  vom
              ausführbaren   Programm   gewährten   erlaubten   Capabilities   erhalten.    Siehe
              capabilities(7).

       ETXTBSY
              Das angegebene Programm war für einen oder mehrere Prozesse zum Schreiben offen.

KONFORM ZU

       POSIX.1-2001,  POSIX.1-2008,  SVr4,  4.3BSD. POSIX dokumentiert das #!-Verhalten nicht, es
       existiert aber (mit einigen Variationen) auf anderen UNIX-Systemen.

ANMERKUNGEN

       Manchmal wird execve() (und die in exec(3)  beschriebenen  dazugehörigen  Funktionen)  als
       »Ausführung  eines  neuen  Prozesses« (oder ähnlich) beschrieben. Dies ist eine hochgradig
       irreführende Beschreibung: es gibt keinen neuen Prozess, viele Attribute  des  aufrufenden
       Prozesses  bleiben  unverändert  (insbesondere  seine PID). execve() arrangiert lediglich,
       dass ein existierender Prozess (der aufrufende Prozess) ein neues Programm ausführt.

       Set-user-ID- und Set-group-ID-Prozesse können nicht mit ptrace(2) verfolgt werden.

       Das Ergebnis des Einhängens eines Dateisystems mit nosuid unterscheidet sich abhängig  von
       der  Linux-Kernelversion. Unter einigen wird die Ausführung von Programmen mit set-user-ID
       und set-group-ID verweigert, wenn das dem  Benutzer  Rechte  geben  würde,  die  er  nicht
       bereits  hatte  (und  EPERM  zurückliefern). Unter anderen werden die Bits set-user-ID und
       set-group-ID ignoriert und exec() erfolgreich ausgeführt.

       Unter Linux können argv und envp als NULL festgelegt werden. In beiden Fällen hat dies den
       gleichen  Effekt wie die Festlegung des Arguments auf einen Zeiger auf eine Liste, die als
       einziges Element den NULL-Zeiger enthält. Nutzen Sie diese nicht standardisierte und nicht
       portable  Misfunktionalität nicht aus! Unter vielen UNIX-Systemen führt die Festlegung von
       argv als NULL zu einem Fehler (EFAULT). Einige  andere  UNIX-Systeme  behandeln  den  Fall
       envp==NULL wie Linux.

       POSIX.1 besagt, dass die von sysconf(3) zurückgelieferten Werte über die Lebensdauer eines
       Prozesses unveränderlich sein sollen. Seit 2.6.23 wird der von _SC_ARG_MAX berichtete Wert
       sich  allerdings  auch  ändern, wenn die Ressourcenbegrenzung RLIMIT_STACK sich ändert, um
       die  Tatsache  zu  berücksichtigen,  dass  die  Begrenzung  des  Platzes  zum  Halten  der
       Befehlszeilenargumente und der Umgebungsvariablen sich geändert hat.

       In  den  meisten  Fällen,  in  denen  execve()  fehlschlägt,  kehrt  die  Steuerung zu dem
       ursprünglichen Abbild zurück und der Aufrufende von execve() kann mit dem Fehler  umgehen.
       In  (seltenen)  Fällen  kann  (typischerweise  durch Ressourcenerschöpfung verursacht) der
       Fehlschlag den Punkt ohne Rückkehr  passieren:  das  ursprüngliche  Abbild  wurde  bereits
       entfernt  aber  das  neue  Abbild  konnte  nicht  komplett gebaut werden. In diesen Fällen
       beendet der Kernel den Prozess mit einem Signal SIGSEGV (SIGKILL bis Linux 3.17).

   Interpreter-Skripte
       Der Kernel legt eine maximal Länge für Text, der den Zeichen »#!« am Anfang eines Skriptes
       folgt,  auf.  Zeichen  hinter  dieser  Begrenzung  werden ignoriert. Vor Linux 5.1 war die
       Begrenzung 127 Zeichen, seit Linux 5.1 ist die Begrenzung 255 Zeichen.

       Die Semantik des Arguments Optionale-Args  eines  Interpreterskriptes  unterscheidet  sich
       zwischen  Implementierungen.  Unter  Linux  wird die gesamte Zeichenkette, die Interpreter
       folgt, als einziges Argument an den Interpreter  übergeben  und  diese  Zeichenkette  kann
       Leerzeichen enthalten. Das Verhalten unterscheidet sich aber auf einigen anderen Systemen.
       Einige Systeme verwenden das erste Leerzeichen, um Optionale-Args zu beenden. Auf  einigen
       Systemen   kann   ein   Interpreterskript  mehrere  Argumente  haben  und  Leerzeichen  in
       Optionale-Args werden zum Begrenzen der Argumente verwandt.

       Linux (wie die meisten anderen modernen UNIX-Systeme) ignoriert die Bits  set-user-ID  und
       set-group-ID bei Skripten.

   execve() und EAGAIN
       Eine  detailliertere Beschreibung des Fehlers EAGAIN, der (seit Linux 3.1) beim Aufruf von
       execve() auftreten kann, ist wie folgt:

       Der  Fehler  EAGAIN  kann  auftreten,  wenn  ein  vorhergehender  Aufruf  von   setuid(2),
       setreuid(2)  oder  setresuid(2)  dazu führte, dass die reale Benutzerkennung des Prozesses
       geändert   wurde   und   diese   Änderung   dazu   führte,   dass   der   Prozess    seine
       Ressourcenbeschränkung  RLIMIT_NPROC  überschritt (d.h. die Anzahl der zu der neuen realen
       UID gehörenden Prozesse überschreitet die Ressourcenbeschränkung). Von Linux 2.6.0 bis 3.0
       führte   dies   dazu,   dass   der   Aufruf  set*uid()  fehlschlug.  (Vor  2.6  wurde  die
       Ressourcenbeschränkung  bei  Prozessen,  die  ihre   Benutzerkennungen   änderten,   nicht
       durchgesetzt.)

       Seit  Linux  3.1  schlägt  in dem gerade beschriebenen Szenario der Aufruf set*uid() nicht
       mehr fehl, da dies zu oft zu Sicherheitslöchern führte, bei denen fehlerhafte  Anwendungen
       nicht den Rückgabewert prüften und annahmen, dass – falls der Aufrufende Root-Rechte hatte
       – der Aufruf immer erfolgreich sein würde. Stattdessen ändert der Aufruf  set*uid()  jetzt
       erfolgreich  die  reale  UID,  aber  der  Kernel  setzt  einen  internen  Schalter  namens
       PF_NPROC_EXCEEDED,  um  zu  vermerken,  dass   die   Ressourcenbeschränkung   RLIMIT_NPROC
       überschritten   wurde.   Falls   der   Schalter  PF_NPROC_EXCEEDED  gesetzt  ist  und  die
       Ressourcenbeschränkung  zum  Zeitpunkt  eines  folgenden   execve()-Aufrufs   immer   noch
       überschritten  ist,  dann  schlägt  dieser  Aufruf  mit  dem  Fehler  EAGAIN  fehl.  Diese
       Kernellogik stellt sicher, dass die Ressourcenbeschränkung RLIMIT_NPROC für  den  häufigen
       Ablauf  bei  privilegierten  Daemons  –  also  fork(2)  + set*uid() + execve() – weiterhin
       durchgesetzt wird.

       Falls die Ressourcenbegrenzung zum Zeitpunkt des Aufrufs execve() noch nicht überschritten
       wurde  (da  andere  zu  dieser  realen UID gehörende Prozesse sich zwischen dem Aufruf von
       set*uid() und dem Aufruf von execve() beendeten), dann gelingt der Aufruf und  der  Kernel
       bereinigt  den  Prozessschalter  PF_NPROC_EXCEEDED.  Der Schalter wird auch auf 0 gesetzt,
       falls ein folgender Aufruf von fork(2) durch diesen Prozess gelingt.

   Geschichtliches
       Unter UNIX V6 wurde die Argumentenliste von einem exec()-Aufruf durch 0  beendet,  während
       die Argumentenliste von main durch -1 beendet wurde. Daher war diese Argumentenliste nicht
       für weitere exec()-Aufrufe direkt verwendbar. Seit UNIX V7 sind beide NULL.

BEISPIELE

       Das folgende Programm ist dafür gedacht, vom  zweiten  folgenden  Programm  ausgeführt  zu
       werden. Es gibt nur seine Befehlszeile (eine pro Zeile) wieder aus.

           /* myecho.c */

           #include <stdio.h>
           #include <stdlib.h>

           int
           main(int argc, char *argv[])
           {
               for (int j = 0; j < argc; j++)
                   printf("argv[%d]: %s\n", j, argv[j]);

               exit(EXIT_SUCCESS);
           }

       Dieses  Programm  kann  zur  Ausführung  des  in  seinem  Befehlszeilenargument  benannten
       Programms verwandt werden:

           /* execve.c */

           #include <stdio.h>
           #include <stdlib.h>
           #include <unistd.h>

           int
           main(int argc, char *argv[])
           {
               char *newargv[] = { NULL, "Hallo", "Welt", NULL };
               char *newenviron[] = { NULL };

               if (argc != 2) {
                printf(stderr, "Aufruf: %s <auszuführende-Datei>\n", argv[0]);
                exit(EXIT_FAILURE);
               }

               newargv[0] = argv[1];

               execve(argv[1], newargv, newenviron);
               perror("execve");   /* execve() kehrt nur im Fehlerfall zurück */
               exit(EXIT_FAILURE);
           }

       Wir können das zweite Programm verwenden, um das erste wie folgt aufzurufen:

           $ cc myecho.c -o myecho
           $ cc execve.c -o execve
           $ ./execve ./myecho
           argv[0]: ./myecho
           argv[1]: Hallo
           argv[2]: Welt

       Wir können diese Programme auch zur Demonstration der Verwendung eines Skript-Interpreters
       verwenden. Dafür erstellen wir ein Skript, dessen »Interpreter« unser myecho-Programm ist.

           $ cat > script
           #!./myecho script-arg
           ^D
           $ chmod +x script

       Wir können dann unser Programm verwenden, um das Skript auszuführen:

           $ ./execve ./script
           argv[0]: ./myecho
           argv[1]: script-arg
           argv[2]: ./script
           argv[3]: Hallo
           argv[4]: Welt

SIEHE AUCH

       chmod(2),   execveat(2),  fork(2),  get_robust_list(2),  ptrace(2),  exec(3),  fexecve(3),
       getopt(3), system(3),  capabilities(7),  credentials(7),  environ(7),  path_resolution(7),
       ld.so(8)

KOLOPHON

       Diese  Seite  ist  Teil  der  Veröffentlichung  5.10  des  Projekts  Linux-man-pages. Eine
       Beschreibung des Projekts, Informationen, wie Fehler  gemeldet  werden  können  sowie  die
       aktuelle Version dieser Seite finden sich unter https://www.kernel.org/doc/man-pages/.

ÜBERSETZUNG

       Die    deutsche    Übersetzung   dieser   Handbuchseite   wurde   von   Helge   Kreutzmann
       <debian@helgefjell.de> erstellt.

       Diese Übersetzung ist Freie Dokumentation;  lesen  Sie  die  GNU  General  Public  License
       Version  3 ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩ oder neuer bezüglich der Copyright-
       Bedingungen. Es wird KEINE HAFTUNG übernommen.

       Wenn Sie Fehler in der Übersetzung dieser Handbuchseite finden, schicken Sie bitte eine E-
       Mail an die Mailingliste der Übersetzer ⟨debian-l10n-german@lists.debian.org⟩.