I've got a problem in which cvs is dangling at the end of a pipe with its stdin/stderr tied through a pipe to a program that's parsing its output (such as emacs with its VC minor mode or CVS major mode). cvs is using ssh to access the CVS server, and this ssh inherits its stderr file from cvs. Now ssh sets O_NONBLOCK on its stderr output, and this also affects both stdout and stderr coming from cvs (since the cvs's fd1 and fd2, and ssh's fd2 all refer to the same kernel object). After this has happened, strace shows that cvs starts experiencing writes that return EAGAIN on its stderr output when the pipe buffer becomes full (which it just ignores). As far as cvs is concerned, this shouldn't happen (it should, however, probably check for the error message and retry the write). ssh's stdout isn't a problem because cvs opens its own pipes for connecting to ssh's stdin and stdout. Note that ssh doesn't set the O_NONBLOCK flag on exit either. As far as strace is concerned, the following two adjacent fcntl64 syscalls are the only ones that deal with stderr's O_NONBLOCK flag. ioctl(2, 0x5401, 0xbffff150) = -1 EINVAL (Invalid argument) fcntl64(0x2, 0x3, 0, 0x2) = 1 fcntl64(0x2, 0x4, 0x801, 0x2) = 0 Thanks, David
hm, what do you suggest?
I would suggest that SSH shouldn't set O_NONBLOCK on its stderr output. It is only for errors after all, and ssh won't normally be writing to it, and so doing that ought not to be a problem.
ssh can't afford for its stderr to ever block, as this would freeze all sessions and port-forwardings. We therefore can't remove the nonblock from stderr.
Mass change of RESOLVED bugs to CLOSED