summaryrefslogtreecommitdiff
path: root/cygwin
diff options
context:
space:
mode:
authorZefram <zefram@fysh.org>2017-12-06 21:27:15 +0000
committerZefram <zefram@fysh.org>2017-12-14 22:48:30 +0000
commit282fc0b3cc2439f69587d980b62bef7f5d5bdfef (patch)
tree6dc6abf858b4903d0adb99d6309a74f84ebf7782 /cygwin
parente135ff695231a81e2a70a739e8d813525432fd4d (diff)
downloadperl-282fc0b3cc2439f69587d980b62bef7f5d5bdfef.tar.gz
make exec keep its argument list more reliably
Bits of exec code were putting the constructed commands into globals PL_Argv and PL_Cmd, which could then be clobbered by reentrancy. These are only global in order to manage their freeing, but that's better managed by using the scope stack. So replace them with automatic variables, with ENTER/SAVEFREEPV/LEAVE to free the memory. Also copy the strings acquired from SVs, to avoid magic clobbering the buffers of SVs already read. Fixes [perl #129888].
Diffstat (limited to 'cygwin')
-rw-r--r--cygwin/cygwin.c28
1 files changed, 18 insertions, 10 deletions
diff --git a/cygwin/cygwin.c b/cygwin/cygwin.c
index a234825eba..fae90af000 100644
--- a/cygwin/cygwin.c
+++ b/cygwin/cygwin.c
@@ -90,11 +90,13 @@ int
do_spawn (char *cmd)
{
dTHX;
- char const **a;
+ char const **argv, **a;
char *s;
char const *metachars = "$&*(){}[]'\";\\?>|<~`\n";
const char *command[4];
+ int result;
+ ENTER;
while (*cmd && isSPACE(*cmd))
cmd++;
@@ -127,13 +129,16 @@ do_spawn (char *cmd)
command[2] = cmd;
command[3] = NULL;
- return do_spawnvp("sh",command);
+ result = do_spawnvp("sh",command);
+ goto leave;
}
- Newx (PL_Argv, (s-cmd)/2+2, const char*);
- PL_Cmd=savepvn (cmd,s-cmd);
- a=PL_Argv;
- for (s=PL_Cmd; *s;) {
+ Newx (argv, (s-cmd)/2+2, const char*);
+ SAVEFREEPV(argv);
+ cmd=savepvn (cmd,s-cmd);
+ SAVEFREEPV(cmd);
+ a=argv;
+ for (s=cmd; *s;) {
while (*s && isSPACE (*s)) s++;
if (*s)
*(a++)=s;
@@ -142,10 +147,13 @@ do_spawn (char *cmd)
*s++='\0';
}
*a = (char*)NULL;
- if (!PL_Argv[0])
- return -1;
-
- return do_spawnvp(PL_Argv[0],(const char * const *)PL_Argv);
+ if (!argv[0])
+ result = -1;
+ else
+ result = do_spawnvp(argv[0],(const char * const *)argv);
+leave:
+ LEAVE;
+ return result;
}
#if (CYGWIN_VERSION_API_MINOR >= 181)