2016-09-16 1 views
1

J'essaie de faire une petite coquille. Mon problème est que quand j'appelle execvp() - j'obtiens des erreurs. Par exemple, lorsque je tape ls -l, il renvoie ls: invalid option -- 'execvp() ne fonctionne pas dans ma coque

Est-ce que quelqu'un peut, s'il vous plaît, m'aider à comprendre pourquoi je reçois cette erreur? Pour mon code, la commande de fonction split obtient l'entrée de l'utilisateur et les divise en commandes séparées. Les commandes séparées sont séparées par le caractère ;.

#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

Etes-vous sûr 'holder' est correctement terminé? Si vous parcourez le code ligne par ligne dans un débogueur, se comporte-t-il comme prévu? Toutes les valeurs des variables sont-elles conformes à vos attentes? –

+0

montrant la sortie de 'pour (int o = 0; o

Répondre

2

Votre problème est que fgets()also reads the newline character. Par conséquent, le dernier argument du tableau execvp() arguments contient un saut de ligne, provoquant ls se plaindre d'un argument non reconnu: ce que vous passez généralement à ls est -l\n; ce que vous devez passer est juste -l sans le retour à la ligne.

Essayez d'ajouter ce code après l'appel fgets pour couper le tampon d'entrée:

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

Merci beaucoup. Je me rendais fou en essayant de comprendre ce qui n'allait pas. – David

+0

J'ai l'impression de rencontrer un problème différent. Quand j'entre "ls -l; ls", il exécute les deux commandes correctement. Cependant, si je tape "ls; ls -l", il exécute la première commande correctement mais "ls -l" ne liste pas les répertoires mais il ne semble pas non plus lancer une erreur. Je reçois juste quelques déclarations nulles sur mon écran – David

+2

@David essaie d'utiliser un débogueur pour tracer le code et trouver le problème. – kfx