Systemaufrufe

Linux Exec-Systemaufruf

Linux Exec-Systemaufruf

Der exec-Systemaufruf wird verwendet, um eine Datei auszuführen, die sich in einem aktiven Prozess befindet. Beim Aufruf von exec wird die vorherige ausführbare Datei ersetzt und die neue Datei ausgeführt.

Genauer gesagt können wir sagen, dass die Verwendung des exec-Systemaufrufs die alte Datei oder das Programm aus dem Prozess durch eine neue Datei oder ein neues Programm ersetzt. Der gesamte Inhalt des Prozesses wird durch ein neues Programm ersetzt.

Das Benutzerdatensegment, das den Systemaufruf exec() ausführt, wird durch die Datendatei ersetzt, deren Name beim Aufruf von exec() im Argument angegeben wird.

Das neue Programm wird in den gleichen Prozessraum geladen. Der aktuelle Prozess wird nur in einen neuen Prozess umgewandelt und daher wird die Prozess-ID-PID nicht geändert, da wir keinen neuen Prozess erstellen, sondern nur einen Prozess durch einen anderen Prozess in exec process ersetzen.

Enthält der aktuell laufende Prozess mehr als einen Thread, werden alle Threads beendet und das neue Prozessabbild geladen und anschließend ausgeführt. Es gibt keine Destruktorfunktionen, die Threads des aktuellen Prozesses beenden.

Die PID des Prozesses wird nicht geändert, aber die Daten, der Code, der Stapel, der Heap usw. des Prozesses werden geändert und durch die des neu geladenen Prozesses ersetzt. Der neue Prozess wird vom Einstiegspunkt ausgeführt.

Der Systemaufruf Exec ist eine Sammlung von Funktionen und in der Programmiersprache C lauten die Standardnamen für diese Funktionen wie folgt:

  1. ausschließen
  2. ausführen
  3. execlp
  4. leitender Angestellter
  5. ausführen
  6. execvp


Dabei ist zu beachten, dass diese Funktionen die gleiche Basis haben ausführender gefolgt von einem oder mehreren Buchstaben. Diese werden im Folgenden erläutert:

e: Es ist ein Array von Zeigern, das auf Umgebungsvariablen zeigt und explizit an den neu geladenen Prozess übergeben wird.

Ich: l ist für die Befehlszeilenargumente, die eine Liste an die Funktion übergeben

p: p ist die Pfadumgebungsvariable, die hilft, die als Argument übergebene Datei zu finden, die in den Prozess geladen werden soll.

v: v steht für die Befehlszeilenargumente. Diese werden als Array von Zeigern an die Funktion übergeben.

Warum wird Exec verwendet??

exec wird verwendet, wenn der Benutzer eine neue Datei oder ein neues Programm im selben Prozess starten möchte.

Innere Arbeitsweise von exec

Beachten Sie die folgenden Punkte, um die Funktionsweise von exec zu verstehen:

  1. Aktuelles Prozessabbild wird mit einem neuen Prozessabbild überschrieben.
  2. Das neue Prozessabbild ist dasjenige, das Sie als exec-Argument übergeben haben
  3. Der aktuell laufende Prozess wird beendet
  4. Neues Prozessabbild hat gleiche Prozess-ID, gleiche Umgebung und gleichen Dateideskriptor (weil Prozess nicht ersetzt wird Prozessabbild wird ersetzt)
  5. Der CPU-Status und der virtuelle Speicher sind betroffen. Das virtuelle Speichermapping des aktuellen Prozessabbilds wird durch den virtuellen Speicher des neuen Prozessabbilds ersetzt.

Syntaxen von Exec-Familienfunktionen:

Im Folgenden sind die Syntaxen für jede Funktion von exec aufgeführt:

int execl(const char* path, const char* arg,…)
int execlp(const char* Datei, const char* arg,…)
int execle(const char* path, const char* arg,… , char* const envp[])
int execv(const char* path, const char* argv[])
int execvp(const char* Datei, const char* argv[])
int execvpe(const char* file, const char* argv[], char *const envp[])

Beschreibung:

