execv,等待,Unix编程,如何等待孩子

时间:2009-09-23 18:13:48

标签: c unix wait execvp

您好我正在使用unix shell,我遇到了两个问题。我想知道你们中是否有人可以帮助我。我的第一个问题是shell不等待子进程终止。实际上,我可以在子进程运行时输入更多命令。我的第二个问题是以下两行。我没有在外壳上显示任何东西。

    fprintf(stderr, "Process name is: %s\n", commandArgv[0]);
    fprintf(stderr, "Child pid = %d\n", pid);

我有以下方法来执行用户输入的进程:即firefox,ls -a等

void execute(char *command[], char *file, int descriptor){
    pid_t pid;
    pid = fork();

    if(pid == -1){
        printf("error in execute has occurred\n");
    }
    if(pid == 0){           
        execvp(*command,command);
        fprintf(stderr, "Process name is: %s\n", commandArgv[0]);
        fprintf(stderr, "Child pid = %d\n", pid);
        wait(&status);
            exit(EXIT_SUCCESS);
    }
    else{
        printf("ignore for now\n");
    }
}

这是我调用execute命令的地方。它工作正常并启动一个过程,但它不会等待它完成。

 execute(commandArgv, "STANDARD",0);

你们有什么想法我可能做错了吗?谢谢,非常感谢您随时帮助我。

3 个答案:

答案 0 :(得分:4)

一旦execvp()运行,它将永远不会返回。它将内存中运行的应用程序替换为所提供的内容。所以你的fprintf()和wait()都在错误的位置。

答案 1 :(得分:1)

除了让实际逻辑正确运行(Stéphane的建议都很好)之外,你可能还想在fprintf-ing之后fflush(stderr),以确保你的错误消息立即发布而不是被缓冲。

答案 2 :(得分:1)

您对流程的工作方式有一点误区。调用execvp后,没有回头路。 fork()使您拥有父项和相同的子项,但execvp将子映像覆盖为您正在调用的命令。

仅当发生严重错误以防止覆盖图像时,execvp 才会返回。所以,你需要在打电话之前打印东西。因此,您可能还想将 EXIT_SUCCESS 更改为 EXIT_FAILURE

现在使用等待还有另一个错误:你总是希望父母等待孩子,而不是相反。你不能要求孩子等。她没有什么可等待的,她会跑步和终止。因此,您需要将 wait()调用移至 else 部分。

void execute(char *command[], char *file, int descriptor)
{
    pid_t pid;
    pid = fork();

    if(pid == -1)
    {
        printf("fork() error in execute() has occurred\n");
        return; /* return here without running the next else statement*/
    }
    if(pid == 0)
    {           
        fprintf(stderr, "Process name is: %s\n", commandArgv[0]);
        fprintf(stderr, "Child pid = %d\n", getpid());
        execvp(*command,command);
        fprintf(stderr, "Error! Can't overwrite child's image!\n");
        exit(EXIT_FAILURE);
    }
    else
    {
        printf("Parent waiting for child pid: %d\n", pid);
        wait(&status);
        printf("Parent running again\n");
    }
}

但是阅读你的问题,也许你实际上不希望父母等待。如果是这种情况,请不要使用 wait()功能。

保重, 贝乔

编辑:一些小错误。孩子的pid是getpid()