簡體   English   中英

子進程未通過fork()退出

[英]Child process not exiting with fork()

我正在用C創建一個簡單的Linux命令外殼。無法理解我的代碼在哪里出現問題。 “命令”是我想作為一個父級的子級進程並發執行的Linux命令字符串的列表。 當所有執行完成后,我希望父項退出該函數。 但是,當我調用exit(0)時,for循環將繼續並再次解析當前命令,從而導致args在execvp中再次執行。 我在這里正確使用fork()和wait()嗎? 我也嘗試過使用waitpid(),但沒有運氣。

void executeShell(char** commands){
    char **arr = commands;
    char *c;
    pid_t pid, wpid;
    int status = 0;

    for (c = *arr; c; c=*++arr){
        // printf("%d-\n", strcmp(command, "exit"));

        if (strcmp(c, "exit") == 0){
            EXIT = 1;
            return;
        }

        printf("Running command \'%s\'...\n", c);

        char** args = parseStringToTokenArray(c, " ");
        free(args);

        /* fork and execute the command */
        pid = fork();
        if(pid < 0){
            perror("fork() error\n");
            return;
        }
        /* child process executes command */
        else if (pid == 0){
            /* 'cd' is not a part of /bin library so handle it manually */
            if (strcmp(args[0], "cd") == 0){
                changeDirectory(args[1]);
            }
            else if (strcmp(args[0], "sdir") == 0){
                searchDirectory(args[1]);
            }else{
                /* parse commands with arguments */
                execvp(args[0], args);//execute the command
            }
            exit(0);// <-----command is finished, so why no exit?
        }                                     
    }                                          
    /* wait for children to complete */          
    while((wpid = wait(&status)) > 0);         
}                                               

如果execvp成功,則整個子進程地址空間將由execvp()調用的程序替換。 這意味着將僅在以下兩種特殊情況(即cdsdir exit(0)調用exit(0) 就您的代碼而言,除非有錯誤,否則execvp()應該永遠不會返回。

另一個問題是,您在分配args后立即釋放了args ,然后繼續在子進程中使用它。 這是未定義的行為。

我在wait代碼中看到的唯一問題是,如果任何子級阻止等待用戶輸入,則父級將阻止等待子級退出。

cd代碼對執行它的子進程以外的任何進程均無效。 父級的當前目錄不受影響。 如您在注釋中所述,可以通過在父級中處理cd而不進行分叉來解決此問題。

暫無
暫無

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

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