This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Fix fd leak in IO::Pipe
authorRoderick Schertler <roderick@gate.net>
Sun, 23 Feb 1997 19:29:57 +0000 (14:29 -0500)
committerChip Salzenberg <chip@atlantic.net>
Fri, 21 Feb 1997 14:41:53 +0000 (02:41 +1200)
Subject: Re: Another goof with IO::Pipe?

On Fri, 21 Feb 1997 18:51:10 -0500 (EST), Ilya Zakharevich <ilya@math.ohio-state.edu> said:
>
> IO::Pipe basically does:
>  $fh = $rw ? $me->reader() : $me->writer(); # close the other end
>         bless $io, "IO::Handle";
>         $io->fdopen($fh, $mode);
>
> In the corresponding place IPC::Open3 adds:
>
>  $fh->close;
>
> Which one is correct?

The ->close is necessary, the IO::Pipe code is leaving two copies of the
pipe in the child.  It dup()s the pipe onto STDIN/STDOUT, but doesn't
then close the pipe.

Here's an fd scan of a child whose parent did ->reader:

    FD  Type            Mode  UID       Inode    File System  FS Type  rdev
    0   char special    0620  roderick  686      13054,42068  dg/ux    23, 8
    1   FIFO special    0000  roderick  23         900,    0  dg/ux       --
    2   char special    0620  roderick  686      13054,42068  dg/ux    23, 8
    4   FIFO special    0000  roderick  23         900,    0  dg/ux       --

fd 4 is original write side of the pipe (the read side was fd 3) which
should have been closed by this point.

p5p-msgid: <pzn2sv722y.fsf@eeyore.ibcinc.com>

ext/IO/lib/IO/Pipe.pm

index 499856a..1768a4a 100644 (file)
@@ -14,7 +14,7 @@ use vars qw($VERSION);
 use Carp;
 use Symbol;
 
 use Carp;
 use Symbol;
 
-$VERSION = "1.09";
+$VERSION = "1.0901";
 
 sub new {
     my $type = shift;
 
 sub new {
     my $type = shift;
@@ -65,6 +65,7 @@ sub _doit {
         }
         bless $io, "IO::Handle";
         $io->fdopen($fh, $mode);
         }
         bless $io, "IO::Handle";
         $io->fdopen($fh, $mode);
+        $fh->close;
 
         if ($do_spawn) {
           $pid = eval { system 1, @_ }; # 1 == P_NOWAIT
 
         if ($do_spawn) {
           $pid = eval { system 1, @_ }; # 1 == P_NOWAIT