Ovid
Ovid

Reputation: 11677

Error in perlipc documentation?

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

Answers (2)

Graham Barr
Graham Barr

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

sarnold
sarnold

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

Related Questions