“更多”如何运作?

时间:2015-03-01 10:30:12

标签: pipe

 #include <stdio.h> 
 #include <unistd.h>
 #include <my_helpers.h>
 #include <stdlib.h>
 #include <time.h>




/*
 * Try to read from from stdin from both parent and child and see 
 * what happens
 */



int main()
{
    char buf[1024];
    int pipefd[2];
    int sts;
    char *childArgv[] = {"/usr/bin/more", NULL};

    if(pipe(pipefd) < 0)
    {
        perror("pipe()");
        exit(2);
    }


    if(fork() == 0)
    {
        if(dup2(pipefd[0], STDIN_FILENO) < 0)
        {
            perror("dup()");
            exit(2);
        }
        close(pipefd[1]);
        execvp("/usr/bin/more", childArgv);


    }
    else
    {
        close(pipefd[0]);
        // in parent 
        while((sts = read(0, buf, 1024)) > 0)
        {
            buf[sts]='\0';
            write(pipefd[1], buf, sts);
        }
        wait();
    }
}

我有一个简单的程序,可以产生更多&#34;更多&#34;它输出父母的写作。 &#34;更多&#34;进程的输入被更改为管道。

我怀疑,&#34;更多&#34;进程与用户交互。它响应&#34; q&#34;,&#34;空间&#34;命令等。我不确定它是如何发生的,因为stdin不是终端。

我的问题的更一般形式是,当更多从管道读取输入时,用户交互如何发生。

1 个答案:

答案 0 :(得分:2)

几乎可以肯定,它将拥有(或创建)/dev/tty(或代表您的终端的其他设备文件)的文件句柄。

因此,即使你从其他地方重定向输入,仍然可以用来从终端本身获取信息。

换句话说,虽然它会从stdin读取数据到页面,但用户中的命令将从其他文件句柄中提取。


举例来说,less程序有一个名为ttyin.c的文件,其中包含一个名为open_getchr()的函数,它包含这一小段:

tty = open("/dev/tty", OPEN_READ);

该功能实际上比这要复杂得多,因为它必须处理MS-DOS,Windows,OS / 2和各种UNIX实现,但这基本上归结为后者。< / p>


对于more具体而言,它不会打开新的文件句柄,而是尝试使用stderr文件句柄的文件描述符作为输入你可以从它的readch()函数中看到:

int readch(void)
{
    unsigned char c;

    errno = 0;
    if (read(fileno(stderr), &c, 1) <= 0) {
        if (errno != EINTR)
            end_it(0);
        else
            c = otty.c_cc[VKILL];
    }
    return (c);
}

您可以使用以下命令验证:

find / | more 2>/dev/null

&#34;打破&#34;更多,在第一页之后退出而不提示输入命令,因为stderr不再引用您的终端设备。