Reputation: 11677
I'm trying to puzzle through something I see in the perlipc documentation.
If you're writing to a pipe, you should also trap SIGPIPE. Otherwise, think of what happens when you start up a pipe to a command that doesn't exist: the open() will in all likelihood succeed (it only reflects the fork()'s success), but then your output will fail--spectacularly. Perl can't know whether the command worked because your command is actually running in a separate process whose exec() might have failed. Therefore, while readers of bogus commands return just a quick end of file, writers to bogus command will trigger a signal they'd better be prepared to handle. Consider:
open(FH, "|bogus") or die "can't fork: $!";
print FH "bang\n" or die "can't write: $!";
close FH or die "can't close: $!";
That won't blow up until the close, and it will blow up with a SIGPIPE. To catch it, you could use this:
$SIG{PIPE} = 'IGNORE';
open(FH, "|bogus") or die "can't fork: $!";
print FH "bang\n" or die "can't write: $!";
close FH or die "can't close: status=$?";
If I'm reading that correctly, it says that the first version will probably not die until the final close.
However, that's not happening on my OS X box (Perl versions 5.8.9 through 5.15.9). It blows up on the open
with a "can't fork: No such file or directory" regardless of whether or not I have the $SIG{PIPE} line in there.
What am I misunderstanding?
Upvotes: 6
Views: 180
Reputation: 56
This was a change implemented back during development of 5.6 so that system() could detect when it failed to fork/exec the child
https://github.com/mirrors/perl/commit/d5a9bfb0fc8643b1208bad4f15e3c88ef46b4160
It is also documented in http://search.cpan.org/dist/perl/pod/perlopentut.pod#Pipe_Opens
which itself points to perlipc, but perlipc does seem to be missing this
Upvotes: 4
Reputation: 104080
Same output on my Perl, v5.14.2
, Ubuntu 12.04:
$ perl
open(FH, "|bogus") or die "can't fork: $!";
print FH "bang\n" or die "can't write: $!";
close FH or die "can't close: $!";
can't fork: No such file or directory at - line 1.
And that error is odd, since it has nothing to do with forking -- they must have added some lookahead-guessing to see if it could execute bogus
. (Which would be a race condition at best, but one likely to provide significantly better error handling in the common case; and only be as inconvenient as the old behavior when the race is lost.)
Upvotes: 0