#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不是终端。
我的问题的更一般形式是,当更多从管道读取输入时,用户交互如何发生。
答案 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
不再引用您的终端设备。