IO::Pipe - close(<handle>) does not set $?

Posted by danboo on Stack Overflow See other posts from Stack Overflow or by danboo
Published on 2013-10-29T21:56:24Z Indexed on 2013/10/30 3:54 UTC
Read the original article Hit count: 79

Filed under:

My understanding is that closing the handle for an IO::Pipe object should be done with the method ($fh->close) and not the built-in (close($fh)).

The other day I goofed and used the built-in out of habit on a IO::Pipe object that was opened to a command that I expected to fail. I was surprised when $? was zero, and my error checking wasn't triggered.

I realized my mistake. If I use the built-in, IO:Pipe can't perform the waitpid() and can't set $?. But what I was surprised by was that perl seemed to still close the pipe without setting $? via the core.

I worked up a little test script to show what I mean:

use 5.012;
use warnings;

use IO::Pipe;

say 'init pipes:';
pipes();
my $fh = IO::Pipe->reader(q(false));
say 'post open pipes:';
pipes();

say 'return: ' . $fh->close;
#say 'return: ' . close($fh);
say 'status: ' . $?;
say q();

say 'post close pipes:';
pipes();

sub pipes
   {
   for my $fd ( glob("/proc/self/fd/*") )
      {
      say readlink($fd) if -p $fd;
      }
   say q();
   }

When using the method it shows the pipe being gone after the close and $? is set as I expected:

init pipes:

post open pipes:
pipe:[992006]

return: 1
status: 256

post close pipes:

And, when using the built-in it also appears to close the pipe, but does not set $?:

init pipes:

post open pipes:
pipe:[952618]

return: 1
status: 0

post close pipes:

It seems odd to me that the built-in results in the pipe closure, but doesn't set $?. Can anyone help explain the discrepancy?

Thanks!

© Stack Overflow or respective owner

Related posts about perl