通过execve从子级调用的排序不会自然终止

时间:2019-04-01 20:46:21

标签: c linux pipe fork execve

我正试图通过已在sort的stdin上重叠的管道来推送一些文本文件。它可以工作,但不能自然终止(有趣的是,按下“ enter”(输入)按钮似乎可以做到)。

//child
if(rc == 0)
{
    alarm(60);
    close(stdin_pipe_fds[1]);

    close(0);
    dup(stdin_pipe_fds[0]);
    close(stdin_pipe_fds[0]);
    execve("/usr/bin/sort", argv, NULL);
    exit(0);
}

//Parent
if(rc >0)
{
    alarm(60);
    close(stdin_pipe_fds[0]);
    close(stdout_pipe_fds[1]);
    close(stderr_pipe_fds[1]);
    while(fscanf(coolFile, "%1023s", newWord) ==1)
    {
        if(strcmp(newWord, "foobar") != 0)
        {
            write(stdin_pipe_fds[1], newWord, (strlen(newWord)+1));
        }
    }
    if(argc == 2)
    {
        write(stdin_pipe, argc[2], 2);
    }
    if(argc == 3)
    {
        write(stdin_pipe, argc[3], 2);
    }
}

}

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

这是一种显示相同效果的简便方法:

$ cd /
$ ls -1 &                              # 1
[1] 58745
myuser@myhost / $ Applications         # 2
Library                                # 3
Network
System
Users
Volumes                                # 4
  1. 命令在后台运行。
  2. 您会收到提示
  3. 命令的输出开始覆盖提示
  4. 退出后台命令,但这不会导致提示重画。由于您没有看到提示(在步骤2中将其删除),因此您认为该进程仍在运行。
  5. 当您按Enter键时,将重新绘制提示。由于现在再次显示可见提示,因此您错误地认为Enter导致程序退出。

相反,您可能只是盲目地键入echo "Hello World"并按Enter键,您会看到shell响应良好。这纯粹是一个表面问题。

要解决此问题,您应该:

  1. 为孩子拥有父母wait(),这样它就不会在孩子面前退出。
  2. 确保父级完全关闭管道(之前等待)。以前,您的父母立即退出并关闭了管道。由于现在它将等待孩子,因此您必须手动关闭管道,以免出现死锁,在死锁中,父母等待孩子退出,而孩子等待父母继续或结束输入。