5 Stimmen

Unix-Pfadsuchfunktion in C

Ich programmiere eine UNIX-Shell und muss den execv()-Systemaufruf verwenden, um einen Prozess zu erstellen. Einer der Parameter für execv() ist der Dateipfad für das ausführbare Programm. Wenn also jemand /bin/ls eingibt, wird das ausführbare Programm ls ausgeführt. Aber was ich brauche, ist eine Funktion, damit beim Eingeben von ls nach dem Dateipfad von ls gesucht wird (ähnlich wie beim which-Befehl). Gibt es eine Funktion, die mir das ermöglicht?

Leider handelt es sich um ein Schulprojekt, und ich darf execvp() nicht verwenden. Ich muss eine Funktion zur Pfadsuche implementieren und dann diesen Dateipfad dem Parameter von execv() hinzufügen.

13voto

Steve Baker Punkte 4217

Verwenden Sie PATH = getenv("PATH"), um den Pfadstring aus der Umgebung zu erhalten, verwenden Sie anschließend aufeinanderfolgende Aufrufe von strtok(PATH,":") und dann strtok(NULL,":"), um die Pfade aus dem PATH-String in ein Array von char **path zu zerlegen, das Sie mit malloc() allozieren müssen. Platzieren Sie path[x] + '/' + argv[0] in einen Puffer und verwenden Sie access(buffer, X_OK), um zu sehen, ob Sie Ihre Datei an diesem Pfad ausführen können. Wenn ja, führen Sie execv(buffer,argv) aus.

0 Stimmen

Beachten Sie, dass Sie eine Kopie des von getenv("PATH") zurückgegebenen Strings erstellen müssen, da Sie andernfalls die Umgebung ändern, wenn Sie strtok() verwenden. Das ist normalerweise keine gute Idee!

3voto

Ich glaube, execvp() tut, was du brauchst.

Bearbeiten: Also fragst du tatsächlich, wie man das manuell macht? In diesem Fall...

  1. Finde deinen PATH in envp (3. Argument von main())
  2. Teile dies in einzelne Pfade auf
  3. Überprüfe das Vorhandensein deines Programms in jedem dieser Pfade mit stat()
  4. Führe das erste aus, das du findest

Oder wenn du eine wirklich solide Implementierung haben möchtest, verwende dies. Es könnte jedoch die Plagiatsdetektoren auslösen :)

1 Stimmen

Die Verwendung von getenv("PATH") ist genauso zuverlässig wie die Verwendung von envp; Sie müssen die Kontrolle über main() haben, um darauf zugreifen zu können.

3voto

Terence Simpson Punkte 4162

Du möchtest execvp(), es wird den im PATH-Variablen angegebenen Pfad durchsuchen, es sei denn, der Dateiname enthält einen '/'.

0 Stimmen

Für diejenigen, die mit der gegebenen excecvp-Lösung nicht zufrieden sind, habe ich diese Frage in diesem Beitrag beantwortet stackoverflow.com/questions/14571215/…

3voto

Terence Simpson Punkte 4162

Wenn Sie execvp nicht verwenden können, könnten Sie die PATH-Variable von char** environ aus oder char* getenv(const char* name) aus erhalten und dann int access(const char* filename, int mode) verwenden, um zu sehen, ob die Datei existiert und ausführbar ist. Ich überlasse Ihnen die Implementierung, da es sich um ein Schulprojekt handelt.

2 Stimmen

Die Verwendung von access() ist nicht ganz zuverlässig; es ist am besten, "exec" auf die Datei zu versuchen. Es gibt eine Vielzahl von Problemen mit access() - einige davon betreffen SUID-Binärdateien. Die Verwendung von access() wird Ihnen sagen, ob die Datei existiert, aber das wird auch ein fehlgeschlagenes execv().

0 Stimmen

@JonathanLeffler Ich arbeite jetzt an dem gleichen Projekt und wir haben dieses Problem umgangen, indem wir X_OK verwendet haben.

2voto

spiv Punkte 2990

Verwenden Sie execvp.

char *args[] = {"ls", (char *) NULL};
execvp("ls", args);

zum Beispiel wird dieses Beispiel /bin/echo ausführen (vorausgesetzt, dass /bin in Ihrem PATH ist).

#include 

int main()
{
    char *args[] = {"echo", "Hallo Welt", (char *) NULL};
    execvp("echo", args);
    return 0;
}

0 Stimmen

Er kann execvp() nicht verwenden, nur execve()

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X