Provided by: manpages-de-dev_4.21.0-2_all bug

BEZEICHNUNG

       execve - Programm ausführen

BIBLIOTHEK

       Standard-C-Bibliothek (libc, -lc)

ÜBERSICHT

       #include <unistd.h>

       int execve(const char *Pfadname, char *const _Nullable argv[],
                  char *const _Nullable 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.

       Diese Handbuchseite beschreibt den Linux-Systemaufruf im Detail; für einen Überblick über die Nomenklatur
       und   die   vielen,  oft  zu  bevorzugenden,  durch  Libc  bereitgestellten  Varianten  dieser  Funktion,
       einschließlich der, die die Umgebungsvariable PATH durchsuchen, siehe exec(3).

       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  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 Linux 2.6.23 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 Linux 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 Linux 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  MiB) begrenzt. Seit Linux 2.6.25 stellt der Kernel auch 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.22 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  gesetzt,  um
       den Fehler anzuzeigen.

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.

STANDARDS

       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  Linux   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 (size_t j = 0; j < argc; j++)
                   printf("argv[%zu]: %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[])
           {
               static char *newargv[] = { NULL, "Hallo", "Welt", NULL };
               static 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),  getauxval(3),
       getopt(3), system(3), capabilities(7), credentials(7), environ(7), path_resolution(7), ld.so(8)

Ü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⟩.