C语言 像bc这样的Unix程序在作为后台作业启动时如何干净地处理输入/输出流?



我注意到Unix bc程序没有打印出它通常的提示符(三个符号">>>>"),当它作为后台进程启动时(就像你以"bc &"执行它一样)。这让我感到困惑,因为根据我对Unix的有限了解,启动一个程序作为后台作业将使它一直运行,直到它试图从stdin中读取,此时它将接收到一个停止自己的信号。

但是将bc作为后台作业运行("bc &")不会导致它至少打印出">>>";在停止之前提示,告诉我程序以某种方式处理了它。我很好奇它是如何做到这一点的。当我编写一个简单的程序,只试图模拟输入/输出交互时,它仍然打印出">>>";在被悬挂之前,看起来一点也不干净,在某些贝壳上的行为甚至更奇怪。

我试着查看Unix bc源代码,我能够跟踪代码的部分,它打印出">>>";提示,但是当作为后台进程启动时,它如何处理不打印提示超出了我的范围。我知道,显然你永远不会在后台启动一个输入/输出交互程序,因为这违背了预期的功能和常识,但我对它背后的概念更感兴趣,比如这是用信号处理实现的,或者这是一些更高级的输入/输出流缓冲,或者其他一些我不熟悉的Unix概念。

您的bc版本所做的第一件事是调用tcsetattr函数。这个函数,当从后台进程调用时,导致SIGTTOU信号被发送到进程,这在默认情况下导致进程停止。

任何操作终端属性的程序(vim, bash,任何使用readlinecurses的程序,…)可能会以完全相同的方式表现。

最新更新