http://qs1969.pair.com?node_id=1109928

salva has asked for the wisdom of the Perl Monks concerning the following question:

I am working on a new backend for my Net::SSH::Any module which uses an external SSH client (ssh or plink) to connect to the remote host. Net::SSH::Any is quite flexible in terms of setting redirections for the remote program streams or capturing the data, so I have developed a layer that is able to handle that and that works on Linux/Unix... and almost on Windows!

The issue I am facing on Windows is that when I run the slave process with its STDIN stream attached to a pipe and, after writing something, I close the perl side, the slave doesn't get the EOF.

The following program shows the issue:

open my $oldin, '<&', \*STDIN or die $!; pipe my($r), my ($w) or die $!; open STDIN, '<&', $r or die $!; my $pid = system 1, 'perl -ne print'; print "pid: $pid\n"; close STDIN or die $!; open STDIN, '<&', $oldin; close $r or die $!; print {$w} "hello world! ($_)\n" for 0..9; close $w or die $!; print "waiting for slave process\n"; waitpid $pid, 0 or die $!

If you run it you will see that the program stalls waiting for the slave to finish.

I can also reproduce the issue with IPC::Open2 open2:

use IPC::Open2 qw(open2); my $pid = open2 ">&STDOUT", my($w), 'perl -ne print' or die $!; print "pid: $pid\n"; print {$w} "hello world! ($_)\n" for 0..9; close $w or die $!; print "waiting for slave process\n"; waitpid $pid, 0 or die $!

On the other hand, when a regular file is used, everything works as expected:

open my $oldin, '<&', \*STDIN or die $!; open STDIN, '<&', \*DATA or die $!; my $pid = system 1, 'perl -ne print'; print "pid: $pid\n"; close STDIN or die $!; open STDIN, '<&', $oldin; print "waiting for slave process\n"; waitpid $pid, 0 or die $! __DATA__ hello world! (from DATA)
And creating the pipe using open with mode |- also works (but I don't want to do it that way because I may also need to redirect STDOUT and STDERR):
my $pid = open my $w, '|-', 'perl -ne print' or die $!; print "pid: $pid\n"; print {$w} "hello world! ($_)\n" for 0..9; close $w or die $!; print "waiting for slave process\n"; waitpid $pid, 0 or die $!
Does anybody have a clue what's going on?

All that occurs to me is that the slave may be inheriting also the write side of the pipe.