[英]solaris: O_NDELAY set on stdin: when process exits the shell exits
TLDR: In Solaris , if O_NDELAY
is set on stdin
by a child process , bash
exits. TLDR:在 Solaris 中,如果子进程在
stdin
上设置了O_NDELAY
,则bash
退出。 Why?为什么?
The following code causes interactive bash
(v4.3.33) or tcsh
(6.19.00) shells to exit after the process finishes running:以下代码导致交互式
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;
}
The versions of ksh
, csh
and zsh
we have aren't affected by this problem.我们拥有的
ksh
、 csh
和zsh
版本不受此问题的影响。
To investigate I ran bash
& csh
under truss
(similar to strace
on Linux) like this:为了进行调查,我在
truss
下运行了bash
& 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
After csh
finishes running the process it does the following:在
csh
完成运行该进程后,它会执行以下操作:
fcntl( 0, F_GETFL ) = FWRITE|FNDELAY
fcntl( 0, F_SETFL, FWRITE) = 0
... which gave me an idea. ......这给了我一个想法。 I changed the program to the commented out code above so it would toggle the state of
O_NDELAY
.我将程序更改为上面注释掉的代码,因此它会切换
O_NDELAY
的状态。 If I run it twice in a row bash doesn't exit.如果我连续运行两次,bash 不会退出。
This answer got me started on the right path.这个答案让我走上了正确的道路。 The man page for
read
(in Solaris) says:用于
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
... so when bash tries to read stdin
it returns 0 causing it to assume EOF was hit. ...所以当 bash 尝试读取
stdin
它返回 0 导致它假设 EOF 被击中。
This page indicates O_NDELAY
shouldn't be used anymore, instead recommending O_NONBLOCK
. 此页面表明不应再使用
O_NDELAY
,而是推荐O_NONBLOCK
。 I've found similar statements regarding O_NDELAY
/ FIONBIO
for various flavors of UNIX.我发现了有关
O_NDELAY
/ FIONBIO
类似声明, FIONBIO
于各种风格的 UNIX。
As an aside, in Linux O_NDELAY == FNDELAY == O_NONBLOCK
, so it's not terribly surprising I was unable to reproduce this problem in that environment. O_NDELAY == FNDELAY == O_NONBLOCK
,在 Linux O_NDELAY == FNDELAY == O_NONBLOCK
,因此我无法在该环境中重现此问题并不奇怪。
Unfortunately, the tool that's doing this isn't one I have the source code for, though from my experimenting I've found ways to work around the problem.不幸的是,执行此操作的工具不是我拥有源代码的工具,尽管通过我的试验,我找到了解决问题的方法。
If nothing else I can make a simple program that removes O_NDELAY
as above then wrap execution of this tool in a shell script that always runs the "fixer" program after the other one.如果没有别的,我可以制作一个简单的程序来删除
O_NDELAY
,然后将这个工具的执行包装在一个 shell 脚本中,该脚本总是在另一个程序之后运行“修复程序”程序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.