From f0f34eb7b67061466f2b89dbc8d13e5807fe94fc Mon Sep 17 00:00:00 2001 From: tg Date: Thu, 2 May 2013 20:21:45 +0000 Subject: [PATCH] =?UTF-8?q?=E2=80=A2=20Allow=20setting=20both=20-o=20posix?= =?UTF-8?q?=20and=20-o=20sh=20(although=20only=20in=20the=20same=20=20=20c?= =?UTF-8?q?ommand;=20setting=20one=20still=20unsets=20the=20other=20at=20f?= =?UTF-8?q?irst)=20=E2=80=A2=20Change=20subst=5Fexstat=20to=20be=20conform?= =?UTF-8?q?ant=20unless=20-o=20sh=20is=20set=20and=20-o=20posix=20isn?= =?UTF-8?q?=E2=80=99t=20=E2=80=A2=20In=20lksh,=20make=20subst=5Fexstat=20(?= =?UTF-8?q?newly)=20conformant=20if=20-o=20posix=20=E2=80=A2=20New=20MKSH?= =?UTF-8?q?=5FBINSHPOSIX=20to=20accompany=20MKSH=5FBINSHREDUCED=20?= =?UTF-8?q?=E2=80=A2=20Sync=20lksh=20manpage=20precisely?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Build.sh | 9 ++++--- check.t | 24 ++++++++++++------ funcs.c | 9 ++++--- lksh.1 | 71 ++++++++++++++++++++++++++++-------------------------- main.c | 15 +++++++++--- misc.c | 23 +++++++++++++----- sh_flags.h | 6 ++--- 7 files changed, 96 insertions(+), 61 deletions(-) diff --git a/Build.sh b/Build.sh index 5a56bc3..576aae2 100644 --- a/Build.sh +++ b/Build.sh @@ -1,5 +1,5 @@ #!/bin/sh -srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.628 2013/04/27 18:12:37 tg Exp $' +srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.629 2013/05/02 20:21:36 tg Exp $' #- # Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011, 2012, 2013 @@ -1367,8 +1367,8 @@ if ac_ifcpp 'ifdef MKSH_SMALL' isset_MKSH_SMALL '' \ check_categories="$check_categories smksh" HAVE_ISSET_MKSH_CONSERVATIVE_FDS=1 # from sh.h fi -ac_ifcpp 'ifdef MKSH_BINSHREDUCED' isset_MKSH_BINSHREDUCED '' \ - "if a reduced-feature sh is requested" && \ +ac_ifcpp 'if defined(MKSH_BINSHPOSIX) || defined(MKSH_BINSHREDUCED)' \ + isset_MKSH_BINSH '' 'if invoking as sh should be handled specially' && \ check_categories="$check_categories binsh" ac_ifcpp 'ifdef MKSH_UNEMPLOYED' isset_MKSH_UNEMPLOYED '' \ "if mksh will be built without job control" && \ @@ -1531,7 +1531,7 @@ else #define EXTERN #define MKSH_INCLUDES_ONLY #include "sh.h" - __RCSID("$MirOS: src/bin/mksh/Build.sh,v 1.628 2013/04/27 18:12:37 tg Exp $"); + __RCSID("$MirOS: src/bin/mksh/Build.sh,v 1.629 2013/05/02 20:21:36 tg Exp $"); int main(void) { printf("Hello, World!\n"); return (0); } EOF case $cm in @@ -2315,6 +2315,7 @@ DEBUG_LEAKS enable freeing resources before exiting MKSHRC_PATH "~/.mkshrc" (do not change) MKSH_A4PB force use of arc4random_pushb MKSH_ASSUME_UTF8 (0=disabled, 1=enabled; default: unset) +MKSH_BINSHPOSIX if */sh or */-sh, enable set -o posix MKSH_BINSHREDUCED if */sh or */-sh, enable set -o sh MKSH_CLRTOEOL_STRING "\033[K" MKSH_CLS_STRING "\033[;H\033[J" diff --git a/check.t b/check.t index 67a7db0..3434b35 100644 --- a/check.t +++ b/check.t @@ -1,4 +1,4 @@ -# $MirOS: src/bin/mksh/check.t,v 1.609 2013/04/27 19:16:23 tg Exp $ +# $MirOS: src/bin/mksh/check.t,v 1.610 2013/05/02 20:21:38 tg 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: read.t,v 1.3 2003/03/10 03:48:16 david Exp $ @@ -4254,7 +4254,7 @@ description: 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. + We honour POSIX except when -o sh is set. category: shell:legacy-no stdin: showf() { @@ -4274,10 +4274,15 @@ stdin: showf set -- `false` echo rv=$? + set -o posix -o sh + 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 + FPOSIX=1 FSH=1 rv=0 --- name: regression-10-legacy description: @@ -4306,10 +4311,15 @@ stdin: showf set -- `false` echo rv=$? + set -o posix -o sh + showf + set -- `false` + echo rv=$? expected-stdout: FPOSIX=0 FSH=0 rv=1 FPOSIX=0 FSH=1 rv=1 - FPOSIX=1 FSH=0 rv=1 + FPOSIX=1 FSH=0 rv=0 + FPOSIX=1 FSH=1 rv=0 --- name: regression-11 description: @@ -6187,7 +6197,7 @@ expected-stdout: --- name: sh-mode-2a description: - Check that sh mode is *not* automatically turned on + Check that posix or sh mode is *not* automatically turned on category: !binsh stdin: ln -s "$__progname" ksh || cp "$__progname" ksh @@ -6196,7 +6206,7 @@ stdin: ln -s "$__progname" ./-sh || cp "$__progname" ./-sh for shell in {,-}{,k}sh; do print -- $shell $(./$shell +l -c \ - '[[ $(set +o) == *@(-o sh)@(| *) ]] && echo sh || echo nosh') + '[[ $(set +o) == *"-o "@(sh|posix)@(| *) ]] && echo sh || echo nosh') done expected-stdout: sh nosh @@ -6206,7 +6216,7 @@ expected-stdout: --- name: sh-mode-2b description: - Check that sh mode *is* automatically turned on + Check that posix or sh mode *is* automatically turned on category: binsh stdin: ln -s "$__progname" ksh || cp "$__progname" ksh @@ -6215,7 +6225,7 @@ stdin: ln -s "$__progname" ./-sh || cp "$__progname" ./-sh for shell in {,-}{,k}sh; do print -- $shell $(./$shell +l -c \ - '[[ $(set +o) == *@(-o sh)@(| *) ]] && echo sh || echo nosh') + '[[ $(set +o) == *"-o "@(sh|posix)@(| *) ]] && echo sh || echo nosh') done expected-stdout: sh sh diff --git a/funcs.c b/funcs.c index 081cd4e..2646d62 100644 --- a/funcs.c +++ b/funcs.c @@ -38,7 +38,7 @@ #endif #endif -__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.242 2013/04/26 21:22:45 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.243 2013/05/02 20:21:41 tg Exp $"); #if HAVE_KILLPG /* @@ -2426,12 +2426,13 @@ c_set(const char **wp) * which assumes the exit value set will be that of the $() * (subst_exstat is cleared in execute() so that it will be 0 * if there are no command substitutions). - * Switched ksh (!posix !sh) to POSIX in mksh R39b. */ #ifdef MKSH_LEGACY_MODE - return (subst_exstat); + /* traditional behaviour, unless set -o posix */ + return (Flag(FPOSIX) ? 0 : subst_exstat); #else - return (Flag(FSH) ? subst_exstat : 0); + /* conformant behaviour, unless set -o sh +o posix */ + return (Flag(FSH) && !Flag(FPOSIX) ? subst_exstat : 0); #endif } diff --git a/lksh.1 b/lksh.1 index d6c1e33..7a0e62f 100644 --- a/lksh.1 +++ b/lksh.1 @@ -1,4 +1,4 @@ -.\" $MirOS: src/bin/mksh/lksh.1,v 1.3 2013/04/27 19:16:25 tg Exp $ +.\" $MirOS: src/bin/mksh/lksh.1,v 1.4 2013/05/02 20:21:43 tg Exp $ .\"- .\" Copyright (c) 2008, 2009, 2010, 2012, 2013 .\" Thorsten “mirabilos” Glaser @@ -72,7 +72,7 @@ .\" with -mandoc, it might implement .Mx itself, but we want to .\" use our own definition. And .Dd must come *first*, always. .\" -.Dd $Mdocdate: April 27 2013 $ +.Dd $Mdocdate: May 2 2013 $ .\" .\" Check which macro package we use, and do other -mdoc setup. .\" @@ -184,7 +184,7 @@ is not suitable for use as .Pa /bin/sh . .It There is no explicit support for interactive use, -nor any command line editing code. +nor any command line editing or history code. Hence, .Nm is not suitable as a user's login shell, either; use @@ -200,19 +200,43 @@ as instead of .Dq MIRBSD KSH . .It -Some -.Nm mksh -specific extensions are missing; specifically, the -.Fl T -command-line option. +.Nm +only offers the traditional ten file descriptors to scripts. .It -Some extensions from other shells, such as +.Nm +uses +.Tn POSIX +arithmetics, which has quite a few implications: +The data type for arithmetics is the host ISO C +.Vt long +data type. +Signed integer wraparound is Undefined Behaviour. +The sign of the result of a modulo operation with at least one +negative operand is unspecified. +Shift operations on negative numbers are unspecified. +Division of the largest negative number by \-1 is Undefined Behaviour. +The compiler is permitted to delete all data and crash the system +if Undefined Behaviour occurs. +.It +The rotation arithmetic operators are not available. +.It +The shift arithmetic operators take all bits of the second operand into +account; if they exceed permitted precision, the result is unspecified. +.It +The .Tn GNU -.Nm bash , -which -.Nm mksh -provides, are missing, for increased compatibility with legacy scripts. +.Nm bash +extension &\*(Gt to redirect stdout and stderr in one go is not parsed. .It +The +.Nm mksh +command line option +.Fl T +is not available. +.It +Unless +.Ic set -o posix +is active, .Nm always uses traditional mode for constructs like: .Bd -literal -offset indent @@ -230,27 +254,6 @@ unlike .At .Nm ksh , does not keep file descriptors \*(Gt 2 private. -.It -Integers use the host C environment's -.Vt long -type, not -.Vt int32_t . -Unsigned arithmetic is done using -.Vt unsigned long , -not -.Vt uint32_t . -Neither value limits nor wraparound is guaranteed. -Dividing the largest negative number by \-1 is Undefined Behaviour -.Po -but might work on 32-bit and 64-bit -.Vt long -types -.Pc . -POSIX, by virtue of including ISO C, makes it legal for code triggering -Undefined Behaviour to remove all your data and crash the system! -.It -.Nm -only offers the traditional ten file descriptors to scripts. .El .Sh SEE ALSO .Xr mksh 1 diff --git a/main.c b/main.c index 941c1f4..a8eed15 100644 --- a/main.c +++ b/main.c @@ -34,7 +34,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/main.c,v 1.263 2013/04/27 18:56:41 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/main.c,v 1.264 2013/05/02 20:21:43 tg Exp $"); extern char **environ; @@ -251,10 +251,19 @@ main_init(int argc, const char *argv[], Source **sp, struct block **lp) if (argi < 0) return (1); +#if defined(MKSH_BINSHPOSIX) || defined(MKSH_BINSHREDUCED) + /* are we called as -sh or /bin/sh or so? */ + if (!strcmp(ccp, "sh")) { + /* either also turns off braceexpand */ +#ifdef MKSH_BINSHPOSIX + /* enable better POSIX conformance */ + change_flag(FPOSIX, OF_FIRSTTIME, true); +#endif #ifdef MKSH_BINSHREDUCED - /* set FSH if we're called as -sh or /bin/sh or so */ - if (!strcmp(ccp, "sh")) + /* enable kludge/compat mode */ change_flag(FSH, OF_FIRSTTIME, true); +#endif + } #endif } diff --git a/misc.c b/misc.c index 5598b59..c932247 100644 --- a/misc.c +++ b/misc.c @@ -30,7 +30,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.210 2013/04/27 19:09:13 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.211 2013/05/02 20:21:44 tg Exp $"); #define KSH_CHVT_FLAG #ifdef MKSH_SMALL @@ -277,11 +277,10 @@ change_flag(enum sh_flag f, int what, bool newset) setgid(kshegid); #endif } else if ((f == FPOSIX || f == FSH) && newval) { - Flag(FPOSIX) = Flag(FSH) = Flag(FBRACEEXPAND) = 0; - Flag(f) = newval; - } - /* Changing interactive flag? */ - if (f == FTALKING) { + /* Turning on -o posix or -o sh? */ + Flag(FBRACEEXPAND) = 0; + } else if (f == FTALKING) { + /* Changing interactive flag? */ if ((what == OF_CMDLINE || what == OF_SET) && procpid == kshpid) Flag(FTALKING_I) = newval; } @@ -306,6 +305,7 @@ parse_args(const char **argv, size_t i; int optc, arrayset = 0; bool sortargs = false; + bool fcompatseen = false; /* First call? Build option strings... */ if (cmd_opts[0] == '\0') { @@ -379,6 +379,17 @@ parse_args(const char **argv, break; } i = option(go.optarg); + if ((i == FPOSIX || i == FSH) && set && !fcompatseen) { + /* + * If running 'set -o posix' or + * 'set -o sh', turn off the other; + * if running 'set -o posix -o sh' + * allow both to be set though. + */ + Flag(FPOSIX) = 0; + Flag(FSH) = 0; + fcompatseen = true; + } if ((i != (size_t)-1) && (set ? 1U : 0U) == Flag(i)) /* * Don't check the context if the flag diff --git a/sh_flags.h b/sh_flags.h index 1c8a30e..788f3f0 100644 --- a/sh_flags.h +++ b/sh_flags.h @@ -1,5 +1,5 @@ #if defined(SHFLAGS_DEFNS) -__RCSID("$MirOS: src/bin/mksh/sh_flags.h,v 1.12 2012/06/28 20:14:17 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/sh_flags.h,v 1.13 2013/05/02 20:21:45 tg Exp $"); #define FN(sname,cname,ochar,flags) /* nothing */ #elif defined(SHFLAGS_ENUMS) #define FN(sname,cname,ochar,flags) cname, @@ -88,7 +88,7 @@ FN("nounset", FNOUNSET, 'u', OF_ANY) /* ./. don't do logical cds/pwds (non-standard) */ FN("physical", FPHYSICAL, 0, OF_ANY) -/* ./. pdksh compat: somewhat more POSIXish mode (non-standard) */ +/* ./. adhere more closely to POSIX even when undesirable */ FN("posix", FPOSIX, 0, OF_ANY) /* -p use suid_profile; privileged shell */ @@ -97,7 +97,7 @@ FN("privileged", FPRIVILEGED, 'p', OF_ANY) /* -r restricted shell */ FN("restricted", FRESTRICTED, 'r', OF_CMDLINE) -/* ./. pdksh compat: called as sh not mksh; kludge mode (non-standard) */ +/* ./. kludge mode for better compat with traditional sh (OS-specific) */ FN("sh", FSH, 0, OF_ANY) /* -s (invocation) parse stdin (pseudo non-standard) */