mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
Cygwin: workaround for ksh to execute #!-less scripts with itself
On Cygwin, ksh does not execute scripts without a #! path in a fork of the ksh process as it does on other systems. Reproducer (run from ksh): $ cat test.sh echo "${BASH_VERSION:-not bash}" echo "${.sh.version}" $ chmod +x test.sh $ ./test.sh 4.4.12(3)-release ./test.sh: line 2: ${.sh.version}: bad substitution The script was executed in bash instead of ksh. After this fix, the output on Cygwin is like ksh on other systems: not bash Version AJM 93u+m/1.1.0-alpha+dev 2022-01-26 This also fixes a number of regression test failures, as quite a few tests create and execute temp scripts without a hashbang path. Analysis: On Cygwin, execve(2) happily executes shell scripts without a #! path with /bin/sh (which is bash --posix). However, ksh relies on execve(2) executing binaries or #! only, as it uses an ENOEXEC failure to decide whether to fork and execute a #!-less shell script with a reinitialized copy of itself via exscript(). src/cmd/ksh93/sh/path.c: path_spawn(): - Look at the magic first two bytes of the file; if it is "MZ" (Mark Zbikowski, originator of the .exe format) or "#!", continue as normal, otherwise simulate an ENOEXEC failure from execve(2) which will cause ksh to fall back on #!-less script execution.
This commit is contained in:
parent
172becffea
commit
fe268fcc91
3 changed files with 29 additions and 2 deletions
|
@ -21,7 +21,7 @@
|
|||
|
||||
#define SH_RELEASE_FORK "93u+m" /* only change if you develop a new ksh93 fork */
|
||||
#define SH_RELEASE_SVER "1.0.0-beta.2" /* semantic version number: https://semver.org */
|
||||
#define SH_RELEASE_DATE "2022-01-24" /* must be in this format for $((.sh.version)) */
|
||||
#define SH_RELEASE_DATE "2022-01-26" /* must be in this format for $((.sh.version)) */
|
||||
#define SH_RELEASE_CPYR "(c) 2020-2022 Contributors to ksh " SH_RELEASE_FORK
|
||||
|
||||
/* Scripts sometimes field-split ${.sh.version}, so don't change amount of whitespace. */
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* *
|
||||
* This software is part of the ast package *
|
||||
* Copyright (c) 1982-2012 AT&T Intellectual Property *
|
||||
* Copyright (c) 2020-2021 Contributors to ksh 93u+m *
|
||||
* Copyright (c) 2020-2022 Contributors to ksh 93u+m *
|
||||
* and is licensed under the *
|
||||
* Eclipse Public License, Version 1.0 *
|
||||
* by AT&T Intellectual Property *
|
||||
|
@ -1214,6 +1214,28 @@ pid_t path_spawn(const char *opath,register char **argv, char **envp, Pathcomp_t
|
|||
path = sp;
|
||||
}
|
||||
#endif /* SHELLMAGIC */
|
||||
#if __CYGWIN__
|
||||
/*
|
||||
* On Cygwin, execve(2) happily executes shell scripts without a #! path with /bin/sh (which is bash --posix).
|
||||
* However, ksh relies on execve(2) executing binaries or #! only, as it uses an ENOEXEC failure to decide
|
||||
* whether to fork and execute a #!-less shell script with a reinitialized copy of itself via exscript() below.
|
||||
* So, simulate that failure if the file is not a Windows executable or a script with a #! path.
|
||||
*/
|
||||
if((n = sh_open(opath,O_RDONLY,0)) >= 0)
|
||||
{
|
||||
uint16_t mz;
|
||||
r = !(read(n,&mz,2)==2 && (mz==0x5A4D || mz==0x2123)); /* "MZ" or "#!" */
|
||||
sh_close(n);
|
||||
}
|
||||
else
|
||||
r = 0;
|
||||
if(r)
|
||||
{
|
||||
pid = -1;
|
||||
errno = ENOEXEC;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#if SHOPT_PFSH
|
||||
if(spawn && !sh_isoption(SH_PFSH))
|
||||
pid = _spawnveg(opath, &argv[0], envp, spawn>>1);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue