To solve the incompatibility issues between mksh-current, old mksh versions

and vendor pdksh versions, re-introduce FPOSIX alongside FSH. The semantics
are now:
‣ set -o posix ⇒
  • disable brace expansion and FSH when triggered
  • use Debian Policy 10.4 compliant non-XSI “echo” builtin
  • do not keep file descriptors > 2 to ksh
‣ set -o sh ⇒
  • set automatically #ifdef MKSH_BINSHREDUCED
  • disable brace expansion and FPOSIX when triggered
  • use Debian Policy 10.4 compliant non-XSI “echo” builtin
  • do not keep file descriptors > 2 to ksh
  • trigger MKSH_MIDNIGHTBSD01ASH_COMPAT mode if compiled in
  • make “set -- $(getopt ab:c "$@")” construct work

Note that the set/getopt one used to behave POSIXly only with FSH or
FPOSIX (depending on the mksh version) set and Bourne-ish with it not
set, so this changes default mksh behaviour to POSIX!
This commit is contained in:
tg 2010-01-28 15:18:51 +00:00
parent 17b04f3879
commit 0c94277ccb
6 changed files with 68 additions and 45 deletions

63
check.t
View File

@ -1,4 +1,4 @@
# $MirOS: src/bin/mksh/check.t,v 1.356 2010/01/25 14:25:13 tg Exp $ # $MirOS: src/bin/mksh/check.t,v 1.357 2010/01/28 15:18:46 tg Exp $
# $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $ # $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $
# $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $ # $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $
# $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $ # $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $
@ -3088,6 +3088,38 @@ stdin:
expected-stdout: expected-stdout:
bye bye
--- ---
name: regression-10
description:
The following:
set -- `false`
echo $?
should print 0 according to POSIX (dash, bash, ksh93, posh)
but not 0 according to the getopt(1) manual page, ksh88, and
Bourne sh (such as /bin/sh on Solaris).
In mksh R39b, we honour POSIX except when -o sh is set.
stdin:
showf() {
[[ -o posix ]]; FPOSIX=$((1-$?))
[[ -o sh ]]; FSH=$((1-$?))
echo -n "FPOSIX=$FPOSIX FSH=$FSH "
}
set +o posix +o sh
showf
set -- `false`
echo rv=$?
set -o sh
showf
set -- `false`
echo rv=$?
set -o posix
showf
set -- `false`
echo rv=$?
expected-stdout:
FPOSIX=0 FSH=0 rv=0
FPOSIX=0 FSH=1 rv=1
FPOSIX=1 FSH=0 rv=0
---
name: regression-11 name: regression-11
description: description:
The following: The following:
@ -4377,35 +4409,6 @@ expected-stdout:
E 0 E 0
F 0 F 0
--- ---
name: exit-subst-1
description:
Used to be regression-10 but was split into two tests.
The following:
set -- `false`
echo $?
should print 0 according to POSIX, but not 0 according to /bin/sh
(XXX on which system?), AT&T ksh88, and the getopt(1) manual page
stdin:
set -- `false`
echo $?
expected-stdout:
1
---
name: exit-subst-2
description:
Used to be regression-10 but was split into two tests.
The following:
set -- `false`
echo $?
should print 0 according to POSIX, but not 0 according to /bin/sh
(XXX on which system?), AT&T ksh88, and the getopt(1) manual page
stdin:
test -n "$POSH_VERSION" || set -o sh
set -- `false`
echo $?
expected-stdout:
0
---
name: test-stlt-1 name: test-stlt-1
description: description:
Check that test also can handle string1 < string2 etc. Check that test also can handle string1 < string2 etc.

15
funcs.c
View File

@ -25,7 +25,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.149 2010/01/25 14:38:01 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.150 2010/01/28 15:18:48 tg Exp $");
#if HAVE_KILLPG #if HAVE_KILLPG
/* /*
@ -539,7 +539,7 @@ c_print(const char **wp)
if (wp[0][0] == 'e') { if (wp[0][0] == 'e') {
/* echo builtin */ /* echo builtin */
wp++; wp++;
if (Flag(FSH)) { if (Flag(FPOSIX) || Flag(FSH)) {
/* Debian Policy 10.4 compliant "echo" builtin */ /* Debian Policy 10.4 compliant "echo" builtin */
if (*wp && !strcmp(*wp, "-n")) { if (*wp && !strcmp(*wp, "-n")) {
/* we recognise "-n" only as the first arg */ /* we recognise "-n" only as the first arg */
@ -2372,8 +2372,9 @@ c_set(const char **wp)
* which assumes the exit value set will be that of the $() * which assumes the exit value set will be that of the $()
* (subst_exstat is cleared in execute() so that it will be 0 * (subst_exstat is cleared in execute() so that it will be 0
* if there are no command substitutions). * if there are no command substitutions).
* Switched ksh (!posix !sh) to POSIX in mksh R39b.
*/ */
return (Flag(FSH) ? 0 : subst_exstat); return (Flag(FSH) ? subst_exstat : 0);
} }
int int
@ -2572,8 +2573,12 @@ c_exec(const char **wp MKSH_A_UNUSED)
for (i = 0; i < NUFILE; i++) { for (i = 0; i < NUFILE; i++) {
if (e->savefd[i] > 0) if (e->savefd[i] > 0)
close(e->savefd[i]); close(e->savefd[i]);
/* For ksh (but not sh), keep anything > 2 private */ /*
if (!Flag(FSH) && i > 2 && e->savefd[i]) * keep all file descriptors > 2 private for ksh,
* but not for POSIX or legacy/kludge sh
*/
if (!Flag(FPOSIX) && !Flag(FSH) && i > 2 &&
e->savefd[i])
fcntl(i, F_SETFD, FD_CLOEXEC); fcntl(i, F_SETFD, FD_CLOEXEC);
} }
e->savefd = NULL; e->savefd = NULL;

4
main.c
View File

@ -33,7 +33,7 @@
#include <locale.h> #include <locale.h>
#endif #endif
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.160 2010/01/25 14:38:02 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/main.c,v 1.161 2010/01/28 15:18:48 tg Exp $");
extern char **environ; extern char **environ;
@ -322,7 +322,7 @@ mksh_init(int argc, const char *argv[])
if (!(s->start = s->str = argv[argi++])) if (!(s->start = s->str = argv[argi++]))
errorf("-c requires an argument"); errorf("-c requires an argument");
#ifdef MKSH_MIDNIGHTBSD01ASH_COMPAT #ifdef MKSH_MIDNIGHTBSD01ASH_COMPAT
/* compatibility to MidnightBSD 0.1 /bin/sh (not desired) */ /* compatibility to MidnightBSD 0.1 /bin/sh (kludge) */
if (Flag(FSH) && argv[argi] && !strcmp(argv[argi], "--")) if (Flag(FSH) && argv[argi] && !strcmp(argv[argi], "--"))
++argi; ++argi;
#endif #endif

7
misc.c
View File

@ -29,7 +29,7 @@
#include <grp.h> #include <grp.h>
#endif #endif
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.136 2010/01/25 14:07:39 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/misc.c,v 1.137 2010/01/28 15:18:49 tg Exp $");
unsigned char chtypes[UCHAR_MAX + 1]; /* type bits for unsigned char */ unsigned char chtypes[UCHAR_MAX + 1]; /* type bits for unsigned char */
@ -232,8 +232,9 @@ change_flag(enum sh_flag f, int what, unsigned int newval)
setegid(kshegid = kshgid = getgid()); setegid(kshegid = kshgid = getgid());
setgid(kshegid); setgid(kshegid);
#endif #endif
} else if (f == FSH && newval) { } else if ((f == FPOSIX || f == FSH) && newval) {
Flag(FBRACEEXPAND) = 0; Flag(FPOSIX) = Flag(FSH) = Flag(FBRACEEXPAND) = 0;
Flag(f) = (unsigned char)newval;
} }
/* Changing interactive flag? */ /* Changing interactive flag? */
if (f == FTALKING) { if (f == FTALKING) {

17
mksh.1
View File

@ -1,4 +1,4 @@
.\" $MirOS: src/bin/mksh/mksh.1,v 1.211 2010/01/27 18:36:19 tg Exp $ .\" $MirOS: src/bin/mksh/mksh.1,v 1.212 2010/01/28 15:18:50 tg Exp $
.\" $OpenBSD: ksh.1,v 1.129 2009/05/28 06:09:06 jmc Exp $ .\" $OpenBSD: ksh.1,v 1.129 2009/05/28 06:09:06 jmc Exp $
.\"- .\"-
.\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 .\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
@ -71,7 +71,7 @@
.\" with -mandoc, it might implement .Mx itself, but we want to .\" with -mandoc, it might implement .Mx itself, but we want to
.\" use our own definition. And .Dd must come *first*, always. .\" use our own definition. And .Dd must come *first*, always.
.\" .\"
.Dd $Mdocdate: January 27 2010 $ .Dd $Mdocdate: January 28 2010 $
.\" .\"
.\" Check which macro package we use .\" Check which macro package we use
.\" .\"
@ -2333,6 +2333,8 @@ will print an error with a line number prepended to it:
.Pp .Pp
File descriptors created by input/output redirections are private to the File descriptors created by input/output redirections are private to the
Korn shell, but passed to sub-processes if Korn shell, but passed to sub-processes if
.Fl o Ic posix
or
.Fl o Ic sh .Fl o Ic sh
is set. is set.
.Ss Arithmetic expressions .Ss Arithmetic expressions
@ -3129,6 +3131,8 @@ enables backslash interpretation (a no-op, since this is normally done), and
suppresses backslash interpretation. suppresses backslash interpretation.
.Pp .Pp
If the If the
.Ic posix
or
.Ic sh .Ic sh
option is set, only the first argument is treated as an option, and only option is set, only the first argument is treated as an option, and only
if it is exactly if it is exactly
@ -3903,10 +3907,17 @@ See the
and and
.Ic pwd .Ic pwd
commands above for more details. commands above for more details.
.It Ic posix
Enable a somewhat more
.Px
like mode.
As a side effect, setting this flag turns off
.Ic braceexpand
mode, which can be turned back on manually.
.It Ic sh .It Ic sh
Enable Enable
.Pa /bin/sh .Pa /bin/sh
.Pq POSIX/kludge .Pq kludge
mode. mode.
Automatically enabled if the basename of the shell invocation begins with Automatically enabled if the basename of the shell invocation begins with
.Dq sh .Dq sh

View File

@ -1,5 +1,5 @@
#if defined(SHFLAGS_DEFNS) #if defined(SHFLAGS_DEFNS)
__RCSID("$MirOS: src/bin/mksh/sh_flags.h,v 1.4 2009/10/02 18:08:37 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/sh_flags.h,v 1.5 2010/01/28 15:18:51 tg Exp $");
#define FN(sname,cname,ochar,flags) /* nothing */ #define FN(sname,cname,ochar,flags) /* nothing */
#elif defined(SHFLAGS_ENUMS) #elif defined(SHFLAGS_ENUMS)
#define FN(sname,cname,ochar,flags) cname, #define FN(sname,cname,ochar,flags) cname,
@ -89,13 +89,16 @@ FN("nounset", FNOUNSET, 'u', OF_ANY)
/* ./. don't do logical cds/pwds (non-standard) */ /* ./. don't do logical cds/pwds (non-standard) */
FN("physical", FPHYSICAL, 0, OF_ANY) FN("physical", FPHYSICAL, 0, OF_ANY)
/* ./. pdksh compat: somewhat more POSIXish mode (non-standard) */
FN("posix", FPOSIX, 0, OF_ANY)
/* -p use suid_profile; privileged shell */ /* -p use suid_profile; privileged shell */
FN("privileged", FPRIVILEGED, 'p', OF_ANY) FN("privileged", FPRIVILEGED, 'p', OF_ANY)
/* -r restricted shell */ /* -r restricted shell */
FN("restricted", FRESTRICTED, 'r', OF_CMDLINE) FN("restricted", FRESTRICTED, 'r', OF_CMDLINE)
/* ./. called as sh (some POSIX, some kludgy) not mksh (non-standard) */ /* ./. pdksh compat: called as sh not mksh; kludge mode (non-standard) */
FN("sh", FSH, 0, OF_ANY) FN("sh", FSH, 0, OF_ANY)
/* -s (invocation) parse stdin (pseudo non-standard) */ /* -s (invocation) parse stdin (pseudo non-standard) */