/* 17May24: Eine eigene einfache Implementierung von execvp ("Execute * Vector in Path"). Das ist ein eigenes Modul, welches wir * zusammenbinden mit dem Haupt-Modul. * * Die Idee ist zu zeigen, wie execvp (welches den PATH auflöst) auf * einer Funktion wie execv (welches immer einen absoluten Pfad zur * ausführbaren Datei braucht). */ #include <stdlib.h> #include <unistd.h> #include <string.h> /* Auch hier brauchen wir die Header-Datei, damit man sichergehen * kann, dass sich unser Programm auch an die Schnittstelle hällt. */ #include "execvp.h" int _execvp(char *cmd, char *argv[]) { /* Wir holen uns erst den PATH aus der Umgebung. Der PATH ist * ein String welches mit Doppelpunkten Verzeichnisse aufzählt wo * man Programme finden kann. Damit wird "ls" zu "/usr/bin/ls" * aufgelöst. */ char *path = getenv("PATH"); /* /usr/bin:/bin:... */ /* Mit strtok können wir `path' Stück für Stück abarbeiten. Wir * teilen immer an den Doppel-Punkten den String und bauen uns * daraus einen absoluten Pfad auf: */ char *dir = strtok(path, ":"); while (dir != NULL) { /* Hier haben wir ein Variable Length Array (VLA) welches so * groß ist, damit es den neuen Dateipfad halten kann. * Danach benutzen wir Funktionen aus string.h um die Datei * aufzubauen. */ char filepath[strlen(dir) + 1 + strlen(cmd) + 1]; strcpy(filepath, dir); strcat(filepath, "/"); strcat(filepath, cmd); /* Mit diesem String versuchen wir spekulativ execv * auszuführen. Wenn es klappt, dann haben wir den Programm * im Prozess ersetzt, ansonsten läuft unser Programm * weiter. */ execv(filepath, argv); /* Wenn wir mit strtok(NULL, ...) aufrufen, dann wird es den * letzten Aufruf fortsetzen, und die nächste Komponente * (Token) bis zu einem ":" zurückgeben -- oder NULL wenn * wir nichts mehr haben. */ dir = strtok(NULL, ":"); } /* Wenn wir hier angekommen sind, dann haben wir nichts gefunden * und deuten einen Fehler an. */ return -1; }