簡體   English   中英

用於Shell的C程序:Execvp打印輸出,然后在執行后台進程時發生分段錯誤

[英]C Program for shell: Execvp prints output and then segmentation fault occurs when executing a background process

我正在編寫一個簡單的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。 這也會導致分段錯誤。

是的,正如Mark Plotnick在評論中指出的那樣,您可能需要&status。 我會使用&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);
    }
}

希望您為外部循環提供的代碼片段可以執行以下操作。

另外,我可能不會對前台執行“ wait(NULL)”。 我會像對待獨立工作一樣對待它。 考慮用戶這樣做的情況:

det1 &
det2 &
...
det9000 &
run_long_30_minute_job

由於您的外殼程序在前台進行了艱苦的等待,因此無法完成分離的作業,因為它們完成后,您將面臨僵屍進程。 使用列表/循環方法,只是在前景完成之前不給用戶提示(例如,它在列表中,只是清除了背景標志的那個)。 換句話說,將列表稱為child_list之類的名稱來表示所有子進程,而不僅僅是背景。 在外循環中入睡。 或者,附加到SIGCHLD並進行一次長時間睡眠

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM