This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Stop eof($glob_copy) from clearing PL_last_in_gv
authorFather Chrysostomos <sprout@cpan.org>
Sun, 18 Dec 2011 07:48:51 +0000 (23:48 -0800)
committerFather Chrysostomos <sprout@cpan.org>
Sun, 18 Dec 2011 07:53:53 +0000 (23:53 -0800)
commit3500db162fc97aafc7cfeaa8c61f6c681810e3b4
tree9cd2869d046a4da614532b2724fd1bc17f8a9855
parente9d7a483027872dd114e87fb75bc9afabf60b654
Stop eof($glob_copy) from clearing PL_last_in_gv

eof had the same bug as tell.  Here is the commit message from
8dc99089, which fixed tell:

----------------------------------------------------------------------

Stop tell($glob_copy) from clearing PL_last_in_gv

This bug is a side effect of rv2gv’s starting to return an incoercible
mortal copy of a coercible glob in 5.14:

$ perl5.12.4 -le 'open FH, "t/test.pl"; $fh=*FH; tell $fh; print tell'
0
$ perl5.14.0 -le 'open FH, "t/test.pl"; $fh=*FH; tell $fh; print tell'
-1

In the first case, tell without arguments is returning the position of
the filehandle.

In the second case, tell with an explicit argument that happens to
be a coercible glob (tell has an implicit rv2gv, so tell $fh is actu-
ally tell *$fh) sets PL_last_in_gv to a mortal copy thereof, which is
freed at the end of the statement, setting PL_last_in_gv to null.  So
there is no ‘last used’ handle by the time we get to the tell without
arguments.

This commit adds a new rv2gv flag that tells it not to copy the glob.

By doing it unconditionally on the kidop, this allows tell(*$fh) to
work the same way.

Let’s hope nobody does tell(*{*$fh}), which will unset PL_last_in_gv
because the inner * returns a mortal copy.

This whole area is really icky.  PL_last_in_gv should be refcounted,
but that would cause handles to leak out of scope, breaking programs
that rely on the auto-closing ‘feature’.
op.c
t/io/tell.t