diff options
author | Tony Cook <tony@develop-help.com> | 2017-01-12 10:26:47 +1100 |
---|---|---|
committer | Tony Cook <tony@develop-help.com> | 2017-09-11 10:59:44 +1000 |
commit | 8ab93df006894c4c166b3684129c3180b5febe48 (patch) | |
tree | 34c3545f0b0adf8e64f51c33be3177ac2eb015cd /doio.c | |
parent | 977bd6d625ba53702249ae8c80cede962e6402b5 (diff) | |
download | perl-8ab93df006894c4c166b3684129c3180b5febe48.tar.gz |
(perl #127663) don't do inplace renaming etc in child threads
This also avoids double closedir()ing the directory handle.
Diffstat (limited to 'doio.c')
-rw-r--r-- | doio.c | 25 |
1 files changed, 20 insertions, 5 deletions
@@ -881,10 +881,12 @@ S_argvout_free(pTHX_ SV *io, MAGIC *mg) { /* note this can be entered once the file has been successfully deleted too */ - assert(mg->mg_obj && SvTYPE(mg->mg_obj) == SVt_PVAV); assert(IoTYPE(io) != IoTYPE_PIPE); - if (IoIFP(io)) { + /* mg_obj can be NULL if a thread is created with the handle open, in which + case we leave any clean up to the parent thread */ + if (mg->mg_obj && IoIFP(io)) { + SV **pid_psv; #ifdef ARGV_USE_ATFUNCTIONS SV **dir_psv; DIR *dir; @@ -911,6 +913,17 @@ S_argvout_free(pTHX_ SV *io, MAGIC *mg) { return 0; } +static int +S_argvout_dup(pTHX_ MAGIC *mg, CLONE_PARAMS *param) { + PERL_UNUSED_ARG(param); + + /* ideally we could just remove the magic from the SV but we don't get the SV here */ + SvREFCNT_dec(mg->mg_obj); + mg->mg_obj = NULL; + + return 0; +} + /* Magic of this type has an AV containing the following: 0: name of the backup file (if any) 1: name of the temp output file @@ -929,8 +942,8 @@ static const MGVTBL argvout_vtbl = NULL, /* svt_clear */ S_argvout_free, /* svt_free */ NULL, /* svt_copy */ - NULL, /* svt_dup */ - NULL /* svt_local */ + S_argvout_dup, /* svt_dup */ + NULL /* svt_local */ }; PerlIO * @@ -1000,6 +1013,7 @@ Perl_nextargv(pTHX_ GV *gv, bool nomagicopen) Gid_t filegid; AV *magic_av = NULL; SV *temp_name_sv = NULL; + MAGIC *mg; TAINT_PROPER("inplace open"); if (oldlen == 1 && *PL_oldname == '-') { @@ -1080,7 +1094,8 @@ Perl_nextargv(pTHX_ GV *gv, bool nomagicopen) av_store(magic_av, ARGVMG_ORIG_DIRP, newSViv(PTR2IV(curdir))); #endif setdefout(PL_argvoutgv); - sv_magicext((SV*)GvIOp(PL_argvoutgv), (SV*)magic_av, PERL_MAGIC_uvar, &argvout_vtbl, NULL, 0); + mg = sv_magicext((SV*)GvIOp(PL_argvoutgv), (SV*)magic_av, PERL_MAGIC_uvar, &argvout_vtbl, NULL, 0); + mg->mg_flags |= MGf_DUP; SvREFCNT_dec(magic_av); PL_lastfd = PerlIO_fileno(IoIFP(GvIOp(PL_argvoutgv))); if (PL_lastfd >= 0) { |