diff options
author | Father Chrysostomos <sprout@cpan.org> | 2011-11-19 14:35:24 -0800 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2011-11-19 16:14:54 -0800 |
commit | 4ee6a9e8e4c361531b7884e075604202a3990a8f (patch) | |
tree | dcde2a11d317475b86f8f04e07052303fe9bfd47 /sv.c | |
parent | 21b5e840ca3d8b2cc03757792df203d73c518fad (diff) | |
download | perl-4ee6a9e8e4c361531b7884e075604202a3990a8f.tar.gz |
Call FETCH once on handle passed as 3rd arg to open()
When open() has three arguments and the second ends with & the third
argument is treated as a handle.
In some cases get-magic was being skipped; in others, it was being
called three times.
This commit fixes it by modifying sv_2io.
In 5.8.x (before commit 7a5fd60d4), sv_2io did not call get-magic at
all except when croaking ("Bad filehandle: %"SVf). In 5.10.0 (after
commit 7a5fd60d4), it started calling get-magic only if the sv was
neither a glob, a reference, or undef. So it has never been reliable
in its invocation of get-magic.
sv_2io now consistently skips get-magic on the sv passed in directly
to it (open(), the only caller in the core, has already called get-
magic before passing it in). It now calls get-magic on SvRV(sv) if
what is passed in is a reference, so open(fh, ">&", \$tied) will work.
Interestingly, open supports multiple levels of references:
\\\\\\\\\\\\open+f,">&",\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
\\\\\\\\\\\*STDOUT;print{f}"Just another Perl hacker,\n",.\\\\\\\y\\\
Diffstat (limited to 'sv.c')
-rw-r--r-- | sv.c | 16 |
1 files changed, 12 insertions, 4 deletions
@@ -8842,15 +8842,23 @@ Perl_sv_2io(pTHX_ SV *const sv) default: if (!SvOK(sv)) Perl_croak(aTHX_ PL_no_usym, "filehandle"); - if (SvROK(sv)) + if (SvROK(sv)) { + SvGETMAGIC(SvRV(sv)); return sv_2io(SvRV(sv)); - gv = gv_fetchsv(sv, 0, SVt_PVIO); + } + gv = gv_fetchsv_nomg(sv, 0, SVt_PVIO); if (gv) io = GvIO(gv); else io = 0; - if (!io) - Perl_croak(aTHX_ "Bad filehandle: %"SVf, SVfARG(sv)); + if (!io) { + SV *newsv = sv; + if (SvGMAGICAL(sv)) { + newsv = sv_newmortal(); + sv_setsv_nomg(newsv, sv); + } + Perl_croak(aTHX_ "Bad filehandle: %"SVf, SVfARG(newsv)); + } break; } return io; |