2012-05-22 3 views
5

Ich baue eine Shell und habe einige Probleme mit dem Systemaufruf 'Execvp'. Ich sah einige andere Fragen zu diesem Thema, aber sie waren vage und schienen nicht vollständig adressiert zu sein (wer auch immer die Fragen stellte, lieferte nicht viele Informationen und bekam keine guten Antworten).Erstellen einer C-Shell. execvp gibt 'No this file' Fehler zurück. Erstellen von Argv-Array on-the-fly mit malloc

Offensichtlich habe ich meine eigene Kommandozeile und lese ich eine Benutzereingabe von stdin wie

mysh some/path $ ps -a 

und ich bin den Aufbau einer args Array als char ** und das Array selbst funktioniert (glaube ich), da wenn ich die Werte in meiner Funktion auszudrucken zeigt es

args[0] = 'ps' 
args[1] = '-a' 
args[2] = '(null)' 

Also, ich rufe Gabel und execvp (CMND, args): in meinem Prozess, in dem CMND „ps“ und args wie oben, und perror usw.

Ich bekomme

'Error: no such file or directory.' 

Muss ich die Variable $ PATH eingeben? Mache ich noch etwas anderes?

Hier ist mein Code für die Erzeugung des args-Array:

char ** get_args(char * cmnd) { 
int index = 0; 
char **args = (char **)emalloc(sizeof(char *)); 
char * copy = (char *) emalloc(sizeof(char)*(strlen(cmnd))); 
strncpy(copy,cmnd,strlen(cmnd)); 
char * tok = strtok(copy," "); 
while(tok != NULL) { 
    args[index] = (char *) emalloc(sizeof(char)*(strlen(tok)+1)); 
    strncpy(args[index],tok,strlen(tok)+1); 
    index++; 
    tok = strtok(NULL," "); 
    args = (char**) erealloc(args,sizeof(char*)*(index+1)); 
} 
args[index] = NULL; 
return args; 
} 

(emalloc und erealloc sind nur malloc und realloc mit Fehler in integrierte Prüfung)

Also dann sehe ich das:

void exec_cmnd(char*cmnd, char**args) { 
pid_t pid; 
if((pid=fork())==0) { 
    execvp(cmnd, args); 
    perror("Error"); 
    free(args); 
    free(cmnd); 
    exit(1); 
} 
else { 
    int ReturnCode; 
    while(pid!=wait(&ReturnCode)) { 
     ; 
    } 
} 
} 

Und wie ich oben sagte, wenn execvp in meinem Prozess aufgerufen wird, scheitert es, wenn ich irgendwelche Argumente liefern, aber ohne sie arbeitet (dh wenn argv == {'ps', NULL})

Wenn Sie weitere Informationen benötigen, zögern Sie nicht zu fragen. Ich muss das lösen.

Antwort

6

Es denken Sie von cmnd passieren als erstes Argument von execvp

Sie nennen es als

ganze Befehlszeile im ersten Argument execvp

Sie haben zu trennen ersten Token (Befehlsname) übergeben

execvp(args[0], args);

+0

Das ist genau richtig. Wenn Sie 'ps -a' ausführen wollen, müssen Sie' execvp ("ps", {"ps", "-a", NULL}) '' aufrufen. – caf

+0

ack. Handfläche zur Stirn. Ja, das war es, danke. :) – matchdav

+0

Frikkin Ockhams Rasiermesser – matchdav

1

Hinweis im Vorbeigehen, dass Sie einen nicht-terminierte String als Ergebnis haben:

char * copy = (char *) emalloc(sizeof(char)*(strlen(cmnd))); 
strncpy(copy, cmnd, strlen(cmnd)); 

strncpy() beendet nicht null für Sie, wenn Sie es so verwenden. Sie müssen auch ein weiteres Byte für die Null zuweisen. Erwägen Sie, strdup() zu verwenden, wenn es für Sie verfügbar ist. Wenn nicht, überlege dir, es zu schreiben. Diese Fehlzuweisung ist selbst bei den Fehlerüberprüfungsversionen von und erealloc() ein Problem.

+1

Oder im Einklang mit dem Thema, verwenden (oder implementieren und verwenden) 'estrdup()'. –

+0

Ich werde das total machen. – matchdav

+0

Ich mache es gerade, vim in meiner Shell laufen. – matchdav

Verwandte Themen