From: Ilya Zakharevich Date: Fri, 17 Jan 1997 04:46:40 +0000 (-0500) Subject: Re: Perl 5.003_21: OS/2 patches X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=e29f6e029e7eba9cda9e4a39a8f10eebff769325;p=p5sagit%2Fp5-mst-13.2.git Re: Perl 5.003_21: OS/2 patches p5p-msgid: <199701170446.XAA28939@monk.mps.ohio-state.edu> --- diff --git a/os2/Changes b/os2/Changes index 9027832..4691e5b 100644 --- a/os2/Changes +++ b/os2/Changes @@ -127,3 +127,9 @@ after 5.003_20: _isterm is substituted instead of isatty, s?random instead of srand. `register' disabled if -DDEBUGGING and not AOUT build: stupid SD386. 3-argument select() was stomping over memory. + +after 5.003_21: + Can start scripts by executing 'dir/script' and + 'script.sh'. Form without extension will call shell only if + the specified file exists (will not look on path) (to prohibit + trying to run shell commands directly). - Needed by magic.t. diff --git a/os2/os2.c b/os2/os2.c index 701bb52..017230f 100644 --- a/os2/os2.c +++ b/os2/os2.c @@ -203,12 +203,12 @@ register SV **mark; register SV **sp; { register char **a; - char *tmps; + char *tmps = NULL; int rc; - int flag = P_WAIT, trueflag; + int flag = P_WAIT, trueflag, err, secondtry = 0; if (sp > mark) { - New(401,Argv, sp - mark + 1, char*); + New(401,Argv, sp - mark + 3, char*); a = Argv; if (mark < sp && SvNIOKp(*(mark+1)) && !SvPOKp(*(mark+1))) { @@ -236,11 +236,41 @@ register SV **sp; ) /* will swawnvp use PATH? */ TAINT_ENV(); /* testing IFS here is overkill, probably */ /* We should check PERL_SH* and PERLLIB_* as well? */ + retry: if (really && *(tmps = SvPV(really, na))) rc = result(trueflag, spawnvp(flag,tmps,Argv)); else rc = result(trueflag, spawnvp(flag,Argv[0],Argv)); + if (rc < 0 && secondtry == 0 + && (!tmps || !*tmps)) { /* Cannot transfer `really' via shell. */ + err = errno; + if (err == ENOENT) { /* No such file. */ + /* One reason may be that EMX added .exe. We suppose + that .exe-less files are automatically shellable. */ + char *no_dir; + (no_dir = strrchr(Argv[0], '/')) + || (no_dir = strrchr(Argv[0], '\\')) + || (no_dir = Argv[0]); + if (!strchr(no_dir, '.')) { + struct stat buffer; + if (stat(Argv[0], &buffer) != -1) { /* File exists. */ + /* Maybe we need to specify the full name here? */ + goto doshell; + } + } + } else if (err == ENOEXEC) { /* Need to send to shell. */ + doshell: + while (a >= Argv) { + *(a + 2) = *a; + a--; + } + *Argv = sh_path; + *(Argv + 1) = "-c"; + secondtry = 1; + goto retry; + } + } if (rc < 0 && dowarn) warn("Can't spawn \"%s\": %s", Argv[0], Strerror(errno)); if (rc < 0) rc = 255 << 8; /* Emulate the fork(). */ @@ -264,7 +294,8 @@ int execf; register char *s; char flags[10]; char *shell, *copt, *news = NULL; - int rc; + int rc, added_shell = 0, err; + char fullcmd[MAXNAMLEN + 1]; #ifdef TRYSHELL if ((shell = getenv("EMXSHELL")) != NULL) @@ -294,6 +325,7 @@ int execf; strcpy(news, sh_path); strcpy(news + l, cmd + 7); cmd = news; + added_shell = 1; } /* save an extra exec if possible */ @@ -348,6 +380,8 @@ int execf; } *a = Nullch; if (Argv[0]) { + int err; + if (execf == EXECF_TRUEEXEC) rc = execvp(Argv[0],Argv); else if (execf == EXECF_EXEC) @@ -356,10 +390,31 @@ int execf; rc = spawnvp(P_NOWAIT,Argv[0],Argv); else rc = result(P_WAIT, spawnvp(P_NOWAIT,Argv[0],Argv)); + if (rc < 0) { + err = errno; + if (err == ENOENT) { /* No such file. */ + /* One reason may be that EMX added .exe. We suppose + that .exe-less files are automatically shellable. */ + char *no_dir; + (no_dir = strrchr(Argv[0], '/')) + || (no_dir = strrchr(Argv[0], '\\')) + || (no_dir = Argv[0]); + if (!strchr(no_dir, '.')) { + struct stat buffer; + if (stat(Argv[0], &buffer) != -1) { /* File exists. */ + /* Maybe we need to specify the full name here? */ + goto doshell; + } + } + } else if (err == ENOEXEC) { /* Need to send to shell. */ + goto doshell; + } + } if (rc < 0 && dowarn) warn("Can't %s \"%s\": %s", - (execf == EXECF_SPAWN ? "spawn" : "exec"), - Argv[0], Strerror(errno)); + ((execf != EXECF_EXEC && execf != EXECF_TRUEEXEC) + ? "spawn" : "exec"), + Argv[0], Strerror(err)); if (rc < 0) rc = 255 << 8; /* Emulate the fork(). */ } else rc = -1;