2017-10-11 45 views
0

我必須製作簡單的shell來讀取命令並按順序執行它們。條件不改變主函數的形式,並且執行函數應該是遞歸的。 主要問題是,它似乎waitpid不起作用。但我知道,我的代碼中存在很多問題。請讓我知道我應該從哪裏開始..簡單的shell在c:waitpid系統調用不起作用

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#define MAX 10 

char cmmd[MAX][256]; 
int sp; 
char *argv[10]; 
int size; 

void ClearLineFromReadBuffer(void){ 
    while(getchar() != '\n'); 
} 
void printCommands(){ 
    size = sp+1; 
    //print by moving stack pointer 
    while(1){ 
     if (sp==-1) break; 
     printf("Command line : %s\n", cmmd[sp]); 
     sp--; 
    } 
    printf("print end\n"); 
} 



void readCommandLines(){ 
    int a = 0; //return of scanf 
    while (1){ //write commends to cmmd untill get ctrl+d 
     printf(">"); 
     a = (scanf("%[^\n]s", cmmd[sp])); //take input to str untill get enter(scanf returns -1) 
     if (a==-1) {sp--; break;} 
     if (a==1) ClearLineFromReadBuffer(); 
     if (a==0) {printf("error"); break;} 
     sp++; 
    } 
    printf("\n"); 
} 

void readACommand(char *line){ //line takes string's name. 
    int i=0; 

    argv[i]=strtok(line," "); //i==0 
    while(strtok(line," ")!=NULL){ 
     i++; 
     argv[i]=strtok(NULL," "); 
    } 
    printf("%s",argv[0]); 
    printf("%s",argv[1]); 
} 

void executeCommands(){ //Recursive function 
    int n = sp; 
    n++; 
    printf("%d",n); 
    printf("%s",cmmd[n]); 
    char *cmd_line = cmmd[n]; //command line which child process will execute 

    unsigned int child_pid; //fork() returns process id of child in parents process 
    int status; //status takes return of child's exit() 
    child_pid=fork(); 
    if (child_pid != 0){ // Parents process 
     printf("parents access"); 
     waitpid(child_pid,&status,0); 
     printf("***Process %d Child process %d DONE with status %x\n\n",getpid(),child_pid,status); 

     sp++; 
     if(sp<size) 
      executeCommands(); 
    } 
    else if (child_pid == 0){ //fork() returns 0 in child process 
     printf("***Process %d Executing Command %s",getpid(),cmd_line); 
     readACommand(cmmd[n]); 
     execve(argv[0],argv,NULL); 
     printf("ERROR - not executing command \"%s\"\n",argv[0]); //can be printed because exec() failed 
    } 
} 

int main(){ 
    readCommandLines(); 
    printCommands(); 
    executeCommands(); 
    return(0); 
} 

這是結果。 enter image description here

+1

可能相關:你必須'NULL'終止你的參數列表。 –

+1

您的令牌循環非常可疑。如果超過2個參數,我認爲它可能是無限的。它不會以NULL結尾。 –

+0

Thanl你。我修好了,併成功分開它,但循環永遠不會結束。你能告訴我什麼是重要的嗎?當我嘗試打印每個argv時,它可以打印到最後一個參數,但仍然保留在while循環中。 –

回答

1

您標記字符串的方式非常錯誤。有很多的strtok電話,因爲你在初始化字符串的循環中調用strtok,不NULL

你的循環可以無限循環加上你的最後一個參數,這是後不是要設置到NULL通過execv需要知道何時參數已用完(沒有大小被傳遞)

這裏的一個獨立的實施例和適當readACommand例程:

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

char *argv[100]; 

void readACommand(char *line){ //line takes string's name. 
    int i=0; 

    argv[i]=strtok(line," "); //i==0 
    while(argv[i]!=NULL){ 
     argv[++i]=strtok(NULL," "); 
    } 
} 

int main() 
{ 
    char line[] = "this is a command"; 
    char **ptr=argv; 

    readACommand(line); 
    while(*ptr != NULL) 
    { 
     printf("Arg: %s\n",*ptr); 
     ptr++; 
    } 
    return 0; 
} 

執行(檢測所述的NULL指針結束):

Arg: this 
Arg: is 
Arg: a 
Arg: command