Ctrl + D后如何重新启动stdin?

时间:2018-07-05 15:14:51

标签: c linux

运行需要终端I输入的程序,可以通过Ctrl + D“关闭” stdin。之后有什么办法可以重新打开标准输入?

1 个答案:

答案 0 :(得分:11)

中和通常在POSIXy系统上,当您在终端中按 Ctrl + D 时,标准输入描述符不会关闭;它只是使伪终端层变得可读,read()返回0。这就是POSIXy系统指示输入结束的方式。

这并不意味着文件描述符(甚至是C库在其顶部提供的流句柄)都已关闭。正如史蒂夫·萨米特(Steve Summit)在评论中提到的那样,您只需要使用clearerr() clear 流的输入结束状态,就可以读取更多数据。这告诉C库您已经注意到状态变化,但是无论如何都想尝试进一步阅读。

当进程正在写入文件,而另一个进程读取文件时,可能会发生类似情况。当阅读器到达文件末尾时,read()返回0,C库将其理解为输入末尾。它设置了一个内部标志,因此除非您调用clearerr(),否则feof()将对该流返回true。现在,如果写者写了更多数据,而读者写了clearerr(),则读者可以读取新写的附加数据。

这完全正常,而且是预期的行为。

总结:

  • 输入结束由read()操作返回0表示,但是文件描述符状态不变,可以正常使用。

  • 终端上的
  • Ctrl + D 只会导致这种情况;向终端打开的文件描述符不会受到任何其他影响,这取决于前台进程读取终端输入来决定其作用。可以继续读取更多数据。

    大多数程序都会在发生这种情况时退出,但这只是一个惯例,而不是技术要求。

  • C库检测到read()返回0,并为该流设置其内部的“输入结束”标志。对于该流,这导致feof()返回true,fgets()返回NULL,fgetc()返回EOF,依此类推。

  • 在流句柄上调用clearerr()将清除该标志,以便下一次读取尝试实际上将尝试从描述符中读取更多数据。

    man 3 clearerr手册页的“描述”部分的第一句话中对此进行了描述。