On 2011-05-17 21:18:15 +0300, Niko Tyni wrote:
> Right. The ssh process sets its stderr to non blocking mode (in
> ssh_session2_open()), and afterwards when the kernel pipe buffer fills
> up, your print() call to the same duplicated file descriptor fails with
> $! set to EAGAIN.
Actually, not stderr, but stdout. A command like (without the "2>&1")
strace -f -o str.out sh -c "env -u SVN_SSH svn diff --diff-cmd diff -x -U80
-c191480 | wc"
gives
581297 dup(0) = 4
581297 dup(1) = 5
581297 dup(2) = 6
581297 fcntl(4, F_SETFD, FD_CLOEXEC) = 0
581297 fcntl(5, F_SETFD, FD_CLOEXEC) = 0
581297 fcntl(6, F_SETFD, FD_CLOEXEC) = 0
581297 ioctl(4, TCGETS2, 0x7ffddf553e90) = -1 ENOTTY (Inappropriate ioctl for
device)
581297 fcntl(4, F_GETFL) = 0 (flags O_RDONLY)
581297 fcntl(4, F_GETFL) = 0 (flags O_RDONLY)
581297 fcntl(4, F_SETFL, O_RDONLY|O_NONBLOCK) = 0
581297 ioctl(5, TCGETS2, 0x7ffddf553e90) = -1 ENOTTY (Inappropriate ioctl for
device)
581297 fcntl(5, F_GETFL) = 0x1 (flags O_WRONLY)
581297 fcntl(5, F_GETFL) = 0x1 (flags O_WRONLY)
581297 fcntl(5, F_SETFL, O_WRONLY|O_NONBLOCK) = 0
Both stdin (fd 0) and stdout (fd 1) are set to nonblocking,
since fd 0 and fd 4 share the file status flags, and ditto
for fd 1 and fd 5.
So I'm wondering why the bug with Subversion doesn't also occur
without the "2>&1".
If I add the "2>&1" as below
strace -f -o str.out sh -c "(env -u SVN_SSH svn diff --diff-cmd diff -x -U80
-c191480) 2>&1 | wc"
I get:
582707 dup(0) = 4
582707 dup(1) = 5
582707 dup(2) = 6
582707 fcntl(4, F_SETFD, FD_CLOEXEC) = 0
582707 fcntl(5, F_SETFD, FD_CLOEXEC) = 0
582707 fcntl(6, F_SETFD, FD_CLOEXEC) = 0
582707 ioctl(4, TCGETS2, 0x7ffe7c961ee0) = -1 ENOTTY (Inappropriate ioctl for
device)
582707 fcntl(4, F_GETFL) = 0 (flags O_RDONLY)
582707 fcntl(4, F_GETFL) = 0 (flags O_RDONLY)
582707 fcntl(4, F_SETFL, O_RDONLY|O_NONBLOCK) = 0
582707 ioctl(5, TCGETS2, 0x7ffe7c961ee0) = -1 ENOTTY (Inappropriate ioctl for
device)
582707 fcntl(5, F_GETFL) = 0x1 (flags O_WRONLY)
582707 fcntl(5, F_GETFL) = 0x1 (flags O_WRONLY)
582707 fcntl(5, F_SETFL, O_WRONLY|O_NONBLOCK) = 0
582707 ioctl(6, TCGETS2, 0x7ffe7c961ee0) = -1 ENOTTY (Inappropriate ioctl for
device)
582707 fcntl(6, F_GETFL) = 0x1 (flags O_WRONLY)
582707 fcntl(6, F_GETFL) = 0x1 (flags O_WRONLY)
582707 fcntl(6, F_SETFL, O_WRONLY|O_NONBLOCK) = 0
Now, every standard fd is set to nonblocking.
I get the same thing without svn, by using:
strace -f -o str.out sh -c "( true | ssh localhost true | cat; ) 2>&1 | wc"
The "true |" part is needed to get the F_SETFL on fd 4.
The "| cat" part is needed to get the F_SETFL on fd 6.
With just "ssh localhost true", only fd 5 is set to nonblocking.
Consider the following Perl script stdout-nonblock, which
• outputs the (non)blocking status of stdout,
• sets stdout to nonblocking (this will be used for the
first test below).
----------------------------------------------------------------
#!/usr/bin/env perl
use strict;
use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
my $flags = fcntl(STDOUT, F_GETFL, 0) or die;
print ($flags & O_NONBLOCK ? "Nonblocking\n" : "Blocking\n");
fcntl(STDOUT, F_SETFL, $flags | O_NONBLOCK) or die;
----------------------------------------------------------------
One gets:
$ sh -c "( ./stdout-nonblock; ./stdout-nonblock; ) 2>&1 | cat"
Blocking
Nonblocking
The 2 stdout-nonblock invocations allow one to confirm that if fd 1 is
set to nonblocking, this affects the parent process, i.e. the shell.
Now, let's test ssh:
$ sh -c "( true | ssh localhost true | cat; ./stdout-nonblock; ) 2>&1 | cat"
Blocking
because ssh resets the fd file status flags to their default.
But the following test shows that a background ssh can affect the shell
(just like it affects Subversion).
$ sh -c "( true | ssh localhost sleep 2 | cat & sleep 1; ./stdout-nonblock; )
2>&1 | cat"
Nonblocking
Ditto with just
$ sh -c "( ssh localhost sleep 2 & sleep 1; ./stdout-nonblock; ) 2>&1 | cat"
Nonblocking
All shells seem to be affected. I'm wondering whether this is also
a bug in the shells or it should be forbidden for programs to change
the file status flags of the standard file descriptors.
--
Vincent Lefèvre <[email protected]> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / Pascaline project (LIP, ENS-Lyon)