子进程没有退出fork()

问题描述 投票:0回答:1

我在C中创建一个简单的Linux命令shell。我无法理解代码出现问题的位置。 “commands”是一系列Linux命令的列表,我希望它们作为一个父项的子进程同时执行。完成所有操作后,我希望父进程退出该函数。但是,当我调用exit(0)时,for循环继续并再次解析当前命令,导致在execvp中再次执行args。我在这里正确使用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);         
}                                               
c fork exec wait waitpid
1个回答
1
投票

如果execvp成功,则整个子进程地址空间将被execvp()调用的程序替换。这意味着exit(0)只会在你的两个特殊情况下被调用,即cdsdir。就你的代码而言,execvp()永远不会返回,除非出现错误。

另一个问题是你在分配之后立即释放args然后继续在你的子进程中使用它。这是未定义的行为。

我用你的wait代码看到的唯一问题是,如果任何一个孩子阻止等待用户输入,父母将阻止等待孩子退出。

cd代码对除了执行它的子进程之外的任何进程都没有影响。父级的当前目录不受影响。正如您在评论中所述,这可以通过在父母处理cd而不用分叉来确定。

© www.soinside.com 2019 - 2024. All rights reserved.