Der Rückgabetyp dieser Funktionen ist Int. Wenn das Prozessabbild erfolgreich ersetzt wurde, wird nichts an die aufrufende Funktion zurückgegeben, da der Prozess, der sie aufgerufen hat, nicht mehr ausgeführt wird. Aber wenn es einen Fehler gibt, wird -1 zurückgegeben. Wenn ein Fehler aufgetreten ist und Fehler ist eingestellt.

In der Syntax:

  1. Pfad wird verwendet, um den vollständigen Pfadnamen der auszuführenden Datei anzugeben.
  1. arg ist das Argument übergeben. Es ist eigentlich der Name der Datei, die dabei ausgeführt wird. Meistens ist der Wert von arg und path gleich.
  1. const char* arg in den Funktionen wird execl(), execlp() und execle() als arg0, arg1, arg2,… ​​, argn . betrachtet. Es ist im Grunde eine Liste von Zeigern auf nullterminierte Strings. Hier zeigt das erste Argument auf den Dateinamen, der wie in Punkt 2 beschrieben ausgeführt wird.
  1. envp ist ein Array, das Zeiger enthält, die auf die Umgebungsvariablen zeigen.
  1. Datei wird verwendet, um den Pfadnamen anzugeben, der den Pfad der neuen Prozessabbilddatei identifiziert.
  1. Die Funktionen von exec-Aufrufen, die mit enden e werden verwendet, um die Umgebung für das neue Prozessabbild zu ändern. Diese Funktionen übergeben die Liste der Umgebungseinstellungen mit dem Argument envp. Dieses Argument ist ein Array von Zeichen, das auf einen nullterminierten String zeigt und eine Umgebungsvariable definiert.

Um die Funktionen der exec-Familie zu verwenden, müssen Sie die folgende Header-Datei in Ihr C-Programm einbinden:

#einschließen

Beispiel 1: Verwendung des exec-Systemaufrufs in einem C-Programm

Betrachten Sie das folgende Beispiel, in dem wir den exec-Systemaufruf in der C-Programmierung in Linux, Ubuntu verwendet haben: Wir haben hier zwei c-Dateien Beispiel.c und hallo.c:

Beispiel.c

CODE:

#einschließen
#einschließen
#einschließen
int main(int argc, char *argv[])

printf("PID des Beispiels.c = %d\n", getpid());
char *args[] = "Hallo", "C", "Programmierung", NULL;
execv("./hallo", Argumente);
printf("Zurück zum Beispiel.c");
0 zurückgeben;

Hallo.c

CODE:

#einschließen
#einschließen
#einschließen
int main(int argc, char *argv[])

printf("Wir sind in Hallo.c\n");
printf("PID von hallo.c = %d\n", getpid());
0 zurückgeben;

AUSGABE:

PID des Beispiels.c = 4733
Wir sind in Hallo.c
PID von hallo.c = 4733

Im obigen Beispiel haben wir ein Beispiel.c-Datei und hallo.c-Datei. Im Beispiel .c-Datei zuerst haben wir die ID des aktuellen Prozesses gedruckt (Dateibeispiel.c läuft im aktuellen Prozess). Dann haben wir in der nächsten Zeile ein Array von Zeichenzeigern erstellt. Das letzte Element dieses Arrays sollte als Endpunkt NULL sein.

Dann haben wir die Funktion execv() verwendet, die den Dateinamen und das Zeichenzeiger-Array als Argument verwendet. Es sollte hier angemerkt werden, dass wir verwendet haben ./ mit dem Dateinamen gibt es den Pfad der Datei an. Da sich die Datei in dem Ordner befindet, in dem Beispiel.c residiert, sodass der vollständige Pfad nicht angegeben werden muss.

Wenn die Funktion execv() aufgerufen wird, wird unser Prozessabbild jetzt durch die Datei Beispiel ersetzt.c ist nicht dabei, aber die Datei hallo.c ist dabei. Es ist zu sehen, dass die Prozess-ID gleich ist, egal ob hallo.c ist Prozessabbild oder Beispiel.c ist Prozessabbild, da Prozess gleich ist und Prozessabbild nur ersetzt wird.

