在stdin上设置solaris:O_NDELAY:当进程退出时,shell退出



TLDR:在Solaris中,如果子进程stdin上设置了O_NDELAY,则bash将退出。为什么?

以下代码导致交互式bash(v4.3.33(或tcsh(6.19.00(shell在进程完成运行后退出:

#include <fcntl.h>
int main() {
fcntl( 0, F_SETFL, O_NDELAY );
//int x = fcntl( 0, F_GETFL );
//fcntl( 0, F_SETFL, ~(x ^ (~O_NDELAY)) );
return 0;
}

我们的kshcshzsh版本不受此问题的影响。

为了调查,我运行了bash&truss下的csh(类似于Linux上的strace(如下:

$ truss -eaf -o bash.txt -u'*' -{v,r,w}all bash --noprofile --norc
$ truss -eaf -o csh.txt -u'*' -{v,r,w}all csh -f

csh完成进程运行后,将执行以下操作:

fcntl( 0, F_GETFL ) = FWRITE|FNDELAY
fcntl( 0, F_SETFL, FWRITE) = 0

这给了我一个主意。我将程序更改为上面注释掉的代码,以便切换O_NDELAY的状态。如果我连续运行两次,bash不会退出。

这个答案让我走上了正确的道路。read(在Solaris中(的手册页显示:
When attempting to read a file associated with a terminal that has no data currently available:
* If O_NDELAY is set, read() returns 0
* If O_NONBLOCK is set, read() returns -1 and sets errno to EAGAIN

因此,当bash尝试读取CCD_ 16时,它返回0,导致它认为EOF被命中。

此页面表示不应再使用O_NDELAY,而应推荐使用O_NONBLOCK。对于各种风格的UNIX,我发现了关于O_NDELAY/FIONBIO的类似语句。

顺便说一句,在LinuxO_NDELAY == FNDELAY == O_NONBLOCK中,我无法在那个环境中重现这个问题也就不足为奇了。

不幸的是,做这件事的工具不是我的源代码,尽管通过我的实验,我找到了解决这个问题的方法。

如果没有其他东西,我可以制作一个简单的程序,如上所述删除CCD_;定影器";一个接一个的程序。

相关内容

  • 没有找到相关文章

最新更新