summaryrefslogtreecommitdiff
path: root/sv.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2011-11-19 14:35:24 -0800
committerFather Chrysostomos <sprout@cpan.org>2011-11-19 16:14:54 -0800
commit4ee6a9e8e4c361531b7884e075604202a3990a8f (patch)
treedcde2a11d317475b86f8f04e07052303fe9bfd47 /sv.c
parent21b5e840ca3d8b2cc03757792df203d73c518fad (diff)
downloadperl-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.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/sv.c b/sv.c
index d9153b6a36..03aff4eb79 100644
--- a/sv.c
+++ b/sv.c
@@ -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;