2016-09-16 3 views
1

Ich versuche, eine kleine Schale zu machen. Mein Problem ist, dass wenn ich rufe execvp() - ich bekomme Fehler. Zum Beispiel, wenn ich in ls -l gebe es ls: invalid option -- 'execvp() funktioniert nicht in meiner Shell

Kann jemand, bitte, mir helfen zu verstehen, warum ich diesen Fehler bekomme? Für meinen Code erhält die Funktion command split die Benutzereingabe und teilt sie in separate Befehle auf. Separate Befehle sind durch ; Zeichen getrennt.

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <sys/wait.h> 
#include <unistd.h> 

#define MAX_CHARACTERS 512 
#define HISTORY_SIZE 10 

int commandSplit(char *c, char *a[], int t[]) { 

int count = 0; 
int total = 0; 
char *temp[MAX_CHARACTERS]; 
char *readCommands = strtok(c, ";"); 
while(readCommands != NULL) { 
    printf("Reading full command: %s\n", readCommands); 
    temp[count] = readCommands; 
    count++; 
    readCommands = strtok(NULL, ";"); 
} 
printf("Done reading full commands\n"); 
for(int i = 0; i < count; i++) { 
    char *read = strtok(temp[i], " "); 
    int track = 0; 
    while(read != NULL) { 
     printf("Reading individual command: %s\n", read); 
     a[total] = read; 
     track++; 
     total++; 
     read = strtok(NULL, " "); 
    } 
    t[i] = track; 
} 

return count; 
} 

int main() { 

int exitProgram = 0; 
char *args[MAX_CHARACTERS]; 

while(!exitProgram) { 

char *commands = (char *)(malloc(MAX_CHARACTERS*sizeof(char))); 
int tracker[MAX_CHARACTERS]; 
int numOfCommands = 0; 
printf("tinyshell> "); 
fgets(commands, MAX_CHARACTERS, stdin); 

if(strlen(commands) == 0) continue; 

numOfCommands = commandSplit(commands, args, tracker); 
printf("There are %i commands!\n", numOfCommands); 

if(strcmp(args[0], "exit") == 0) { 
    printf("Exiting\n"); 
    exitProgram = 1; 
    continue; 
} 

int l = 0; 
for(int i = 0; i < numOfCommands; i++) { 
    int status; 
    char *holder[tracker[i]+1]; 
    for(int j = 0; j < tracker[i]; j++) { 
     holder[j] = args[l]; 
     printf("Assiging holder:%s\n", holder[j]); 
     l++; 
    } 
    holder[tracker[i]] = NULL; 
    printf("What is holder? \n"); 
    for(int o = 0; o < tracker[i]; o++) printf("%s", holder[o]); 
    pid_t p = fork(); 
    pid_t waiting; 
    if(p == 0) { 
    printf("I am in child process\n"); 
    execvp(holder[0], holder); 

    fprintf(stderr, "Child process could not execvp!\n"); 
    exit(1); 
    } 
    else { 
     if(p < 0) { 
      fprintf(stderr, "Fork FAILED!\n"); 
     } 
     else { 
      waiting = wait(&status); 
      printf("Child %d, status %d\n", waiting, status); 
     } 
    } 
    for(int i = 0; i < numOfCommands; i++) { 
     args[i] = NULL; 
    } 
} 

} 

return 0; 

} 
+0

Sind Sie sicher, dass 'Berechtigten korrekt beendet wird? Wenn Sie in einem Debugger Zeile für Zeile durch den Code gehen, verhält er sich dann wie erwartet? Sind alle Variablenwerte wie erwartet? –

+0

zeigt die Ausgabe von 'für (int o = 0; o

Antwort

2

Ihr Problem ist, dass fgets()also reads the newline character. Als Ergebnis enthält das letzte Argument des Arrays execvp() einen Zeilenumbruch, was dazu führt, dass ls über ein nicht erkanntes Argument klagen: Was Sie tatsächlich an ls übergeben haben, ist -l\n; Was Sie passieren müssen, ist nur -l ohne die Newline.

Versuchen Sie diesen Code nach dem fgets Anruf Hinzufügen der Eingangspuffer zu trimmen:

int len; 
len = strlen(commands); 
if (len > 0 && commands[len-1] == '\n') { 
    commands[len-1] = '\0'; 
} 
+0

Vielen Dank. Ich machte mich selbst verrückt und versuchte herauszufinden, was falsch war. – David

+0

Ich habe anscheinend ein anderes Problem. Wenn ich "ls -l; ls" eintrage, führt es beide Befehle aus. Wenn ich jedoch "ls; ls -l" eintippe, führt es den ersten Befehl korrekt aus, aber "ls -l" listet die Verzeichnisse nicht auf, aber es scheint auch keinen Fehler zu geben. Ich bekomme nur ein paar Null-Anweisungen auf meinem Bildschirm – David

+2

@ David versuchen, mit einem Debugger den Code zu verfolgen und das Problem zu finden. – kfx

Verwandte Themen