1

我想编写一个小程序,打印出一个长列表,可以通过(或)在终端中分页,以便可以从头到脚检查列表...moreless

该程序:

  • fork' 关闭more执行程序的子进程
  • 在父进程中,打印列表
  • 在父/子之间有一个pipe设置,以便父打印到的列表stdout被发送到more程序的stdin

代码:

int main(int argc, char *argv[])
{
    int pager, status;
    int pipes[2];

    pipe(pipes);

    pager = fork();

    if (pager == 0) { // child

        dup2(pipes[0], 0);
        close(pipes[1]);
        char *args[] = {"more", NULL}; 
        execvp(args[0], args);

    } else { // parent

        dup2(pipes[1], 1);

        int x;
        for (x = 0; x < 500; x++) {
            printf("Hello World! %d\n", x);
        }  

        close(pipes[0]);
        close(pipes[1]);

        wait(&status);
    } 

    return 0;
}

我大部分时间都在工作:

  • “Hello World!...”消息的长列表打印在终端上,由 a 剪裁,--More--因此我知道基本管道设置正在运行。
  • 如果我[q]在整个列表完成打印(退出more进程)之前按下,程序(父/子)按预期退出

我遇到的唯一问题是,如果我一直按[space][return](它会推进由 给出的输出more)并到达列表的末尾(第 500 个“Hello World!...”消息),那么终端就会挂起。按[q]是没有反应的(我必须 [ctrl+c]出去)。

父进程卡在wait. 即使我关闭了父级中的两个管道,该过程也没有退出more

4

1 回答 1

1

在您的代码中,您正在关闭pipe[0]这不是您正在写给孩子的描述符。你这样做dup2(pipes[1], 1)是为了告诉孩子管道已经结束,你必须关闭你正在写的那个。

close(1);

当然,如果您打算使用 stdout 继续您的流程,您必须恢复原始输出,因为它现在将被关闭。

于 2014-01-03T12:11:45.857 回答