web-dev-qa-db-fra.com

Écrire un Shell simple en C en utilisant fork / execvp

Je dois développer un Shell simple en C en utilisant les appels système fork ()/execvp (). Jusqu'à présent, mon code prend une commande, la divise en utilisant strtok dans un tableau argv, puis j'appelle fork pour créer un enfant et exécuter la commande. Je travaille là-dessus dans ubuntu où la plupart des commandes sont dans le répertoire/bin /, donc j'ajoute le nom du programme (par exemple/bin/ls) et je l'utilise pour le premier arg de execvp, puis je lui donne le tableau argv . Mon programme fonctionne si je tape la commande "ls", mais lorsque j'essaie d'autres commandes ou même "ls -l", je reçois une option "ls: invalid". Je ne sais pas ce que je fais mal ici.

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

#define BUFFER_LEN 1024

int main(){
    char line[BUFFER_LEN];  //get command line
    char* argv[100];        //user command
    char* path= "/bin/";    //set path at bin
    char progpath[20];      //full file path
    int argc;               //arg count

while(1){

    printf("My Shell>> ");                    //print Shell Prompt

        if(!fgets(line, BUFFER_LEN, stdin)){  //get command and put it in line
        break;                                //if user hits CTRL+D break
    }
    if(strcmp(line, "exit\n")==0){            //check if command is exit
        break;
    }

    char *token;                  //split command into separate strings
    token = strtok(line," ");
    int i=0;
    while(token!=NULL){
        argv[i]=token;      
        token = strtok(NULL," ");
        i++;
    }
    argv[i]=NULL;                     //set last value to NULL for execvp

    argc=i;                           //get arg count
    for(i=0; i<argc; i++){
        printf("%s\n", argv[i]);      //print command/args
    }
    strcpy(progpath, path);           //copy /bin/ to file path
    strcat(progpath, argv[0]);            //add program to path

    for(i=0; i<strlen(progpath); i++){    //delete newline
        if(progpath[i]=='\n'){      
            progpath[i]='\0';
        }
    }
    int pid= fork();              //fork child

    if(pid==0){               //Child
        execvp(progpath,argv);
        fprintf(stderr, "Child process could not do execvp\n");

    }else{                    //Parent
        wait(NULL);
        printf("Child exited\n");
    }

}
} 
9
C1116

L'option non valide est parce que fgets() conserve le '\n' lorsque vous appuyez sur Entrée, essayez ceci

if(!fgets(line, BUFFER_LEN, stdin))
    break;
size_t length = strlen(line);
if (line[length - 1] == '\n')
    line[length - 1] = '\0';

lorsque vous essayez d'appeler ls -l tu passes "-l\n" comme option, d'où le message.

Vous devrez changer

strcmp(line, "exit\n")

à

strcmp(line, "exit")
7
Iharob Al Asimi