==================== Durchsuchen von PATH [TOP] ==================== Da die Funktion _execvpe_ nicht Bestandteil von POSIX ist, wäre es reizvoll, diese selbst zu implementieren. So sieht unter Linux die Schnittstelle hierfür aus: ---- CODE (type=c) ------------------------------------------------------------ int execvpe(const char *file, char *const argv[], char *const envp[]); ------------------------------------------------------------------------------- Wie könnte diese realisiert werden? * Falls _file_ irgendeinen „/“ enthält, sollte _execvpe_ äquivalent zu _execve_ sein. * Der Inhalt der PATH-Umgebungsvariablen lässt sich mit `getenv("PATH")` abrufen. Die einzelnen Verzeichnisse sind dabei durch Doppelpunkte voneinander getrennt. Eine Möglichkeit, die einzelnen Verzeichnisse zu durchlaufen, bieten die Funktionen `strtok` bzw. `strtok_r` aus `#include `. Beispiel: :import: session02/path.c ---- SHELL (path=session02) ------------------ gcc -Wall -o path path.c echo $PATH ./path ---------------------------------------------- Warum wurde hier _strdup_ verwendet? * Bei jedem Verzeichnis aus dem Pfad wäre nun zu testen, ob es das Kommando in diesem Pfad gibt. Dies könnte erfolgen, indem ein zusammengesetzter Pfadname gebaut wird. Es geht aber auch ohne: - Sie können das Verzeichnis eröffnen mit folgender Variante von _open_: ---- CODE (type=c) ------------------------------------------------------ int dirfd = open(dir, O_DIRECTORY|O_SEARCH); ------------------------------------------------------------------------- `O_DIRECTORY` stellt sicher, dass das es ein Verzeichnis sein muss und `O_SEARCH` gibt an, dass wir das Verzeichnis nur durchsuchen können möchten. Beide Flags sind in `#include ` definiert. - Mit dem Systemaufruf _openat_ können Sie das Verzeichnis, zu dem relativ ein Pfad interpretiert wird, als Dateideskriptor angeben: ---- CODE (type=c) ------------------------------------------------------ int openat(int fd, const char *path, int oflag, ...); ------------------------------------------------------------------------- Wenn Sie die Datei nur ausführen können möchten, genügt als Flag hier `O_EXEC`. - Eine Datei, die Sie mit `O_EXEC` eröffnet haben, können Sie direkt bei dem Systemaufruf _fexecve_ angeben: ---- CODE (type=c) ------------------------------------------------------ int fexecve(int fd, char *const argv[], char *const envp[]); ------------------------------------------------------------------------- Aufgabe ======= Implementieren Sie die Funktion _execvpe_ wie beschrieben und verwenden Sie diese in Ihrer bisherigen Lösung. :navigate: up -> doc:index back -> doc:session02/page02 next -> doc:session02/page04