summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/PerlIO-scalar/scalar.xs13
-rw-r--r--ext/PerlIO-scalar/t/scalar.t16
2 files changed, 26 insertions, 3 deletions
diff --git a/ext/PerlIO-scalar/scalar.xs b/ext/PerlIO-scalar/scalar.xs
index eac682b5c3..87c5682388 100644
--- a/ext/PerlIO-scalar/scalar.xs
+++ b/ext/PerlIO-scalar/scalar.xs
@@ -314,12 +314,21 @@ PerlIO *
PerlIOScalar_dup(pTHX_ PerlIO * f, PerlIO * o, CLONE_PARAMS * param,
int flags)
{
+ /* Duplication causes the scalar layer to be pushed on to clone, caus-
+ ing the cloned scalar to be set to the empty string by
+ PerlIOScalar_pushed. So set aside our scalar temporarily. */
+ PerlIOScalar * const os = PerlIOSelf(o, PerlIOScalar);
+ SV * const var = os->var;
+ os->var = newSVpvs("");
if ((f = PerlIOBase_dup(aTHX_ f, o, param, flags))) {
PerlIOScalar *fs = PerlIOSelf(f, PerlIOScalar);
- PerlIOScalar *os = PerlIOSelf(o, PerlIOScalar);
- /* var has been set by implicit push */
+ /* var has been set by implicit push, so replace it */
+ SvREFCNT_dec(fs->var);
+ fs->var = PerlIO_sv_dup(aTHX_ var, param);
fs->posn = os->posn;
}
+ SvREFCNT_dec(os->var);
+ os->var = var;
return f;
}
diff --git a/ext/PerlIO-scalar/t/scalar.t b/ext/PerlIO-scalar/t/scalar.t
index a02107b17d..18bbda9404 100644
--- a/ext/PerlIO-scalar/t/scalar.t
+++ b/ext/PerlIO-scalar/t/scalar.t
@@ -16,7 +16,7 @@ use Fcntl qw(SEEK_SET SEEK_CUR SEEK_END); # Not 0, 1, 2 everywhere.
$| = 1;
-use Test::More tests => 79;
+use Test::More tests => 81;
my $fh;
my $var = "aaa\n";
@@ -360,3 +360,17 @@ SKIP: {
ok has_trailing_nul $memfile,
'write appends null when growing string after seek past end';
}
+
+# [perl #112780] Cloning of in-memory handles
+SKIP: {
+ skip "no threads", 2 if !$Config::Config{useithreads};
+ require threads;
+ my $str = '';
+ open my $fh, ">", \$str;
+ $str = 'a';
+ is scalar threads::async(sub { my $foo = $str; $foo })->join, "a",
+ 'scalars behind in-memory handles are cloned properly';
+ print $fh "a";
+ is scalar async { print $fh "b"; $str }->join, "ab",
+ 'printing to a cloned in-memory handle works';
+}