2012-04-15 29 views
1

Ich habe einige Probleme mit Execve. Ich versuche, eine Shell zu erstellen, die genau wie die Bash-Shell funktionieren kann, aber ich habe Probleme mit dem gegabelten Kind, das einen Befehl ausführt. Hier ist, was ich für das Kind habe. cmd ist ein char * mit dem Befehl, dass der Benutzer eingegeben Allerdings, wenn ich dieses Programm ausführen, bekomme ich diesen Fehler aus perror.Execve - Keine solche Datei oder Verzeichnis?

execve error: No such file or directory. 

ich das Programm mit einem einfachen ls versucht habe, und es sollte machen path = "/ bin/ls" und führe es aus (ich habe bestätigt, dass dies mein ls-Befehl ist), aber es beschwert sich immer noch. Was mache ich falsch? Vielen Dank!

Code:

if(pid == 0){ 

    // Parse the command 
    char * word = strtok(cmd, " "); 
    char path[128] = "/bin/"; 
    strcat(path, word); 

    // Execute the process 
    char * newenvp[] = { NULL }; 
    char * newargv[] = { path, NULL }; 
    ret = execve(path, newargv, newenvp); 
    if(ret == -1){ 
     perror("execve error"); 
    } 

    return EXIT_SUCCESS; 

} 
+0

Haben Sie überprüft, dass 'Pfad' enthält, was Sie denken, dass es tut? Vor allem, weil 'strtok()' in seiner Funktionsweise etwas notorisch nervt und leicht Müll produzieren kann, wenn Sie nicht genau nach seinen Regeln spielen? – geekosaur

+0

Nichts falsch, dass ich sehen kann. Warum werfen Sie nicht 'printf()' ein, um den endgültigen Inhalt von 'path' anzuzeigen, um sicherzustellen, dass' strtok' das Richtige tut - der 'execve'-Aufruf selbst sieht gut aus. –

+0

Warum setzen Sie die Umgebung auf leer? Sie sollten wahrscheinlich plain 'execv()' verwenden, um Ihre aktuelle Umgebung zu verwenden, oder 'environ' als drittes Argument an 'execve()' übergeben. Ich bezweifle, dass dies die Ursache Ihres Problems ist, aber es ist eine bessere Übung. (Es ist auch oft sinnvoll, 'execv (newargv [0], newargv);' oder 'execve (newargv [0], newargv, environ) zu verwenden;'. Es hat keinen Sinn, den Rückgabestatus eines der 'exec *()' Funktionen: Wenn es zurückgegeben wird, ist es fehlgeschlagen; wenn es erfolgreich ist, wird es nicht zurückgegeben.) –

Antwort

4

Die erste, was ich würde tun würde einzufügen:

printf ("[%s]\n", path); 

vor dem Aufruf von execve. Das sollte bestätigen, dass die ausführbare Datei das ist, was Sie denken.

Dieser Code von Ihnen sieht okay solange die Eingangs Sie in sie sind Fütterung korrekt ist und die ausführbare Datei tatsächlich ist zur Verfügung. Zum Beispiel arbeitet das folgende komplette Programm auf meinem Debian-Box fein:

#include <stdio.h> 
#include <string.h> 
#include <unistd.h> 

int main (int argc, char *argv[]) { 
    if (argc > 1) { 
     char * word = strtok (argv[1], " "); 
     char path[128] = "/bin/"; 
     strcat (path, word); 

     char * newenvp[] = { NULL }; 
     char * newargv[] = { path, NULL }; 
     printf ("[%s]\n", path); 
     int ret = execve (path, newargv, newenvp); 
     if (ret == -1) { 
      perror("execve error"); 
     } 
    } 
    return 0; 
} 

Ausgeben, wenn ich ./testprog ls laufen, etwas entlang der Linien von:

[/bin/ls] 
kidsshares.ods paxwords birthdays homeloantracking.gnumeric 
shares2011.ods backup0.sh development lexar 
accounts.ods backup1.sh photos  testprog.c 
testprog 
+0

Das Problem gefunden, danke für den Vorschlag! Ich druckte meinen Pfad mit write() aus, was die Tatsache ignorierte, dass ich meinen Null-Terminator vermisste. – theeggman85

0

Wenn Sie nicht wollen, manuell zu reisen durch das Dateisystem, um die richtige binäre zu finden, gibt es execlp (mit einem zusätzlichen p). Von der Manpage:

The execlp(), execvp(), and execvpe() functions duplicate the actions of the shell in searching for an executable file if the specified filename does not contain a slash (/) character. The file is sought in the colon-separated list of directory pathnames specified in the PATH environment variable. If this variable isn't defined, the path list defaults to the current directory followed by the list of directories returned by confstr(_CS_PATH). (This confstr(3) call typically returns the value "/bin:/usr/bin".) [...]

Verwandte Themen