Dann haben wir hier noch etwas zu beachten, nämlich die printf()-Anweisung, nachdem execv() nicht ausgeführt wurde. Dies liegt daran, dass die Kontrolle nie wieder auf das alte Prozessabbild zurückgeführt wird, wenn es durch ein neues Prozessabbild ersetzt wird. Die Steuerung kehrt erst dann zum Funktionsaufruf zurück, wenn das Ersetzen des Prozessabbilds nicht erfolgreich ist. (Der Rückgabewert ist in diesem Fall -1).

Unterschied zwischen fork() und exec() Systemaufrufen:

Der Systemaufruf fork() wird verwendet, um eine exakte Kopie eines laufenden Prozesses zu erstellen, und die erstellte Kopie ist der untergeordnete Prozess und der laufende Prozess ist der übergeordnete Prozess. Während der Systemaufruf exec() verwendet wird, um ein Prozessabbild durch ein neues Prozessabbild zu ersetzen. Daher gibt es im exec()-Systemaufruf kein Konzept von Eltern- und Kindprozessen.

Beim Systemaufruf fork() werden Eltern- und Kindprozess gleichzeitig ausgeführt. Bei einem exec()-Systemaufruf kehrt die Steuerung jedoch, wenn das Ersetzen des Prozessabbilds erfolgreich ist, nicht dorthin zurück, wo die exec-Funktion aufgerufen wurde, sondern führt den neuen Prozess aus. Die Steuerung wird nur im Fehlerfall zurück übertragen.

Beispiel 2: Kombination von fork()- und exec()-Systemaufrufen

Betrachten Sie das folgende Beispiel, in dem wir sowohl fork()- als auch exec()-Systemaufrufe im selben Programm verwendet haben:

Beispiel.c

CODE:

#einschließen
#einschließen
#einschließen
int main(int argc, char *argv[])

printf("PID des Beispiels.c = %d\n", getpid());
pid_tp;
p = Gabel();
wenn(p==-1)

printf("Beim Aufrufen von fork() ist ein Fehler aufgetreten");

wenn(p==0)

printf("Wir sind im Kindprozess\n");
printf("Hallo rufen.c vom Kindprozess\n");
char *args[] = "Hallo", "C", "Programmierung", NULL;
execv("./hallo", Argumente);

sonst

printf("Wir sind im Elternprozess");

0 zurückgeben;

Hallo.c:

CODE:

#einschließen
#einschließen
#einschließen
int main(int argc, char *argv[])

printf("Wir sind in Hallo.c\n");
printf("PID von hallo.c = %d\n", getpid());
0 zurückgeben;

AUSGABE:

PID des Beispiels.c = 4790
Wir befinden uns im Elternprozess
Wir befinden uns im Kinderprozess
Hallo anrufen.c vom Kindprozess
Wir sind in hallo.c
PID von hallo.c = 4791

In diesem Beispiel haben wir den Systemaufruf fork() verwendet. Wenn der untergeordnete Prozess erstellt wird, wird p 0 zugewiesen und dann werden wir zum untergeordneten Prozess übergehen. Nun wird der Anweisungsblock mit if(p==0) ausgeführt. Eine Meldung wird angezeigt und wir haben den execv()-Systemaufruf und das aktuelle untergeordnete Prozessabbild verwendet, das ein Beispiel ist.c wird durch hallo ersetzt.c. Vor dem Aufruf von execv() waren Child- und Parent-Prozesse gleich.

Es ist ersichtlich, dass die PID des Beispiels.c und hallo.c ist jetzt anders. Dies liegt daran, dass Beispiel.c ist das übergeordnete Prozessabbild und hallo.c ist das Kindprozessabbild.

So verwenden Sie die GameConqueror-Cheat-Engine unter Linux
Der Artikel enthält eine Anleitung zur Verwendung der GameConqueror-Cheat-Engine unter Linux. Viele Benutzer, die Spiele unter Windows spielen, verwen...
Beste Spielkonsolen-Emulatoren für Linux
Dieser Artikel listet beliebte Spielekonsolen-Emulationssoftware auf, die für Linux verfügbar ist. Emulation ist eine Softwarekompatibilitätsschicht, ...
Beste Linux-Distributionen für Gaming im Jahr 2021
Das Linux-Betriebssystem hat sich weit von seinem ursprünglichen, einfachen, serverbasierten Aussehen entfernt. Dieses Betriebssystem hat sich in den ...