#!/usr/bin/perl
use strict;
use warnings;
use IPC::Open3;
use IO::Select;
my @cmd = qw'echo bar'; # writing to 'echo' fails
#my @cmd = qw'cat'; # ... while 'cat' works
open3(my $wh, my $rh, undef, @cmd);
# tiny delay, so the command gets enough time to close STDIN
# (prevent potential race condition, in this demo script)
select undef,undef,undef, 0.1;
my $msg = "foo";
#-----
print $wh "$msg\n";
close $wh;
#-----
my $data = "";
if (IO::Select->new($rh)->can_read()) {
print "reading from $rh ('@cmd |')\n";
while (sysread($rh, my $buffer, 1000)) {
$data .= $buffer;
}
}
print "data: $data\n";
####
#-----
# handle SIGPIPE ourselves, so we don't get killed
$SIG{PIPE} = sub { warn "BROKEN PIPE\n" };
if (my ($w) = IO::Select->new($wh)->can_write()) {
if (print $w "$msg\n") {
print "wrote '$msg' to $w ('| @cmd')\n";
close $w;
} else {
warn "print to $w FAILED\n";
# we'll have gotten a SIGPIPE, too
}
} else {
warn "$wh not ready for writing\n";
}
#-----
####
BROKEN PIPE
print to GLOB(0x6ff5b0) FAILED
reading from GLOB(0x6ff360) ('echo bar |')
data: bar
####
wrote 'foo' to GLOB(0x63c160) ('| cat')
reading from GLOB(0x6ff5a0) ('cat |')
data: foo
####
GLOB(0x6ff5b0) not ready for writing
reading from GLOB(0x6ff360) ('echo bar |')
data: bar