diff options
author | Zefram <zefram@fysh.org> | 2017-12-06 21:27:15 +0000 |
---|---|---|
committer | Zefram <zefram@fysh.org> | 2017-12-14 22:48:30 +0000 |
commit | 282fc0b3cc2439f69587d980b62bef7f5d5bdfef (patch) | |
tree | 6dc6abf858b4903d0adb99d6309a74f84ebf7782 /djgpp | |
parent | e135ff695231a81e2a70a739e8d813525432fd4d (diff) | |
download | perl-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 'djgpp')
-rw-r--r-- | djgpp/djgpp.c | 36 |
1 files changed, 23 insertions, 13 deletions
diff --git a/djgpp/djgpp.c b/djgpp/djgpp.c index d1c09aad67..24d12f254b 100644 --- a/djgpp/djgpp.c +++ b/djgpp/djgpp.c @@ -150,9 +150,10 @@ do_aspawn (pTHX_ SV *really,SV **mark,SV **sp) int do_spawn2 (pTHX_ char *cmd,int execf) { - char **a,*s,*shell,*metachars; - int rc,unixysh; + char **argv,**a,*s,*shell,*metachars; + int rc,unixysh,result; + ENTER; if ((shell=getenv("SHELL"))==NULL && (shell=getenv("COMSPEC"))==NULL) shell="c:\\command.com" EXTRA; @@ -189,14 +190,18 @@ do_spawn2 (pTHX_ char *cmd,int execf) } doshell: if (execf==EXECF_EXEC) - return convretcode (execl (shell,shell,unixysh ? "-c" : "/c",cmd,NULL),cmd,execf); - return convretcode (system (cmd),cmd,execf); + result = convretcode (execl (shell,shell,unixysh ? "-c" : "/c",cmd,NULL),cmd,execf); + else + result = convretcode (system (cmd),cmd,execf); + goto leave; } - Newx (PL_Argv,(s-cmd)/2+2,char*); - PL_Cmd=savepvn (cmd,s-cmd); - a=PL_Argv; - for (s=PL_Cmd; *s;) { + Newx (argv,(s-cmd)/2+2,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; @@ -205,14 +210,19 @@ doshell: *s++='\0'; } *a=NULL; - if (!PL_Argv[0]) - return -1; + if (!argv[0]) { + result = -1; + goto leave; + } if (execf==EXECF_EXEC) - rc=execvp (PL_Argv[0],PL_Argv); + rc=execvp (argv[0],argv); else - rc=spawnvp (P_WAIT,PL_Argv[0],PL_Argv); - return convretcode (rc,PL_Argv[0],execf); + rc=spawnvp (P_WAIT,argv[0],argv); + result = convretcode (rc,argv[0],execf); +leave: + LEAVE; + return result; } int |