df824c9
From 8fe3452cc6ac7af8c08c2044cd3757018a9c8887 Mon Sep 17 00:00:00 2001
df824c9
From: Zefram <zefram@fysh.org>
df824c9
Date: Fri, 22 Dec 2017 05:32:41 +0000
df824c9
Subject: [PATCH] preserve numericness of system() args on Win32
df824c9
MIME-Version: 1.0
df824c9
Content-Type: text/plain; charset=UTF-8
df824c9
Content-Transfer-Encoding: 8bit
df824c9
df824c9
On Windows there's a nasty variation in the meaning of arguments
df824c9
to Perl's system(), in which a numeric first argument isn't used as
df824c9
part of the command to run, but instead selects between two different
df824c9
operations to perform with the command (whether to wait for the command
df824c9
to complete or not).  Therefore the reduction of argument scalars to
df824c9
their operative values in the parent process, which was added in commit
df824c9
64def2aeaeb63f92dadc6dfa33486c1d7b311963, needs to preserve numericness
df824c9
of arguments on Windows.  Fixes [perl #132633].
df824c9
df824c9
Signed-off-by: Petr Písař <ppisar@redhat.com>
df824c9
---
df824c9
 pp_sys.c | 35 +++++++++++++++++++++++++++++++----
df824c9
 1 file changed, 31 insertions(+), 4 deletions(-)
df824c9
df824c9
diff --git a/pp_sys.c b/pp_sys.c
df824c9
index beb60da4c6..0649794104 100644
df824c9
--- a/pp_sys.c
df824c9
+++ b/pp_sys.c
df824c9
@@ -4393,12 +4393,39 @@ PP(pp_system)
df824c9
 # endif
df824c9
 
df824c9
     while (++MARK <= SP) {
df824c9
-	SV *origsv = *MARK;
df824c9
+	SV *origsv = *MARK, *copysv;
df824c9
 	STRLEN len;
df824c9
 	char *pv;
df824c9
-	pv = SvPV(origsv, len);
df824c9
-	*MARK = newSVpvn_flags(pv, len,
df824c9
-		    (SvFLAGS(origsv) & SVf_UTF8) | SVs_TEMP);
df824c9
+	SvGETMAGIC(origsv);
df824c9
+#ifdef WIN32
df824c9
+	/*
df824c9
+	 * Because of a nasty platform-specific variation on the meaning
df824c9
+	 * of arguments to this op, we must preserve numeric arguments
df824c9
+	 * as numeric, not just retain the string value.
df824c9
+	 */
df824c9
+	if (SvNIOK(origsv) || SvNIOKp(origsv)) {
df824c9
+	    copysv = newSV_type(SVt_PVNV);
df824c9
+	    sv_2mortal(copysv);
df824c9
+	    if (SvPOK(origsv) || SvPOKp(origsv)) {
df824c9
+		pv = SvPV_nomg(origsv, len);
df824c9
+		sv_setpvn(copysv, pv, len);
df824c9
+		SvPOK_off(copysv);
df824c9
+	    }
df824c9
+	    if (SvIOK(origsv) || SvIOKp(origsv))
df824c9
+		SvIV_set(copysv, SvIVX(origsv));
df824c9
+	    if (SvNOK(origsv) || SvNOKp(origsv))
df824c9
+		SvNV_set(copysv, SvNVX(origsv));
df824c9
+	    SvFLAGS(copysv) |= SvFLAGS(origsv) &
df824c9
+		(SVf_IOK|SVf_NOK|SVf_POK|SVp_IOK|SVp_NOK|SVp_POK|
df824c9
+		    SVf_UTF8|SVf_IVisUV);
df824c9
+	} else
df824c9
+#endif
df824c9
+	{
df824c9
+	    pv = SvPV_nomg(origsv, len);
df824c9
+	    copysv = newSVpvn_flags(pv, len,
df824c9
+			(SvFLAGS(origsv) & SVf_UTF8) | SVs_TEMP);
df824c9
+	}
df824c9
+	*MARK = copysv;
df824c9
     }
df824c9
     MARK = ORIGMARK;
df824c9
 
df824c9
-- 
df824c9
2.13.6
df824c9