OSDN Git Service

Upgrade to mksh R57.
authorElliott Hughes <enh@google.com>
Tue, 26 Mar 2019 19:34:31 +0000 (12:34 -0700)
committerElliott Hughes <enh@google.com>
Tue, 26 Mar 2019 19:38:33 +0000 (12:38 -0700)
R57 rolls up bugfixes, with few hard changes:

[gecko2] Update operating environment reporting for the Macintosh
[Martijn Dekker] make ${foo#'bar'} in here document behave like ksh93
[Martijn Dekker] quote empty strings for re-entry into shell
[tg, G.raud Meyer] Improve documentation, especially for tty states
[tg] Protect against entering line editing with bad saved tty state
[tg] Fix set -o allexport for arrays (which we apparently do)
[tg] Handle lseek(2) returning -1 as pointed out by Coverity Scan
[tg] Fix left-padding UTF-8 strings
[tg, G.raud Meyer] Fix using the “-m” flag on the command line
[tg] Update to UCD 11.0.0
[multiplexd] Fix a segfault using ^W during search in Vi mode
[tg] Fix an error message; add a test for controlling tty
[tg] Permit unsetting LINES and COLUMNS, for those who need it
[tg] Fix manpage bug (RedHat BZ#1612173)
[tg] Minor spelling cleanup
[tg] Unbreak high-bit7 (nōn-ASCII) heredoc separators (LP#1779179)
[tg] Allow dumping high-bit7-char-containing strings in DEBUG mode
[tg] Add some testcases for behaviour questions popped up in IRC
[tg] Trick a GCC warning, to make up for it ignoring lint(1) hints
[tg] Add O_MAYEXEC support for CLIP OS
[tg] Make dup-to-self with ksh-style fd≥3 closing work; catern via IRC
[tg] Add compat glue for newer GNU groff mdoc to the manpages
[tg] Trigger EXIT trap after single-command subshells (Debian #910276)
[tg] Document set -eo pipefail caveat (LP#1804504)
[tg] Fix MKSH_EARLY_LOCALE_TRACKING warning
[tg] Document that, when your Unix is broken, GIGO applies (LP#1817959)
[tg] Improve error message for inaccessible executables (LP#1817789)

Test: treehugger
Change-Id: Ib5447fc474e509698bd04cdf70ed14b54e84d27a

22 files changed:
Android.bp
Android.patch.txt
src/Build.sh [changed mode: 0755->0644]
src/check.t
src/edit.c
src/exec.c
src/expr.c
src/funcs.c
src/histrap.c
src/jehanne.c [new file with mode: 0644]
src/jobs.c
src/lex.c
src/lksh.1
src/main.c
src/misc.c
src/mksh.1
src/sh.h
src/sh_flags.gen
src/sh_flags.opt
src/shf.c
src/tree.c
src/var.c

index 4e491e0..b7edef2 100644 (file)
@@ -107,7 +107,7 @@ cc_defaults {
         "-DHAVE_SYS_ERRLIST_DECL=0",
         "-DHAVE_SYS_SIGLIST_DECL=1",
         "-DHAVE_PERSISTENT_HISTORY=0",
-        "-DMKSH_BUILD_R=563",
+        "-DMKSH_BUILD_R=571",
 
         // Additional flags
         "-DMKSH_DEFAULT_PROFILEDIR=\"/system/etc\"",
index c3cf892..15118e3 100644 (file)
@@ -1,5 +1,6 @@
---- mksh-R56b/funcs.c  2017-05-05 15:53:55.000000000 -0700
-+++ src/funcs.c        2017-09-22 16:19:44.327000462 -0700
+diff -ru mksh-R57/funcs.c src/funcs.c
+--- mksh-R57/funcs.c   2018-10-20 14:04:55.000000000 -0700
++++ src/funcs.c        2019-03-26 12:05:23.976821773 -0700
 @@ -103,7 +103,9 @@
        {Tsgbreak, c_brkcont},
        {T__builtin, c_builtin},
  #ifdef __MirBSD__
        /* alias to "true" for historical reasons */
        {"domainname", c_true},
---- mksh-R56b/main.c   2017-04-28 04:14:14.000000000 -0700
-+++ src/main.c 2017-09-22 15:58:14.134149037 -0700
-@@ -410,6 +410,12 @@
-               }
-       }
+diff -ru mksh-R57/main.c src/main.c
+--- mksh-R57/main.c    2019-01-05 05:24:45.000000000 -0800
++++ src/main.c 2019-03-26 12:05:23.980821764 -0700
+@@ -399,6 +399,12 @@
+       /* import environment */
+       init_environ();
  
 +      /* override default PATH regardless of environment */
 +#ifdef MKSH_DEFPATH_OVERRIDE
old mode 100755 (executable)
new mode 100644 (file)
index ebf4e1c..be3f711
@@ -1,5 +1,5 @@
 #!/bin/sh
-srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.731 2018/01/13 21:38:06 tg Exp $'
+srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.734 2019/03/01 16:18:13 tg Exp $'
 #-
 # Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
 #              2011, 2012, 2013, 2014, 2015, 2016, 2017
@@ -418,6 +418,7 @@ ac_flags() {
                        #include <unistd.h>
                        int main(void) { return (isatty(0)); }
                EOF
+               #'
        fi
        eval fv=\$HAVE_CAN_`upper $vn`
        if test -n "$fl"; then
@@ -1060,11 +1061,12 @@ AIX)
 Darwin)
        vv '|' "hwprefs machine_type os_type os_class >&2"
        vv '|' "sw_vers >&2"
-       vv '|' "system_profiler SPSoftwareDataType SPHardwareDataType >&2"
+       vv '|' "system_profiler -detailLevel mini SPSoftwareDataType SPHardwareDataType >&2"
        vv '|' "/bin/sh --version >&2"
        vv '|' "xcodebuild -version >&2"
        vv '|' "uname -a >&2"
-       vv '|' "sysctl kern.version hw.machine hw.model hw.memsize hw.availcpu hw.cpufrequency hw.byteorder hw.cpu64bit_capable >&2"
+       vv '|' "sysctl kern.version hw.machine hw.model hw.memsize hw.availcpu hw.ncpu hw.cpufrequency hw.byteorder hw.cpu64bit_capable >&2"
+       vv '|' "sysctl hw.cpufrequency hw.byteorder hw.cpu64bit_capable hw.ncpu >&2"
        ;;
 IRIX*)
        vv '|' "uname -a >&2"
@@ -2427,7 +2429,7 @@ addsrcs '!' HAVE_STRLCPY strlcpy.c
 addsrcs USE_PRINTF_BUILTIN printf.c
 test 1 = "$USE_PRINTF_BUILTIN" && add_cppflags -DMKSH_PRINTF_BUILTIN
 test 1 = "$HAVE_CAN_VERB" && CFLAGS="$CFLAGS -verbose"
-add_cppflags -DMKSH_BUILD_R=563
+add_cppflags -DMKSH_BUILD_R=571
 
 $e $bi$me: Finished configuration testing, now producing output.$ao
 
index ea414d3..d5df4cb 100644 (file)
@@ -1,8 +1,9 @@
-# $MirOS: src/bin/mksh/check.t,v 1.801 2018/01/14 01:47:33 tg Exp $
+# $MirOS: src/bin/mksh/check.t,v 1.812 2019/03/01 16:17:29 tg Exp $
 # -*- mode: sh -*-
 #-
 # Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
-#            2011, 2012, 2013, 2014, 2015, 2016, 2017
+#            2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018,
+#            2019
 #      mirabilos <m@mirbsd.org>
 #
 # Provided that these terms and disclaimer and all copyright notices
@@ -30,7 +31,7 @@
 # (2013/12/02 20:39:44) http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/regress/bin/ksh/?sortby=date
 
 expected-stdout:
-       @(#)MIRBSD KSH R56 2018/01/14
+       @(#)MIRBSD KSH R57 2019/03/01
 description:
        Check base version of full shell
 stdin:
@@ -39,7 +40,7 @@ name: KSH_VERSION
 category: !shell:legacy-yes
 ---
 expected-stdout:
-       @(#)LEGACY KSH R56 2018/01/14
+       @(#)LEGACY KSH R57 2019/03/01
 description:
        Check base version of legacy shell
 stdin:
@@ -162,6 +163,38 @@ stdin:
 expected-stdout:
        ;
 ---
+name: selftest-tty-absent
+description:
+       Check that a controlling tty is not present as regress:no-ctty was used
+       (if this test fails for you DO NOT PASS regress:no-ctty and fix every
+       other test that fails: why u use it if u haz ctty?)
+category: regress:no-ctty
+env-setup: !ENV=./envf!
+file-setup: file 644 "envf"
+       PS1=X
+arguments: !-i!
+stdin:
+       echo ok
+expected-stdout:
+       ok
+expected-stderr-pattern:
+       /mksh: warning: won't have full job control\nXX/
+---
+name: selftest-tty-present
+description:
+       Check that a controlling tty is present as regress:no-ctty was not used
+need-ctty: yes
+env-setup: !ENV=./envf!
+file-setup: file 644 "envf"
+       PS1=X
+arguments: !-i!
+stdin:
+       echo ok
+expected-stdout:
+       ok
+expected-stderr: !
+       XX
+---
 name: alias-1
 description:
        Check that recursion is detected/avoided in aliases.
@@ -2455,7 +2488,7 @@ expected-stdout:
 name: glob-range-3
 description:
        Check that globbing matches the right things...
-# breaks on Mac OSX (HFS+ non-standard Unicode canonical decomposition)
+# breaks on Mac OSX (HFS+ non-standard UTF-8 canonical decomposition)
 # breaks on Cygwin 1.7 (files are now UTF-16 or something)
 # breaks on QNX 6.4.1 (says RT)
 category: !os:cygwin,!os:darwin,!os:msys,!os:nto,!os:os2,!os:os390
@@ -3033,6 +3066,19 @@ expected-stdout:
        got four on fd#4
        got five on fd#5
 ---
+name: heredoc-15
+description:
+       Check high-bit7 separators work
+stdin:
+       u=ä
+       tr a-z A-Z <<-…
+               m${u}h
+       …
+       echo ok
+expected-stdout:
+       MäH
+       ok
+---
 name: heredoc-comsub-1
 description:
        Tests for here documents in COMSUB, taken from Austin ML
@@ -3526,6 +3572,25 @@ stdin:
 expected-stdout:
        'blah  1'
 ---
+name: single-quotes-in-heredoc-trim
+description:
+       In some cases, single quotes inside {} in heredoc are not normal
+stdin:
+       x=notOK
+       cat <<EOF
+       1: ${x#not} ${x:+${x#not}}
+       2: ${x#\n\o\t} ${x:+${x#\n\o\t}}
+       3: ${x#"not"} ${x:+${x#"not"}}
+       4: ${x#'not'} ${x:+${x#'not'}}
+       5: ${x#$'not'} ${x:+${x#$'not'}}
+       EOF
+expected-stdout:
+       1: OK OK
+       2: OK OK
+       3: OK OK
+       4: OK OK
+       5: OK OK
+---
 name: history-basic
 description:
        See if we can test history at all
@@ -6835,6 +6900,21 @@ expected-stdout:
        3 10 .
        4 -2147483646 .
 ---
+name: export-1
+description:
+       Check allexport works, basic
+stdin:
+       qa=1
+       set -A qb 2 3
+       set -a
+       qc=4
+       set -A qd 5 6
+       export -p | grep '^export q'
+expected-stdout:
+       export qc=4
+       export qd[0]=5
+       export qd[1]=6
+---
 name: readonly-0
 description:
        Ensure readonly is honoured for assignments and unset
@@ -7065,7 +7145,7 @@ stdin:
        print =4
        (exec lq)
 expected-stdout-pattern:
-       /=1\none\n=2\ntwo\n=3\n.*: ls: not found\n=4\ntf\n/
+       /=1\none\n=2\ntwo\n=3\n.*: ls: inaccessible or not found\n=4\ntf\n/
 ---
 name: exec-ksh88
 description:
@@ -7086,7 +7166,7 @@ stdin:
        print =4
        (exec lq)
 expected-stdout-pattern:
-       /=1\n.*: print: not found\n=2\n.*: foo: not found\n=3\n.*: ls: not found\n=4\ntf\n/
+       /=1\n.*: print: inaccessible or not found\n=2\n.*: foo: inaccessible or not found\n=3\n.*: ls: inaccessible or not found\n=4\ntf\n/
 ---
 name: xxx-what-do-you-call-this-1
 stdin:
@@ -7179,6 +7259,32 @@ expected-stdout:
        HI
        2 4
 ---
+name: xxx-substitution-eval-order-2
+description:
+       Check some corner cases
+stdin:
+       unset var
+       i=42
+       : ${var+${q[i=777]}} required to be lazy by POSIX
+       echo 1=$i
+       var=meow
+       i=42
+       : ${var+${q[i=777]}} eval since var is now set
+       echo 2=$i
+       unset var
+       i=42
+       : ${var#${q[i=777]}} pattern is needed even if var is empty
+       echo 3=$i
+       var=meow
+       i=42
+       : ${var#${q[i=777]}}
+       echo 4=$i
+expected-stdout:
+       1=42
+       2=777
+       3=777
+       4=777
+---
 name: xxx-set-option-1
 description:
        Check option parsing in set
@@ -7280,6 +7386,28 @@ expected-stdout:
        trap: 4
        exit: 4
 ---
+name: xxx-stat-1
+description:
+       Check that tests on files are consistent
+stdin:
+       mkdir a
+       echo x >a/b
+       test -e a/b; echo 1e $? .
+       test -f a/b; echo 1f $? .
+       chmod 0 a
+       test -e a/b; echo 2e $? .
+       test -f a/b; echo 2f $? .
+       chmod 700 a
+       test -e a/b; echo 3e $? .
+       test -f a/b; echo 3f $? .
+expected-stdout:
+       1e 0 .
+       1f 0 .
+       2e 1 .
+       2f 1 .
+       3e 0 .
+       3f 0 .
+---
 name: xxx-clean-chars-1
 description:
        Check MAGIC character is stuffed correctly
@@ -7836,6 +7964,23 @@ expected-stdout:
        EXtrap
        = noeval-undef 1 .
 ---
+name: exit-trap-3
+description:
+       Check that the EXIT trap is run in many places, Debian #910276
+stdin:
+       fkt() {
+               trap -- "echo $1 >&2" EXIT
+       }
+       fkt shell_exit
+       $(fkt fn_exit)
+       $(trap -- "echo comsub_exit >&2" EXIT)
+       (trap -- "echo subshell_exit >&2" EXIT)
+expected-stderr:
+       fn_exit
+       comsub_exit
+       subshell_exit
+       shell_exit
+---
 name: exit-trap-interactive
 description:
        Check that interactive shell doesn't exit via EXIT trap on syntax error
@@ -8444,12 +8589,32 @@ stdin:
 expected-stdout:
        <16#1     > <     16#1> <16#000001> <16#1     > <     16#1> <0000016#1>
 ---
+name: typeset-padding-3
+description:
+       Check for a regression in which UTF-8 wasn’t left-padded right
+stdin:
+       set -U
+       nl=$'\n'
+       typeset -L20 x='.  ak'
+       typeset -R20 y='.  ak'
+       print -r -- "<$x> (1$nl<12345678910 345678920$nl<$y> 1)"
+       typeset -L20 x='.  aẞ'
+       typeset -R20 y='.  aẞ'
+       print -r -- "<$x> (2$nl<12345678910 345678920$nl<$y> 2)"
+expected-stdout:
+       <.  ak               > (1
+       <12345678910 345678920
+       <               .  ak> 1)
+       <.  aẞ               > (2
+       <12345678910 345678920
+       <               .  aẞ> 2)
+---
 name: utf8bom-1
 description:
        Check that the UTF-8 Byte Order Mark is ignored as the first
        multibyte character of the shell input (with -c, from standard
        input, as file, or as eval argument), but nowhere else
-# breaks on Mac OSX (HFS+ non-standard Unicode canonical decomposition)
+# breaks on Mac OSX (HFS+ non-standard UTF-8 canonical decomposition)
 category: !os:darwin,!shell:ebcdic-yes
 stdin:
        mkdir foo
@@ -10328,7 +10493,7 @@ expected-stdout:
 ---
 name: integer-base-one-3Ws
 description:
-       some sample code for hexdumping Unicode
+       some sample code for hexdumping UCS-2
        not NUL safe; input lines must be NL terminated
 stdin:
        set -U
@@ -10496,7 +10661,7 @@ expected-stdout:
 ---
 name: integer-base-one-3Wr
 description:
-       some sample code for hexdumping Unicode; NUL and binary safe
+       some sample code for hexdumping UCS-2; NUL and binary safe
 stdin:
        set -U
        {
@@ -10616,7 +10781,7 @@ expected-stdout:
 ---
 name: integer-base-one-5A
 description:
-       Check to see that we’re NUL and Unicode safe
+       Check to see that we’re NUL and UCS safe
 category: !shell:ebcdic-yes
 stdin:
        set +U
@@ -10630,7 +10795,7 @@ expected-stdout:
 ---
 name: integer-base-one-5E
 description:
-       Check to see that we’re NUL and Unicode safe
+       Check to see that we’re NUL and UCS safe
 category: !shell:ebcdic-no
 stdin:
        set +U
@@ -10644,7 +10809,7 @@ expected-stdout:
 ---
 name: integer-base-one-5W
 description:
-       Check to see that we’re NUL and Unicode safe
+       Check to see that we’re NUL and UCS safe
 stdin:
        set -U
        print 'a\0b€c' >x
@@ -11139,6 +11304,34 @@ stdin:
 expected-stdout:
        Fowl
 ---
+name: fd-cloexec-3
+description:
+       Another check for close-on-exec
+stdin:
+       print '#!'"$__progname" >ts
+       cat >>ts <<'EOF'
+       s=ERR
+       read -rN-1 -u$1 s 2>/dev/null; e=$?
+       print -r -- "($1, $((!e)), $s)"
+       EOF
+       chmod +x ts
+       print foo >tx
+       runtest() {
+               s=$1; shift
+               print -r -- $("$__progname" "$@" -c "$s") "$@" .
+       }
+       runtest 'exec 3<tx; ./ts 3 3<&3; ./ts 3'
+       runtest 'exec 3<tx; ./ts 3 3<&3; ./ts 3' -o posix
+       runtest 'exec 3<tx; ./ts 3 3<&3; ./ts 3' -o sh
+       runtest 'exec 3<tx; ./ts 4 4<&3; ./ts 4 4<&3'
+       runtest 'exec 3<tx; ./ts 3 3<&3; ./ts 3 3<&3'
+expected-stdout:
+       (3, 1, foo) (3, 0, ERR) .
+       (3, 1, foo) (3, 1, ) -o posix .
+       (3, 1, foo) (3, 1, ) -o sh .
+       (4, 1, foo) (4, 1, ) .
+       (3, 1, foo) (3, 1, ) .
+---
 name: comsub-1a
 description:
        COMSUB are now parsed recursively, so this works
index 0e51780..c231af1 100644 (file)
@@ -28,7 +28,7 @@
 
 #ifndef MKSH_NO_CMDLINE_EDITING
 
-__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.342 2018/01/14 00:03:00 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.343 2018/07/15 16:16:38 tg Exp $");
 
 /*
  * in later versions we might use libtermcap for this, but since external
@@ -3831,7 +3831,7 @@ vi_hook(int ch)
                        vs = save_es;
 
                        i = (unsigned)srchlen;
-                       while (--i >= n)
+                       while (i-- > n)
                                vs->linelen -= char_len(locpat[i]);
                        srchlen = (int)n;
                        vs->cursor = vs->linelen;
index 8330174..8231b54 100644 (file)
@@ -2,7 +2,8 @@
 
 /*-
  * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
- *              2011, 2012, 2013, 2014, 2015, 2016, 2017
+ *              2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018,
+ *              2019
  *     mirabilos <m@mirbsd.org>
  *
  * Provided that these terms and disclaimer and all copyright notices
@@ -23,7 +24,7 @@
 
 #include "sh.h"
 
-__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.201 2017/10/11 21:09:24 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.206 2019/03/01 16:17:53 tg Exp $");
 
 #ifndef MKSH_DEFAULT_EXECSHELL
 #define MKSH_DEFAULT_EXECSHELL MKSH_UNIXROOT "/bin/sh"
@@ -429,6 +430,12 @@ execute(struct op * volatile t,
                up = makenv();
                restoresigs();
                cleanup_proc_env();
+               /* I/O redirection cleanup to be done in child process */
+               if (!Flag(FPOSIX) && !Flag(FSH) && t->left->ioact != NULL)
+                       for (iowp = t->left->ioact; *iowp != NULL; iowp++)
+                               if ((*iowp)->ioflag & IODUPSELF)
+                                       fcntl((*iowp)->unit, F_SETFD, 0);
+               /* try to execute */
                {
                        union mksh_ccphack cargs;
 
@@ -820,7 +827,8 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap,
                if (!(tp->flag&ISSET)) {
                        if (tp->u2.errnov == ENOENT) {
                                rv = 127;
-                               warningf(true, Tf_sD_s, cp, Tnot_found);
+                               warningf(true, Tf_sD_s_s, cp,
+                                   "inaccessible or", Tnot_found);
                        } else {
                                rv = 126;
                                warningf(true, Tf_sD_sD_s, cp, "can't execute",
@@ -862,7 +870,7 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap,
  Leave:
        if (flags & XEXEC) {
                exstat = rv & 0xFF;
-               unwind(LLEAVE);
+               unwind(LEXIT);
        }
        return (rv);
 }
@@ -886,7 +894,7 @@ scriptexec(struct op *tp, const char **ap)
        *tp->args-- = tp->str;
 
 #ifndef MKSH_SMALL
-       if ((fd = binopen2(tp->str, O_RDONLY)) >= 0) {
+       if ((fd = binopen2(tp->str, O_RDONLY | O_MAYEXEC)) >= 0) {
                unsigned char *cp;
 #ifndef MKSH_EBCDIC
                unsigned short m;
@@ -1011,7 +1019,7 @@ scriptexec(struct op *tp, const char **ap)
        cap.ro = ap;
        execve(args.rw[0], args.rw, cap.rw);
 
-       /* report both the programme that was run and the bogus interpreter */
+       /* report both the program that was run and the bogus interpreter */
        errorf(Tf_sD_sD_s, tp->str, sh, cstrerror(errno));
 }
 
@@ -1485,9 +1493,11 @@ iosetup(struct ioword *iop, struct tbl *tp)
                        afree(sp, ATEMP);
                        return (-1);
                }
-               if (u == (int)iop->unit)
+               if (u == (int)iop->unit) {
                        /* "dup from" == "dup to" */
+                       iop->ioflag |= IODUPSELF;
                        return (0);
+               }
                break;
            }
        }
index 499b961..5d2c869 100644 (file)
@@ -23,7 +23,7 @@
 
 #include "sh.h"
 
-__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.103 2018/01/14 01:29:47 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.105 2018/08/10 02:53:33 tg Exp $");
 
 #define EXPRTOK_DEFNS
 #include "exprtok.h"
@@ -885,7 +885,7 @@ static int mb_ucsbsearch(const struct mb_ucsrange arr[], size_t elems,
     unsigned int val) MKSH_A_PURE;
 
 /*
- * Generated from the Unicode Character Database, Version 10.0.0, by
+ * Generated from the UCD 11.0.0 by
  * MirOS: contrib/code/Snippets/eawparse,v 1.12 2017/09/06 16:05:45 tg Exp $
  */
 
@@ -909,12 +909,13 @@ static const struct mb_ucsrange mb_ucs_combining[] = {
        { 0x0730, 0x074A },
        { 0x07A6, 0x07B0 },
        { 0x07EB, 0x07F3 },
+       { 0x07FD, 0x07FD },
        { 0x0816, 0x0819 },
        { 0x081B, 0x0823 },
        { 0x0825, 0x0827 },
        { 0x0829, 0x082D },
        { 0x0859, 0x085B },
-       { 0x08D4, 0x08E1 },
+       { 0x08D3, 0x08E1 },
        { 0x08E3, 0x0902 },
        { 0x093A, 0x093A },
        { 0x093C, 0x093C },
@@ -927,6 +928,7 @@ static const struct mb_ucsrange mb_ucs_combining[] = {
        { 0x09C1, 0x09C4 },
        { 0x09CD, 0x09CD },
        { 0x09E2, 0x09E3 },
+       { 0x09FE, 0x09FE },
        { 0x0A01, 0x0A02 },
        { 0x0A3C, 0x0A3C },
        { 0x0A41, 0x0A42 },
@@ -953,6 +955,7 @@ static const struct mb_ucsrange mb_ucs_combining[] = {
        { 0x0BC0, 0x0BC0 },
        { 0x0BCD, 0x0BCD },
        { 0x0C00, 0x0C00 },
+       { 0x0C04, 0x0C04 },
        { 0x0C3E, 0x0C40 },
        { 0x0C46, 0x0C48 },
        { 0x0C4A, 0x0C4D },
@@ -1072,6 +1075,7 @@ static const struct mb_ucsrange mb_ucs_combining[] = {
        { 0xA825, 0xA826 },
        { 0xA8C4, 0xA8C5 },
        { 0xA8E0, 0xA8F1 },
+       { 0xA8FF, 0xA8FF },
        { 0xA926, 0xA92D },
        { 0xA947, 0xA951 },
        { 0xA980, 0xA982 },
@@ -1173,7 +1177,7 @@ mb_ucsbsearch(const struct mb_ucsrange arr[], size_t elems, unsigned int val)
        return (0);
 }
 
-/* Unix column width of a wide character (Unicode code point, really) */
+/* Unix column width of a wide character (UCS code point, really) */
 int
 utf_wcwidth(unsigned int wc)
 {
index 5179192..ade00d6 100644 (file)
@@ -38,7 +38,7 @@
 #endif
 #endif
 
-__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.353 2018/01/14 01:26:49 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.355 2018/10/20 21:04:28 tg Exp $");
 
 #if HAVE_KILLPG
 /*
@@ -499,7 +499,7 @@ c_print(const char **wp)
                                                Xput(xs, xp, '\\');
                                        }
                                } else if ((unsigned int)c > 0xFF) {
-                                       /* generic function returned Unicode */
+                                       /* generic function returned UCS */
                                        po.ts[utf_wctomb(po.ts, c - 0x100)] = 0;
                                        c = 0;
                                        do {
@@ -2970,6 +2970,37 @@ test_eval(Test_env *te, Test_op op, const char *opnd1, const char *opnd2,
        case TO_STGT:
                return (strcmp(opnd1, opnd2) > 0);
 
+       /* -nt */
+       case TO_FILNT:
+               /*
+                * ksh88/ksh93 succeed if file2 can't be stated
+                * (subtly different from 'does not exist').
+                */
+               return (stat(opnd1, &b1) == 0 &&
+                   (((s = stat(opnd2, &b2)) == 0 &&
+                   b1.st_mtime > b2.st_mtime) || s < 0));
+
+       /* -ot */
+       case TO_FILOT:
+               /*
+                * ksh88/ksh93 succeed if file1 can't be stated
+                * (subtly different from 'does not exist').
+                */
+               return (stat(opnd2, &b2) == 0 &&
+                   (((s = stat(opnd1, &b1)) == 0 &&
+                   b1.st_mtime < b2.st_mtime) || s < 0));
+
+       /* -ef */
+       case TO_FILEQ:
+               return (stat (opnd1, &b1) == 0 && stat (opnd2, &b2) == 0 &&
+                   b1.st_dev == b2.st_dev && b1.st_ino == b2.st_ino);
+
+       /* all other cases */
+       case TO_NONOP:
+       case TO_NONNULL:
+               /* throw the error */
+               break;
+
        /* -eq */
        case TO_INTEQ:
        /* -ne */
@@ -3006,37 +3037,6 @@ test_eval(Test_env *te, Test_op op, const char *opnd1, const char *opnd2,
                        break;
                }
                /* NOTREACHED */
-
-       /* -nt */
-       case TO_FILNT:
-               /*
-                * ksh88/ksh93 succeed if file2 can't be stated
-                * (subtly different from 'does not exist').
-                */
-               return (stat(opnd1, &b1) == 0 &&
-                   (((s = stat(opnd2, &b2)) == 0 &&
-                   b1.st_mtime > b2.st_mtime) || s < 0));
-
-       /* -ot */
-       case TO_FILOT:
-               /*
-                * ksh88/ksh93 succeed if file1 can't be stated
-                * (subtly different from 'does not exist').
-                */
-               return (stat(opnd2, &b2) == 0 &&
-                   (((s = stat(opnd1, &b1)) == 0 &&
-                   b1.st_mtime < b2.st_mtime) || s < 0));
-
-       /* -ef */
-       case TO_FILEQ:
-               return (stat (opnd1, &b1) == 0 && stat (opnd2, &b2) == 0 &&
-                   b1.st_dev == b2.st_dev && b1.st_ino == b2.st_ino);
-
-       /* all other cases */
-       case TO_NONOP:
-       case TO_NONNULL:
-               /* throw the error */
-               break;
        }
        (*te->error)(te, 0, "internal error: unknown op");
        return (1);
index 6b9396e..985b2a3 100644 (file)
@@ -3,7 +3,7 @@
 
 /*-
  * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
- *              2011, 2012, 2014, 2015, 2016, 2017
+ *              2011, 2012, 2014, 2015, 2016, 2017, 2018
  *     mirabilos <m@mirbsd.org>
  *
  * Provided that these terms and disclaimer and all copyright notices
@@ -27,7 +27,7 @@
 #include <sys/file.h>
 #endif
 
-__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.166 2017/08/07 23:25:09 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.167 2018/04/28 17:16:54 tg Exp $");
 
 Trap sigtraps[ksh_NSIG + 1];
 static struct sigaction Sigact_ign;
@@ -879,7 +879,8 @@ hist_persist_init(void)
                }
        }
  hist_trunc_done:
-       histfsize = lseek(histfd, (off_t)0, SEEK_END);
+       if ((histfsize = lseek(histfd, (off_t)0, SEEK_END)) < 0)
+               goto hist_init_fail;
  hist_init_tail:
        mksh_unlkfd(histfd);
 }
@@ -962,8 +963,9 @@ writehistfile(int lno, const char *cmd)
        unsigned char *base, *news;
 
        mksh_lockfd(histfd);
-       sizenow = lseek(histfd, (off_t)0, SEEK_END);
-       if (sizenow < histfsize) {
+       if ((sizenow = lseek(histfd, (off_t)0, SEEK_END)) < 0)
+               goto bad;
+       else if (sizenow < histfsize) {
                /* the file has shrunk; trust it just appending the new data */
                /* well, for now, anyway… since mksh strdups all into memory */
                /* we can use a nicer approach some time later… */
@@ -998,7 +1000,8 @@ writehistfile(int lno, const char *cmd)
                hist_finish();
                return;
        }
-       histfsize = lseek(histfd, (off_t)0, SEEK_END);
+       if ((histfsize = lseek(histfd, (off_t)0, SEEK_END)) < 0)
+               goto bad;
        mksh_unlkfd(histfd);
 }
 
diff --git a/src/jehanne.c b/src/jehanne.c
new file mode 100644 (file)
index 0000000..ba0eb0f
--- /dev/null
@@ -0,0 +1,36 @@
+/*-
+ * Copyright (c) 2017
+ *     Giacomo Tesio <giacomo@tesio.it>
+ *
+ * Provided that these terms and disclaimer and all copyright notices
+ * are retained or reproduced in an accompanying document, permission
+ * is granted to deal in this work without restriction, including un-
+ * limited rights to use, publicly perform, distribute, sell, modify,
+ * merge, give away, or sublicence.
+ *
+ * This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
+ * the utmost extent permitted by applicable law, neither express nor
+ * implied; without malicious intent or gross negligence. In no event
+ * may a licensor, author or contributor be held liable for indirect,
+ * direct, other damage, loss, or other issues arising in any way out
+ * of dealing in the work, even if advised of the possibility of such
+ * damage or existence of a defect, except proven that it results out
+ * of said person's immediate fault when using the work as intended.
+ *-
+ * Initialisation code for the Jehanne operating system (a Plan 9 de-
+ * rivative, using GCC)
+ */
+
+static const char __rcsid[] __attribute__((__used__)) =
+    "$MirOS: src/bin/mksh/jehanne.c,v 1.1 2017/12/22 16:30:00 tg Exp $";
+
+#include <u.h>
+#include <lib9.h>
+#include <posix.h>
+
+void
+__application_newlib_init(int argc, char *argv[])
+{
+       rfork(RFFDG | RFREND | RFNOTEG);
+       libposix_emulate_SIGCHLD();
+}
index a0b9b79..66e31aa 100644 (file)
@@ -23,7 +23,7 @@
 
 #include "sh.h"
 
-__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.125 2018/01/05 20:08:34 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.127 2018/07/15 16:23:10 tg Exp $");
 
 #if HAVE_KILLPG
 #define mksh_killpg            killpg
@@ -169,12 +169,6 @@ static void tty_init_state(void);
 void
 j_init(void)
 {
-#ifndef MKSH_UNEMPLOYED
-       bool mflagset = Flag(FMONITOR) != 127;
-
-       Flag(FMONITOR) = 0;
-#endif
-
 #ifndef MKSH_NOPROSPECTOFWORK
        (void)sigemptyset(&sm_default);
        sigprocmask(SIG_SETMASK, &sm_default, NULL);
@@ -190,8 +184,8 @@ j_init(void)
 #endif
 
 #ifndef MKSH_UNEMPLOYED
-       if (!mflagset && Flag(FTALKING))
-               Flag(FMONITOR) = 1;
+       if (Flag(FMONITOR) == 127)
+               Flag(FMONITOR) = Flag(FTALKING);
 
        /*
         * shl_j is used to do asynchronous notification (used in
@@ -1932,7 +1926,7 @@ tty_init_talking(void)
                break;
        case 2:
 #ifndef MKSH_DISABLE_TTY_WARNING
-               warningf(false, Tf_sD_s_s, Tcant_find, Ttty_fd,
+               warningf(false, Tf_s_sD_s, Tcant_find, Ttty_fd,
                    cstrerror(errno));
 #endif
                break;
index 9300311..8c75a98 100644 (file)
--- a/src/lex.c
+++ b/src/lex.c
@@ -23,7 +23,7 @@
 
 #include "sh.h"
 
-__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.247 2018/01/14 01:44:01 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.250 2018/10/20 18:34:14 tg Exp $");
 
 /*
  * states while lexing word
@@ -77,12 +77,17 @@ typedef struct lex_state {
        short nparen;
        /* type of this state */
        uint8_t type;
+       /* extra flags */
+       uint8_t ls_flags;
 } Lex_state;
 #define ls_base                u.base
 #define ls_start       u.start
 #define ls_bool                u.abool
 #define ls_adelim      u.adelim
 
+/* ls_flags */
+#define LS_HEREDOC     BIT(0)
+
 typedef struct {
        Lex_state *base;
        Lex_state *end;
@@ -147,9 +152,11 @@ getsc_r(int c)
 #define STATE_BSIZE    8
 
 #define PUSH_STATE(s)  do {                                    \
+       uint8_t state_flags = statep->ls_flags;                 \
        if (++statep == state_info.end)                         \
                statep = push_state_i(&state_info, statep);     \
        state = statep->type = (s);                             \
+       statep->ls_flags = state_flags;                         \
 } while (/* CONSTCOND */ 0)
 
 #define POP_STATE()    do {                                    \
@@ -242,6 +249,7 @@ yylex(int cf)
 
        /* Initial state: one of SWORD SLETPAREN SHEREDELIM SBASE */
        statep->type = state;
+       statep->ls_flags = (cf & HEREDOC) ? LS_HEREDOC : 0;
 
        /* collect non-special or quoted characters to form word */
        while (!((c = getsc()) == 0 ||
@@ -319,7 +327,7 @@ yylex(int cf)
                                break;
                        case ORD('\''):
  open_ssquote_unless_heredoc:
-                               if ((cf & HEREDOC))
+                               if ((statep->ls_flags & LS_HEREDOC))
                                        goto store_char;
                                *wp++ = OQUOTE;
                                ignore_backslash_newline++;
@@ -357,7 +365,7 @@ yylex(int cf)
                                c = getsc();
                                switch (c) {
                                case ORD('"'):
-                                       if ((cf & HEREDOC))
+                                       if ((statep->ls_flags & LS_HEREDOC))
                                                goto heredocquote;
                                        /* FALLTHROUGH */
                                case ORD('\\'):
@@ -388,6 +396,8 @@ yylex(int cf)
                                        if ((unsigned int)c == ORD('(' /*)*/)) {
                                                *wp++ = EXPRSUB;
                                                PUSH_SRETRACE(SASPAREN);
+                                               /* unneeded? */
+                                               /*statep->ls_flags &= ~LS_HEREDOC;*/
                                                statep->nparen = 2;
                                                *retrace_info->xp++ = '(';
                                        } else {
@@ -434,6 +444,8 @@ yylex(int cf)
                                                        *wp++ = ADELIM;
                                                        *wp++ = ':';
                                                        PUSH_STATE(SBRACE);
+                                                       /* perhaps unneeded? */
+                                                       statep->ls_flags &= ~LS_HEREDOC;
                                                        PUSH_STATE(SADELIM);
                                                        statep->ls_adelim.delimiter = ':';
                                                        statep->ls_adelim.num = 1;
@@ -449,6 +461,8 @@ yylex(int cf)
                                                        }
                                                        ungetsc(c);
                                                        PUSH_STATE(SBRACE);
+                                                       /* perhaps unneeded? */
+                                                       statep->ls_flags &= ~LS_HEREDOC;
                                                        PUSH_STATE(SADELIM);
                                                        statep->ls_adelim.delimiter = ':';
                                                        statep->ls_adelim.num = 2;
@@ -466,6 +480,8 @@ yylex(int cf)
                                                } else
                                                        ungetsc(c);
                                                PUSH_STATE(SBRACE);
+                                               /* perhaps unneeded? */
+                                               statep->ls_flags &= ~LS_HEREDOC;
                                                PUSH_STATE(SADELIM);
                                                statep->ls_adelim.delimiter = '/';
                                                statep->ls_adelim.num = 1;
@@ -489,6 +505,8 @@ yylex(int cf)
                                                        PUSH_STATE(STBRACEBOURNE);
                                                else
                                                        PUSH_STATE(STBRACEKORN);
+                                               /* single-quotes-in-heredoc-trim */
+                                               statep->ls_flags &= ~LS_HEREDOC;
                                        } else {
                                                ungetsc(c);
                                                if (state == SDQUOTE ||
@@ -496,6 +514,8 @@ yylex(int cf)
                                                        PUSH_STATE(SQBRACE);
                                                else
                                                        PUSH_STATE(SBRACE);
+                                               /* here no LS_HEREDOC removal */
+                                               /* single-quotes-in-heredoc-braces */
                                        }
                                } else if (ctype(c, C_ALPHX)) {
                                        *wp++ = OSUBST;
@@ -601,7 +621,8 @@ yylex(int cf)
                case SSQUOTE:
                        if ((unsigned int)c == ORD('\'')) {
                                POP_STATE();
-                               if ((cf & HEREDOC) || state == SQBRACE)
+                               if ((statep->ls_flags & LS_HEREDOC) ||
+                                   state == SQBRACE)
                                        goto store_char;
                                *wp++ = CQUOTE;
                                ignore_backslash_newline--;
@@ -1155,7 +1176,7 @@ readhere(struct ioword *iop)
                        /* Newline terminates here document marker */
                        goto heredoc_found_terminator;
                }
-       } else if (c == *eofp++)
+       } else if ((unsigned int)c == ord(*eofp++))
                /* store; then read and compare next character */
                goto heredoc_store_and_loop;
        /* nope, mismatch; read until end of line */
@@ -1338,7 +1359,7 @@ getsc_line(Source *s)
 {
        char *xp = Xstring(s->xs, xp), *cp;
        bool interactive = Flag(FTALKING) && s->type == SSTDIN;
-       bool have_tty = tobool(interactive && (s->flags & SF_TTY));
+       bool have_tty = interactive && (s->flags & SF_TTY) && tty_hasstate;
 
        /* Done here to ensure nothing odd happens when a timeout occurs */
        XcheckN(s->xs, xp, LINE);
index c3a82cb..0d6b226 100644 (file)
@@ -1,6 +1,6 @@
-.\" $MirOS: src/bin/mksh/lksh.1,v 1.23 2017/04/02 13:38:02 tg Exp $
+.\" $MirOS: src/bin/mksh/lksh.1,v 1.25 2018/12/25 19:38:08 tg Exp $
 .\"-
-.\" Copyright (c) 2008, 2009, 2010, 2012, 2013, 2015, 2016, 2017
+.\" Copyright (c) 2008, 2009, 2010, 2012, 2013, 2015, 2016, 2017, 2018
 .\"    mirabilos <m@mirbsd.org>
 .\"
 .\" Provided that these terms and disclaimer and all copyright notices
@@ -74,7 +74,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 2 2017 $
+.Dd $Mdocdate: December 25 2018 $
 .\"
 .\" Check which macro package we use, and do other -mdoc setup.
 .\"
@@ -82,6 +82,7 @@
 .      if \ 1\*[.T]\ 1utf8\ 1 .tr \[la]\*(Lt
 .      if \ 1\*[.T]\ 1utf8\ 1 .tr \[ra]\*(Gt
 .      ie d volume-ds-1 .ds tT gnu
+.      el .ie d doc-volume-ds-1 .ds tT gnp
 .      el .ds tT bsd
 .\}
 .el .ds tT ucb
@@ -94,7 +95,7 @@
 .      nr curr-font \n[.f]
 .      nr curr-size \n[.ps]
 .      ds str-Mx \f[\n[curr-font]]\s[\n[curr-size]u]
-.      ds str-Mx1 \*[Tn-font-size]\%MirOS\*[str-Mx]
+.      ds str-Mx1 \*[Tn-font-size]\%MirBSD\*[str-Mx]
 .      if !\n[arg-limit] \
 .      if \n[.$] \{\
 .      ds macro-name Mx
 .      ds sP \s0
 .      ds tN \*[Tn-font-size]
 .\}
+.el .ie "\*(tT"gnp" \{\
+.      eo
+.      de Mx
+.      nr doc-curr-font \n[.f]
+.      nr doc-curr-size \n[.ps]
+.      ds doc-str-Mx \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u]
+.      ds doc-str-Mx1 \*[doc-Tn-font-size]\%MirBSD\*[doc-str-Mx]
+.      if !\n[doc-arg-limit] \
+.      if \n[.$] \{\
+.      ds doc-macro-name Mx
+.      doc-parse-args \$@
+.      \}
+.      if (\n[doc-arg-limit] > \n[doc-arg-ptr]) \{\
+.      nr doc-arg-ptr +1
+.      ie (\n[doc-type\n[doc-arg-ptr]] == 2) \
+.      as doc-str-Mx1 \~\*[doc-arg\n[doc-arg-ptr]]
+.      el \
+.      nr doc-arg-ptr -1
+.      \}
+.      ds doc-arg\n[doc-arg-ptr] "\*[doc-str-Mx1]
+.      nr doc-type\n[doc-arg-ptr] 2
+.      ds doc-space\n[doc-arg-ptr] "\*[doc-space]
+.      nr doc-num-args (\n[doc-arg-limit] - \n[doc-arg-ptr])
+.      nr doc-arg-limit \n[doc-arg-ptr]
+.      if \n[doc-num-args] \
+.      doc-parse-space-vector
+.      doc-print-recursive
+..
+.      ec
+.      ds sP \s0
+.      ds tN \*[doc-Tn-font-size]
+.\}
 .el \{\
 .      de Mx
 .      nr cF \\n(.f
 .      nr cZ \\n(.s
 .      ds aa \&\f\\n(cF\s\\n(cZ
 .      if \\n(aC==0 \{\
-.              ie \\n(.$==0 \&MirOS\\*(aa
+.              ie \\n(.$==0 \&MirBSD\\*(aa
 .              el .aV \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
 .      \}
 .      if \\n(aC>\\n(aP \{\
 .              nr aP \\n(aP+1
 .              ie \\n(C\\n(aP==2 \{\
-.                      as b1 \&MirOS\ #\&\\*(A\\n(aP\\*(aa
+.                      as b1 \&MirBSD\ #\&\\*(A\\n(aP\\*(aa
 .                      ie \\n(aC>\\n(aP \{\
 .                              nr aP \\n(aP+1
 .                              nR
 .                      el .aZ
 .              \}
 .              el \{\
-.                      as b1 \&MirOS\\*(aa
+.                      as b1 \&MirBSD\\*(aa
 .                      nR
 .              \}
 .      \}
@@ -304,9 +337,11 @@ is not exactly specified.
 .Pp
 Talk to the
 .Mx
-development team using the mailing list at
-.Aq miros\-mksh@mirbsd.org
-or the
+development team and users using the mailing list at
+.Aq Mt miros\-mksh@mirbsd.org
+(please note the EU-DSGVO/GDPR notice on
+.Pa http://www.mirbsd.org/rss.htm#lists
+and in the SMTP banner!) or the
 .Li \&#\&!/bin/mksh
 .Pq or Li \&#ksh
 IRC channel at
index ad20c94..41dd6da 100644 (file)
@@ -5,7 +5,8 @@
 
 /*-
  * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
- *              2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018
+ *              2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018,
+ *              2019
  *     mirabilos <m@mirbsd.org>
  *
  * Provided that these terms and disclaimer and all copyright notices
@@ -34,7 +35,7 @@
 #include <locale.h>
 #endif
 
-__RCSID("$MirOS: src/bin/mksh/main.c,v 1.347 2018/01/13 21:45:07 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/main.c,v 1.351 2019/01/05 13:24:18 tg Exp $");
 
 #ifndef MKSHRC_PATH
 #define MKSHRC_PATH    "~/.mkshrc"
@@ -463,7 +464,7 @@ main_init(int argc, const char *argv[], Source **sp, struct block **lp)
        /* Set this before parsing arguments */
        Flag(FPRIVILEGED) = (kshuid != ksheuid || kshgid != kshegid) ? 2 : 0;
 
-       /* this to note if monitor is set on command line (see below) */
+       /* record if monitor is set on command line (see j_init() in jobs.c) */
 #ifndef MKSH_UNEMPLOYED
        Flag(FMONITOR) = 127;
 #endif
@@ -519,7 +520,7 @@ main_init(int argc, const char *argv[], Source **sp, struct block **lp)
 #else
                s->file = argv[argi++];
 #endif
-               s->u.shf = shf_open(s->file, O_RDONLY, 0,
+               s->u.shf = shf_open(s->file, O_RDONLY | O_MAYEXEC, 0,
                    SHF_MAPHI | SHF_CLEXEC);
                if (s->u.shf == NULL) {
                        shl_stdout_ok = false;
@@ -719,7 +720,7 @@ include(const char *name, int argc, const char **argv, bool intr_ok)
        volatile int old_argc;
        int i;
 
-       shf = shf_open(name, O_RDONLY, 0, SHF_MAPHI | SHF_CLEXEC);
+       shf = shf_open(name, O_RDONLY | O_MAYEXEC, 0, SHF_MAPHI | SHF_CLEXEC);
        if (shf == NULL)
                return (-1);
 
@@ -1965,7 +1966,7 @@ x_mkraw(int fd, mksh_ttyst *ocb, bool forread)
        /* OSF/1 processes lnext when ~icanon */
        cb.c_cc[VLNEXT] = _POSIX_VDISABLE;
 #endif
-       /* SunOS 4.1.x & OSF/1 processes discard(flush) when ~icanon */
+       /* SunOS 4.1.x and OSF/1 process discard(flush) when ~icanon */
 #if defined(VDISCARD) && defined(_POSIX_VDISABLE)
        cb.c_cc[VDISCARD] = _POSIX_VDISABLE;
 #endif
@@ -2061,6 +2062,7 @@ void
 recheck_ctype(void)
 {
        const char *ccp;
+       uint8_t old_utfmode = UTFMODE;
 
        ccp = str_val(global("LC_ALL"));
        if (ccp == null)
@@ -2078,7 +2080,7 @@ recheck_ctype(void)
                UTFMODE = 1;
 #endif
 
-       if (Flag(FPOSIX))
+       if (Flag(FPOSIX) && UTFMODE && !old_utfmode)
                warningf(true, "early locale tracking enabled UTF-8 mode while in POSIX mode, you are now noncompliant");
 }
 #endif
index e51dcb1..cddc516 100644 (file)
@@ -32,7 +32,7 @@
 #include <grp.h>
 #endif
 
-__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.291 2018/01/14 00:03:03 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.293 2018/08/10 02:53:35 tg Exp $");
 
 #define KSH_CHVT_FLAG
 #ifdef MKSH_SMALL
@@ -1346,7 +1346,14 @@ print_value_quoted(struct shf *shf, const char *s)
        const unsigned char *p = (const unsigned char *)s;
        bool inquote = true;
 
-       /* first, check whether any quotes are needed */
+       /* first, special-case empty strings (for re-entrancy) */
+       if (!*s) {
+               shf_putc('\'', shf);
+               shf_putc('\'', shf);
+               return;
+       }
+
+       /* non-empty; check whether any quotes are needed */
        while (rtt2asc(c = *p++) >= 32)
                if (ctype(c, C_QUOTE | C_SPC))
                        inquote = false;
@@ -2449,7 +2456,7 @@ getrusage(int what, struct rusage *ru)
  * and fp (put back a char) for backslash escapes,
  * assuming the first call to *fg gets the char di-
  * rectly after the backslash; return the character
- * (0..0xFF), Unicode (wc + 0x100), or -1 if no known
+ * (0..0xFF), UCS (wc + 0x100), or -1 if no known
  * escape sequence was found
  */
 int
@@ -2531,9 +2538,9 @@ unbksl(bool cstyle, int (*fg)(void), void (*fp)(int))
                /**
                 * x:   look for a hexadecimal number with up to
                 *      two (C style: arbitrary) digits; convert
-                *      to raw octet (C style: Unicode if >0xFF)
+                *      to raw octet (C style: UCS if >0xFF)
                 * u/U: look for a hexadecimal number with up to
-                *      four (U: eight) digits; convert to Unicode
+                *      four (U: eight) digits; convert to UCS
                 */
                wc = 0;
                n = 0;
@@ -2555,7 +2562,7 @@ unbksl(bool cstyle, int (*fg)(void), void (*fp)(int))
                if (!n)
                        goto unknown_escape;
                if ((cstyle && wc > 0xFF) || fc != 'x')
-                       /* Unicode marker */
+                       /* UCS marker */
                        wc += 0x100;
                break;
        case '\'':
index aa67ac9..2e83428 100644 (file)
@@ -1,8 +1,9 @@
-.\" $MirOS: src/bin/mksh/mksh.1,v 1.451 2017/08/16 21:40:14 tg Exp $
+.\" $MirOS: src/bin/mksh/mksh.1,v 1.463 2019/03/01 16:17:31 tg Exp $
 .\" $OpenBSD: ksh.1,v 1.160 2015/07/04 13:27:04 feinerer Exp $
 .\"-
 .\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
-.\"            2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017
+.\"            2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017,
+.\"            2018, 2019
 .\"    mirabilos <m@mirbsd.org>
 .\"
 .\" Provided that these terms and disclaimer and all copyright notices
@@ -76,7 +77,7 @@
 .\" with -mandoc, it might implement .Mx itself, but we want to
 .\" use our own definition. And .Dd must come *first*, always.
 .\"
-.Dd $Mdocdate: August 16 2017 $
+.Dd $Mdocdate: March 1 2019 $
 .\"
 .\" Check which macro package we use, and do other -mdoc setup.
 .\"
@@ -84,6 +85,7 @@
 .      if \ 1\*[.T]\ 1utf8\ 1 .tr \[la]\*(Lt
 .      if \ 1\*[.T]\ 1utf8\ 1 .tr \[ra]\*(Gt
 .      ie d volume-ds-1 .ds tT gnu
+.      el .ie d doc-volume-ds-1 .ds tT gnp
 .      el .ds tT bsd
 .\}
 .el .ds tT ucb
@@ -96,7 +98,7 @@
 .      nr curr-font \n[.f]
 .      nr curr-size \n[.ps]
 .      ds str-Mx \f[\n[curr-font]]\s[\n[curr-size]u]
-.      ds str-Mx1 \*[Tn-font-size]\%MirOS\*[str-Mx]
+.      ds str-Mx1 \*[Tn-font-size]\%MirBSD\*[str-Mx]
 .      if !\n[arg-limit] \
 .      if \n[.$] \{\
 .      ds macro-name Mx
 .      ds sP \s0
 .      ds tN \*[Tn-font-size]
 .\}
+.el .ie "\*(tT"gnp" \{\
+.      eo
+.      de Mx
+.      nr doc-curr-font \n[.f]
+.      nr doc-curr-size \n[.ps]
+.      ds doc-str-Mx \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u]
+.      ds doc-str-Mx1 \*[doc-Tn-font-size]\%MirBSD\*[doc-str-Mx]
+.      if !\n[doc-arg-limit] \
+.      if \n[.$] \{\
+.      ds doc-macro-name Mx
+.      doc-parse-args \$@
+.      \}
+.      if (\n[doc-arg-limit] > \n[doc-arg-ptr]) \{\
+.      nr doc-arg-ptr +1
+.      ie (\n[doc-type\n[doc-arg-ptr]] == 2) \
+.      as doc-str-Mx1 \~\*[doc-arg\n[doc-arg-ptr]]
+.      el \
+.      nr doc-arg-ptr -1
+.      \}
+.      ds doc-arg\n[doc-arg-ptr] "\*[doc-str-Mx1]
+.      nr doc-type\n[doc-arg-ptr] 2
+.      ds doc-space\n[doc-arg-ptr] "\*[doc-space]
+.      nr doc-num-args (\n[doc-arg-limit] - \n[doc-arg-ptr])
+.      nr doc-arg-limit \n[doc-arg-ptr]
+.      if \n[doc-num-args] \
+.      doc-parse-space-vector
+.      doc-print-recursive
+..
+.      ec
+.      ds sP \s0
+.      ds tN \*[doc-Tn-font-size]
+.\}
 .el \{\
 .      de Mx
 .      nr cF \\n(.f
 .      nr cZ \\n(.s
 .      ds aa \&\f\\n(cF\s\\n(cZ
 .      if \\n(aC==0 \{\
-.              ie \\n(.$==0 \&MirOS\\*(aa
+.              ie \\n(.$==0 \&MirBSD\\*(aa
 .              el .aV \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
 .      \}
 .      if \\n(aC>\\n(aP \{\
 .              nr aP \\n(aP+1
 .              ie \\n(C\\n(aP==2 \{\
-.                      as b1 \&MirOS\ #\&\\*(A\\n(aP\\*(aa
+.                      as b1 \&MirBSD\ #\&\\*(A\\n(aP\\*(aa
 .                      ie \\n(aC>\\n(aP \{\
 .                              nr aP \\n(aP+1
 .                              nR
 .                      el .aZ
 .              \}
 .              el \{\
-.                      as b1 \&MirOS\\*(aa
+.                      as b1 \&MirBSD\\*(aa
 .                      nR
 .              \}
 .      \}
@@ -1046,7 +1080,7 @@ and
 .Dq Li \eu#### ,
 .Dq #
 means a hexadecimal digit, of which there may be none up to four or eight;
-these escapes translate a Unicode codepoint to UTF-8.
+these escapes translate a Universal Coded Character Set codepoint to UTF-8.
 Furthermore,
 .Dq Li \eE
 and
@@ -1082,7 +1116,7 @@ and yield raw octets; hexadecimal sequences
 greedily eat up as many hexadecimal digits
 .Dq #
 as they can and terminate with the first non-hexadecimal digit;
-these translate a Unicode codepoint to UTF-8.
+these translate a Universal Coded Character Set codepoint to UTF-8.
 The sequence
 .Dq Li \ec# ,
 where
@@ -1364,6 +1398,10 @@ or
 where
 .Ar name
 is a parameter name.
+Substitutions of an an array in scalar context, i.e. without an
+.Ar expr
+in the latter form mentioned above, expand the element with the key
+.Dq 0 .
 Substitution of all array elements with
 .Pf ${ Ns Ar name Ns \&[*]}
 and
@@ -1519,11 +1557,7 @@ on it; if
 .Ar word
 is not needed, it is not evaluated.
 .Pp
-The following forms of parameter substitution can also be used (if
-.Ar name
-is an array, the element with the key
-.Dq 0
-will be substituted in scalar context):
+The following forms of parameter substitution can also be used:
 .Pp
 .Bl -tag -width Ds -compact
 .It Pf ${# Ns Ar name Ns \&}
@@ -1823,10 +1857,10 @@ built-in command will display the resulting directory when a match is found
 in any search path other than the empty path.
 .It Ev COLUMNS
 Set to the number of columns on the terminal or window.
-Always set, defaults to 80, unless the
-value as reported by
+If never unset and not imported, always set dynamically;
+unless the value as reported by
 .Xr stty 1
-is non-zero and sane enough (minimum is 12x3); similar for
+is non-zero and sane enough (minimum is 12x3), defaults to 80; similar for
 .Ev LINES .
 This parameter is used by the interactive line editing modes and by the
 .Ic select ,
@@ -1995,7 +2029,7 @@ The line number of the function or shell script that is currently being
 executed.
 .It Ev LINES
 Set to the number of lines on the terminal or window.
-Always set, defaults to 24.
+Defaults to 24; always set, unless imported or unset.
 See
 .Ev COLUMNS .
 .It Ev OLDPWD
@@ -2651,7 +2685,8 @@ as required by the standard), as that's unsafe to do.
 As a special
 .Nm mksh
 extension, numbers to the base of one are treated as either (8-bit
-transparent) ASCII or Unicode codepoints, depending on the shell's
+transparent) ASCII or Universal Coded Character Set codepoints,
+depending on the shell's
 .Ic utf8\-mode
 flag (current setting).
 The
@@ -2664,7 +2699,7 @@ instead of
 is also supported.
 Note that NUL bytes (integral value of zero) cannot be used.
 An unset or empty parameter evaluates to 0 in integer context.
-In Unicode mode, raw octets are mapped into the range EF80..EFFF as in
+In UTF-8 mode, raw octets are mapped into the range EF80..EFFF as in
 OPTU-8, which is in the PUA and has been assigned by CSUR for this use.
 If more than one octet in ASCII mode, or a sequence of more than one
 octet not forming a valid and minimal CESU-8 sequence is passed, the
@@ -2903,8 +2938,6 @@ option is turned on for the function's duration.
 The
 .Dq export
 attribute of functions is currently not used.
-In the original Korn shell,
-exported functions are visible to shell scripts that are executed.
 .Pp
 Since functions are executed in the current shell environment, parameter
 assignments made inside functions are visible after the function completes.
@@ -4667,15 +4700,15 @@ the user CPU time (time spent running in user mode), and the system CPU time
 (time spent running in kernel mode).
 Times are reported to standard error; the format of the output is:
 .Pp
-.Dl "0m0.00s real     0m0.00s user     0m0.00s system"
+.Dl "0m0.03s real     0m0.02s user     0m0.01s system"
 .Pp
 If the
 .Fl p
 option is given the output is slightly longer:
 .Bd -literal -offset indent
-real     0.00
-user     0.00
-sys      0.00
+real     0.03
+user     0.02
+sys      0.01
 .Ed
 .Pp
 It is an error to specify the
@@ -4700,8 +4733,8 @@ Print the accumulated user and system times used both by the shell
 and by processes that the shell started which have exited.
 The format of the output is:
 .Bd -literal -offset indent
-0m0.00s 0m0.00s
-0m0.00s 0m0.00s
+0m0.01s 0m0.00s
+0m0.04s 0m0.02s
 .Ed
 .Pp
 .It Ic trap Ar n Op Ar signal ...
@@ -4932,9 +4965,9 @@ when used with the
 .Fl i
 option which meant upper case letters would never be used for bases greater
 than 10.
-See the
+See
 .Fl U
-option.)
+above.)
 .Pp
 For functions,
 .Fl u
@@ -4944,9 +4977,9 @@ See
 above for the implications of this.
 .It Fl x
 Export attribute.
-Parameters (or functions) are placed in the environment of
-any executed commands.
-Exported functions are not yet implemented.
+Parameters are placed in the environment of any executed commands.
+Functions cannot be exported for security reasons
+.Pq Dq shellshock .
 .It Fl Z Ns Op Ar n
 Zero fill attribute.
 If not combined with
@@ -4954,7 +4987,7 @@ If not combined with
 this is the same as
 .Fl R ,
 except zero padding is used instead of space padding.
-For integers, the number instead of the base is padded.
+For integers, the number is padded, not the base.
 .El
 .Pp
 If any of the
@@ -5211,14 +5244,12 @@ or
 .Ic set Fl o Ic monitor ) ,
 as it is for interactive shells, the processes of a job are placed in their
 own process group.
-Foreground jobs can be stopped by typing the suspend
-character from the terminal (normally \*(haZ), jobs can be restarted in either the
-foreground or background using the
+Foreground jobs can be stopped by typing the suspend character from
+the terminal (normally \*(haZ); jobs can be restarted in either the
+foreground or background using the commands
 .Ic fg
 and
-.Ic bg
-commands, and the state of the terminal is saved or restored when a foreground
-job is stopped or restarted, respectively.
+.Ic bg .
 .Pp
 Note that only commands that create processes (e.g. asynchronous commands,
 subshell commands and non-built-in, non-function commands) can be stopped;
@@ -5332,6 +5363,17 @@ If another attempt
 is immediately made to exit the shell, the running jobs are sent a
 .Dv SIGHUP
 signal and the shell exits.
+.Ss Terminal state
+The state of the controlling terminal can be modified by a command
+executed in the foreground, whether or not job control is enabled, but
+the modified terminal state is only kept past the job's lifetime and used
+for later command invocations if the command exits successfully (i.e.\&
+with an exit status of 0).
+When such a job is momentarily stopped or restarted, the terminal state
+is saved and restored, respectively, but it will not be kept afterwards.
+In interactive mode, when line editing is enabled, the terminal state is
+saved before being reconfigured by the shell for the line editor, then
+restored before running a command.
 .Ss POSIX mode
 Entering
 .Ic set Fl o Ic posix
@@ -6650,7 +6692,7 @@ locale.
 .Ic utf8\-mode
 .Em must
 be disabled in POSIX mode, and it
-only supports the Unicode BMP (Basic Multilingual Plane) and maps
+only supports the BMP (Basic Multilingual Plane) of UCS and maps
 raw octets into the U+EF80..U+EFFF wide character range; compare
 .Sx Arithmetic expressions .
 The following
@@ -6671,7 +6713,24 @@ case ${KSH_VERSION:\-} in
        esac ;;
 esac
 .Ed
-In near future, (Unicode) locale tracking will be implemented though.
+In near future, (UTF-8) locale tracking will be implemented though.
+.Pp
+Using
+.Ic set Fl o Ic pipefail
+makes the following construct error out:
+.Bd -literal -offset indent
+set -e
+for x in 1 2; do
+       false && echo $x
+done \*(Ba cat
+.Ed
+This is because, while the
+.Dq Li &&\&
+ensures that the inner command's failure is not taken, it sets
+the entire for..done loop's errorlevel, which is passed on by
+.Fl o Ic pipefail .
+Invert the inner command:
+.Li true \*(Ba\*(Ba echo $x
 .Pp
 See also the FAQ below.
 .Sh BUGS
@@ -6697,7 +6756,7 @@ for the in-memory portion of the history is slow, should use
 .Xr memmove 3 .
 .Pp
 This document attempts to describe
-.Nm mksh\ R56
+.Nm mksh\ R57
 and up,
 .\" with vendor patches from insert-your-name-here,
 compiled without any options impacting functionality, such as
@@ -6713,10 +6772,11 @@ for an operating environment supporting all of its advanced needs.
 .Pp
 Please report bugs in
 .Nm
-to the
+to the public development mailing list at
 .Aq Mt miros\-mksh@mirbsd.org
-mailing list
-or in the
+(please note the EU-DSGVO/GDPR notice on
+.Pa http://www.mirbsd.org/rss.htm#lists
+and in the SMTP banner!) or in the
 .Li \&#\&!/bin/mksh
 .Pq or Li \&#ksh
 IRC channel at
@@ -6782,6 +6842,10 @@ Run the shell in POSIX mode (and possibly
 instead of
 .Nm mksh ) :
 .Dl set \-o posix
+.Ss "I forbid stat(2) in my SELinux policy, and some things do not work!"
+Don't break Unix.
+Read up on the GIGO principle.
+Duh.
 .Ss "My prompt from <some other shell> does not work!"
 Contact us on the mailing list or on IRC, we'll convert it for you.
 .Ss "Something is going wrong with my while...read loop"
index 53629b1..a974bbd 100644 (file)
--- a/src/sh.h
+++ b/src/sh.h
 #endif
 
 #ifdef EXTERN
-__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.858 2018/01/14 01:47:36 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.870 2019/03/01 16:18:14 tg Exp $");
 #endif
-#define MKSH_VERSION "R56 2018/01/14"
+#define MKSH_VERSION "R57 2019/03/01"
 
 /* arithmetic types: C implementation */
 #if !HAVE_CAN_INTTYPES
@@ -491,6 +491,10 @@ extern int __cdecl setegid(gid_t);
 #define O_BINARY       0
 #endif
 
+#ifndef O_MAYEXEC
+#define O_MAYEXEC      0
+#endif
+
 #ifdef MKSH__NO_SYMLINK
 #undef S_ISLNK
 #define S_ISLNK(m)     (/* CONSTCOND */ 0)
@@ -643,7 +647,7 @@ char *ucstrstr(char *, const char *);
 #endif
 #endif
 
-#if (!defined(MKSH_BUILDMAKEFILE4BSD) && !defined(MKSH_BUILDSH)) || (MKSH_BUILD_R != 563)
+#if (!defined(MKSH_BUILDMAKEFILE4BSD) && !defined(MKSH_BUILDSH)) || (MKSH_BUILD_R != 571)
 #error Must run Build.sh to compile this.
 extern void thiswillneverbedefinedIhope(void);
 int
@@ -783,7 +787,7 @@ enum sh_flag {
 };
 
 #define Flag(f)        (shell_flags[(int)(f)])
-#define UTFMODE        Flag(FUNICODE)
+#define UTFMODE        Flag(FUNNYCODE)
 
 /*
  * parsing & execution environment
@@ -1950,10 +1954,11 @@ struct ioword {
 #define IOSKIP         BIT(5)  /* <<-, skip ^\t* */
 #define IOCLOB         BIT(6)  /* >|, override -o noclobber */
 #define IORDUP         BIT(7)  /* x<&y (as opposed to x>&y) */
-#define IONAMEXP       BIT(8)  /* name has been expanded */
-#define IOBASH         BIT(9)  /* &> etc. */
-#define IOHERESTR      BIT(10) /* <<< (here string) */
-#define IONDELIM       BIT(11) /* null delimiter (<<) */
+#define IODUPSELF      BIT(8)  /* x>&x (as opposed to x>&y) */
+#define IONAMEXP       BIT(9)  /* name has been expanded */
+#define IOBASH         BIT(10) /* &> etc. */
+#define IOHERESTR      BIT(11) /* <<< (here string) */
+#define IONDELIM       BIT(12) /* null delimiter (<<) */
 
 /* execute/exchild flags */
 #define XEXEC  BIT(0)          /* execute without forking */
@@ -2637,7 +2642,7 @@ const char *wdscan(const char *, int);
 #define WDS_TPUTS      BIT(0)          /* tputS (dumpwdvar) mode */
 char *wdstrip(const char *, int);
 void tfree(struct op *, Area *);
-void dumpchar(struct shf *, int);
+void dumpchar(struct shf *, unsigned char);
 void dumptree(struct shf *, struct op *);
 void dumpwdvar(struct shf *, const char *);
 void dumpioact(struct shf *shf, struct op *t);
index 24b3359..af44328 100644 (file)
@@ -21,7 +21,7 @@
 
 #ifndef SHFLAGS_OPTCS
 #if defined(SHFLAGS_DEFNS)
-__RCSID("$MirOS: src/bin/mksh/sh_flags.opt,v 1.5 2017/02/18 02:33:15 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/sh_flags.opt,v 1.6 2018/08/10 02:53:39 tg Exp $");
 #elif defined(SHFLAGS_ENUMS)
 #define FN(sname,cname,flags,ochar)    cname,
 #define F0(sname,cname,flags,ochar)    cname = 0,
@@ -77,7 +77,7 @@ FN("sh", FSH, OF_ANY, 0)
 FN("stdin", FSTDIN, OF_CMDLINE, 's')
 #endif
 FN("trackall", FTRACKALL, OF_ANY, 'h')
-FN("utf8-mode", FUNICODE, OF_ANY, 'U')
+FN("utf8-mode", FUNNYCODE, OF_ANY, 'U')
 FN("verbose", FVERBOSE, OF_ANY, 'v')
 #ifndef MKSH_NO_CMDLINE_EDITING
 FN("vi", FVI, OF_ANY, 0)
index 795d198..c2f554e 100644 (file)
@@ -19,7 +19,7 @@
  */
 
 @SHFLAGS_DEFNS
-__RCSID("$MirOS: src/bin/mksh/sh_flags.opt,v 1.5 2017/02/18 02:33:15 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/sh_flags.opt,v 1.6 2018/08/10 02:53:39 tg Exp $");
 @SHFLAGS_ENUMS
 #define FN(sname,cname,flags,ochar)    cname,
 #define F0(sname,cname,flags,ochar)    cname = 0,
@@ -153,7 +153,7 @@ FN("trackall", FTRACKALL, OF_ANY
 
 /* -U  enable UTF-8 processing (non-standard) */
 >U|
-FN("utf8-mode", FUNICODE, OF_ANY
+FN("utf8-mode", FUNNYCODE, OF_ANY
 
 /* -v  echo input */
 >v|
index 2ee0ec1..a37f4da 100644 (file)
--- a/src/shf.c
+++ b/src/shf.c
@@ -27,7 +27,7 @@
 
 #include "sh.h"
 
-__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.97 2018/01/14 01:28:16 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.98 2018/08/10 02:53:39 tg Exp $");
 
 /* flags to shf_emptybuf() */
 #define EB_READSW      0x01    /* about to switch to reading */
@@ -1304,7 +1304,7 @@ ebcdic_init(void)
                 * and the C1 control characters other than NEL are
                 * hopeless, but we map EBCDIC NEL to ASCII LF so we
                 * cannot even use C1 NEL.
-                * If ever we map to Unicode, bump the table width to
+                * If ever we map to UCS, bump the table width to
                 * an unsigned int, and or the raw unconverted EBCDIC
                 * values with 0x01000000 instead.
                 */
index 5e7326b..335e3fb 100644 (file)
@@ -23,7 +23,7 @@
 
 #include "sh.h"
 
-__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.95 2018/01/14 00:03:05 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.97 2018/10/20 18:46:00 tg Exp $");
 
 #define INDENT 8
 
@@ -808,7 +808,7 @@ vistree(char *dst, size_t sz, struct op *t)
                c = ksh_unctrl(c);
        } else if (UTFMODE && rtt2asc(c) > 0x7F) {
                /* better not try to display broken multibyte chars */
-               /* also go easy on the Unicode: no U+FFFD here */
+               /* also go easy on the UCS: no U+FFFD here */
                c = ORD('?');
        }
        *dst++ = c;
@@ -821,7 +821,7 @@ vistree(char *dst, size_t sz, struct op *t)
 
 #ifdef DEBUG
 void
-dumpchar(struct shf *shf, int c)
+dumpchar(struct shf *shf, unsigned char c)
 {
        if (ksh_isctrl(c)) {
                /* C0 or C1 control character or DEL */
index 5219507..1263547 100644 (file)
--- a/src/var.c
+++ b/src/var.c
@@ -28,7 +28,7 @@
 #include <sys/sysctl.h>
 #endif
 
-__RCSID("$MirOS: src/bin/mksh/var.c,v 1.223 2018/01/13 23:55:15 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/var.c,v 1.226 2018/07/15 17:21:24 tg Exp $");
 
 /*-
  * Variables
@@ -54,7 +54,7 @@ static int special(const char *);
 static void unspecial(const char *);
 static void getspec(struct tbl *);
 static void setspec(struct tbl *);
-static void unsetspec(struct tbl *);
+static void unsetspec(struct tbl *, bool);
 static int getint(struct tbl *, mksh_ari_u *, bool);
 static const char *array_index_calc(const char *, bool *, uint32_t *);
 
@@ -105,7 +105,7 @@ popblock(void)
                        if ((vq = global(vp->name))->flag & ISSET)
                                setspec(vq);
                        else
-                               unsetspec(vq);
+                               unsetspec(vq, false);
                }
        if (l->flags & BF_DOGETOPTS)
                user_opt = l->getopts_state;
@@ -707,7 +707,7 @@ formatstr(struct tbl *vp, const char *s)
                        if (vp->flag & ZEROFIL)
                                while (*s == '0')
                                        s++;
-                       shf_snprintf(p, nlen + 1, "%-*.*s",
+                       shf_snprintf(p, psiz, "%-*.*s",
                                vp->u2.field, vp->u2.field, s);
                }
        } else
@@ -1054,7 +1054,7 @@ unset(struct tbl *vp, int flags)
        vp->flag &= SPECIAL | ((flags & 1) ? 0 : ARRAY|DEFINED);
        if (vp->flag & SPECIAL)
                /* responsible for 'unspecial'ing var */
-               unsetspec(vp);
+               unsetspec(vp, true);
 }
 
 /*
@@ -1441,7 +1441,7 @@ setspec(struct tbl *vp)
 }
 
 static void
-unsetspec(struct tbl *vp)
+unsetspec(struct tbl *vp, bool dounset)
 {
        /*
         * AT&T ksh man page says OPTIND, OPTARG and _ lose special
@@ -1466,13 +1466,13 @@ unsetspec(struct tbl *vp)
 #endif
        case V_IFS:
                set_ifs(TC_IFSWS);
-               break;
+               return;
        case V_PATH:
                afree(path, APERM);
                strdupx(path, def_path, APERM);
                /* clear tracked aliases */
                flushcom(true);
-               break;
+               return;
 #ifndef MKSH_NO_CMDLINE_EDITING
        case V_TERM:
                x_initterm(null);
@@ -1484,14 +1484,14 @@ unsetspec(struct tbl *vp)
                        afree(tmpdir, APERM);
                        tmpdir = NULL;
                }
-               break;
+               return;
        case V_LINENO:
        case V_RANDOM:
        case V_SECONDS:
        case V_TMOUT:
                /* AT&T ksh leaves previous value in place */
                unspecial(vp->name);
-               break;
+               return;
 #ifdef MKSH_EARLY_LOCALE_TRACKING
        case V_LANG:
        case V_LC_ALL:
@@ -1499,6 +1499,12 @@ unsetspec(struct tbl *vp)
                recheck_ctype();
                return;
 #endif
+       /* should not become unspecial, but allow unsetting */
+       case V_COLUMNS:
+       case V_LINES:
+               if (dounset)
+                       unspecial(vp->name);
+               return;
        }
 }
 
@@ -1617,6 +1623,9 @@ set_array(const char *var, bool reset, const char **vals)
                unset(vp, 1);
                /* allocate-by-access the [0] element to keep in scope */
                arraysearch(vp, 0);
+               /* honour set -o allexport */
+               if (Flag(FEXPORT))
+                       typeset(ccp, EXPORT, 0, 0, 0);
        }
        /*
         * TODO: would be nice for assignment to completely succeed or