2015-10-04 29 views
0

我正在編寫一個簡單的C程序來創建我自己的shell。它將輸入作爲命令並執行它們。但是當我嘗試在後臺執行一個進程時(也就是說,我從父進程派生一個進程,父進程不會等待子進程完成,而是在子進程在後臺運行時繼續執行更多輸入命令。 )execvp會執行命令,但會立即發出分段錯誤。 你能幫我嗎?我將發佈我認爲相關的代碼的一部分。如果您需要了解更多信息,請告知我,我會相應地編輯我的問題。C程序shell:Execvp打印輸出,然後在執行後臺進程時發生分段錯誤

while(1){ 

pid = fork(); 
     if(pid == 0) 
      executeCommand(info); 
     else 
      { 
       if(info->boolBackground ==1) 
        { 
         waitpid(pid , status , WNOHANG); 
        } 
       else 
        wait(NULL);      
      } 

} //Info contains the command to be executed and it's arguments. 

這裏是我executeCommand功能:

void executeCommand(parseInfo * info) 
{ 
    FILE *infile, *outfile; 
    struct commandType * com; 
    char * cmd; 
    int i , status; 
    cmd = (char*)malloc(1024); 
    strcpy(cmd , info->CommArray[0].command); 
    if(info->boolOutfile == 1) 
     { 
      outfile = fopen(info->outFile, "w"); 
      dup2(fileno(outfile), 1); 
     } 
    if(info->boolInfile == 1) 
     { 
      infile = fopen(info->inFile, "r"); 
      dup2(fileno(infile), 0); 
     } 
    status = execvp(cmd , info->CommArray[0].VarList); //VarList contains the arguments 
    if(status == -1){ 
     printf("%s\n",strerror(errno));} 

    exit(0); 
} 

當我給一個輸入命令:ls & (&意味着LS應在背景中執行。) ,它派生一個子進程,其執行ls並打印目錄中的文件/目錄列表,然後給出分段錯誤。你能發現錯誤嗎?我試着用簡單的ls命令在後臺運行execvp。它也導致分段錯誤。

+0

如果status不是指針,那麼在'waitpid'調用中,您可能需要'''status'。 –

回答

0

是的,正如Mark Plotnick在評論中指出的,您可能需要&狀態。我會使用& info-> status。此外,如果你做的超脫的工作,你需要保持他們的信息對象的列表,並做他們waitpid函數循環:

forall (info in detached_detach_job_list) { 
    pid = waitpid(info->pid,&info->status,WNOHANG); 
    if (pid > 0) { 
     report_status(info); 
     remove_job_from_list(info); 
    } 
} 

希望,你給你的外環代碼FRAG做這樣的事情。

此外,我可能不會爲前景做「等待(NULL)」。我會把它看成是一個分離的工作。考慮一個用戶可以這樣做的情況:

det1 & 
det2 & 
... 
det9000 & 
run_long_30_minute_job

因爲你的shell在前臺上做了一個艱苦的等待,所以當它們完成時它不能收穫分離的作業,並且最終會導致殭屍進程。執行列表/循環的方法,只是在前臺完成之前不給用戶一個提示(例如它在列表中,它只是清除了背景標誌的那個)。換句話說,調用列表類似child_list來表示所有子進程,而不僅僅是背景。在外環中睡一覺。或者,附加到SIGCHLD並做一次長時間睡眠

相關問題