[英]C: Reading From Stdin Resets Terminal Attributes?
我正在研究一个C项目,该项目应该类似于Unix的“更多”命令。 像“更多”一样,如果没有给出文件,则该程序应该能够从文件(如果指定)或stdin中获取输入(因此,可以将其他程序的输出通过管道传输到其中),并将其显示到stdout。 也像“更多”一样,应该禁用回显和规范模式,这是通过以下代码完成的:
//change terminal attributes
tcgetattr(0, &info); //Get info
tcgetattr(0, &orig_inf); //Save original info
info.c_lflag &= ~ECHO; //Disable echo
info.c_lflag &= ~ICANON; //Disable canonical mode
info.c_cc[VMIN] = 1; //Get 1 char at a time
tcsetattr(0, TCSANOW, &info); //Set attributes
要从键盘读取用户命令,我将显式打开“ dev / tty”,而不仅仅是从stdin中读取:
//Open cmd stream
if((cmd = fopen("/dev/tty", "r")) == NULL){
perror("Failure opening command stream");
tcsetattr(0, TCSANOW, &orig_inf);
exit(EXIT_FAILURE);
}
并使用getc(cmd)读取它们。 当用户提供要读取的文件时,此方法工作正常,但如果程序正在从stdin接收输入,则似乎终端属性已被重置。 我可以看到我尝试键入的每个命令(这意味着回显再次打开),除非我按Enter键,否则命令不会发送到程序(这意味着规范模式已被重新激活)。 我已经在网络和所有手册页中搜索了几乎所有正在使用的系统调用,并且似乎找不到原因。
如果有人知道为什么会这样以及如何解决它,将不胜感激。
谢谢!
似乎缺少(至少没有在问题中说明)的是,您正在打开/dev/tty
来读取命令,并且正在通过文件描述符重置原始标准输入。 但是没有提到使用fdreopen
或dup2
:
0
(FILENO_STDIN),所以它与fileno(cmd)
是不同的文件描述符-除非您使用dup2
替换它。 open
而不是fopen
打开设备,这仅仅是因为open
提供了对该过程的更多控制。 然后,将使用fdreopen
从fdreopen
中获取缓冲的流。 例如,在/dev/tty
上使用fopen
,您可能忽略了该流中的实际设置, 这些设置不一定与您在文件描述符0
上重新配置的设置相同。 一个相关的问题可能是: stdin和STDIN_FILENO有什么区别? 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.