繁体   English   中英

C:从Stdin读取会重置终端属性吗?

[英]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来读取命令,并且正在通过文件描述符重置原始标准输入。 但是没有提到使用fdreopendup2

  • 因为您引用的是文件描述符0 (FILENO_STDIN),所以它与fileno(cmd)是不同的文件描述符-除非您使用dup2替换它。
  • 通常,一个人使用open而不是fopen打开设备,这仅仅是因为open提供了对该过程的更多控制。 然后,将使用fdreopenfdreopen中获取缓冲的流。

例如,在/dev/tty上使用fopen ,您可能忽略了流中的实际设置, 这些设置不一定与您在文件描述符0上重新配置的设置相同。 一个相关的问题可能是: stdin和STDIN_FILENO有什么区别?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM