fix for Tie::File test failures on windows: the problem was
Gurusamy Sarathy [Mon, 12 May 2003 01:40:46 +0000 (01:40 +0000)]
that Tie::File did not close any file handles it opens internally,
leading to file handle leaks and t/tf* temporary file littering;
we now close the handle iff Tie::File opened it

this fix unearths what appears to be a perl bug in localizing globs:
09_gen_rs.t fails due to a prematurely closed filehandle, although
it wasn't explicitly closed anywhere by the code (renaming the
*FH at line 97 to *FH1 makes it work, but I haven't done this
to allow the bug to be tracked down)

p4raw-id: //depot/perl@19498

lib/Tie/File.pm

index a478688..26014dd 100644 (file)
@@ -97,6 +97,7 @@ sub TIEARRAY {
     $fh = \do { local *FH };   # only works in 5.005 and later
     sysopen $fh, $file, $opts{mode}, 0666 or return;
     binmode $fh;
+    ++$opts{ourfh};
   }
   { my $ofh = select $fh; $| = 1; select $ofh } # autoflush on write
   if (defined $opts{discipline} && $] >= 5.006) {
@@ -407,6 +408,10 @@ sub DESTROY {
   my $self = shift;
   $self->flush if $self->_is_deferring;
   $self->{cache}->delink if defined $self->{cache}; # break circular link
+  if ($self->{fh} and $self->{ourfh}) {
+      delete $self->{ourfh};
+      close delete $self->{fh};
+  }
 }
 
 sub _splice {
@@ -2289,6 +2294,11 @@ means no pipes or sockets.  If C<Tie::File> can detect that you
 supplied a non-seekable handle, the C<tie> call will throw an
 exception.  (On Unix systems, it can detect this.)
 
+Note that Tie::File will only close any filehandles that it opened
+internally.  If you passed it a filehandle as above, you "own" the
+filehandle, and are responsible for closing it after you have untied
+the @array.
+
 =head1 Deferred Writing
 
 (This is an advanced feature.  Skip this section on first reading.)