OSDN Git Service

Upgrade to mksh 50.
authorElliott Hughes <enh@google.com>
Thu, 7 Aug 2014 19:59:26 +0000 (12:59 -0700)
committerElliott Hughes <enh@google.com>
Mon, 6 Oct 2014 20:44:21 +0000 (13:44 -0700)
Bug: 16569301
Bug: 17814343

(cherry picked from commit 737fdce098f804459a925438e48dd711c31bbc9e)

Change-Id: I7e8a142bec5f553f9e1a2568245582fe8fa14314

31 files changed:
Android.mk
Makefrag.inc [new file with mode: 0644]
mkmf.sh
src/Build.sh
src/check.pl
src/check.t
src/dot.mkshrc
src/edit.c
src/eval.c
src/exec.c
src/expr.c
src/funcs.c
src/histrap.c
src/jobs.c
src/lex.c
src/main.c
src/mirhash.h [new file with mode: 0644]
src/misc.c
src/mksh.1
src/rlimits.gen [new file with mode: 0644]
src/rlimits.opt [new file with mode: 0644]
src/sh.h
src/sh_flags.gen [new file with mode: 0644]
src/sh_flags.h [deleted file]
src/sh_flags.opt [new file with mode: 0644]
src/shf.c
src/signames.inc [new file with mode: 0644]
src/strlcpy.c
src/syn.c
src/tree.c
src/var.c

index 9989f67..8f910a1 100644 (file)
@@ -20,7 +20,8 @@ include $(BUILD_PREBUILT)
 
 include $(CLEAR_VARS)
 
-LOCAL_MODULE:=         sh
+LOCAL_MODULE := sh
+LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
 
 # mksh source files
 LOCAL_SRC_FILES:=      src/lalloc.c src/edit.c src/eval.c src/exec.c \
@@ -41,7 +42,9 @@ LOCAL_CFLAGS:=                -DMKSHRC_PATH=\"/system/etc/mkshrc\" \
                -DMKSH_DONT_EMIT_IDSTRING -DMKSH_NOPWNAM -DMKSH_BUILDSH \
                -D_GNU_SOURCE -DSETUID_CAN_FAIL_WITH_EAGAIN \
                -DHAVE_ATTRIBUTE_BOUNDED=0 -DHAVE_ATTRIBUTE_FORMAT=1 \
-               -DHAVE_ATTRIBUTE_NORETURN=1 -DHAVE_ATTRIBUTE_UNUSED=1 \
+               -DHAVE_ATTRIBUTE_NORETURN=1 \
+               -DHAVE_ATTRIBUTE_PURE=1 \
+               -DHAVE_ATTRIBUTE_UNUSED=1 \
                -DHAVE_ATTRIBUTE_USED=1 -DHAVE_SYS_TIME_H=1 -DHAVE_TIME_H=1 \
                -DHAVE_BOTH_TIME_H=1 -DHAVE_SYS_BSDTYPES_H=0 \
                -DHAVE_SYS_FILE_H=1 -DHAVE_SYS_MKDEV_H=0 -DHAVE_SYS_MMAN_H=1 \
@@ -54,14 +57,16 @@ LOCAL_CFLAGS:=              -DMKSHRC_PATH=\"/system/etc/mkshrc\" \
                -DHAVE_CAN_INT8TYPE=1 -DHAVE_CAN_UCBINT8=1 -DHAVE_RLIM_T=1 \
                -DHAVE_SIG_T=1 -DHAVE_SYS_ERRLIST=0 -DHAVE_SYS_SIGNAME=1 \
                -DHAVE_SYS_SIGLIST=1 -DHAVE_FLOCK=1 -DHAVE_LOCK_FCNTL=1 \
-               -DHAVE_GETRUSAGE=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_KILLPG=1 \
+               -DHAVE_GETRUSAGE=1 \
+               -DHAVE_GETSID=1 \
+               -DHAVE_GETTIMEOFDAY=1 -DHAVE_KILLPG=1 \
                -DHAVE_MEMMOVE=1 -DHAVE_MKNOD=0 -DHAVE_MMAP=1 -DHAVE_NICE=1 \
                -DHAVE_REVOKE=0 -DHAVE_SETLOCALE_CTYPE=0 \
                -DHAVE_LANGINFO_CODESET=0 -DHAVE_SELECT=1 -DHAVE_SETRESUGID=1 \
                -DHAVE_SETGROUPS=1 -DHAVE_STRERROR=1 -DHAVE_STRSIGNAL=0 \
                -DHAVE_STRLCPY=1 -DHAVE_FLOCK_DECL=1 -DHAVE_REVOKE_DECL=1 \
                -DHAVE_SYS_ERRLIST_DECL=0 -DHAVE_SYS_SIGLIST_DECL=1 \
-               -DHAVE_PERSISTENT_HISTORY=0 -DMKSH_BUILD_R=481
+               -DHAVE_PERSISTENT_HISTORY=0 -DMKSH_BUILD_R=501
 
 # check_categories= shell:legacy-no int:32 android convfds no-histfile
 
diff --git a/Makefrag.inc b/Makefrag.inc
new file mode 100644 (file)
index 0000000..403281f
--- /dev/null
@@ -0,0 +1,40 @@
+# Makefile fragment for building mksh R50 2014/06/29
+
+PROG=          mksh
+MAN=           mksh.1
+SRCS=          lalloc.c eval.c exec.c expr.c funcs.c histrap.c jobs.c lex.c main.c misc.c shf.c syn.c tree.c var.c edit.c
+SRCS_FP=       ../src/lalloc.c ../src/eval.c ../src/exec.c ../src/expr.c ../src/funcs.c ../src/histrap.c ../src/jobs.c ../src/lex.c ../src/main.c ../src/misc.c ../src/shf.c ../src/syn.c ../src/tree.c ../src/var.c ../src/edit.c
+OBJS_BP=        lalloc.o eval.o exec.o expr.o funcs.o histrap.o jobs.o lex.o main.o misc.o shf.o syn.o tree.o var.o edit.o
+INDSRCS=       emacsfn.h rlimits.opt sh.h sh_flags.opt var_spec.h
+NONSRCS_INST=  dot.mkshrc $(MAN)
+NONSRCS_NOINST=        Build.sh Makefile Rebuild.sh check.pl check.t test.sh
+CC=            /huge-ssd/lmp-dev/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-gcc
+CFLAGS=                 -fno-exceptions -Wno-multichar -msoft-float -fpic -fPIE -ffunction-sections -fdata-sections -funwind-tables -fstack-protector -Wa,--noexecstack -Werror=format-security -fno-short-enums -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -Wno-unused-but-set-variable -fno-builtin-sin -fno-strict-volatile-bitfields -Wno-psabi -mthumb-interwork -fmessage-length=0 -W -Wall -Wno-unused -Winit-self -Wpointer-arith -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -g -Wstrict-aliasing=2 -fgcse-after-reload -frerun-cse-after-loop -frename-registers -mthumb -Os -fomit-frame-pointer -fno-strict-aliasing -Wno-deprecated-declarations -fno-asynchronous-unwind-tables -fwrapv
+CPPFLAGS=      -I. -I'../src'  -I/huge-ssd/lmp-dev/libnativehelper/include/nativehelper -isystem /huge-ssd/lmp-dev/system/core/include -isystem /huge-ssd/lmp-dev/hardware/libhardware/include -isystem /huge-ssd/lmp-dev/hardware/libhardware_legacy/include -isystem /huge-ssd/lmp-dev/hardware/ril/include -isystem /huge-ssd/lmp-dev/libnativehelper/include -isystem /huge-ssd/lmp-dev/frameworks/native/include -isystem /huge-ssd/lmp-dev/frameworks/native/opengl/include -isystem /huge-ssd/lmp-dev/frameworks/av/include -isystem /huge-ssd/lmp-dev/frameworks/base/include -isystem /huge-ssd/lmp-dev/external/skia/include -isystem /huge-ssd/lmp-dev/out/target/product/hammerhead/obj/include -isystem /huge-ssd/lmp-dev/bionic/libc/arch-arm/include -isystem /huge-ssd/lmp-dev/bionic/libc/include -isystem /huge-ssd/lmp-dev/bionic/libstdc++/include -isystem /huge-ssd/lmp-dev/bionic/libc/kernel/uapi -isystem /huge-ssd/lmp-dev/bionic/libc/kernel/uapi/asm-arm -isystem /huge-ssd/lmp-dev/bionic/libm/include -isystem /huge-ssd/lmp-dev/bionic/libm/include/arm -isystem /huge-ssd/lmp-dev/bionic/libthread_db/include -D_FORTIFY_SOURCE=2 -include /huge-ssd/lmp-dev/build/core/combo/include/arch/linux-arm/AndroidConfig.h -I/huge-ssd/lmp-dev/build/core/combo/include/arch/linux-arm/ -DANDROID -DNDEBUG -UDEBUG -DDEBUG_LEAKS -DMKSH_ASSUME_UTF8 -DMKSH_CONSERVATIVE_FDS -DMKSH_DONT_EMIT_IDSTRING -DMKSH_NOPWNAM -DMKSH_BUILDSH -D_GNU_SOURCE -DSETUID_CAN_FAIL_WITH_EAGAIN -DHAVE_ATTRIBUTE_BOUNDED=0 -DHAVE_ATTRIBUTE_FORMAT=1 -DHAVE_ATTRIBUTE_NORETURN=1 -DHAVE_ATTRIBUTE_PURE=1 -DHAVE_ATTRIBUTE_UNUSED=1 -DHAVE_ATTRIBUTE_USED=1 -DHAVE_SYS_TIME_H=1 -DHAVE_TIME_H=1 -DHAVE_BOTH_TIME_H=1 -DHAVE_SYS_BSDTYPES_H=0 -DHAVE_SYS_FILE_H=1 -DHAVE_SYS_MKDEV_H=0 -DHAVE_SYS_MMAN_H=1 -DHAVE_SYS_PARAM_H=1 -DHAVE_SYS_RESOURCE_H=1 -DHAVE_SYS_SELECT_H=1 -DHAVE_SYS_SYSMACROS_H=1 -DHAVE_BSTRING_H=0 -DHAVE_GRP_H=1 -DHAVE_LIBGEN_H=1 -DHAVE_LIBUTIL_H=0 -DHAVE_PATHS_H=1 -DHAVE_STDINT_H=1 -DHAVE_STRINGS_H=1 -DHAVE_TERMIOS_H=1 -DHAVE_ULIMIT_H=0 -DHAVE_VALUES_H=0 -DHAVE_CAN_INTTYPES=1 -DHAVE_CAN_UCBINTS=1 -DHAVE_CAN_INT8TYPE=1 -DHAVE_CAN_UCBINT8=1 -DHAVE_RLIM_T=1 -DHAVE_SIG_T=1 -DHAVE_SYS_ERRLIST=0 -DHAVE_SYS_SIGNAME=1 -DHAVE_SYS_SIGLIST=1 -DHAVE_FLOCK=1 -DHAVE_LOCK_FCNTL=1 -DHAVE_GETRUSAGE=1 -DHAVE_GETSID=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_KILLPG=1 -DHAVE_MEMMOVE=1 -DHAVE_MKNOD=0 -DHAVE_MMAP=1 -DHAVE_NICE=1 -DHAVE_REVOKE=0 -DHAVE_SETLOCALE_CTYPE=0 -DHAVE_LANGINFO_CODESET=0 -DHAVE_SELECT=1 -DHAVE_SETRESUGID=1 -DHAVE_SETGROUPS=1 -DHAVE_STRERROR=1 -DHAVE_STRSIGNAL=0 -DHAVE_STRLCPY=1 -DHAVE_FLOCK_DECL=1 -DHAVE_REVOKE_DECL=1 -DHAVE_SYS_ERRLIST_DECL=0 -DHAVE_SYS_SIGLIST_DECL=1 -DHAVE_PERSISTENT_HISTORY=0 -DMKSH_BUILD_R=501
+LDFLAGS=        -nostdlib -Bdynamic -fPIE -pie -Wl,-dynamic-linker,/system/bin/linker -Wl,--gc-sections -Wl,-z,nocopyreloc -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--warn-shared-textrel -Wl,--fatal-warnings -Wl,--icf=safe -Wl,--fix-cortex-a8 -Wl,--no-undefined /huge-ssd/lmp-dev/out/target/product/hammerhead/obj/lib/crtbegin_dynamic.o
+LIBS=           -L/huge-ssd/lmp-dev/out/target/product/hammerhead/obj/lib -Wl,-rpath-link=/huge-ssd/lmp-dev/out/target/product/hammerhead/obj/lib -Wl,--no-whole-archive /huge-ssd/lmp-dev/out/target/product/hammerhead/obj/STATIC_LIBRARIES/libcompiler_rt-extras_intermediates/libcompiler_rt-extras.a -lc /huge-ssd/lmp-dev/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8/bin/../lib/gcc/arm-linux-androideabi/4.8/armv7-a/libgcc.a /huge-ssd/lmp-dev/out/target/product/hammerhead/obj/lib/crtend_android.o
+
+.depend $(OBJS_BP): rlimits.gen sh_flags.gen
+rlimits.gen: ../src/Build.sh ../src/rlimits.opt
+                       srcfile=../src/rlimits.opt; BUILDSH_RUN_GENOPT=1; . ../src/Build.sh
+sh_flags.gen: ../src/Build.sh ../src/sh_flags.opt
+                       srcfile=../src/sh_flags.opt; BUILDSH_RUN_GENOPT=1; . ../src/Build.sh
+
+# not BSD make only:
+#VPATH=                ../src
+#all: $(PROG)
+#$(PROG): $(OBJS_BP)
+#      $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS_BP) $(LIBS)
+#$(OBJS_BP): $(SRCS_FP) $(NONSRCS)
+#.c.o:
+#      $(CC) $(CFLAGS) $(CPPFLAGS) -c $<
+
+# for all make variants:
+#REGRESS_FLAGS=        -f
+#regress:
+#      ./test.sh $(REGRESS_FLAGS)
+check_categories= shell:legacy-no int:32 android convfds no-histfile
+
+# for BSD make only:
+#.PATH: ../src
+#.include <bsd.prog.mk>
diff --git a/mkmf.sh b/mkmf.sh
index f819e0d..193dae2 100644 (file)
--- a/mkmf.sh
+++ b/mkmf.sh
@@ -49,10 +49,10 @@ LIBS=
 # possible to the values used later. (You also must example the
 # results gathered from Makefrag.inc to see they are the same
 # across all Android platforms, or add appropriate ifdefs.)
-# Since we no longer use the NDK, the AOSP has to have been
-# built before using this script (targetting generic/emulator).
+# Since we no longer use the NDK, AOSP has to have been
+# built before using this script.
 
-CC=$aospdir/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7/bin/arm-linux-androideabi-gcc
+CC=$aospdir/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-gcc
 addvar CPPFLAGS \
     -I$aospdir/libnativehelper/include/nativehelper \
     -isystem $aospdir/system/core/include \
@@ -65,7 +65,7 @@ addvar CPPFLAGS \
     -isystem $aospdir/frameworks/av/include \
     -isystem $aospdir/frameworks/base/include \
     -isystem $aospdir/external/skia/include \
-    -isystem $aospdir/out/target/product/generic/obj/include \
+    -isystem $ANDROID_PRODUCT_OUT/obj/include \
     -isystem $aospdir/bionic/libc/arch-arm/include \
     -isystem $aospdir/bionic/libc/include \
     -isystem $aospdir/bionic/libstdc++/include \
@@ -134,15 +134,15 @@ addvar LDFLAGS \
     -Wl,--icf=safe \
     -Wl,--fix-cortex-a8 \
     -Wl,--no-undefined \
-    $aospdir/out/target/product/generic/obj/lib/crtbegin_dynamic.o
+    $ANDROID_PRODUCT_OUT/obj/lib/crtbegin_dynamic.o
 addvar LIBS \
-    -L$aospdir/out/target/product/generic/obj/lib \
-    -Wl,-rpath-link=$aospdir/out/target/product/generic/obj/lib \
+    -L$ANDROID_PRODUCT_OUT/obj/lib \
+    -Wl,-rpath-link=$ANDROID_PRODUCT_OUT/obj/lib \
     -Wl,--no-whole-archive \
-    $aospdir/out/target/product/generic/obj/STATIC_LIBRARIES/libcompiler_rt-extras_intermediates/libcompiler_rt-extras.a \
+    $ANDROID_PRODUCT_OUT/obj/STATIC_LIBRARIES/libcompiler_rt-extras_intermediates/libcompiler_rt-extras.a \
     -lc \
-    $aospdir/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7/bin/../lib/gcc/arm-linux-androideabi/4.7/armv7-a/libgcc.a \
-    $aospdir/out/target/product/generic/obj/lib/crtend_android.o
+    $aospdir/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8/bin/../lib/gcc/arm-linux-androideabi/4.8/armv7-a/libgcc.a \
+    $ANDROID_PRODUCT_OUT/obj/lib/crtend_android.o
 
 
 ### Flags used by test builds
index 45af9dd..8ef6cb6 100644 (file)
@@ -1,8 +1,8 @@
 #!/bin/sh
-srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.645 2013/08/10 13:44:25 tg Exp $'
+srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.662 2014/06/29 10:56:08 tg Exp $'
 #-
 # Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
-#              2011, 2012, 2013
+#              2011, 2012, 2013, 2014
 #      Thorsten Glaser <tg@mirbsd.org>
 #
 # Provided that these terms and disclaimer and all copyright notices
@@ -28,9 +28,6 @@ srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.645 2013/08/10 13:44:25 tg Exp $'
 LC_ALL=C
 export LC_ALL
 
-echo "For the build logs, demonstrate that /dev/null and /dev/tty exist:"
-ls -l /dev/null /dev/tty
-
 case $ZSH_VERSION:$VERSION in
 :zsh*) ZSH_VERSION=2 ;;
 esac
@@ -46,6 +43,162 @@ if test -d /usr/xpg4/bin/. >/dev/null 2>&1; then
        export PATH
 fi
 
+nl='
+'
+safeIFS='      '
+safeIFS=" $safeIFS$nl"
+IFS=$safeIFS
+allu=QWERTYUIOPASDFGHJKLZXCVBNM
+alll=qwertyuiopasdfghjklzxcvbnm
+alln=0123456789
+alls=______________________________________________________________
+
+genopt_die() {
+       if test -n "$1"; then
+               echo >&2 "E: $*"
+               echo >&2 "E: in '$srcfile': '$line'"
+       else
+               echo >&2 "E: invalid input in '$srcfile': '$line'"
+       fi
+       rm -f "$bn.gen"
+       exit 1
+}
+
+genopt_soptc() {
+       optc=`echo "$line" | sed 's/^[<>]\(.\).*$/\1/'`
+       test x"$optc" = x'|' && return
+       optclo=`echo "$optc" | tr $allu $alll`
+       if test x"$optc" = x"$optclo"; then
+               islo=1
+       else
+               islo=0
+       fi
+       sym=`echo "$line" | sed 's/^[<>]/|/'`
+       o_str=$o_str$nl"<$optclo$islo$sym"
+}
+
+genopt_scond() {
+       case x$cond in
+       x)
+               cond=
+               ;;
+       x*' '*)
+               cond=`echo "$cond" | sed 's/^ //'`
+               cond="#if $cond"
+               ;;
+       x'!'*)
+               cond=`echo "$cond" | sed 's/^!//'`
+               cond="#ifndef $cond"
+               ;;
+       x*)
+               cond="#ifdef $cond"
+               ;;
+       esac
+}
+
+do_genopt() {
+       srcfile=$1
+       test -f "$srcfile" || genopt_die Source file \$srcfile not set.
+       bn=`basename "$srcfile" | sed 's/.opt$//'`
+       o_gen=
+       o_str=
+       o_sym=
+       ddefs=
+       state=0
+       exec <"$srcfile"
+       IFS=
+       while IFS= read line; do
+               IFS=$safeIFS
+               case $state:$line in
+               2:'|'*)
+                       # end of input
+                       o_sym=`echo "$line" | sed 's/^.//'`
+                       o_gen=$o_gen$nl"#undef F0"
+                       o_gen=$o_gen$nl"#undef FN"
+                       o_gen=$o_gen$ddefs
+                       state=3
+                       ;;
+               1:@@)
+                       # begin of data block
+                       o_gen=$o_gen$nl"#endif"
+                       o_gen=$o_gen$nl"#ifndef F0"
+                       o_gen=$o_gen$nl"#define F0 FN"
+                       o_gen=$o_gen$nl"#endif"
+                       state=2
+                       ;;
+               *:@@*)
+                       genopt_die ;;
+               0:@*|1:@*)
+                       # begin of a definition block
+                       sym=`echo "$line" | sed 's/^@//'`
+                       if test $state = 0; then
+                               o_gen=$o_gen$nl"#if defined($sym)"
+                       else
+                               o_gen=$o_gen$nl"#elif defined($sym)"
+                       fi
+                       ddefs="$ddefs$nl#undef $sym"
+                       state=1
+                       ;;
+               0:*|3:*)
+                       genopt_die ;;
+               1:*)
+                       # definition line
+                       o_gen=$o_gen$nl$line
+                       ;;
+               2:'<'*'|'*)
+                       genopt_soptc
+                       ;;
+               2:'>'*'|'*)
+                       genopt_soptc
+                       cond=`echo "$line" | sed 's/^[^|]*|//'`
+                       genopt_scond
+                       case $optc in
+                       '|') optc=0 ;;
+                       *) optc=\'$optc\' ;;
+                       esac
+                       IFS= read line || genopt_die Unexpected EOF
+                       IFS=$safeIFS
+                       test -n "$cond" && o_gen=$o_gen$nl"$cond"
+                       o_gen=$o_gen$nl"$line, $optc)"
+                       test -n "$cond" && o_gen=$o_gen$nl"#endif"
+                       ;;
+               esac
+       done
+       case $state:$o_sym in
+       3:) genopt_die Expected optc sym at EOF ;;
+       3:*) ;;
+       *) genopt_die Missing EOF marker ;;
+       esac
+       echo "$o_str" | sort | while IFS='|' read x opts cond; do
+               IFS=$safeIFS
+               test -n "$x" || continue
+               genopt_scond
+               test -n "$cond" && echo "$cond"
+               echo "\"$opts\""
+               test -n "$cond" && echo "#endif"
+       done | {
+               echo "#ifndef $o_sym$o_gen"
+               echo "#else"
+               cat
+               echo "#undef $o_sym"
+               echo "#endif"
+       } >"$bn.gen"
+       IFS=$safeIFS
+       return 0
+}
+
+if test x"$BUILDSH_RUN_GENOPT" = x"1"; then
+       set x -G "$srcfile"
+       shift
+fi
+if test x"$1" = x"-G"; then
+       do_genopt "$2"
+       exit $?
+fi
+
+echo "For the build logs, demonstrate that /dev/null and /dev/tty exist:"
+ls -l /dev/null /dev/tty
+
 v() {
        $e "$*"
        eval "$@"
@@ -66,18 +219,12 @@ vq() {
 rmf() {
        for _f in "$@"; do
                case $_f in
-               Build.sh|check.pl|check.t|dot.mkshrc|*.c|*.h|*.ico|*.1) ;;
+               Build.sh|check.pl|check.t|dot.mkshrc|*.1|*.c|*.h|*.ico|*.opt) ;;
                *) rm -f "$_f" ;;
                esac
        done
 }
 
-allu=QWERTYUIOPASDFGHJKLZXCVBNM
-alll=qwertyuiopasdfghjklzxcvbnm
-alln=0123456789
-alls=______________________________________________________________
-nl='
-'
 tcfn=no
 bi=
 ui=
@@ -193,8 +340,9 @@ ac_testn() {
 ac_ifcpp() {
        expr=$1; shift
        ac_testn "$@" <<-EOF
+               #include <unistd.h>
                extern int thiswillneverbedefinedIhope(void);
-               int main(void) { return (
+               int main(void) { return (isatty(0) +
                #$expr
                    0
                #else
@@ -251,7 +399,8 @@ ac_flags() {
        else
                ac_testn can_$vn '' "$ft" <<-'EOF'
                        /* evil apo'stroph in comment test */
-                       int main(void) { return (0); }
+                       #include <unistd.h>
+                       int main(void) { return (isatty(0)); }
                EOF
        fi
        eval fv=\$HAVE_CAN_`upper $vn`
@@ -291,19 +440,14 @@ ac_header() {
                esac
        done
        echo "#include <$hf>" >>x
-       echo 'int main(void) { return (0); }' >>x
+       echo '#include <unistd.h>' >>x
+       echo 'int main(void) { return (isatty(0)); }' >>x
        ac_testn "$hv" "" "<$hf>" <x
        rmf x
        test 1 = $na || ac_cppflags
 }
 
 addsrcs() {
-       addsrcs_s=0
-       if test x"$1" = x"-s"; then
-               # optstatic
-               addsrcs_s=1
-               shift
-       fi
        if test x"$1" = x"!"; then
                fr=0
                shift
@@ -311,13 +455,6 @@ addsrcs() {
                fr=1
        fi
        eval i=\$$1
-       if test $addsrcs_s = 1; then
-               if test -f "$2" || test -f "$srcdir/$2"; then
-                       # always add $2, since it exists
-                       fr=1
-                       i=1
-               fi
-       fi
        test $fr = "$i" && case " $SRCS " in
        *\ $2\ *)       ;;
        *)              SRCS="$SRCS $2" ;;
@@ -325,9 +462,21 @@ addsrcs() {
 }
 
 
-curdir=`pwd` srcdir=`dirname "$0" 2>/dev/null` check_categories=
-test -n "$srcdir" || srcdir=. # in case dirname does not exist
-dstversion=`sed -n '/define MKSH_VERSION/s/^.*"\([^"]*\)".*$/\1/p' $srcdir/sh.h`
+curdir=`pwd` srcdir=`dirname "$0" 2>/dev/null`
+case x$srcdir in
+x)
+       srcdir=.
+       ;;
+*\ *|*"        "*|*"$nl"*)
+       echo >&2 Source directory should not contain space or tab or newline.
+       echo >&2 Errors may occur.
+       ;;
+*"'"*)
+       echo Source directory must not contain single quotes.
+       exit 1
+       ;;
+esac
+dstversion=`sed -n '/define MKSH_VERSION/s/^.*"\([^"]*\)".*$/\1/p' "$srcdir/sh.h"`
 add_cppflags -DMKSH_BUILDSH
 
 e=echo
@@ -336,6 +485,7 @@ eq=0
 pm=0
 cm=normal
 optflags=-std-compile-opts
+check_categories=
 last=
 tfn=
 legacy=0
@@ -362,6 +512,10 @@ do
        :-c)
                last=c
                ;;
+       :-G)
+               echo "$me: Do not call me with '-G'!" >&2
+               exit 1
+               ;;
        :-g)
                # checker, debug, valgrind build
                add_cppflags -DDEBUG
@@ -423,7 +577,7 @@ if test -d $tfn || test -d $tfn.exe; then
        echo "$me: Error: ./$tfn is a directory!" >&2
        exit 1
 fi
-rmf a.exe* a.out* conftest.c *core core.* lft ${tfn}* no *.bc *.ll *.o \
+rmf a.exe* a.out* conftest.c *core core.* lft ${tfn}* no *.bc *.ll *.o *.gen \
     Rebuild.sh signames.inc test.sh x vv.out
 
 SRCS="lalloc.c eval.c exec.c expr.c funcs.c histrap.c jobs.c"
@@ -462,7 +616,7 @@ oswarn=
 ccpc=-Wc,
 ccpl=-Wl,
 tsts=
-ccpr='|| for _f in ${tcfn}*; do case $_f in Build.sh|check.pl|check.t|dot.mkshrc|*.c|*.h|*.ico|*.1) ;; *) rm -f "$_f" ;; esac; done'
+ccpr='|| for _f in ${tcfn}*; do case $_f in Build.sh|check.pl|check.t|dot.mkshrc|*.1|*.c|*.h|*.ico|*.opt) ;; *) rm -f "$_f" ;; esac; done'
 
 # Evil hack
 if test x"$TARGET_OS" = x"Android"; then
@@ -786,7 +940,12 @@ AIX)
        ;;
 Darwin)
        vv '|' "hwprefs machine_type os_type os_class >&2"
+       vv '|' "sw_vers >&2"
+       vv '|' "system_profiler 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"
        ;;
 IRIX*)
        vv '|' "uname -a >&2"
@@ -905,7 +1064,10 @@ vv ']' "$CPP $CFLAGS $CPPFLAGS $NOWARN conftest.c | \
 sed 's/^/[ /' x
 eval `cat x`
 rmf x vv.out
-echo 'int main(void) { return (0); }' >conftest.c
+cat >conftest.c <<'EOF'
+#include <unistd.h>
+int main(void) { return (isatty(0)); }
+EOF
 case $ct in
 ack)
        # work around "the famous ACK const bug"
@@ -1091,13 +1253,15 @@ if ac_ifcpp 'if 0' compiler_fails '' \
        dec)
                CFLAGS="$CFLAGS ${ccpl}-non_shared"
                ac_testn can_delexe compiler_fails 0 'for the -non_shared linker option' <<-EOF
-                       int main(void) { return (0); }
+                       #include <unistd.h>
+                       int main(void) { return (isatty(0)); }
                EOF
                ;;
        dmc)
                CFLAGS="$CFLAGS ${ccpl}/DELEXECUTABLE"
                ac_testn can_delexe compiler_fails 0 'for the /DELEXECUTABLE linker option' <<-EOF
-                       int main(void) { return (0); }
+                       #include <unistd.h>
+                       int main(void) { return (isatty(0)); }
                EOF
                ;;
        *)
@@ -1193,7 +1357,8 @@ kencc|tcc|tendra)
        ;;
 sunpro)
        cat >x <<-'EOF'
-               int main(void) { return (0); }
+               #include <unistd.h>
+               int main(void) { return (isatty(0)); }
                #define __IDSTRING_CONCAT(l,p)  __LINTED__ ## l ## _ ## p
                #define __IDSTRING_EXPAND(l,p)  __IDSTRING_CONCAT(l,p)
                #define pad                     void __IDSTRING_EXPAND(__LINE__,x)(void) { }
@@ -1235,7 +1400,9 @@ gcc)
        # mksh is not written in CFrustFrust!
        ac_flags 1 no_eh_frame -fno-asynchronous-unwind-tables
        ac_flags 1 fnostrictaliasing -fno-strict-aliasing
-       ac_flags 1 fstackprotectorall -fstack-protector-all
+       ac_flags 1 fstackprotectorstrong -fstack-protector-strong
+       test 1 = $HAVE_CAN_FSTACKPROTECTORSTRONG || \
+           ac_flags 1 fstackprotectorall -fstack-protector-all
        test $cm = dragonegg && case " $CC $CFLAGS $LDFLAGS " in
        *\ -fplugin=*dragonegg*) ;;
        *) ac_flags 1 fplugin_dragonegg -fplugin=dragonegg ;;
@@ -1356,8 +1523,8 @@ ac_test attribute_bounded '' 'for __attribute__((__bounded__))' <<-'EOF'
        #include <string.h>
        #undef __attribute__
        int xcopy(const void *, void *, size_t)
-           __attribute__((__bounded__ (__buffer__, 1, 3)))
-           __attribute__((__bounded__ (__buffer__, 2, 3)));
+           __attribute__((__bounded__(__buffer__, 1, 3)))
+           __attribute__((__bounded__(__buffer__, 2, 3)));
        int main(int ac, char *av[]) { return (xcopy(av[0], av[--ac], 1)); }
        int xcopy(const void *s, void *d, size_t n) {
                /*
@@ -1379,7 +1546,7 @@ ac_test attribute_format '' 'for __attribute__((__format__))' <<-'EOF'
        #undef __attribute__
        #undef fprintf
        extern int fprintf(FILE *, const char *format, ...)
-           __attribute__((__format__ (__printf__, 2, 3)));
+           __attribute__((__format__(__printf__, 2, 3)));
        int main(int ac, char **av) { return (fprintf(stderr, "%s%d", *av, ac)); }
        #endif
 EOF
@@ -1396,14 +1563,29 @@ ac_test attribute_noreturn '' 'for __attribute__((__noreturn__))' <<-'EOF'
        void fnord(void) { exit(0); }
        #endif
 EOF
+ac_test attribute_pure '' 'for __attribute__((__pure__))' <<-'EOF'
+       #if defined(__TenDRA__) || (defined(__GNUC__) && (__GNUC__ < 2))
+       extern int thiswillneverbedefinedIhope(void);
+       /* force a failure: TenDRA and gcc 1.42 have false positive here */
+       int main(void) { return (thiswillneverbedefinedIhope()); }
+       #else
+       #include <unistd.h>
+       #undef __attribute__
+       int foo(const char *) __attribute__((__pure__));
+       int main(int ac, char **av) { return (foo(av[ac - 1]) + isatty(0)); }
+       int foo(const char *s) { return ((int)s[0]); }
+       #endif
+EOF
 ac_test attribute_unused '' 'for __attribute__((__unused__))' <<-'EOF'
        #if defined(__TenDRA__) || (defined(__GNUC__) && (__GNUC__ < 2))
        extern int thiswillneverbedefinedIhope(void);
        /* force a failure: TenDRA and gcc 1.42 have false positive here */
        int main(void) { return (thiswillneverbedefinedIhope()); }
        #else
+       #include <unistd.h>
+       #undef __attribute__
        int main(int ac __attribute__((__unused__)), char **av
-           __attribute__((__unused__))) { return (0); }
+           __attribute__((__unused__))) { return (isatty(0)); }
        #endif
 EOF
 ac_test attribute_used '' 'for __attribute__((__used__))' <<-'EOF'
@@ -1412,8 +1594,10 @@ ac_test attribute_used '' 'for __attribute__((__used__))' <<-'EOF'
        /* force a failure: TenDRA and gcc 1.42 have false positive here */
        int main(void) { return (thiswillneverbedefinedIhope()); }
        #else
+       #include <unistd.h>
+       #undef __attribute__
        static const char fnord[] __attribute__((__used__)) = "42";
-       int main(void) { return (0); }
+       int main(void) { return (isatty(0)); }
        #endif
 EOF
 
@@ -1465,7 +1649,8 @@ ac_test both_time_h '' 'whether <sys/time.h> and <time.h> can both be included'
        #include <sys/types.h>
        #include <sys/time.h>
        #include <time.h>
-       int main(void) { struct tm tm; return ((int)sizeof(tm)); }
+       #include <unistd.h>
+       int main(void) { struct tm tm; return ((int)sizeof(tm) + isatty(0)); }
 EOF
 ac_header sys/bsdtypes.h
 ac_header sys/file.h sys/types.h
@@ -1491,11 +1676,12 @@ ac_header values.h
 # Environment: definitions
 #
 echo '#include <sys/types.h>
+#include <unistd.h>
 /* check that off_t can represent 2^63-1 correctly, thx FSF */
-#define LARGE_OFF_T (((off_t)1 << 62) - 1 + ((off_t)1 << 62))
+#define LARGE_OFF_T ((((off_t)1 << 31) << 31) - 1 + (((off_t)1 << 31) << 31))
 int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 &&
     LARGE_OFF_T % 2147483647 == 1) ? 1 : -1];
-int main(void) { return (0); }' >lft.c
+int main(void) { return (isatty(0)); }' >lft.c
 ac_testn can_lfs '' "for large file support" <lft.c
 save_CPPFLAGS=$CPPFLAGS
 add_cppflags -D_FILE_OFFSET_BITS=64
@@ -1546,7 +1732,7 @@ ac_test rlim_t <<-'EOF'
        #include <sys/resource.h>
        #endif
        #include <unistd.h>
-       int main(void) { return ((int)(rlim_t)0); }
+       int main(void) { return (((int)(rlim_t)0) + isatty(0)); }
 EOF
 
 # only testn: added later below
@@ -1598,8 +1784,8 @@ else
                #define EXTERN
                #define MKSH_INCLUDES_ONLY
                #include "sh.h"
-               __RCSID("$MirOS: src/bin/mksh/Build.sh,v 1.645 2013/08/10 13:44:25 tg Exp $");
-               int main(void) { printf("Hello, World!\n"); return (0); }
+               __RCSID("$MirOS: src/bin/mksh/Build.sh,v 1.662 2014/06/29 10:56:08 tg Exp $");
+               int main(void) { printf("Hello, World!\n"); return (isatty(0)); }
 EOF
        case $cm in
        llvm)
@@ -1638,12 +1824,14 @@ test x"NetBSD" = x"$TARGET_OS" && $e Ignore the compatibility warning.
 ac_testn sys_errlist '' "the sys_errlist[] array and sys_nerr" <<-'EOF'
        extern const int sys_nerr;
        extern const char * const sys_errlist[];
-       int main(void) { return (*sys_errlist[sys_nerr - 1]); }
+       extern int isatty(int);
+       int main(void) { return (*sys_errlist[sys_nerr - 1] + isatty(0)); }
 EOF
 ac_testn _sys_errlist '!' sys_errlist 0 "the _sys_errlist[] array and _sys_nerr" <<-'EOF'
        extern const int _sys_nerr;
        extern const char * const _sys_errlist[];
-       int main(void) { return (*_sys_errlist[_sys_nerr - 1]); }
+       extern int isatty(int);
+       int main(void) { return (*_sys_errlist[_sys_nerr - 1] + isatty(0)); }
 EOF
 if test 1 = "$HAVE__SYS_ERRLIST"; then
        add_cppflags -Dsys_nerr=_sys_nerr
@@ -1656,11 +1844,13 @@ for what in name list; do
        uwhat=`upper $what`
        ac_testn sys_sig$what '' "the sys_sig${what}[] array" <<-EOF
                extern const char * const sys_sig${what}[];
-               int main(void) { return (sys_sig${what}[0][0]); }
+               extern int isatty(int);
+               int main(void) { return (sys_sig${what}[0][0] + isatty(0)); }
        EOF
        ac_testn _sys_sig$what '!' sys_sig$what 0 "the _sys_sig${what}[] array" <<-EOF
                extern const char * const _sys_sig${what}[];
-               int main(void) { return (_sys_sig${what}[0][0]); }
+               extern int isatty(int);
+               int main(void) { return (_sys_sig${what}[0][0] + isatty(0)); }
        EOF
        eval uwhat_v=\$HAVE__SYS_SIG$uwhat
        if test 1 = "$uwhat_v"; then
@@ -1703,6 +1893,11 @@ ac_test getrusage <<-'EOF'
        }
 EOF
 
+ac_test getsid <<-'EOF'
+       #include <unistd.h>
+       int main(void) { return ((int)getsid(0)); }
+EOF
+
 ac_test gettimeofday <<-'EOF'
        #define MKSH_INCLUDES_ONLY
        #include "sh.h"
@@ -1722,7 +1917,7 @@ ac_test memmove <<-'EOF'
        #include <strings.h>
        #endif
        int main(int ac, char *av[]) {
-               return (*(int *)(void *)memmove(av[0], av[1], ac));
+               return (*(int *)(void *)memmove(av[0], av[1], (size_t)ac));
        }
 EOF
 
@@ -1894,12 +2089,12 @@ EOF
 ac_test sys_errlist_decl sys_errlist 0 "for declaration of sys_errlist[] and sys_nerr" <<-'EOF'
        #define MKSH_INCLUDES_ONLY
        #include "sh.h"
-       int main(void) { return (*sys_errlist[sys_nerr - 1]); }
+       int main(void) { return (*sys_errlist[sys_nerr - 1] + isatty(0)); }
 EOF
 ac_test sys_siglist_decl sys_siglist 0 'for declaration of sys_siglist[]' <<-'EOF'
        #define MKSH_INCLUDES_ONLY
        #include "sh.h"
-       int main(void) { return (sys_siglist[0][0]); }
+       int main(void) { return (sys_siglist[0][0] + isatty(0)); }
 EOF
 
 #
@@ -1970,7 +2165,7 @@ cta(ptr_fits_in_long, sizeof(ptrdiff_t) <= sizeof(long));
                char padding[64 - NUM];
        };
 char ctasserts_dblcheck[sizeof(struct ctasserts) == 64 ? 1 : -1];
-       int main(void) { return (sizeof(ctasserts_dblcheck)); }
+       int main(void) { return (sizeof(ctasserts_dblcheck) + isatty(0)); }
 EOF
 CFLAGS=$save_CFLAGS
 eval test 1 = \$HAVE_COMPILE_TIME_ASSERTS_$$ || exit 1
@@ -2054,6 +2249,9 @@ if test 0 = $HAVE_SYS_SIGNAME; then
 #define NSIG (SIGMAX+1)
 #elif defined(_SIGMAX)
 #define NSIG (_SIGMAX+1)
+#else
+/* XXX better error out, see sh.h */
+#define NSIG 64
 #endif
 #endif
 int
@@ -2072,9 +2270,9 @@ mksh_cfg= NSIG
        test $printf = echo || test "`printf %d 42`" = 42 || printf=echo
        test $printf = echo || NSIG=`printf %d "$NSIG" 2>/dev/null`
        $printf "NSIG=$NSIG ... "
-       sigs="INT SEGV ABRT KILL ALRM BUS CHLD CLD CONT DIL EMT FPE HUP ILL"
-       sigs="$sigs INFO IO IOT LOST PIPE PROF PWR QUIT RESV SAK STOP SYS TERM"
-       sigs="$sigs TRAP TSTP TTIN TTOU URG USR1 USR2 VTALRM WINCH XCPU XFSZ"
+       sigs="ABRT FPE ILL INT SEGV TERM ALRM BUS CHLD CONT HUP KILL PIPE QUIT"
+       sigs="$sigs STOP TSTP TTIN TTOU USR1 USR2 POLL PROF SYS TRAP URG VTALRM"
+       sigs="$sigs XCPU XFSZ INFO WINCH EMT IO DIL LOST PWR SAK CLD IOT RESV"
        test 1 = $HAVE_CPP_DD && test $NSIG -gt 1 && sigs="$sigs "`vq \
            "$CPP $CFLAGS $CPPFLAGS $NOWARN -dD conftest.c" | \
            grep '[      ]SIG[A-Z0-9][A-Z0-9]*[  ]' | \
@@ -2108,12 +2306,11 @@ mksh_cfg= NSIG
        $e done.
 fi
 
-addsrcs -s '!' HAVE_STRLCPY strlcpy.c
+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"
-test -n "$LDSTATIC" && add_cppflags -DMKSH_OPTSTATIC
-add_cppflags -DMKSH_BUILD_R=481
+add_cppflags -DMKSH_BUILD_R=501
 
 $e $bi$me: Finished configuration testing, now producing output.$ao
 
@@ -2175,6 +2372,10 @@ cat >test.sh <<-EOF
        fi
        (( vflag )) && args[\${#args[*]}]=-v
        (( xflag )) && args[\${#args[*]}]=-x    # force usage by synerr
+       if [[ -n \$TMPDIR && -d \$TMPDIR/. ]]; then
+               args[\${#args[*]}]=-T
+               args[\${#args[*]}]=\$TMPDIR
+       fi
        print Testing mksh for conformance:
        fgrep -e MirOS: -e MIRBSD "\$sflag"
        print "This shell is actually:\\n\\t\$KSH_VERSION"
@@ -2224,6 +2425,10 @@ llvm)
        ;;
 esac
 echo ": # work around NeXTstep bug" >Rebuild.sh
+for file in "$srcdir"/*.opt; do
+       echo "echo + Running genopt on '$file'..."
+       echo "(srcfile='$file'; BUILDSH_RUN_GENOPT=1; . '$srcdir/Build.sh')"
+done >>Rebuild.sh
 echo set -x >>Rebuild.sh
 for file in $SRCS; do
        op=`echo x"$file" | sed 's/^x\(.*\)\.c$/\1./'`
@@ -2253,8 +2458,15 @@ echo tcfn=$mkshexe >>Rebuild.sh
 echo "$CC $CFLAGS $LDFLAGS -o \$tcfn $lobjs $LIBS $ccpr" >>Rebuild.sh
 echo "test -f \$tcfn || exit 1; $SIZE \$tcfn" >>Rebuild.sh
 if test $cm = makefile; then
-       extras='emacsfn.h sh.h sh_flags.h var_spec.h'
+       extras='emacsfn.h rlimits.opt sh.h sh_flags.opt var_spec.h'
        test 0 = $HAVE_SYS_SIGNAME && extras="$extras signames.inc"
+       gens= genq=
+       for file in "$srcdir"/*.opt; do
+               genf=`basename "$file" | sed 's/.opt$/.gen/'`
+               gens="$gens $genf"
+               genq="$genq$nl$genf: $srcdir/Build.sh $file
+                       srcfile=$file; BUILDSH_RUN_GENOPT=1; . $srcdir/Build.sh"
+       done
        cat >Makefrag.inc <<EOF
 # Makefile fragment for building mksh $dstversion
 
@@ -2272,6 +2484,8 @@ CPPFLAGS= $CPPFLAGS
 LDFLAGS=       $LDFLAGS
 LIBS=          $LIBS
 
+.depend \$(OBJS_BP):$gens$genq
+
 # not BSD make only:
 #VPATH=                $srcdir
 #all: \$(PROG)
@@ -2295,6 +2509,10 @@ EOF
        $e Generated Makefrag.inc successfully.
        exit 0
 fi
+for file in "$srcdir"/*.opt; do
+       $e "+ Running genopt on '$file'..."
+       do_genopt "$file" || exit 1
+done
 if test $cm = combine; then
        objs="-o $mkshexe"
        for file in $SRCS; do
index ecd8f8d..e71564d 100644 (file)
@@ -1,8 +1,8 @@
-# $MirOS: src/bin/mksh/check.pl,v 1.32 2013/07/21 18:35:56 tg Exp $
-# $OpenBSD: th,v 1.16 2013/06/14 20:52:08 millert Exp $
+# $MirOS: src/bin/mksh/check.pl,v 1.36 2014/06/09 13:25:50 tg Exp $
+# $OpenBSD: th,v 1.1 2013/12/02 20:39:44 millert Exp $
 #-
 # Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011,
-#              2012, 2013
+#              2012, 2013, 2014
 #      Thorsten Glaser <tg@mirbsd.org>
 #
 # Provided that these terms and disclaimer and all copyright notices
@@ -172,7 +172,6 @@ BEGIN {
 
 use Getopt::Std;
 use Config;
-use File::Temp qw/ :mktemp /;
 
 $os = defined $^O ? $^O : 'unknown';
 
@@ -251,7 +250,7 @@ die "$prog: no test set specified (use -s)\n" if !defined $opt_s;
 $test_prog = $opt_p;
 $verbose = defined $opt_v && $opt_v;
 $test_set = $opt_s;
-$temp_dir = $opt_T || "/tmp";
+$temp_base = $opt_T || "/tmp";
 if (defined $opt_t) {
     die "$prog: bad -t argument (should be number > 0): $opt_t\n"
        if $opt_t !~ /^\d+$/ || $opt_t <= 0;
@@ -300,6 +299,18 @@ chop($pwd = `pwd 2>/dev/null`);
 die "$prog: couldn't get current working directory\n" if $pwd eq '';
 die "$prog: couldn't cd to $pwd - $!\n" if !chdir($pwd);
 
+die "$prog: couldn't cd to $temp_base - $!\n" if !chdir($temp_base);
+die "$prog: couldn't get temporary directory base\n" unless -d '.';
+$temps = sprintf("chk%d-%d.", $$, time());
+$tempi = 0;
+until (mkdir(($tempdir = sprintf("%s%03d", $temps, $tempi)), 0700)) {
+    die "$prog: couldn't get temporary directory\n" if $tempi++ >= 999;
+}
+die "$prog: couldn't cd to $tempdir - $!\n" if !chdir($tempdir);
+chop($temp_dir = `pwd 2>/dev/null`);
+die "$prog: couldn't get temporary directory\n" if $temp_dir eq '';
+die "$prog: couldn't cd to $pwd - $!\n" if !chdir($pwd);
+
 if (!$program_kludge) {
     $test_prog = "$pwd/$test_prog" if substr($test_prog, 0, 1) ne '/';
     die "$prog: $test_prog is not executable - bye\n"
@@ -314,15 +325,12 @@ $SIG{'ALRM'} = 'catch_sigalrm';
 $| = 1;
 
 # Create temp files
-($fh, $temps) = mkstemp("${temp_dir}/rts.XXXXXXXX");
-close($fh);
-($fh, $tempi) = mkstemp("${temp_dir}/rti.XXXXXXXX");
-close($fh);
-($fh, $tempo) = mkstemp("${temp_dir}/rto.XXXXXXXX");
-close($fh);
-($fh, $tempe) = mkstemp("${temp_dir}/rte.XXXXXXXX");
-close($fh);
-$tempdir = mkdtemp("${temp_dir}/rtd.XXXXXXXX");
+$temps = "${temp_dir}/rts";
+$tempi = "${temp_dir}/rti";
+$tempo = "${temp_dir}/rto";
+$tempe = "${temp_dir}/rte";
+$tempdir = "${temp_dir}/rtd";
+mkdir($tempdir, 0700) or die "$prog: couldn't mkdir $tempdir - $!\n";
 
 if (-d $test_set) {
     $file_prefix_skip = length($test_set) + 1;
@@ -365,6 +373,7 @@ cleanup_exit
     unlink($tempi, $tempo, $tempe, $temps);
     &scrub_dir($tempdir) if defined $tempdir;
     rmdir($tempdir) if defined $tempdir;
+    rmdir($temp_dir) if defined $temp_dir;
 
     if ($sig) {
        $SIG{$sig} = 'DEFAULT';
@@ -903,7 +912,7 @@ eval_exit
     } else {
        $expr = $expect;
        $expr =~ s/\b([wse])\b/\$$1/g;
-       $expr =~ s/\b(SIG[A-Z0-9]+)\b/&$1/g;
+       $expr =~ s/\b(SIG[A-Z][A-Z0-9]*)\b/&$1/g;
     }
     $w = eval $expr;
     if ($@ ne '') {
@@ -923,12 +932,13 @@ read_test
     %test = ();
     %cnt = ();
     while (<$in>) {
+       chop;
        next if /^\s*$/;
        next if /^ *#/;
        last if /^\s*---\s*$/;
        $start_lineno = $. if !defined $start_lineno;
        if (!/^([-\w]+):\s*(|\S|\S.*\S)\s*$/) {
-           print STDERR "$prog:$file:$.: unrecognised line\n";
+           print STDERR "$prog:$file:$.: unrecognised line \"$_\"\n";
            return undef;
        }
        ($field, $val) = ($1, $2);
@@ -1154,7 +1164,7 @@ read_test
                print STDERR "$prog:$test{':long-name'}: expected-exit value $val not in 0..255\n";
                return undef;
            }
-       } elsif ($val !~ /^([\s<>+-=*%\/&|!()]|\b[wse]\b|\bSIG[A-Z0-9]+\b)+$/) {
+       } elsif ($val !~ /^([\s<>+-=*%\/&|!()]|\b[wse]\b|\bSIG[A-Z][A-Z0-9]*\b)+$/) {
            print STDERR "$prog:$test{':long-name'}: bad expected-exit expression: $val\n";
            return undef;
        }
index 8df826f..6db4f3a 100644 (file)
@@ -1,12 +1,8 @@
-# $MirOS: src/bin/mksh/check.t,v 1.629 2013/08/14 20:26:15 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 $
-# $OpenBSD: regress.t,v 1.15 2013/07/01 17:25:27 jca Exp $
-# $OpenBSD: obsd-regress.t,v 1.5 2013/07/01 17:25:27 jca Exp $
+# $MirOS: src/bin/mksh/check.t,v 1.654 2014/06/29 11:28:26 tg Exp $
+# OpenBSD src/regress/bin/ksh updated: 2013/12/02 20:39:44
 #-
 # Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
-#            2011, 2012, 2013
+#            2011, 2012, 2013, 2014
 #      Thorsten Glaser <tg@mirbsd.org>
 #
 # Provided that these terms and disclaimer and all copyright notices
@@ -31,7 +27,7 @@
 # http://www.freebsd.org/cgi/cvsweb.cgi/src/tools/regression/bin/test/regress.sh?rev=HEAD
 
 expected-stdout:
-       @(#)MIRBSD KSH R48 2013/08/14
+       @(#)MIRBSD KSH R50 2014/06/29
 description:
        Check version of shell.
 stdin:
@@ -40,7 +36,7 @@ name: KSH_VERSION
 category: shell:legacy-no
 ---
 expected-stdout:
-       @(#)LEGACY KSH R48 2013/08/14
+       @(#)LEGACY KSH R50 2014/06/29
 description:
        Check version of legacy shell.
 stdin:
@@ -74,6 +70,18 @@ stdin:
 expected-stdout:
        <fnord>
 ---
+name: selftest-exec
+description:
+       Ensure that the test run directory (default /tmp but can be changed
+       with check.pl flag -T or test.sh $TMPDIR) is not mounted noexec, as
+       we execute scripts from the scratch directory during several tests.
+stdin:
+       print '#!'"$__progname"'\necho tf' >lq
+       chmod +x lq
+       ./lq
+expected-stdout:
+       tf
+---
 name: selftest-env
 description:
        Just output the environment variables set (always fails)
@@ -1640,6 +1648,14 @@ expected-stdout:
        1=02.
        2=02.
 ---
+name: expand-number-1
+description:
+       Check that positional arguments do not overflow
+stdin:
+       echo "1 ${12345678901234567890} ."
+expected-stdout:
+       1  .
+---
 name: eglob-bad-1
 description:
        Check that globbing isn't done when glob has syntax error
@@ -2071,12 +2087,18 @@ stdin:
        echo [!-ab]*
        echo [!ab]*
        echo []ab]*
+       :>'./!bc'
+       :>'./^bc'
+       echo [^ab]*
+       echo [!ab]*
 expected-stdout:
        -bc abc bbc
        -bc abc bbc
        cbc
        -bc cbc
        abc bbc
+       ^bc abc bbc
+       !bc -bc ^bc cbc
 ---
 name: glob-range-2
 description:
@@ -2126,6 +2148,18 @@ stdin:
 expected-stdout:
        -bc abc bbc cbc ebc
 ---
+name: glob-trim-1
+description:
+       Check against a regression from fixing IFS-subst-2
+stdin:
+       x='#foo'
+       print -r "before='$x'"
+       x=${x%%#*}
+       print -r "after ='$x'"
+expected-stdout:
+       before='#foo'
+       after =''
+---
 name: heredoc-1
 description:
        Check ordering/content of redundent here documents.
@@ -3689,6 +3723,28 @@ expected-stdout:
        12: [A] [B] [] [D]
         <13> <A> <B> <> <D>
 ---
+name: IFS-subst-2
+description:
+       Check leading whitespace after trim does not make a field
+stdin:
+       showargs() { for i; do echo -n " <$i>"; done; echo; }
+       x="X 1 2"
+       showargs 1 shift ${x#X}
+expected-stdout:
+        <1> <shift> <1> <2>
+---
+name: IFS-arith-1
+description:
+       http://austingroupbugs.net/view.php?id=832
+stdin:
+       ${ZSH_VERSION+false} || emulate sh
+       ${BASH_VERSION+set -o posix}
+       showargs() { for x in "$@"; do echo -n "<$x> "; done; echo .; }
+       IFS=0
+       showargs $((1230456))
+expected-stdout:
+       <123> <456> .
+---
 name: integer-base-err-1
 description:
        Can't have 0 base (causes shell to exit)
@@ -4806,11 +4862,12 @@ description:
        them exit 0. The POSIX behaviour is needed by BSD make.
 stdin:
        set -e
-       echo `false; echo hi`
+       echo `false; echo hi` $(<this-file-does-not-exist)
        echo $?
 expected-stdout:
        
        0
+expected-stderr-pattern: /this-file-does-not-exist/
 ---
 name: regression-40
 description:
@@ -5426,6 +5483,18 @@ expected-stdout:
 expected-stderr-pattern:
        /read-only/
 ---
+name: readonly-4
+description:
+       Do not permit bypassing readonly for first array item
+stdin:
+       set -A arr -- foo bar
+       readonly arr
+       arr=baz
+       print -r -- "${arr[@]}"
+expected-exit: e != 0
+expected-stderr-pattern:
+       /read[ -]?only/
+---
 name: syntax-1
 description:
        Check that lone ampersand is a syntax error
@@ -6444,6 +6513,7 @@ stdin:
        echo 6 "$("$__progname" -c '! (exit 23) | (exit 42) | :; echo $?')" .
        echo 7 "$("$__progname" -o pipefail -c '(exit 23) | (exit 42) | :; echo $?')" .
        echo 8 "$("$__progname" -o pipefail -c '! (exit 23) | (exit 42) | :; echo $?')" .
+       echo 9 "$("$__progname" -o pipefail -c 'x=$( (exit 23) | (exit 42) | :); echo $?')" .
 expected-stdout:
        1 42 .
        2 0 .
@@ -6453,6 +6523,7 @@ expected-stdout:
        6 1 .
        7 42 .
        8 0 .
+       9 42 .
 ---
 name: persist-history-1
 description:
@@ -6733,7 +6804,6 @@ expected-stdout:
        r='fc -e -'
        source='PATH=$PATH:. command .'
        stop='kill -STOP'
-       suspend='kill -STOP $$'
        type='whence -v'
 ---
 name: aliases-1-hartz4
@@ -6802,7 +6872,6 @@ expected-stdout:
        r='fc -e -'
        source='PATH=$PATH:. command .'
        stop='kill -STOP'
-       suspend='kill -STOP $$'
        type='whence -v'
 ---
 name: aliases-3b
@@ -6826,7 +6895,6 @@ expected-stdout:
        r='fc -e -'
        source='PATH=$PATH:. command .'
        stop='kill -STOP'
-       suspend='kill -STOP $$'
        type='whence -v'
 ---
 name: aliases-2b-hartz4
@@ -7000,12 +7068,19 @@ stdin:
        v="c d"
        set -A foo -- [1]=\$v [2]="$v" [4]='$v' [0]=a [5]=b
        echo "${#foo[*]}|${foo[0]}|${foo[1]}|${foo[2]}|${foo[3]}|${foo[4]}|${foo[5]}|"
+       # we don't want this at all:
+       #       5|a|$v|c d||$v|b|
+       set -A arr "[5]=meh"
+       echo "<${arr[0]}><${arr[5]}>"
 expected-stdout:
-       5|a|$v|c d||$v|b|
+       5|[1]=$v|[2]=c d|[4]=$v|[0]=a|[5]=b||
+       <[5]=meh><>
 ---
 name: arrays-5
 description:
        Check if bash-style arrays with specified indices work as expected
+       (taken out temporarily to fix arrays-4; see also arrays-9a comment)
+category: disabled
 stdin:
        v="c d"
        foo=([1]=\$v [2]="$v" [4]='$v' [0]=a [5]=b)
@@ -7013,10 +7088,17 @@ stdin:
        x=([128]=foo bar baz)
        echo k= ${!x[*]} .
        echo v= ${x[*]} .
+       # Check that we do not break this by globbing
+       :>b=blah
+       bleh=5
+       typeset -a arr
+       arr+=([bleh]=blah)
+       echo "<${arr[0]}><${arr[5]}>"
 expected-stdout:
        5|a|$v|c d||$v|b|
        k= 128 129 130 .
        v= foo bar baz .
+       <><blah>
 ---
 name: arrays-6
 description:
@@ -7078,15 +7160,15 @@ stdin:
        echo !arz[0]: ${!arz[0]}
        echo !arz[1]: ${!arz[1]}
 expected-stdout:
-       !arz: 0
-       !arz[0]:
-       !arz[1]:
        !arz: arz
-       !arz[0]: 0
-       !arz[1]:
-       !arz: 0
-       !arz[0]:
-       !arz[1]:
+       !arz[0]: arz[0]
+       !arz[1]: arz[1]
+       !arz: arz
+       !arz[0]: arz[0]
+       !arz[1]: arz[1]
+       !arz: arz
+       !arz[0]: arz[0]
+       !arz[1]: arz[1]
 ---
 name: arrays-8
 description:
@@ -7177,11 +7259,11 @@ description:
 stdin:
        unset foo; foo=(bar); foo+=(baz); echo 1 ${!foo[*]} : ${foo[*]} .
        unset foo; foo=(foo bar); foo+=(baz); echo 2 ${!foo[*]} : ${foo[*]} .
-       unset foo; foo=([2]=foo [0]=bar); foo+=(baz [5]=quux); echo 3 ${!foo[*]} : ${foo[*]} .
+#      unset foo; foo=([2]=foo [0]=bar); foo+=(baz [5]=quux); echo 3 ${!foo[*]} : ${foo[*]} .
 expected-stdout:
        1 0 1 : bar baz .
        2 0 1 2 : foo bar baz .
-       3 0 2 3 5 : bar foo baz quux .
+#      3 0 2 3 5 : bar foo baz quux .
 ---
 name: arrays-9b
 description:
@@ -7660,14 +7742,9 @@ stdin:
        typeset -i8 foo=10
        bar=baz
        unset baz
-       bla=foo
        print ${foo@#} ${bar@#} ${baz@#} .
-       print ${foo@#123} ${bar@#456} ${baz@#789} .
-       print ${foo@#bla} ${bar@#bar} ${baz@#OPTIND} .
 expected-stdout:
-       D50219A0 20E5DB5B 00000000 .
-       554A1C76 004A212E CB209562 .
-       6B21CF91 20E5DB5B 124EA49D .
+       9B15FBFB CFBDD32B 00000000 .
 ---
 name: varexpand-special-quote
 description:
@@ -8772,7 +8849,7 @@ expected-stdout:
 ---
 name: oksh-eval
 description:
-       $OpenBSD: eval.sh,v 1.1 2010/03/24 08:29:44 fgsch Exp $
+       Check expansions.
 stdin:
        a=
        for n in ${a#*=}; do echo 1hu ${n} .; done
@@ -8932,8 +9009,7 @@ stdin:
 ---
 name: oksh-varfunction-mod1
 description:
-       $OpenBSD: varfunction.sh,v 1.1 2003/12/15 05:28:40 otto Exp $
-       Calling
+       (Inspired by PR 2450 on OpenBSD.) Calling
                FOO=bar f
        where f is a ksh style function, should not set FOO in the current
        env. If f is a Bourne style function, FOO should be set. Furthermore,
@@ -8941,7 +9017,6 @@ description:
        from oksh, setting FOO in the function itself must change the value in
        setting FOO in the function itself should not change the value in
        global environment.
-       Inspired by PR 2450.
 stdin:
        print '#!'"$__progname"'\nunset RANDOM\nexport | while IFS= read -r' \
            'RANDOM; do eval '\''print -r -- "$RANDOM=$'\''"$RANDOM"'\'\"\'\; \
@@ -10502,7 +10577,7 @@ expected-stdout:
        ir2: ir2
        s1: ir2=ind
        s2: typeset -n ir2
-       !ind[1]: 1
+       !ind[1]: blub[1]
        !ir2: ir2
        ind[1]: e2
        ir2: e3
index cbd13ed..99cc9a1 100644 (file)
@@ -1,8 +1,8 @@
 # $Id$
-# $MirOS: src/bin/mksh/dot.mkshrc,v 1.84 2013/08/10 13:43:50 tg Exp $
+# $MirOS: src/bin/mksh/dot.mkshrc,v 1.88 2014/01/11 18:09:39 tg Exp $
 #-
 # Copyright (c) 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010,
-#              2011, 2012, 2013
+#              2011, 2012, 2013, 2014
 #      Thorsten Glaser <tg@mirbsd.org>
 #
 # Provided that these terms and disclaimer and all copyright notices
@@ -105,14 +105,14 @@ function chpwd {
 }
 chpwd .
 function cd {
-       builtin cd "$@"
+       builtin cd "$@" || return $?
        chpwd "$@"
 }
 function cd_csh {
        local d t=${1/#~/$DIRSTACKBASE}
 
        if ! d=$(builtin cd "$t" 2>&1); then
-               print -u2 "${1}: ${d##*$t - }."
+               print -u2 "${1}: ${d##*cd: $t: }."
                return 1
        fi
        cd "$t"
@@ -333,9 +333,12 @@ function Lb64encode {
        (( u )) || set -U
 }
 
-# mksh NUL counting, never zero
-typeset -Z11 -Uui16 Lnzathash_v
-function Lnzathash_add {
+# Better Avalanche for the Jenkins Hash
+typeset -Z11 -Uui16 Lbafh_v
+function Lbafh_init {
+       Lbafh_v=0
+}
+function Lbafh_add {
        [[ -o utf8-mode ]]; local u=$?
        set +U
        local s
@@ -348,37 +351,20 @@ function Lnzathash_add {
        local -i i=0 n=${#s[*]}
 
        while (( i < n )); do
-               ((# Lnzathash_v = (Lnzathash_v + s[i++] + 1) * 1025 ))
-               ((# Lnzathash_v ^= Lnzathash_v >> 6 ))
+               ((# Lbafh_v = (Lbafh_v + s[i++] + 1) * 1025 ))
+               ((# Lbafh_v ^= Lbafh_v >> 6 ))
        done
 
        (( u )) || set -U
 }
-function Lnzaathash_end {
-       ((# Lnzathash_v *= 1025 ))
-       ((# Lnzathash_v ^= Lnzathash_v >> 6 ))
-       ((# Lnzathash_v += Lnzathash_v << 3 ))
-       ((# Lnzathash_v = (Lnzathash_v ^
-           (Lnzathash_v >> 11)) * 32769 ))
-       print ${Lnzathash_v#16#}
-}
-function Lnzaathash {
-       Lnzathash_v=0
-       Lnzathash_add "$@"
-       Lnzaathash_end
-}
-function Lnzathash {
-       Lnzathash_v=0
-       Lnzathash_add "$@"
-       Lnzathash_end
-}
-function Lnzathash_end {
-       if (( Lnzathash_v )); then
-               Lnzaathash_end
-       else
-               Lnzathash_v=1
-               print ${Lnzathash_v#16#}
-       fi
+function Lbafh_finish {
+       local -Ui t
+
+       ((# t = (((Lbafh_v >> 7) & 0x01010101) * 0x1B) ^ \
+           ((Lbafh_v << 1) & 0xFEFEFEFE) ))
+       ((# Lbafh_v = t ^ (t >>> 8) ^ (Lbafh_v >>> 8) ^ \
+           (Lbafh_v >>> 16) ^ (Lbafh_v >>> 24) ))
+       :
 }
 
 # strip comments (and leading/trailing whitespace if IFS is set) from
index 675e7ed..2459db7 100644 (file)
@@ -1,11 +1,11 @@
-/*     $OpenBSD: edit.c,v 1.38 2013/06/03 15:41:59 tedu Exp $  */
+/*     $OpenBSD: edit.c,v 1.39 2013/12/17 16:37:05 deraadt Exp $       */
 /*     $OpenBSD: edit.h,v 1.9 2011/05/30 17:14:35 martynas Exp $       */
-/*     $OpenBSD: emacs.c,v 1.44 2011/09/05 04:50:33 marco Exp $        */
-/*     $OpenBSD: vi.c,v 1.26 2009/06/29 22:50:19 martynas Exp $        */
+/*     $OpenBSD: emacs.c,v 1.48 2013/12/17 16:37:05 deraadt Exp $      */
+/*     $OpenBSD: vi.c,v 1.28 2013/12/18 16:45:46 deraadt Exp $ */
 
 /*-
  * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
- *              2011, 2012, 2013
+ *              2011, 2012, 2013, 2014
  *     Thorsten Glaser <tg@mirbsd.org>
  *
  * Provided that these terms and disclaimer and all copyright notices
@@ -28,7 +28,7 @@
 
 #ifndef MKSH_NO_CMDLINE_EDITING
 
-__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.270 2013/08/14 20:26:17 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.275 2014/01/05 21:57:24 tg Exp $");
 
 /*
  * in later versions we might use libtermcap for this, but since external
@@ -82,7 +82,7 @@ static int x_basename(const char *, const char *);
 static void x_free_words(int, char **);
 static int x_escape(const char *, size_t, int (*)(const char *, size_t));
 static int x_emacs(char *);
-static void x_init_prompt(void);
+static void x_init_prompt(bool);
 #if !MKSH_S_NOVI
 static int x_vi(char *);
 #endif
@@ -148,6 +148,7 @@ x_getc(void)
                                if (x_cols != xx_cols && editmode == 1) {
                                        /* redraw line in Emacs mode */
                                        xx_cols = x_cols;
+                                       x_init_prompt(false);
                                        x_e_rebuildline(MKSH_CLRTOEOL_STRING);
                                }
                        }
@@ -960,12 +961,11 @@ static void x_delete(size_t, bool);
 static size_t x_bword(void);
 static size_t x_fword(bool);
 static void x_goto(char *);
-static char *x_bs0(char *, char *);
+static char *x_bs0(char *, char *) MKSH_A_PURE;
 static void x_bs3(char **);
 static int x_size_str(char *);
 static int x_size2(char *, char **);
 static void x_zots(char *);
-static void x_zotc2(int);
 static void x_zotc3(char **);
 static void x_load_hist(char **);
 static int x_search(char *, int, int);
@@ -990,7 +990,7 @@ static int x_fold_case(int);
 #endif
 static char *x_lastcp(void);
 static void do_complete(int, Comp_type);
-static size_t x_nb2nc(size_t);
+static size_t x_nb2nc(size_t) MKSH_A_PURE;
 
 static int unget_char = -1;
 
@@ -1167,16 +1167,17 @@ x_e_getmbc(char *sbuf)
 }
 
 static void
-x_init_prompt(void)
+x_init_prompt(bool doprint)
 {
-       prompt_trunc = pprompt(prompt, 0);
+       prompt_trunc = pprompt(prompt, doprint ? 0 : -1);
        pwidth = prompt_trunc % x_cols;
        prompt_trunc -= pwidth;
        if ((mksh_uari_t)pwidth > ((mksh_uari_t)x_cols - 3 - MIN_EDIT_SPACE)) {
                /* force newline after prompt */
                prompt_trunc = -1;
                pwidth = 0;
-               x_e_putc2('\n');
+               if (doprint)
+                       x_e_putc2('\n');
        }
 }
 
@@ -1196,7 +1197,7 @@ x_emacs(char *buf)
        x_histp = histptr + 1;
        x_last_command = XFUNC_error;
 
-       x_init_prompt();
+       x_init_prompt(true);
        x_displen = (xx_cols = x_cols) - 2 - (x_col = pwidth);
        x_adj_done = 0;
        x_adj_ok = true;
@@ -1606,7 +1607,7 @@ x_size_str(char *cp)
 static int
 x_size2(char *cp, char **dcp)
 {
-       int c = *(unsigned char *)cp;
+       uint8_t c = *(unsigned char *)cp;
 
        if (UTFMODE && (c > 0x7F))
                return (utf_widthadj(cp, (const char **)dcp));
@@ -1615,7 +1616,7 @@ x_size2(char *cp, char **dcp)
        if (c == '\t')
                /* Kludge, tabs are always four spaces. */
                return (4);
-       if (c < ' ' || c == 0x7f)
+       if (ISCTRL(c) && /* but not C1 */ c < 0x80)
                /* control unsigned char */
                return (2);
        return (1);
@@ -1632,19 +1633,6 @@ x_zots(char *str)
 }
 
 static void
-x_zotc2(int c)
-{
-       if (c == '\t') {
-               /* Kludge, tabs are always four spaces. */
-               x_e_puts("    ");
-       } else if (c < ' ' || c == 0x7f) {
-               x_e_putc2('^');
-               x_e_putc2(UNCTRL(c));
-       } else
-               x_e_putc2(c);
-}
-
-static void
 x_zotc3(char **cp)
 {
        unsigned char c = **(unsigned char **)cp;
@@ -1653,7 +1641,7 @@ x_zotc3(char **cp)
                /* Kludge, tabs are always four spaces. */
                x_e_puts("    ");
                (*cp)++;
-       } else if (c < ' ' || c == 0x7f) {
+       } else if (ISCTRL(c) && /* but not C1 */ c < 0x80) {
                x_e_putc2('^');
                x_e_putc2(UNCTRL(c));
                (*cp)++;
@@ -1765,7 +1753,10 @@ x_newline(int c MKSH_A_UNUSED)
 static int
 x_end_of_text(int c MKSH_A_UNUSED)
 {
-       x_zotc2(edchars.eof);
+       char tmp = edchars.eof;
+       char *cp = &tmp;
+
+       x_zotc3(&cp);
        x_putc('\r');
        x_putc('\n');
        x_flush();
@@ -2377,6 +2368,7 @@ x_mapin(const char *cp, Area *ap)
                /* XXX -- should handle \^ escape? */
                if (*cp == '^') {
                        cp++;
+                       /*XXX or ^^ escape? this is ugly. */
                        if (*cp >= '?')
                                /* includes '?'; ASCII */
                                *op++ = CTRL(*cp);
@@ -2398,7 +2390,7 @@ x_mapout2(int c, char **buf)
 {
        char *p = *buf;
 
-       if (c < ' ' || c == 0x7f) {
+       if (ISCTRL(c)) {
                *p++ = '^';
                *p++ = UNCTRL(c);
        } else
@@ -3341,8 +3333,6 @@ x_mode(bool onoff)
 #if !MKSH_S_NOVI
 /* +++ vi editing mode +++ */
 
-#define Ctrl(c)                (c&0x1f)
-
 struct edstate {
        char *cbuf;
        ssize_t winleft;
@@ -3363,7 +3353,7 @@ static void save_cbuf(void);
 static void restore_cbuf(void);
 static int putbuf(const char *, ssize_t, bool);
 static void del_range(int, int);
-static int findch(int, int, bool, bool);
+static int findch(int, int, bool, bool) MKSH_A_PURE;
 static int forwword(int);
 static int backword(int);
 static int endword(int);
@@ -3376,13 +3366,14 @@ static void redraw_line(bool);
 static void refresh(int);
 static int outofwin(void);
 static void rewindow(void);
-static int newcol(int, int);
+static int newcol(unsigned char, int);
 static void display(char *, char *, int);
 static void ed_mov_opt(int, char *);
 static int expand_word(int);
 static int complete_word(int, int);
 static int print_expansions(struct edstate *, int);
-#define char_len(c)    ((c) < ' ' || (c) == 0x7F ? 2 : 1)
+#define char_len(c)    ((ISCTRL((unsigned char)c) && \
+                       /* but not C1 */ (unsigned char)c < 0x80) ? 2 : 1)
 static void x_vi_zotc(int);
 static void vi_error(void);
 static void vi_macro_reset(void);
@@ -3535,7 +3526,7 @@ x_vi(char *buf)
        es = &ebuf;
        undo = &undobuf;
 
-       x_init_prompt();
+       x_init_prompt(true);
        x_col = pwidth;
 
        if (wbuf_len != x_cols - 3 && ((wbuf_len = x_cols - 3))) {
@@ -3556,7 +3547,7 @@ x_vi(char *buf)
        x_flush();
        while (/* CONSTCOND */ 1) {
                if (macro.p) {
-                       c = *macro.p++;
+                       c = (unsigned char)*macro.p++;
                        /* end of current macro? */
                        if (!c) {
                                /* more macros left to finish? */
@@ -3618,7 +3609,7 @@ vi_hook(int ch)
 
        case VNORMAL:
                if (insert != 0) {
-                       if (ch == Ctrl('v')) {
+                       if (ch == CTRL('v')) {
                                state = VLIT;
                                ch = '^';
                        }
@@ -3730,7 +3721,7 @@ vi_hook(int ch)
                break;
 
        case VXCH:
-               if (ch == Ctrl('['))
+               if (ch == CTRL('['))
                        state = VNORMAL;
                else {
                        curcmd[cmdlen++] = ch;
@@ -3739,7 +3730,7 @@ vi_hook(int ch)
                break;
 
        case VSEARCH:
-               if (ch == '\r' || ch == '\n' /*|| ch == Ctrl('[')*/ ) {
+               if (ch == '\r' || ch == '\n' /*|| ch == CTRL('[')*/ ) {
                        restore_cbuf();
                        /* Repeat last search? */
                        if (srchlen == 0) {
@@ -3754,10 +3745,10 @@ vi_hook(int ch)
                                memcpy(srchpat, locpat, srchlen + 1);
                        }
                        state = VCMD;
-               } else if (ch == edchars.erase || ch == Ctrl('h')) {
+               } else if (ch == edchars.erase || ch == CTRL('h')) {
                        if (srchlen != 0) {
                                srchlen--;
-                               es->linelen -= char_len((unsigned char)locpat[srchlen]);
+                               es->linelen -= char_len(locpat[srchlen]);
                                es->cursor = es->linelen;
                                refresh(0);
                                return (0);
@@ -3772,10 +3763,10 @@ vi_hook(int ch)
                        refresh(0);
                        return (0);
                } else if (ch == edchars.werase) {
-                       int i, n = srchlen;
+                       unsigned int i, n;
                        struct edstate new_es, *save_es;
 
-                       new_es.cursor = n;
+                       new_es.cursor = srchlen;
                        new_es.cbuf = locpat;
 
                        save_es = es;
@@ -3783,9 +3774,10 @@ vi_hook(int ch)
                        n = backword(1);
                        es = save_es;
 
-                       for (i = srchlen; --i >= n; )
-                               es->linelen -= char_len((unsigned char)locpat[i]);
-                       srchlen = n;
+                       i = (unsigned)srchlen;
+                       while (--i >= n)
+                               es->linelen -= char_len(locpat[i]);
+                       srchlen = (int)n;
                        es->cursor = es->linelen;
                        refresh(0);
                        return (0);
@@ -3794,12 +3786,12 @@ vi_hook(int ch)
                                vi_error();
                        else {
                                locpat[srchlen++] = ch;
-                               if (ch < ' ' || ch == 0x7f) {
+                               if (ISCTRL(ch) && /* but not C1 */ ch < 0x80) {
                                        if ((size_t)es->linelen + 2 >
                                            (size_t)es->cbufsize)
                                                vi_error();
                                        es->cbuf[es->linelen++] = '^';
-                                       es->cbuf[es->linelen++] = ch ^ '@';
+                                       es->cbuf[es->linelen++] = UNCTRL(ch);
                                } else {
                                        if (es->linelen >= es->cbufsize)
                                                vi_error();
@@ -3910,7 +3902,7 @@ nextstate(int ch)
                return (VXCH);
        else if (ch == '.')
                return (VREDO);
-       else if (ch == Ctrl('v'))
+       else if (ch == CTRL('v'))
                return (VVERSION);
        else if (is_cmd(ch))
                return (VCMD);
@@ -3923,7 +3915,7 @@ vi_insert(int ch)
 {
        int tcursor;
 
-       if (ch == edchars.erase || ch == Ctrl('h')) {
+       if (ch == edchars.erase || ch == CTRL('h')) {
                if (insert == REPLACE) {
                        if (es->cursor == undo->cursor) {
                                vi_error();
@@ -3980,7 +3972,7 @@ vi_insert(int ch)
         * buffer (if user inserts & deletes char, ibuf gets trashed and
         * we don't want to use it)
         */
-       if (first_insert && ch != Ctrl('['))
+       if (first_insert && ch != CTRL('['))
                saved_inslen = 0;
        switch (ch) {
        case '\0':
@@ -3990,7 +3982,7 @@ vi_insert(int ch)
        case '\n':
                return (1);
 
-       case Ctrl('['):
+       case CTRL('['):
                expanded = NONE;
                if (first_insert) {
                        first_insert = false;
@@ -4008,19 +4000,19 @@ vi_insert(int ch)
                        return (redo_insert(lastac - 1));
 
        /* { Begin nonstandard vi commands */
-       case Ctrl('x'):
+       case CTRL('x'):
                expand_word(0);
                break;
 
-       case Ctrl('f'):
+       case CTRL('f'):
                complete_word(0, 0);
                break;
 
-       case Ctrl('e'):
+       case CTRL('e'):
                print_expansions(es, 0);
                break;
 
-       case Ctrl('i'):
+       case CTRL('i'):
                if (Flag(FVITABCOMPLETE)) {
                        complete_word(0, 0);
                        break;
@@ -4075,8 +4067,8 @@ vi_cmd(int argcnt, const char *cmd)
                }
                switch (*cmd) {
 
-               case Ctrl('l'):
-               case Ctrl('r'):
+               case CTRL('l'):
+               case CTRL('r'):
                        redraw_line(true);
                        break;
 
@@ -4263,7 +4255,7 @@ vi_cmd(int argcnt, const char *cmd)
 
                case 'j':
                case '+':
-               case Ctrl('n'):
+               case CTRL('n'):
                        if (grabhist(modified, hnum + argcnt) < 0)
                                return (-1);
                        else {
@@ -4274,7 +4266,7 @@ vi_cmd(int argcnt, const char *cmd)
 
                case 'k':
                case '-':
-               case Ctrl('p'):
+               case CTRL('p'):
                        if (grabhist(modified, hnum - argcnt) < 0)
                                return (-1);
                        else {
@@ -4506,26 +4498,26 @@ vi_cmd(int argcnt, const char *cmd)
                /* AT&T ksh */
                case '=':
                /* Nonstandard vi/ksh */
-               case Ctrl('e'):
+               case CTRL('e'):
                        print_expansions(es, 1);
                        break;
 
 
                /* Nonstandard vi/ksh */
-               case Ctrl('i'):
+               case CTRL('i'):
                        if (!Flag(FVITABCOMPLETE))
                                return (-1);
                        complete_word(1, argcnt);
                        break;
 
                /* some annoying AT&T kshs */
-               case Ctrl('['):
+               case CTRL('['):
                        if (!Flag(FVIESCCOMPLETE))
                                return (-1);
                /* AT&T ksh */
                case '\\':
                /* Nonstandard vi/ksh */
-               case Ctrl('f'):
+               case CTRL('f'):
                        complete_word(1, argcnt);
                        break;
 
@@ -4533,7 +4525,7 @@ vi_cmd(int argcnt, const char *cmd)
                /* AT&T ksh */
                case '*':
                /* Nonstandard vi/ksh */
-               case Ctrl('x'):
+               case CTRL('x'):
                        expand_word(1);
                        break;
 
@@ -4612,7 +4604,7 @@ domove(int argcnt, const char *cmd, int sub)
                break;
 
        case 'h':
-       case Ctrl('h'):
+       case CTRL('h'):
                if (!sub && es->cursor == 0)
                        return (-1);
                ncursor = es->cursor - argcnt;
@@ -5028,7 +5020,7 @@ grabsearch(int save, int start, int fwd, const char *pat)
 {
        char *hptr;
        int hist;
-       int anchored;
+       bool anchored;
 
        if ((start == 0 && fwd == 0) || (start >= hlast - 1 && fwd == 1))
                return (-1);
@@ -5036,7 +5028,7 @@ grabsearch(int save, int start, int fwd, const char *pat)
                start++;
        else
                start--;
-       anchored = *pat == '^' ? (++pat, 1) : 0;
+       anchored = *pat == '^' ? (++pat, true) : false;
        if ((hist = findhist(start, fwd, pat, anchored)) < 0) {
                /* (start != 0 && fwd && match(holdbufp, pat) >= 0) */
                if (start != 0 && fwd && strcmp(holdbufp, pat) >= 0) {
@@ -5125,7 +5117,7 @@ rewindow(void)
 }
 
 static int
-newcol(int ch, int col)
+newcol(unsigned char ch, int col)
 {
        if (ch == '\t')
                return ((col | 7) + 1);
@@ -5153,10 +5145,10 @@ display(char *wb1, char *wb2, int leftside)
                                *twb1++ = ' ';
                        } while (++col < winwidth && (col & 7) != 0);
                else if (col < winwidth) {
-                       if (ch < ' ' || ch == 0x7f) {
+                       if (ISCTRL(ch) && /* but not C1 */ ch < 0x80) {
                                *twb1++ = '^';
                                if (++col < winwidth) {
-                                       *twb1++ = ch ^ '@';
+                                       *twb1++ = UNCTRL(ch);
                                        col++;
                                }
                        } else {
@@ -5433,9 +5425,9 @@ print_expansions(struct edstate *est, int cmd MKSH_A_UNUSED)
 static void
 x_vi_zotc(int c)
 {
-       if (c < ' ' || c == 0x7f) {
+       if (ISCTRL(c)) {
                x_putc('^');
-               c ^= '@';
+               c = UNCTRL(c);
        }
        x_putc(c);
 }
index b6ff1dc..62a2fad 100644 (file)
@@ -1,8 +1,8 @@
-/*     $OpenBSD: eval.c,v 1.39 2013/07/01 17:25:27 jca Exp $   */
+/*     $OpenBSD: eval.c,v 1.40 2013/09/14 20:09:30 millert Exp $       */
 
 /*-
  * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
- *              2011, 2012, 2013
+ *              2011, 2012, 2013, 2014
  *     Thorsten Glaser <tg@mirbsd.org>
  *
  * Provided that these terms and disclaimer and all copyright notices
@@ -23,7 +23,7 @@
 
 #include "sh.h"
 
-__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.142 2013/07/24 18:03:57 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.150 2014/06/09 11:16:07 tg Exp $");
 
 /*
  * string expansion
@@ -74,7 +74,7 @@ static const char *maybe_expand_tilde(const char *, XString *, char **, int);
 static char *homedir(char *);
 #endif
 static void alt_expand(XPtrV *, char *, char *, char *, int);
-static int utflen(const char *);
+static int utflen(const char *) MKSH_A_PURE;
 static void utfincptr(const char *, mksh_ari_t *);
 
 /* UTFMODE functions */
@@ -324,9 +324,9 @@ expand(
                                }
                                continue;
                        case EXPRSUB:
-                               word = IFS_WORD;
                                tilde_ok = 0;
                                if (f & DONTRUNCOMMAND) {
+                                       word = IFS_WORD;
                                        *dp++ = '$'; *dp++ = '('; *dp++ = '(';
                                        while (*sp != '\0') {
                                                Xcheck(ds, dp);
@@ -343,11 +343,10 @@ expand(
                                        v_evaluate(&v, substitute(sp, 0),
                                            KSH_UNWIND_ERROR, true);
                                        sp = strnul(sp) + 1;
-                                       cp = str_val(&v);
-                                       while (*cp) {
-                                               Xcheck(ds, dp);
-                                               *dp++ = *cp++;
-                                       }
+                                       x.str = str_val(&v);
+                                       type = XSUB;
+                                       if (f & DOBLANK)
+                                               doblank++;
                                }
                                continue;
                        case OSUBST: {
@@ -412,27 +411,10 @@ expand(
                                        if (stype)
                                                sp += slen;
                                        switch (stype & 0x17F) {
-                                       case 0x100 | '#': {
-                                               char *beg, *end;
-                                               mksh_ari_t seed;
-                                               register uint32_t h;
-
-                                               beg = wdcopy(sp, ATEMP);
-                                               end = beg + (wdscan(sp, CSUBST) - sp);
-                                               end[-2] = EOS;
-                                               end = wdstrip(beg, 0);
-                                               afree(beg, ATEMP);
-                                               evaluate(substitute(end, 0),
-                                                   &seed, KSH_UNWIND_ERROR, true);
-                                               /* hash with seed, for now */
-                                               h = seed;
-                                               NZATUpdateString(h,
-                                                   str_val(st->var));
-                                               NZAATFinish(h);
+                                       case 0x100 | '#':
                                                x.str = shf_smprintf("%08X",
-                                                   (unsigned int)h);
+                                                   (unsigned int)hash(str_val(st->var)));
                                                break;
-                                       }
                                        case 0x100 | 'Q': {
                                                struct shf shf;
 
@@ -700,7 +682,7 @@ expand(
                                *dp = '\0';
                                quote = st->quotep;
                                f = st->f;
-                               if (f&DOBLANK)
+                               if (f & DOBLANK)
                                        doblank--;
                                switch (st->stype & 0x17F) {
                                case '#':
@@ -719,11 +701,12 @@ expand(
                                         */
                                        x.str = trimsub(str_val(st->var),
                                                dp, st->stype);
-                                       if (x.str[0] != '\0' || st->quotep)
+                                       if (x.str[0] != '\0') {
+                                               word = IFS_WS;
                                                type = XSUB;
-                                       else
-                                               type = XNULLSUB;
-                                       if (f&DOBLANK)
+                                       else
+                                               type = quote ? XSUB : XNULLSUB;
+                                       if (f & DOBLANK)
                                                doblank++;
                                        st = st->prev;
                                        continue;
@@ -755,7 +738,7 @@ expand(
                                            dp, len), KSH_UNWIND_ERROR);
                                        x.str = str_val(st->var);
                                        type = XSUB;
-                                       if (f&DOBLANK)
+                                       if (f & DOBLANK)
                                                doblank++;
                                        st = st->prev;
                                        continue;
@@ -773,7 +756,7 @@ expand(
                                case 0x100 | 'Q':
                                        dp = Xrestpos(ds, dp, st->base);
                                        type = XSUB;
-                                       if (f&DOBLANK)
+                                       if (f & DOBLANK)
                                                doblank++;
                                        st = st->prev;
                                        continue;
@@ -810,12 +793,14 @@ expand(
                         * other stuff inside the quotes).
                         */
                        type = XBASE;
-                       if (f&DOBLANK) {
+                       if (f & DOBLANK) {
                                doblank--;
                                /*
-                                * not really correct: x=; "$x$@" should
-                                * generate a null argument and
-                                * set A; "${@:+}" shouldn't.
+                                * XXX not really correct:
+                                *      x=; "$x$@"
+                                * should generate a null argument and
+                                *      set A; "${@:+}"
+                                * shouldn't.
                                 */
                                if (dp == Xstring(ds, dp))
                                        word = IFS_WS;
@@ -826,7 +811,7 @@ expand(
                case XSUBMID:
                        if ((c = *x.str++) == 0) {
                                type = XBASE;
-                               if (f&DOBLANK)
+                               if (f & DOBLANK)
                                        doblank--;
                                continue;
                        }
@@ -847,7 +832,7 @@ expand(
                                        word = IFS_WORD;
                                if ((x.str = *x.u.strv++) == NULL) {
                                        type = XBASE;
-                                       if (f&DOBLANK)
+                                       if (f & DOBLANK)
                                                doblank--;
                                        continue;
                                }
@@ -896,7 +881,7 @@ expand(
                                if (x.split)
                                        subst_exstat = waitlast();
                                type = XBASE;
-                               if (f&DOBLANK)
+                               if (f & DOBLANK)
                                        doblank--;
                                continue;
                        }
@@ -1269,17 +1254,12 @@ varsub(Expand *xp, const char *sp, const char *word,
                        if (*sp == '!' && sp[1]) {
                                ++sp;
                                xp->var = global(sp);
-                               if (vstrchr(sp, '[')) {
-                                       if (xp->var->flag & ISSET)
-                                               xp->str = shf_smprintf("%lu",
-                                                   arrayindex(xp->var));
-                                       else
-                                               xp->str = null;
-                               } else if (xp->var->flag & ISSET)
-                                       xp->str = xp->var->name;
+                               if (vstrchr(sp, '['))
+                                       xp->str = shf_smprintf("%s[%lu]",
+                                           xp->var->name,
+                                           arrayindex(xp->var));
                                else
-                                       /* ksh93 compat */
-                                       xp->str = "0";
+                                       xp->str = xp->var->name;
                        } else {
                                xp->var = global(sp);
                                xp->str = str_val(xp->var);
index 50ec9ca..70ef83d 100644 (file)
@@ -2,7 +2,7 @@
 
 /*-
  * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
- *              2011, 2012, 2013
+ *              2011, 2012, 2013, 2014
  *     Thorsten Glaser <tg@mirbsd.org>
  *
  * Provided that these terms and disclaimer and all copyright notices
@@ -23,7 +23,7 @@
 
 #include "sh.h"
 
-__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.125 2013/07/21 20:44:44 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.132 2014/06/24 18:38:31 tg Exp $");
 
 #ifndef MKSH_DEFAULT_EXECSHELL
 #define MKSH_DEFAULT_EXECSHELL "/bin/sh"
@@ -462,7 +462,7 @@ execute(struct op * volatile t,
        if (vp_pipest->flag & INT_L) {
                unset(vp_pipest, 1);
                vp_pipest->flag = DEFINED | ISSET | INTEGER | RDONLY |
-                   ARRAY | INT_U;
+                   ARRAY | INT_U | INT_L;
                vp_pipest->val.i = rv;
        }
 
@@ -604,19 +604,15 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap,
                                /* go on, use the builtin */
                                break;
 #endif
-#if !defined(MKSH_SMALL)
                } else if (tp->val.f == c_trap) {
                        t->u.evalflags &= ~DOTCOMEXEC;
                        break;
-#endif
                } else
                        break;
                tp = findcom(ap[0], fcflags & (FC_BI|FC_FUNC));
        }
-#if !defined(MKSH_SMALL)
        if (t->u.evalflags & DOTCOMEXEC)
                flags |= XEXEC;
-#endif
        l_expand = e->loc;
        if (keepasn_ok && (!ap[0] || (tp && (tp->flag & KEEPASN))))
                type_flags = 0;
@@ -656,7 +652,7 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap,
                /* but assign in there as usual */
                typeset(cp, type_flags, 0, 0, 0);
                if (bourne_function_call && !(type_flags & EXPORT))
-                       typeset(cp, LOCAL|LOCAL_COPY|EXPORT, 0, 0, 0);
+                       typeset(cp, LOCAL | LOCAL_COPY | EXPORT, 0, 0, 0);
        }
 
        if (Flag(FXTRACE)) {
@@ -816,7 +812,7 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap,
 
                /* set $_ to programme's full path */
                /* setstr() can't fail here */
-               setstr(typeset("_", LOCAL|EXPORT, 0, INTEGER, 0),
+               setstr(typeset("_", LOCAL | EXPORT, 0, INTEGER, 0),
                    tp->val.s, KSH_RETURN_ERROR);
 
                if (flags&XEXEC) {
@@ -869,7 +865,7 @@ scriptexec(struct op *tp, const char **ap)
        *tp->args-- = tp->str;
 
 #ifndef MKSH_SMALL
-       if ((fd = open(tp->str, O_RDONLY)) >= 0) {
+       if ((fd = open(tp->str, O_RDONLY | O_BINARY)) >= 0) {
                /* read first MAXINTERP octets from file */
                if (read(fd, buf, sizeof(buf)) <= 0)
                        /* read error -> no good */
@@ -884,14 +880,14 @@ scriptexec(struct op *tp, const char **ap)
                fd = (char *)cp - buf;          /* either 0 or (if BOM) 3 */
 
                /* scan for newline (or CR) or NUL _before_ end of buffer */
-               while ((char *)cp < (buf + sizeof(buf)))
+               while ((size_t)((char *)cp - buf) < sizeof(buf))
                        if (*cp == '\0' || *cp == '\n' || *cp == '\r') {
                                *cp = '\0';
                                break;
                        } else
                                ++cp;
                /* if the shebang line is longer than MAXINTERP, bail out */
-               if ((char *)cp >= (buf + sizeof(buf)))
+               if ((size_t)((char *)cp - buf) >= sizeof(buf))
                        goto noshebang;
 
                /* restore begin of shebang position (buf+0 or buf+3) */
@@ -923,6 +919,10 @@ scriptexec(struct op *tp, const char **ap)
                                *tp->args-- = (char *)cp;
                }
  noshebang:
+               if (buf[0] == 0x7F && buf[1] == 'E' && buf[2] == 'L' &&
+                   buf[3] == 'F')
+                       errorf("%s: not executable: %d-bit ELF file", tp->str,
+                           32 * ((uint8_t)buf[4]));
                fd = buf[0] << 8 | buf[1];
                if ((fd == /* OMAGIC */ 0407) ||
                    (fd == /* NMAGIC */ 0410) ||
@@ -931,7 +931,6 @@ scriptexec(struct op *tp, const char **ap)
                    (fd == /* ECOFF_I386 */ 0x4C01) ||
                    (fd == /* ECOFF_M68K */ 0x0150 || fd == 0x5001) ||
                    (fd == /* ECOFF_SH */   0x0500 || fd == 0x0005) ||
-                   (fd == 0x7F45 && buf[2] == 'L' && buf[3] == 'F') ||
                    (fd == /* "MZ" */ 0x4D5A) ||
                    (fd == /* gzip */ 0x1F8B))
                        errorf("%s: not executable: magic %04X", tp->str, fd);
@@ -1374,7 +1373,7 @@ iosetup(struct ioword *iop, struct tbl *tp)
                        warningf(true, "%s: %s", cp, "restricted");
                        return (-1);
                }
-               u = open(cp, flags, 0666);
+               u = open(cp, flags | O_BINARY, 0666);
        }
        if (u < 0) {
                /* herein() may already have printed message */
@@ -1507,7 +1506,7 @@ herein(struct ioword *iop, char **resbuf)
         * so temp doesn't get removed too soon).
         */
        h = maketemp(ATEMP, TT_HEREDOC_EXP, &e->temps);
-       if (!(shf = h->shf) || (fd = open(h->tffn, O_RDONLY, 0)) < 0) {
+       if (!(shf = h->shf) || (fd = open(h->tffn, O_RDONLY | O_BINARY, 0)) < 0) {
                i = errno;
                warningf(true, "can't %s temporary file %s: %s",
                    !shf ? "create" : "open", h->tffn, cstrerror(i));
@@ -1669,7 +1668,7 @@ static Test_op
 dbteste_isa(Test_env *te, Test_meta meta)
 {
        Test_op ret = TO_NONOP;
-       int uqword;
+       bool uqword;
        const char *p;
 
        if (!*te->pos.wp)
index e91c0da..057666e 100644 (file)
@@ -1,8 +1,8 @@
-/*     $OpenBSD: expr.c,v 1.22 2013/03/28 08:39:28 nicm Exp $  */
+/*     $OpenBSD: expr.c,v 1.23 2013/12/17 16:37:06 deraadt Exp $       */
 
 /*-
  * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
- *              2011, 2012, 2013
+ *              2011, 2012, 2013, 2014
  *     Thorsten Glaser <tg@mirbsd.org>
  *
  * Provided that these terms and disclaimer and all copyright notices
@@ -23,7 +23,7 @@
 
 #include "sh.h"
 
-__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.72 2013/07/21 18:38:56 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.76 2014/06/24 19:53:19 tg Exp $");
 
 /* the order of these enums is constrained by the order of opinfo[] */
 enum token {
@@ -916,8 +916,7 @@ ksh_access(const char *fn, int mode)
        return (rv);
 }
 
-#ifndef MKSH_mirbsd_wcwidth
-/* From: X11/xc/programs/xterm/wcwidth.c,v 1.6 2013/05/31 23:27:09 tg Exp $ */
+/* From: X11/xc/programs/xterm/wcwidth.c,v 1.8 2014/06/24 19:53:53 tg Exp $ */
 
 struct mb_ucsrange {
        unsigned short beg;
@@ -925,11 +924,11 @@ struct mb_ucsrange {
 };
 
 static int mb_ucsbsearch(const struct mb_ucsrange arr[], size_t elems,
-    unsigned int val);
+    unsigned int val) MKSH_A_PURE;
 
 /*
- * Generated by MirOS: contrib/code/Snippets/eawparse,v 1.1 2013/05/31 23:27:16 tg Exp $
- * from Unicode 6.2.0
+ * Generated by MirOS: contrib/code/Snippets/eawparse,v 1.2 2013/11/30 13:45:17 tg Exp $
+ * from the Unicode Character Database, Version 7.0.0
  */
 
 static const struct mb_ucsrange mb_ucs_combining[] = {
@@ -940,8 +939,9 @@ static const struct mb_ucsrange mb_ucs_combining[] = {
        { 0x05C1, 0x05C2 },
        { 0x05C4, 0x05C5 },
        { 0x05C7, 0x05C7 },
-       { 0x0600, 0x0604 },
+       { 0x0600, 0x0605 },
        { 0x0610, 0x061A },
+       { 0x061C, 0x061C },
        { 0x064B, 0x065F },
        { 0x0670, 0x0670 },
        { 0x06D6, 0x06DD },
@@ -958,8 +958,7 @@ static const struct mb_ucsrange mb_ucs_combining[] = {
        { 0x0825, 0x0827 },
        { 0x0829, 0x082D },
        { 0x0859, 0x085B },
-       { 0x08E4, 0x08FE },
-       { 0x0900, 0x0902 },
+       { 0x08E4, 0x0902 },
        { 0x093A, 0x093A },
        { 0x093C, 0x093C },
        { 0x0941, 0x0948 },
@@ -995,16 +994,19 @@ static const struct mb_ucsrange mb_ucs_combining[] = {
        { 0x0B82, 0x0B82 },
        { 0x0BC0, 0x0BC0 },
        { 0x0BCD, 0x0BCD },
+       { 0x0C00, 0x0C00 },
        { 0x0C3E, 0x0C40 },
        { 0x0C46, 0x0C48 },
        { 0x0C4A, 0x0C4D },
        { 0x0C55, 0x0C56 },
        { 0x0C62, 0x0C63 },
+       { 0x0C81, 0x0C81 },
        { 0x0CBC, 0x0CBC },
        { 0x0CBF, 0x0CBF },
        { 0x0CC6, 0x0CC6 },
        { 0x0CCC, 0x0CCD },
        { 0x0CE2, 0x0CE3 },
+       { 0x0D01, 0x0D01 },
        { 0x0D41, 0x0D44 },
        { 0x0D4D, 0x0D4D },
        { 0x0D62, 0x0D63 },
@@ -1050,13 +1052,14 @@ static const struct mb_ucsrange mb_ucs_combining[] = {
        { 0x17C6, 0x17C6 },
        { 0x17C9, 0x17D3 },
        { 0x17DD, 0x17DD },
-       { 0x180B, 0x180D },
+       { 0x180B, 0x180E },
        { 0x18A9, 0x18A9 },
        { 0x1920, 0x1922 },
        { 0x1927, 0x1928 },
        { 0x1932, 0x1932 },
        { 0x1939, 0x193B },
        { 0x1A17, 0x1A18 },
+       { 0x1A1B, 0x1A1B },
        { 0x1A56, 0x1A56 },
        { 0x1A58, 0x1A5E },
        { 0x1A60, 0x1A60 },
@@ -1064,6 +1067,7 @@ static const struct mb_ucsrange mb_ucs_combining[] = {
        { 0x1A65, 0x1A6C },
        { 0x1A73, 0x1A7C },
        { 0x1A7F, 0x1A7F },
+       { 0x1AB0, 0x1ABE },
        { 0x1B00, 0x1B03 },
        { 0x1B34, 0x1B34 },
        { 0x1B36, 0x1B3A },
@@ -1073,7 +1077,7 @@ static const struct mb_ucsrange mb_ucs_combining[] = {
        { 0x1B80, 0x1B81 },
        { 0x1BA2, 0x1BA5 },
        { 0x1BA8, 0x1BA9 },
-       { 0x1BAB, 0x1BAB },
+       { 0x1BAB, 0x1BAD },
        { 0x1BE6, 0x1BE6 },
        { 0x1BE8, 0x1BE9 },
        { 0x1BED, 0x1BED },
@@ -1085,12 +1089,13 @@ static const struct mb_ucsrange mb_ucs_combining[] = {
        { 0x1CE2, 0x1CE8 },
        { 0x1CED, 0x1CED },
        { 0x1CF4, 0x1CF4 },
-       { 0x1DC0, 0x1DE6 },
+       { 0x1CF8, 0x1CF9 },
+       { 0x1DC0, 0x1DF5 },
        { 0x1DFC, 0x1DFF },
        { 0x200B, 0x200F },
        { 0x202A, 0x202E },
        { 0x2060, 0x2064 },
-       { 0x206A, 0x206F },
+       { 0x2066, 0x206F },
        { 0x20D0, 0x20F0 },
        { 0x2CEF, 0x2CF1 },
        { 0x2D7F, 0x2D7F },
@@ -1113,11 +1118,13 @@ static const struct mb_ucsrange mb_ucs_combining[] = {
        { 0xA9B3, 0xA9B3 },
        { 0xA9B6, 0xA9B9 },
        { 0xA9BC, 0xA9BC },
+       { 0xA9E5, 0xA9E5 },
        { 0xAA29, 0xAA2E },
        { 0xAA31, 0xAA32 },
        { 0xAA35, 0xAA36 },
        { 0xAA43, 0xAA43 },
        { 0xAA4C, 0xAA4C },
+       { 0xAA7C, 0xAA7C },
        { 0xAAB0, 0xAAB0 },
        { 0xAAB2, 0xAAB4 },
        { 0xAAB7, 0xAAB8 },
@@ -1130,7 +1137,7 @@ static const struct mb_ucsrange mb_ucs_combining[] = {
        { 0xABED, 0xABED },
        { 0xFB1E, 0xFB1E },
        { 0xFE00, 0xFE0F },
-       { 0xFE20, 0xFE26 },
+       { 0xFE20, 0xFE2D },
        { 0xFEFF, 0xFEFF },
        { 0xFFF9, 0xFFFB }
 };
@@ -1188,4 +1195,3 @@ utf_wcwidth(unsigned int wc)
                return (2);
        return (1);
 }
-#endif
index 53ab789..77d9494 100644 (file)
@@ -1,11 +1,11 @@
-/*     $OpenBSD: c_ksh.c,v 1.33 2009/02/07 14:03:24 kili Exp $ */
-/*     $OpenBSD: c_sh.c,v 1.43 2013/04/19 17:39:45 deraadt Exp $       */
+/*     $OpenBSD: c_ksh.c,v 1.34 2013/12/17 16:37:05 deraadt Exp $      */
+/*     $OpenBSD: c_sh.c,v 1.44 2013/09/04 15:49:18 millert Exp $       */
 /*     $OpenBSD: c_test.c,v 1.18 2009/03/01 20:11:06 otto Exp $        */
-/*     $OpenBSD: c_ulimit.c,v 1.17 2008/03/21 12:51:19 millert Exp $   */
+/*     $OpenBSD: c_ulimit.c,v 1.19 2013/11/28 10:33:37 sobrado Exp $   */
 
 /*-
  * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
- *              2010, 2011, 2012, 2013
+ *              2010, 2011, 2012, 2013, 2014
  *     Thorsten Glaser <tg@mirbsd.org>
  *
  * Provided that these terms and disclaimer and all copyright notices
@@ -38,7 +38,7 @@
 #endif
 #endif
 
-__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.244 2013/06/03 22:28:32 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.256 2014/06/09 13:25:52 tg Exp $");
 
 #if HAVE_KILLPG
 /*
@@ -60,6 +60,10 @@ __RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.244 2013/06/03 22:28:32 tg Exp $");
 #define c_ulimit       c_true
 #endif
 
+#if !defined(MKSH_UNEMPLOYED) && HAVE_GETSID
+static int c_suspend(const char **);
+#endif
+
 /* getn() that prints error */
 static int
 bi_getn(const char *as, int *ai)
@@ -123,6 +127,9 @@ const struct builtin mkshbuiltins[] = {
        {"*=return", c_exitreturn},
        {Tsgset, c_set},
        {"*=shift", c_shift},
+#if !defined(MKSH_UNEMPLOYED) && HAVE_GETSID
+       {"suspend", c_suspend},
+#endif
        {"test", c_test},
        {"*=times", c_times},
        {"*=trap", c_trap},
@@ -641,6 +648,7 @@ c_typeset(const char **wp)
        const char *opts;
        const char *fieldstr = NULL, *basestr = NULL;
        bool localv = false, func = false, pflag = false, istset = true;
+       enum namerefflag new_refflag = SRF_NOP;
 
        switch (**wp) {
 
@@ -721,7 +729,7 @@ c_typeset(const char **wp)
                        flag = LCASEV;
                        break;
                case 'n':
-                       set_refflag = (builtin_opt.info & GI_PLUS) ?
+                       new_refflag = (builtin_opt.info & GI_PLUS) ?
                            SRF_DISABLE : SRF_ENABLE;
                        break;
                /* export, readonly: POSIX -p flag */
@@ -745,8 +753,6 @@ c_typeset(const char **wp)
                        flag = EXPORT;
                        break;
                case '?':
- errout:
-                       set_refflag = SRF_NOP;
                        return (1);
                }
                if (builtin_opt.info & GI_PLUS) {
@@ -761,10 +767,10 @@ c_typeset(const char **wp)
        }
 
        if (fieldstr && !bi_getn(fieldstr, &field))
-               goto errout;
+               return (1);
        if (basestr && (!bi_getn(basestr, &base) || base < 1 || base > 36)) {
                bi_errorf("%s: %s", "bad integer base", basestr);
-               goto errout;
+               return (1);
        }
 
        if (!(builtin_opt.info & GI_MINUSMINUS) && wp[builtin_opt.optind] &&
@@ -776,9 +782,9 @@ c_typeset(const char **wp)
        }
 
        if (func && (((fset|fclr) & ~(TRACE|UCASEV_AL|EXPORT)) ||
-           set_refflag != SRF_NOP)) {
+           new_refflag != SRF_NOP)) {
                bi_errorf("only -t, -u and -x options may be used with -f");
-               goto errout;
+               return (1);
        }
        if (wp[builtin_opt.optind]) {
                /*
@@ -802,10 +808,18 @@ c_typeset(const char **wp)
                 * are also set in this command
                 */
                if ((fset & (LJUST | RJUST | ZEROFIL | UCASEV_AL | LCASEV |
-                   INTEGER | INT_U | INT_L)) || set_refflag != SRF_NOP)
+                   INTEGER | INT_U | INT_L)) || new_refflag != SRF_NOP)
                        fclr |= ~fset & (LJUST | RJUST | ZEROFIL | UCASEV_AL |
                            LCASEV | INTEGER | INT_U | INT_L);
        }
+       if (new_refflag != SRF_NOP) {
+               fclr &= ~(ARRAY | ASSOC);
+               fset &= ~(ARRAY | ASSOC);
+               fclr |= EXPORT;
+               fset |= ASSOC;
+               if (new_refflag == SRF_DISABLE)
+                       fclr |= ASSOC;
+       }
 
        /* set variables and attributes */
        if (wp[builtin_opt.optind] &&
@@ -836,14 +850,12 @@ c_typeset(const char **wp)
                                }
                        } else if (!typeset(wp[i], fset, fclr, field, base)) {
                                bi_errorf("%s: %s", wp[i], "is not an identifier");
-                               goto errout;
+                               return (1);
                        }
                }
-               set_refflag = SRF_NOP;
                return (rv);
        }
 
-       set_refflag = SRF_NOP;
        /* list variables and attributes */
 
        /* no difference at this point.. */
@@ -1345,8 +1357,10 @@ c_kill(const char **wp)
                        for (; wp[i]; i++) {
                                if (!bi_getn(wp[i], &n))
                                        return (1);
+#if (NSIG < 128)
                                if (n > 128 && n < 128 + NSIG)
                                        n -= 128;
+#endif
                                if (n > 0 && n < NSIG)
                                        shprintf("%s\n", sigtraps[n].name);
                                else
@@ -3333,16 +3347,6 @@ ptest_error(Test_env *te, int ofs, const char *msg)
 #define SOFT   0x1
 #define HARD   0x2
 
-struct limits {
-       const char *name;
-       int resource;           /* resource to get/set */
-       unsigned int factor;    /* multiply by to get rlim_{cur,max} values */
-       char option;
-};
-
-static void print_ulimit(const struct limits *, int);
-static int set_ulimit(const struct limits *, const char *, int);
-
 /* Magic to divine the 'm' and 'v' limits */
 
 #ifdef RLIMIT_AS
@@ -3385,165 +3389,38 @@ static int set_ulimit(const struct limits *, const char *, int);
 #undef ULIMIT_M_IS_VMEM
 #endif
 
+#if defined(ULIMIT_M_IS_RSS) && defined(ULIMIT_M_IS_VMEM)
+# error nonsensical m ulimit
+#endif
+
+#if defined(ULIMIT_V_IS_VMEM) && defined(ULIMIT_V_IS_AS)
+# error nonsensical v ulimit
+#endif
+
+#define RLIMITS_DEFNS
+#include "rlimits.gen"
+
+static void print_ulimit(const struct limits *, int);
+static int set_ulimit(const struct limits *, const char *, int);
+
+static const struct limits * const rlimits[] = {
+#define RLIMITS_ITEMS
+#include "rlimits.gen"
+};
+
+static const char rlimits_opts[] =
+#define RLIMITS_OPTCS
+#include "rlimits.gen"
+    ;
 
 int
 c_ulimit(const char **wp)
 {
-       static const struct limits limits[] = {
-               /* do not use options -H, -S or -a or change the order */
-#ifdef RLIMIT_CPU
-               { "time(cpu-seconds)", RLIMIT_CPU, 1, 't' },
-#endif
-#ifdef RLIMIT_FSIZE
-               { "file(blocks)", RLIMIT_FSIZE, 512, 'f' },
-#endif
-#ifdef RLIMIT_CORE
-               { "coredump(blocks)", RLIMIT_CORE, 512, 'c' },
-#endif
-#ifdef RLIMIT_DATA
-               { "data(KiB)", RLIMIT_DATA, 1024, 'd' },
-#endif
-#ifdef RLIMIT_STACK
-               { "stack(KiB)", RLIMIT_STACK, 1024, 's' },
-#endif
-#ifdef RLIMIT_MEMLOCK
-               { "lockedmem(KiB)", RLIMIT_MEMLOCK, 1024, 'l' },
-#endif
-#ifdef RLIMIT_NOFILE
-               { "nofiles(descriptors)", RLIMIT_NOFILE, 1, 'n' },
-#endif
-#ifdef RLIMIT_NPROC
-               { "processes", RLIMIT_NPROC, 1, 'p' },
-#endif
-#ifdef RLIMIT_SWAP
-               { "swap(KiB)", RLIMIT_SWAP, 1024, 'w' },
-#endif
-#ifdef RLIMIT_LOCKS
-               { "flocks", RLIMIT_LOCKS, -1, 'L' },
-#endif
-#ifdef RLIMIT_TIME
-               { "humantime(seconds)", RLIMIT_TIME, 1, 'T' },
-#endif
-#ifdef RLIMIT_NOVMON
-               { "vnodemonitors", RLIMIT_NOVMON, 1, 'V' },
-#endif
-#ifdef RLIMIT_SIGPENDING
-               { "sigpending", RLIMIT_SIGPENDING, 1, 'i' },
-#endif
-#ifdef RLIMIT_MSGQUEUE
-               { "msgqueue(bytes)", RLIMIT_MSGQUEUE, 1, 'q' },
-#endif
-#ifdef RLIMIT_AIO_MEM
-               { "AIOlockedmem(KiB)", RLIMIT_AIO_MEM, 1024, 'M' },
-#endif
-#ifdef RLIMIT_AIO_OPS
-               { "AIOoperations", RLIMIT_AIO_OPS, 1, 'O' },
-#endif
-#ifdef RLIMIT_TCACHE
-               { "cachedthreads", RLIMIT_TCACHE, 1, 'C' },
-#endif
-#ifdef RLIMIT_SBSIZE
-               { "sockbufsiz(KiB)", RLIMIT_SBSIZE, 1024, 'B' },
-#endif
-#ifdef RLIMIT_PTHREAD
-               { "threadsperprocess", RLIMIT_PTHREAD, 1, 'P' },
-#endif
-#ifdef RLIMIT_NICE
-               { "maxnice", RLIMIT_NICE, 1, 'e' },
-#endif
-#ifdef RLIMIT_RTPRIO
-               { "maxrtprio", RLIMIT_RTPRIO, 1, 'r' },
-#endif
-#if defined(ULIMIT_M_IS_RSS)
-               { "resident-set(KiB)", RLIMIT_RSS, 1024, 'm' },
-#elif defined(ULIMIT_M_IS_VMEM)
-               { "memory(KiB)", RLIMIT_VMEM, 1024, 'm' },
-#endif
-#if defined(ULIMIT_V_IS_VMEM)
-               { "virtual-memory(KiB)", RLIMIT_VMEM, 1024, 'v' },
-#elif defined(ULIMIT_V_IS_AS)
-               { "address-space(KiB)", RLIMIT_AS, 1024, 'v' },
-#endif
-               { NULL, 0, 0, 0 }
-       };
-       static const char opts[] = "a"
-#ifdef RLIMIT_SBSIZE
-           "B"
-#endif
-#ifdef RLIMIT_TCACHE
-           "C"
-#endif
-#ifdef RLIMIT_CORE
-           "c"
-#endif
-#ifdef RLIMIT_DATA
-           "d"
-#endif
-#ifdef RLIMIT_NICE
-           "e"
-#endif
-#ifdef RLIMIT_FSIZE
-           "f"
-#endif
-           "H"
-#ifdef RLIMIT_SIGPENDING
-           "i"
-#endif
-#ifdef RLIMIT_LOCKS
-           "L"
-#endif
-#ifdef RLIMIT_MEMLOCK
-           "l"
-#endif
-#ifdef RLIMIT_AIO_MEM
-           "M"
-#endif
-#if defined(ULIMIT_M_IS_RSS) || defined(ULIMIT_M_IS_VMEM)
-           "m"
-#endif
-#ifdef RLIMIT_NOFILE
-           "n"
-#endif
-#ifdef RLIMIT_AIO_OPS
-           "O"
-#endif
-#ifdef RLIMIT_PTHREAD
-           "P"
-#endif
-#ifdef RLIMIT_NPROC
-           "p"
-#endif
-#ifdef RLIMIT_MSGQUEUE
-           "q"
-#endif
-#ifdef RLIMIT_RTPRIO
-           "r"
-#endif
-           "S"
-#ifdef RLIMIT_STACK
-           "s"
-#endif
-#ifdef RLIMIT_TIME
-           "T"
-#endif
-#ifdef RLIMIT_CPU
-           "t"
-#endif
-#ifdef RLIMIT_NOVMON
-           "V"
-#endif
-#if defined(ULIMIT_V_IS_VMEM) || defined(ULIMIT_V_IS_AS)
-           "v"
-#endif
-#ifdef RLIMIT_SWAP
-           "w"
-#endif
-           ;
+       size_t i = 0;
        int how = SOFT | HARD, optc, what = 'f';
        bool all = false;
-       const struct limits *l;
 
-       while ((optc = ksh_getopt(wp, &builtin_opt, opts)) != -1)
+       while ((optc = ksh_getopt(wp, &builtin_opt, rlimits_opts)) != -1)
                switch (optc) {
                case 'H':
                        how = HARD;
@@ -3555,31 +3432,32 @@ c_ulimit(const char **wp)
                        all = true;
                        break;
                case '?':
-                       bi_errorf("usage: ulimit [-%s] [value]", opts);
+                       bi_errorf("usage: ulimit [-%s] [value]", rlimits_opts);
                        return (1);
                default:
                        what = optc;
                }
 
-       for (l = limits; l->name && l->option != what; l++)
-               ;
-       if (!l->name) {
-               internal_warningf("ulimit: %c", what);
-               return (1);
+       while (i < NELEM(rlimits)) {
+               if (rlimits[i]->optchar == what)
+                       goto found;
+               ++i;
        }
-
+       internal_warningf("ulimit: %c", what);
+       return (1);
+ found:
        if (wp[builtin_opt.optind]) {
                if (all || wp[builtin_opt.optind + 1]) {
                        bi_errorf("too many arguments");
                        return (1);
                }
-               return (set_ulimit(l, wp[builtin_opt.optind], how));
+               return (set_ulimit(rlimits[i], wp[builtin_opt.optind], how));
        }
        if (!all)
-               print_ulimit(l, how);
-       else for (l = limits; l->name; l++) {
-               shprintf("%-20s ", l->name);
-               print_ulimit(l, how);
+               print_ulimit(rlimits[i], how);
+       else for (i = 0; i < NELEM(rlimits); ++i) {
+               shprintf("%-20s ", rlimits[i]->name);
+               print_ulimit(rlimits[i], how);
        }
        return (0);
 }
@@ -3611,7 +3489,11 @@ set_ulimit(const struct limits *l, const char *v, int how)
        }
 
        if (getrlimit(l->resource, &limit) < 0) {
-               /* some can't be read, e.g. Linux RLIMIT_LOCKS */
+#ifndef MKSH_SMALL
+               bi_errorf("limit %s could not be read, contact the mksh developers: %s",
+                   l->name, cstrerror(errno));
+#endif
+               /* some can't be read */
                limit.rlim_cur = RLIM_INFINITY;
                limit.rlim_max = RLIM_INFINITY;
        }
@@ -3735,7 +3617,7 @@ c_cat(const char **wp)
                        fn = *wp++;
                        if (fn[0] == '-' && fn[1] == '\0')
                                fd = STDIN_FILENO;
-                       else if ((fd = open(fn, O_RDONLY)) < 0) {
+                       else if ((fd = open(fn, O_RDONLY | O_BINARY)) < 0) {
                                eno = errno;
                                bi_errorf("%s: %s", fn, cstrerror(eno));
                                rv = 1;
@@ -3761,14 +3643,12 @@ c_cat(const char **wp)
                                break;
                        while (n) {
                                w = write(STDOUT_FILENO, cp, n);
-                               eno = errno;
-                               /* give the user a chance to ^C out */
-                               intrcheck();
                                if (w == -1) {
-                                       if (eno == EINTR)
+                                       if (errno == EINTR)
                                                /* interrupted, try again */
                                                continue;
                                        /* an error occured during writing */
+                                       eno = errno;
                                        bi_errorf("%s: %s", "<stdout>",
                                            cstrerror(eno));
                                        rv = 1;
@@ -3844,3 +3724,24 @@ c_sleep(const char **wp)
        return (rv);
 }
 #endif
+
+#if !defined(MKSH_UNEMPLOYED) && HAVE_GETSID
+static int
+c_suspend(const char **wp)
+{
+       if (wp[1] != NULL) {
+               bi_errorf("too many arguments");
+               return (1);
+       }
+       if (Flag(FLOGIN)) {
+               /* Can't suspend an orphaned process group. */
+               if (getpgid(kshppid) == getpgid(0) ||
+                   getsid(kshppid) != getsid(0)) {
+                       bi_errorf("can't suspend a login shell");
+                       return (1);
+               }
+       }
+       j_suspend();
+       return (0);
+}
+#endif
index 3b28f23..d15cc8d 100644 (file)
@@ -3,7 +3,7 @@
 
 /*-
  * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
- *              2011, 2012
+ *              2011, 2012, 2014
  *     Thorsten Glaser <tg@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.131 2012/12/28 02:28:35 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.134 2014/06/09 13:25:53 tg Exp $");
 
 Trap sigtraps[NSIG + 1];
 static struct sigaction Sigact_ign;
@@ -442,7 +442,7 @@ hist_get(const char *str, bool approx, bool allow_cur)
                        hp = NULL;
                }
        } else {
-               int anchored = *str == '?' ? (++str, 0) : 1;
+               bool anchored = *str == '?' ? (++str, false) : true;
 
                /* the -1 is to avoid the current fc command */
                if ((n = findhist(histptr - history - 1, 0, str, anchored)) < 0)
@@ -509,7 +509,7 @@ histnum(int n)
  * direction.
  */
 int
-findhist(int start, int fwd, const char *str, int anchored)
+findhist(int start, int fwd, const char *str, bool anchored)
 {
        char **hp;
        int maxhist = histptr - history;
@@ -720,7 +720,8 @@ hist_init(Source *s)
 
  retry:
        /* we have a file and are interactive */
-       if ((fd = open(hname, O_RDWR | O_CREAT | O_APPEND, 0600)) < 0)
+       if ((fd = open(hname, O_RDWR | O_CREAT | O_APPEND | O_BINARY,
+           0600)) < 0)
                return;
 
        histfd = savefd(fd);
@@ -756,7 +757,7 @@ hist_init(Source *s)
                        /* create temporary file */
                        nhname = shf_smprintf("%s.%d", hname, (int)procpid);
                        if ((fd = open(nhname, O_RDWR | O_CREAT | O_TRUNC |
-                           O_EXCL, 0600)) < 0) {
+                           O_EXCL | O_BINARY, 0600)) < 0) {
                                /* just don't truncate then, meh. */
                                goto hist_trunc_dont;
                        }
@@ -976,6 +977,7 @@ inittraps(void)
        trap_exstat = -1;
 
        /* Populate sigtraps based on sys_signame and sys_siglist. */
+       /*XXX this is idiotic, use a multi-key/value hashtable! */
        for (i = 0; i <= NSIG; i++) {
                sigtraps[i].signal = i;
                if (i == ksh_SIGERR) {
index 3277c78..0216a34 100644 (file)
@@ -1,8 +1,8 @@
-/*     $OpenBSD: jobs.c,v 1.39 2009/12/13 04:36:48 deraadt Exp $       */
+/*     $OpenBSD: jobs.c,v 1.40 2013/09/04 15:49:18 millert Exp $       */
 
 /*-
  * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011,
- *              2012, 2013
+ *              2012, 2013, 2014
  *     Thorsten Glaser <tg@mirbsd.org>
  *
  * Provided that these terms and disclaimer and all copyright notices
@@ -23,7 +23,7 @@
 
 #include "sh.h"
 
-__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.100 2013/07/26 20:33:23 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.104 2014/06/10 22:17:09 tg Exp $");
 
 #if HAVE_KILLPG
 #define mksh_killpg            killpg
@@ -225,6 +225,54 @@ proc_errorlevel(Proc *p)
        }
 }
 
+#if !defined(MKSH_UNEMPLOYED) && HAVE_GETSID
+/* suspend the shell */
+void
+j_suspend(void)
+{
+       struct sigaction sa, osa;
+
+       /* Restore tty and pgrp. */
+       if (ttypgrp_ok) {
+               if (tty_hasstate)
+                       mksh_tcset(tty_fd, &tty_state);
+               if (restore_ttypgrp >= 0) {
+                       if (tcsetpgrp(tty_fd, restore_ttypgrp) < 0) {
+                               warningf(false, "%s: %s %s: %s", "j_suspend",
+                                   "tcsetpgrp", "failed", cstrerror(errno));
+                       } else if (setpgid(0, restore_ttypgrp) < 0) {
+                               warningf(false, "%s: %s %s: %s", "j_suspend",
+                                   "setpgid", "failed", cstrerror(errno));
+                       }
+               }
+       }
+
+       /* Suspend the shell. */
+       memset(&sa, 0, sizeof(sa));
+       sigemptyset(&sa.sa_mask);
+       sa.sa_handler = SIG_DFL;
+       sigaction(SIGTSTP, &sa, &osa);
+       kill(0, SIGTSTP);
+
+       /* Back from suspend, reset signals, pgrp and tty. */
+       sigaction(SIGTSTP, &osa, NULL);
+       if (ttypgrp_ok) {
+               if (restore_ttypgrp >= 0) {
+                       if (setpgid(0, kshpid) < 0) {
+                               warningf(false, "%s: %s %s: %s", "j_suspend",
+                                   "setpgid", "failed", cstrerror(errno));
+                               ttypgrp_ok = false;
+                       } else if (tcsetpgrp(tty_fd, kshpid) < 0) {
+                               warningf(false, "%s: %s %s: %s", "j_suspend",
+                                   "tcsetpgrp", "failed", cstrerror(errno));
+                               ttypgrp_ok = false;
+                       }
+               }
+               tty_init_state();
+       }
+}
+#endif
+
 /* job cleanup before shell exit */
 void
 j_exit(void)
@@ -1222,6 +1270,15 @@ j_waitj(Job *j,
                                rv = vp->val.i;
                        p = p->next;
                }
+       } else if (Flag(FPIPEFAIL) && (j->proc_list != NULL)) {
+               Proc *p = j->proc_list;
+               int i;
+
+               while (p != NULL) {
+                       if ((i = proc_errorlevel(p)))
+                               rv = i;
+                       p = p->next;
+               }
        }
 
        if (!(flags & JW_ASYNCNOTIFY)
@@ -1281,7 +1338,11 @@ j_sigchld(int sig MKSH_A_UNUSED)
        getrusage(RUSAGE_CHILDREN, &ru0);
        do {
 #ifndef MKSH_NOPROSPECTOFWORK
-               pid = waitpid(-1, &status, (WNOHANG|WUNTRACED));
+               pid = waitpid(-1, &status, (WNOHANG |
+#ifdef WCONTINUED
+                   WCONTINUED |
+#endif
+                   WUNTRACED));
 #else
                pid = wait(&status);
 #endif
@@ -1320,6 +1381,13 @@ j_sigchld(int sig MKSH_A_UNUSED)
                if (WIFSTOPPED(status))
                        p->state = PSTOPPED;
                else
+#ifdef WIFCONTINUED
+                 if (WIFCONTINUED(status)) {
+                       p->state = j->state = PRUNNING;
+                       /* skip check_job(), no-op in this case */
+                       continue;
+               } else
+#endif
 #endif
                  if (WIFSIGNALED(status))
                        p->state = PSIGNALLED;
index e58d8b8..9d39998 100644 (file)
--- a/src/lex.c
+++ b/src/lex.c
@@ -1,8 +1,8 @@
-/*     $OpenBSD: lex.c,v 1.47 2013/03/03 19:11:34 guenther Exp $       */
+/*     $OpenBSD: lex.c,v 1.49 2013/12/17 16:37:06 deraadt Exp $        */
 
 /*-
  * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
- *              2011, 2012, 2013
+ *              2011, 2012, 2013, 2014
  *     Thorsten Glaser <tg@mirbsd.org>
  *
  * Provided that these terms and disclaimer and all copyright notices
@@ -23,7 +23,7 @@
 
 #include "sh.h"
 
-__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.188 2013/08/10 13:44:31 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.193 2014/06/29 11:28:28 tg Exp $");
 
 /*
  * states while lexing word
@@ -159,9 +159,10 @@ getsc_r(int c)
        state = statep->type;                                   \
 } while (/* CONSTCOND */ 0)
 
-#define PUSH_SRETRACE()        do {                                    \
+#define PUSH_SRETRACE(s) do {                                  \
        struct sretrace_info *ri;                               \
                                                                \
+       PUSH_STATE(s);                                          \
        statep->ls_start = Xsavepos(ws, wp);                    \
        ri = alloc(sizeof(struct sretrace_info), ATEMP);        \
        Xinit(ri->xs, ri->xp, 64, ATEMP);                       \
@@ -176,6 +177,7 @@ getsc_r(int c)
        dp = (void *)retrace_info;                              \
        retrace_info = retrace_info->next;                      \
        afree(dp, ATEMP);                                       \
+       POP_STATE();                                            \
 } while (/* CONSTCOND */ 0)
 
 /**
@@ -404,9 +406,8 @@ yylex(int cf)
                                        c = getsc();
                                        if (c == '(') /*)*/ {
                                                *wp++ = EXPRSUB;
-                                               PUSH_STATE(SASPAREN);
+                                               PUSH_SRETRACE(SASPAREN);
                                                statep->nparen = 2;
-                                               PUSH_SRETRACE();
                                                *retrace_info->xp++ = '(';
                                        } else {
                                                ungetsc(c);
@@ -650,7 +651,6 @@ yylex(int cf)
                                if (statep->nparen == 1) {
                                        /* end of EXPRSUB */
                                        POP_SRETRACE();
-                                       POP_STATE();
 
                                        if ((c2 = getsc()) == /*(*/ ')') {
                                                cz = strlen(sp) - 2;
@@ -833,8 +833,7 @@ yylex(int cf)
                                } else if (c2 == '"') {
                                        /* FALLTHROUGH */
                        case '"':
-                                       state = statep->type = SHEREDQUOTE;
-                                       PUSH_SRETRACE();
+                                       PUSH_SRETRACE(SHEREDQUOTE);
                                        break;
                                }
                                ungetsc(c2);
@@ -1440,6 +1439,7 @@ getsc_line(Source *s)
                alarm(0);
        }
        cp = Xstring(s->xs, xp);
+       rndpush(cp);
        s->start = s->str = cp;
        strip_nuls(Xstring(s->xs, xp), Xlength(s->xs, xp));
        /* Note: if input is all nulls, this is not eof */
@@ -1521,9 +1521,10 @@ set_prompt(int to, Source *s)
 int
 pprompt(const char *cp, int ntruncate)
 {
-       int columns = 0, lines = 0;
-       bool indelimit = false;
        char delimiter = 0;
+       bool doprint = (ntruncate != -1);
+       bool indelimit = false;
+       int columns = 0, lines = 0;
 
        /*
         * Undocumented AT&T ksh feature:
@@ -1552,18 +1553,19 @@ pprompt(const char *cp, int ntruncate)
                else if (UTFMODE && ((unsigned char)*cp > 0x7F)) {
                        const char *cp2;
                        columns += utf_widthadj(cp, &cp2);
-                       if (indelimit ||
-                           (ntruncate < (x_cols * lines + columns)))
+                       if (doprint && (indelimit ||
+                           (ntruncate < (x_cols * lines + columns))))
                                shf_write(cp, cp2 - cp, shl_out);
                        cp = cp2 - /* loop increment */ 1;
                        continue;
                } else
                        columns++;
-               if ((*cp != delimiter) &&
+               if (doprint && (*cp != delimiter) &&
                    (indelimit || (ntruncate < (x_cols * lines + columns))))
                        shf_putc(*cp, shl_out);
        }
-       shf_flush(shl_out);
+       if (doprint)
+               shf_flush(shl_out);
        return (x_cols * lines + columns);
 }
 
index 291ab40..cc49349 100644 (file)
@@ -1,11 +1,11 @@
-/*     $OpenBSD: main.c,v 1.52 2013/06/15 17:25:19 millert Exp $       */
+/*     $OpenBSD: main.c,v 1.54 2013/11/28 10:33:37 sobrado Exp $       */
 /*     $OpenBSD: tty.c,v 1.9 2006/03/14 22:08:01 deraadt Exp $ */
-/*     $OpenBSD: io.c,v 1.22 2006/03/17 16:30:13 millert Exp $ */
+/*     $OpenBSD: io.c,v 1.23 2013/12/17 16:37:06 deraadt Exp $ */
 /*     $OpenBSD: table.c,v 1.15 2012/02/19 07:52:30 otto Exp $ */
 
 /*-
  * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
- *              2011, 2012, 2013
+ *              2011, 2012, 2013, 2014
  *     Thorsten Glaser <tg@mirbsd.org>
  *
  * Provided that these terms and disclaimer and all copyright notices
@@ -34,7 +34,7 @@
 #include <locale.h>
 #endif
 
-__RCSID("$MirOS: src/bin/mksh/main.c,v 1.269 2013/07/25 18:07:46 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/main.c,v 1.280 2014/06/09 12:28:17 tg Exp $");
 
 extern char **environ;
 
@@ -48,7 +48,6 @@ extern char **environ;
 
 static uint8_t isuc(const char *);
 static int main_init(int, const char *[], Source **, struct block **);
-uint32_t chvt_rndsetup(const void *, size_t);
 void chvt_reinit(void);
 static void reclaim(void);
 static void remove_temps(struct temp *);
@@ -76,7 +75,6 @@ static const char *initcoms[] = {
        /* not in Android for political reasons */
        /* not in ARGE mksh due to no job control */
        "stop=kill -STOP",
-       "suspend=kill -STOP $$",
 #endif
        "autoload=typeset -fu",
        "functions=typeset -f",
@@ -144,21 +142,6 @@ rndsetup(void)
        return ((mksh_uari_t)h);
 }
 
-uint32_t
-chvt_rndsetup(const void *bp, size_t sz)
-{
-       register uint32_t h;
-
-       NZATInit(h);
-       /* variation through pid, ppid, and the works */
-       NZATUpdateMem(h, &rndsetupstate, sizeof(rndsetupstate));
-       /* some variation, some possibly entropy, depending on OE */
-       NZATUpdateMem(h, bp, sz);
-       NZAATFinish(h);
-
-       return (h);
-}
-
 void
 chvt_reinit(void)
 {
@@ -247,6 +230,23 @@ main_init(int argc, const char *argv[], Source **sp, struct block **lp)
        if (!*ccp)
                ccp = empty_argv[0];
 
+       /*
+        * Turn on nohup by default. (AT&T ksh does not have a nohup
+        * option - it always sends the hup).
+        */
+       Flag(FNOHUP) = 1;
+
+       /*
+        * Turn on brace expansion by default. AT&T kshs that have
+        * alternation always have it on.
+        */
+       Flag(FBRACEEXPAND) = 1;
+
+       /*
+        * Turn on "set -x" inheritance by default.
+        */
+       Flag(FXTRACEREC) = 1;
+
        /* define built-in commands and see if we were called as one */
        ktinit(APERM, &builtins,
            /* currently up to 51 builtins: 75% of 128 = 2^7 */
@@ -329,25 +329,6 @@ main_init(int argc, const char *argv[], Source **sp, struct block **lp)
        /* setstr can't fail here */
        setstr(vp, def_path, KSH_RETURN_ERROR);
 
-       /*
-        * Turn on nohup by default for now - will change to off
-        * by default once people are aware of its existence
-        * (AT&T ksh does not have a nohup option - it always sends
-        * the hup).
-        */
-       Flag(FNOHUP) = 1;
-
-       /*
-        * Turn on brace expansion by default. AT&T kshs that have
-        * alternation always have it on.
-        */
-       Flag(FBRACEEXPAND) = 1;
-
-       /*
-        * Turn on "set -x" inheritance by default.
-        */
-       Flag(FXTRACEREC) = 1;
-
 #ifndef MKSH_NO_CMDLINE_EDITING
        /*
         * Set edit mode to emacs by default, may be overridden
@@ -361,9 +342,14 @@ main_init(int argc, const char *argv[], Source **sp, struct block **lp)
 #endif
 
        /* import environment */
-       if (environ != NULL)
-               for (wp = (const char **)environ; *wp != NULL; wp++)
+       if (environ != NULL) {
+               wp = (const char **)environ;
+               while (*wp != NULL) {
+                       rndpush(*wp);
                        typeset(*wp, IMPORT | EXPORT, 0, 0, 0);
+                       ++wp;
+               }
+       }
 
        /* for security */
        typeset(initifs, 0, 0, 0, 0);
@@ -421,7 +407,7 @@ main_init(int argc, const char *argv[], Source **sp, struct block **lp)
        setint_n((vp_pipest = global("PIPESTATUS")), 0, 10);
 
        /* Set this before parsing arguments */
-       Flag(FPRIVILEGED) = kshuid != ksheuid || kshgid != kshegid;
+       Flag(FPRIVILEGED) = (kshuid != ksheuid || kshgid != kshegid) ? 2 : 0;
 
        /* this to note if monitor is set on command line (see below) */
 #ifndef MKSH_UNEMPLOYED
@@ -436,44 +422,6 @@ main_init(int argc, const char *argv[], Source **sp, struct block **lp)
                        return (1);
        }
 
-#if defined(DEBUG) && !defined(MKSH_LEGACY_MODE)
-       /* test wraparound of arithmetic types */
-       {
-               volatile long xl;
-               volatile unsigned long xul;
-               volatile int xi;
-               volatile unsigned int xui;
-               volatile mksh_ari_t xa;
-               volatile mksh_uari_t xua, xua2;
-               volatile uint8_t xc;
-
-               xa = 2147483647;
-               xua = 2147483647;
-               ++xa;
-               ++xua;
-               xua2 = xa;
-               xl = xa;
-               xul = xua;
-               xa = 0;
-               xua = 0;
-               --xa;
-               --xua;
-               xi = xa;
-               xui = xua;
-               xa = -1;
-               xua = xa;
-               ++xa;
-               ++xua;
-               xc = 0;
-               --xc;
-               if ((xua2 != 2147483648UL) ||
-                   (xl != (-2147483647L-1)) || (xul != 2147483648UL) ||
-                   (xi != -1) || (xui != 4294967295U) ||
-                   (xa != 0) || (xua != 0) || (xc != 255))
-                       errorf("integer wraparound test failed");
-       }
-#endif
-
        /* process this later only, default to off (hysterical raisins) */
        utf_flag = UTFMODE;
        UTFMODE = 0;
@@ -485,7 +433,6 @@ main_init(int argc, const char *argv[], Source **sp, struct block **lp)
                s = pushs(SSTRINGCMDLINE, ATEMP);
                if (!(s->start = s->str = argv[argi++]))
                        errorf("%s %s", "-c", "requires an argument");
-#if !defined(MKSH_SMALL)
                while (*s->str) {
                        if (*s->str != ' ' && ctype(*s->str, C_QUOTE))
                                break;
@@ -494,7 +441,6 @@ main_init(int argc, const char *argv[], Source **sp, struct block **lp)
                if (!*s->str)
                        s->flags |= SF_MAYEXEC;
                s->str = s->start;
-#endif
 #ifdef MKSH_MIDNIGHTBSD01ASH_COMPAT
                /* compatibility to MidnightBSD 0.1 /bin/sh (kludge) */
                if (Flag(FSH) && argv[argi] && !strcmp(argv[argi], "--"))
@@ -543,12 +489,14 @@ main_init(int argc, const char *argv[], Source **sp, struct block **lp)
 #ifndef MKSH_ASSUME_UTF8
                        /* auto-detect from locale or environment */
                        utf_flag = 4;
-#elif MKSH_ASSUME_UTF8
+#else /* this may not be an #elif */
+#if MKSH_ASSUME_UTF8
                        utf_flag = 1;
 #else
                        /* always disable UTF-8 (for interactive) */
                        utf_flag = 0;
 #endif
+#endif
                }
 #ifndef MKSH_NO_CMDLINE_EDITING
                x_init();
@@ -637,22 +585,22 @@ main_init(int argc, const char *argv[], Source **sp, struct block **lp)
        if (!current_wd[0] && Flag(FTALKING))
                warningf(false, "can't determine current directory");
 
-       if (Flag(FLOGIN)) {
+       if (Flag(FLOGIN))
                include(MKSH_SYSTEM_PROFILE, 0, NULL, true);
-               if (!Flag(FPRIVILEGED))
-                       include(substitute("$HOME/.profile", 0), 0,
-                           NULL, true);
-       }
-       if (Flag(FPRIVILEGED))
+       if (!Flag(FPRIVILEGED)) {
+               if (Flag(FLOGIN))
+                       include(substitute("$HOME/.profile", 0), 0, NULL, true);
+               if (Flag(FTALKING)) {
+                       cp = substitute(substitute("${ENV:-" MKSHRC_PATH "}",
+                           0), DOTILDE);
+                       if (cp[0] != '\0')
+                               include(cp, 0, NULL, true);
+               }
+       } else {
                include(MKSH_SUID_PROFILE, 0, NULL, true);
-       else if (Flag(FTALKING)) {
-               char *env_file;
-
-               /* include $ENV */
-               env_file = substitute(substitute("${ENV:-" MKSHRC_PATH "}", 0),
-                   DOTILDE);
-               if (*env_file != '\0')
-                       include(env_file, 0, NULL, true);
+               /* turn off -p if not set explicitly */
+               if (Flag(FPRIVILEGED) != 1)
+                       change_flag(FPRIVILEGED, OF_INTERNAL, false);
        }
 
        if (restricted) {
@@ -873,11 +821,8 @@ shell(Source * volatile s, volatile bool toplevel)
                                        unwind(LEXIT);
                                break;
                        }
-               }
-#if !defined(MKSH_SMALL)
-                 else if ((s->flags & SF_MAYEXEC) && t->type == TCOM)
+               } else if ((s->flags & SF_MAYEXEC) && t->type == TCOM)
                        t->u.evalflags |= DOTCOMEXEC;
-#endif
                if (!Flag(FNOEXEC) || (s->flags & SF_TTY))
                        exstat = execute(t, 0, NULL) & 0xFF;
 
@@ -1659,7 +1604,8 @@ maketemp(Area *ap, Temp_type type, struct temp **tlist)
        } while (len < 5);
 
        /* cyclically attempt to open a temporary file */
-       while ((i = open(tp->tffn, O_CREAT | O_EXCL | O_RDWR, 0600)) < 0) {
+       while ((i = open(tp->tffn, O_CREAT | O_EXCL | O_RDWR | O_BINARY,
+           0600)) < 0) {
                if (errno != EEXIST)
                        goto maketemp_out;
                /* count down from z to a then from 9 to 0 */
@@ -1921,9 +1867,10 @@ x_mkraw(int fd, mksh_ttyst *ocb, bool forread)
 
        cb = *ocb;
        if (forread) {
+               cb.c_iflag &= ~(ISTRIP);
                cb.c_lflag &= ~(ICANON) | ECHO;
        } else {
-               cb.c_iflag &= ~(INLCR | ICRNL);
+               cb.c_iflag &= ~(INLCR | ICRNL | ISTRIP);
                cb.c_lflag &= ~(ISIG | ICANON | ECHO);
        }
 #if defined(VLNEXT) && defined(_POSIX_VDISABLE)
diff --git a/src/mirhash.h b/src/mirhash.h
new file mode 100644 (file)
index 0000000..481aac0
--- /dev/null
@@ -0,0 +1,218 @@
+/*-
+ * Copyright © 2011, 2014
+ *     Thorsten Glaser <tg@mirbsd.org>
+ *
+ * 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.
+ *-
+ * This file provides BAFH (Better Avalanche for the Jenkins Hash) as
+ * inline macro bodies that operate on “register uint32_t” variables,
+ * with variants that use their local intermediate registers.
+ *
+ * Usage note for BAFH with entropy distribution: input up to 4 bytes
+ * is best combined into a 32-bit unsigned integer, which is then run
+ * through BAFHFinish_reg for mixing and then used as context instead
+ * of 0. Longer input should be handled the same: take the first four
+ * bytes as IV after mixing then add subsequent bytes the same way.
+ * This needs counting input bytes and is endian-dependent, thus not,
+ * for speed reasons, specified for the regular stable hash, but very
+ * much recommended if the actual output value may differ across runs
+ * (so is using a random value instead of 0 for the IV).
+ */
+
+#ifndef SYSKERN_MIRHASH_H
+#define SYSKERN_MIRHASH_H 1
+#define SYSKERN_MIRHASH_BAFH
+
+#include <sys/types.h>
+
+__RCSID("$MirOS: src/bin/mksh/mirhash.h,v 1.2 2014/06/29 11:48:05 tg Exp $");
+
+/*-
+ * BAFH itself is defined by the following primitives:
+ *
+ * • BAFHInit(ctx) initialises the hash context, which consists of a
+ *   sole 32-bit unsigned integer (ideally in a register), to 0.
+ *   It is possible to use any initial value out of [0; 2³²[ – which
+ *   is, in fact, recommended if using BAFH for entropy distribution
+ *   – but for a regular stable hash, the IV 0 is needed.
+ *
+ * • BAFHUpdateOctet(ctx,val) compresses the unsigned 8-bit quantity
+ *   into the hash context. The algorithm used is Jenkins’ one-at-a-
+ *   time, except that an additional constant 1 is added so that, if
+ *   the context is (still) zero, adding a NUL byte is not ignored.
+ *
+ * • BAFHror(eax,cl) evaluates to the unsigned 32-bit integer “eax”,
+ *   rotated right by “cl” ∈ [0;31]; no casting, be careful!
+ *
+ * • BAFHFinish(ctx) avalanches the context around so every sub-byte
+ *   depends on all input octets; afterwards, the context variable’s
+ *   value is the hash output. BAFH does not use any padding, nor is
+ *   the input length added; this is due to the common use case (for
+ *   quick entropy distribution and use with a hashtable).
+ *   Warning: BAFHFinish uses the MixColumn algorithm of AES – which
+ *   is reversible (to avoid introducing funnels and reducing entro‐
+ *   py), so blinding may need to be employed for some uses, e.g. in
+ *   mksh, after a fork.
+ *
+ * The BAFHUpdateOctet and BAFHFinish are available in two flavours:
+ * suffixed with _reg (assumes the context is in a register) or _mem
+ * (which doesn’t).
+ *
+ * The following high-level macros (with _reg and _mem variants) are
+ * available:
+ *
+ * • BAFHUpdateMem(ctx,buf,len) adds a memory block to a context.
+ * • BAFHUpdateStr(ctx,buf) is equivalent to using len=strlen(buf).
+ * • BAFHHostMem(ctx,buf,len) calculates the hash of the memory buf‐
+ *   fer using the first 4 octets (mixed) for IV, as outlined above;
+ *   the result is endian-dependent; “ctx” assumed to be a register.
+ * • BAFHHostStr(ctx,buf) does the same for C strings.
+ *
+ * All macros may use ctx multiple times in their expansion, but all
+ * other arguments are always evaluated at most once.
+ *
+ * To stay portable, never use the BAFHHost*() macros (these are for
+ * host-local entropy shuffling), and encode numbers using ULEB128.
+ */
+
+#define BAFHInit(h) do {                                       \
+       (h) = 0;                                                \
+} while (/* CONSTCOND */ 0)
+
+#define BAFHUpdateOctet_reg(h,b) do {                          \
+       (h) += (uint8_t)(b);                                    \
+       ++(h);                                                  \
+       (h) += (h) << 10;                                       \
+       (h) ^= (h) >> 6;                                        \
+} while (/* CONSTCOND */ 0)
+
+#define BAFHUpdateOctet_mem(m,b) do {                          \
+       register uint32_t BAFH_h = (m);                         \
+                                                               \
+       BAFHUpdateOctet_reg(BAFH_h, (b));                       \
+       (m) = BAFH_h;                                           \
+} while (/* CONSTCOND */ 0)
+
+#define BAFHror(eax,cl) (((eax) >> (cl)) | ((eax) << (32 - (cl))))
+
+#define BAFHFinish_reg(h) do {                                 \
+       register uint32_t BAFHFinish_v;                         \
+                                                               \
+       BAFHFinish_v = ((h) >> 7) & 0x01010101U;                \
+       BAFHFinish_v += BAFHFinish_v << 1;                      \
+       BAFHFinish_v += BAFHFinish_v << 3;                      \
+       BAFHFinish_v ^= ((h) << 1) & 0xFEFEFEFEU;               \
+                                                               \
+       BAFHFinish_v ^= BAFHror(BAFHFinish_v, 8);               \
+       BAFHFinish_v ^= ((h) = BAFHror((h), 8));                \
+       BAFHFinish_v ^= ((h) = BAFHror((h), 8));                \
+       (h) = BAFHror((h), 8) ^ BAFHFinish_v;                   \
+} while (/* CONSTCOND */ 0)
+
+#define BAFHFinish_mem(m) do {                                 \
+       register uint32_t BAFHFinish_v, BAFH_h = (m);           \
+                                                               \
+       BAFHFinish_v = (BAFH_h >> 7) & 0x01010101U;             \
+       BAFHFinish_v += BAFHFinish_v << 1;                      \
+       BAFHFinish_v += BAFHFinish_v << 3;                      \
+       BAFHFinish_v ^= (BAFH_h << 1) & 0xFEFEFEFEU;            \
+                                                               \
+       BAFHFinish_v ^= BAFHror(BAFHFinish_v, 8);               \
+       BAFHFinish_v ^= (BAFH_h = BAFHror(BAFH_h, 8));          \
+       BAFHFinish_v ^= (BAFH_h = BAFHror(BAFH_h, 8));          \
+       (m) = BAFHror(BAFH_h, 8) ^ BAFHFinish_v;                \
+} while (/* CONSTCOND */ 0)
+
+#define BAFHUpdateMem_reg(h,p,z) do {                          \
+       register const uint8_t *BAFHUpdate_p;                   \
+       register size_t BAFHUpdate_z = (z);                     \
+                                                               \
+       BAFHUpdate_p = (const void *)(p);                       \
+       while (BAFHUpdate_z--)                                  \
+               BAFHUpdateOctet_reg((h), *BAFHUpdate_p++);      \
+} while (/* CONSTCOND */ 0)
+
+/* meh should have named them _r/m but that’s not valid C */
+#define BAFHUpdateMem_mem(m,p,z) do {                          \
+       register uint32_t BAFH_h = (m);                         \
+                                                               \
+       BAFHUpdateMem_reg(BAFH_h, (p), (z));                    \
+       (m) = BAFH_h;                                           \
+} while (/* CONSTCOND */ 0)
+
+#define BAFHUpdateStr_reg(h,s) do {                            \
+       register const uint8_t *BAFHUpdate_s;                   \
+       register uint8_t BAFHUpdate_c;                          \
+                                                               \
+       BAFHUpdate_s = (const void *)(s);                       \
+       while ((BAFHUpdate_c = *BAFHUpdate_s++) != 0)           \
+               BAFHUpdateOctet_reg((h), BAFHUpdate_c);         \
+} while (/* CONSTCOND */ 0)
+
+#define BAFHUpdateStr_mem(m,s) do {                            \
+       register uint32_t BAFH_h = (m);                         \
+                                                               \
+       BAFHUpdateStr_reg(BAFH_h, (s));                         \
+       (m) = BAFH_h;                                           \
+} while (/* CONSTCOND */ 0)
+
+#define BAFHHostMem(h,p,z) do {                                        \
+       register const uint8_t *BAFHUpdate_p;                   \
+       register size_t BAFHUpdate_z = (z);                     \
+       size_t BAFHHost_z;                                      \
+       union {                                                 \
+               uint8_t as_u8[4];                               \
+               uint32_t as_u32;                                \
+       } BAFHHost_v;                                           \
+                                                               \
+       BAFHUpdate_p = (const void *)(p);                       \
+       BAFHHost_v.as_u32 = 0;                                  \
+       BAFHHost_z = BAFHUpdate_z < 4 ? BAFHUpdate_z : 4;       \
+       memcpy(BAFHHost_v.as_u8, BAFHUpdate_p, BAFHHost_z);     \
+       BAFHUpdate_p += BAFHHost_z;                             \
+       BAFHUpdate_z -= BAFHHost_z;                             \
+       (h) = BAFHHost_v.as_u32;                                \
+       BAFHFinish_reg(h);                                      \
+       while (BAFHUpdate_z--)                                  \
+               BAFHUpdateOctet_reg((h), *BAFHUpdate_p++);      \
+       BAFHFinish_reg(h);                                      \
+} while (/* CONSTCOND */ 0)
+
+#define BAFHHostStr(h,s) do {                                  \
+       register const uint8_t *BAFHUpdate_s;                   \
+       register uint8_t BAFHUpdate_c;                          \
+       union {                                                 \
+               uint8_t as_u8[4];                               \
+               uint32_t as_u32;                                \
+       } BAFHHost_v;                                           \
+                                                               \
+       BAFHUpdate_s = (const void *)(s);                       \
+       if ((BAFHHost_v.as_u8[0] = *BAFHUpdate_s) != 0)         \
+               ++BAFHUpdate_s;                                 \
+       if ((BAFHHost_v.as_u8[1] = *BAFHUpdate_s) != 0)         \
+               ++BAFHUpdate_s;                                 \
+       if ((BAFHHost_v.as_u8[2] = *BAFHUpdate_s) != 0)         \
+               ++BAFHUpdate_s;                                 \
+       if ((BAFHHost_v.as_u8[3] = *BAFHUpdate_s) != 0)         \
+               ++BAFHUpdate_s;                                 \
+       (h) = BAFHHost_v.as_u32;                                \
+       BAFHFinish_reg(h);                                      \
+       while ((BAFHUpdate_c = *BAFHUpdate_s++) != 0)           \
+               BAFHUpdateOctet_reg((h), BAFHUpdate_c);         \
+       BAFHFinish_reg(h);                                      \
+} while (/* CONSTCOND */ 0)
+
+#endif
index adf4bc4..82d47d6 100644 (file)
@@ -1,9 +1,9 @@
-/*     $OpenBSD: misc.c,v 1.37 2009/04/19 20:34:05 sthen Exp $ */
+/*     $OpenBSD: misc.c,v 1.38 2013/11/28 10:33:37 sobrado Exp $       */
 /*     $OpenBSD: path.c,v 1.12 2005/03/30 17:16:37 deraadt Exp $       */
 
 /*-
  * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
- *              2011, 2012, 2013
+ *              2011, 2012, 2013, 2014
  *     Thorsten Glaser <tg@mirbsd.org>
  *
  * Provided that these terms and disclaimer and all copyright notices
@@ -30,7 +30,7 @@
 #include <grp.h>
 #endif
 
-__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.214 2013/08/11 14:57:09 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.219 2014/01/05 21:57:27 tg Exp $");
 
 #define KSH_CHVT_FLAG
 #ifdef MKSH_SMALL
@@ -49,10 +49,11 @@ __RCSID("$MirOS: src/bin/mksh/misc.c,v 1.214 2013/08/11 14:57:09 tg Exp $");
 unsigned char chtypes[UCHAR_MAX + 1];
 
 static const unsigned char *pat_scan(const unsigned char *,
-    const unsigned char *, bool);
+    const unsigned char *, bool) MKSH_A_PURE;
 static int do_gmatch(const unsigned char *, const unsigned char *,
-    const unsigned char *, const unsigned char *);
-static const unsigned char *cclass(const unsigned char *, unsigned char);
+    const unsigned char *, const unsigned char *) MKSH_A_PURE;
+static const unsigned char *cclass(const unsigned char *, unsigned char)
+    MKSH_A_PURE;
 #ifdef KSH_CHVT_CODE
 static void chvt(const Getopt *);
 #endif
@@ -125,7 +126,7 @@ Xcheck_grow(XString *xsp, const char *xp, size_t more)
 
 
 #define SHFLAGS_DEFNS
-#include "sh_flags.h"
+#include "sh_flags.gen"
 
 #define OFC(i) (options[i][-2])
 #define OFF(i) (((const unsigned char *)options[i])[-1])
@@ -133,7 +134,7 @@ Xcheck_grow(XString *xsp, const char *xp, size_t more)
 
 const char * const options[] = {
 #define SHFLAGS_ITEMS
-#include "sh_flags.h"
+#include "sh_flags.gen"
 };
 
 /*
@@ -271,6 +272,7 @@ change_flag(enum sh_flag f, int what, bool newset)
 
                /*XXX this can probably be optimised */
                kshegid = kshgid = getgid();
+               ksheuid = kshuid = getuid();
 #if HAVE_SETRESUGID
                DO_SETUID(setresgid, (kshegid, kshegid, kshegid));
 #if HAVE_SETGROUPS
@@ -278,9 +280,8 @@ change_flag(enum sh_flag f, int what, bool newset)
                setgroups(1, &kshegid);
 #endif
                DO_SETUID(setresuid, (ksheuid, ksheuid, ksheuid));
-#else
+#else /* !HAVE_SETRESUGID */
                /* seteuid, setegid, setgid don't EAGAIN on Linux */
-               ksheuid = kshuid = getuid();
 #ifndef MKSH__NO_SETEUGID
                seteuid(ksheuid);
 #endif
@@ -289,7 +290,7 @@ change_flag(enum sh_flag f, int what, bool newset)
                setegid(kshegid);
 #endif
                setgid(kshegid);
-#endif
+#endif /* !HAVE_SETRESUGID */
        } else if ((f == FPOSIX || f == FSH) && newval) {
                /* Turning on -o posix or -o sh? */
                Flag(FBRACEEXPAND) = 0;
@@ -341,10 +342,20 @@ parse_args(const char **argv,
     int what,
     bool *setargsp)
 {
-       static char cmd_opts[NELEM(options) + 5]; /* o:T:\0 */
-       static char set_opts[NELEM(options) + 6]; /* A:o;s\0 */
+       static const char cmd_opts[] =
+#define SHFLAGS_NOT_SET
+#define SHFLAGS_OPTCS
+#include "sh_flags.gen"
+#undef SHFLAGS_NOT_SET
+           ;
+       static const char set_opts[] =
+#define SHFLAGS_NOT_CMD
+#define SHFLAGS_OPTCS
+#include "sh_flags.gen"
+#undef SHFLAGS_NOT_CMD
+           ;
        bool set;
-       char *opts;
+       const char *opts;
        const char *array = NULL;
        Getopt go;
        size_t i;
@@ -352,36 +363,6 @@ parse_args(const char **argv,
        bool sortargs = false;
        bool fcompatseen = false;
 
-       /* First call? Build option strings... */
-       if (cmd_opts[0] == '\0') {
-               char ch, *p = cmd_opts, *q = set_opts;
-
-               /* see cmd_opts[] declaration */
-               *p++ = 'o';
-               *p++ = ':';
-#ifdef KSH_CHVT_FLAG
-               *p++ = 'T';
-               *p++ = ':';
-#endif
-               /* see set_opts[] declaration */
-               *q++ = 'A';
-               *q++ = ':';
-               *q++ = 'o';
-               *q++ = ';';
-               *q++ = 's';
-
-               for (i = 0; i < NELEM(options); i++) {
-                       if ((ch = OFC(i))) {
-                               if (OFF(i) & OF_CMDLINE)
-                                       *p++ = ch;
-                               if (OFF(i) & OF_SET)
-                                       *q++ = ch;
-                       }
-               }
-               *p = '\0';
-               *q = '\0';
-       }
-
        if (what == OF_CMDLINE) {
                const char *p = argv[0], *q;
                /*
@@ -1972,7 +1953,6 @@ c_cd(const char **wp)
 
 
 #ifdef KSH_CHVT_CODE
-extern uint32_t chvt_rndsetup(const void *, size_t);
 extern void chvt_reinit(void);
 
 static void
@@ -2016,9 +1996,9 @@ chvt(const Getopt *go)
 #endif
            }
        }
-       if ((fd = open(dv, O_RDWR)) < 0) {
+       if ((fd = open(dv, O_RDWR | O_BINARY)) < 0) {
                sleep(1);
-               if ((fd = open(dv, O_RDWR)) < 0) {
+               if ((fd = open(dv, O_RDWR | O_BINARY)) < 0) {
                        errorf("%s: %s %s", "chvt", "can't open", dv);
                }
        }
index 621aa97..19291ce 100644 (file)
@@ -1,8 +1,8 @@
-.\" $MirOS: src/bin/mksh/mksh.1,v 1.320 2013/08/10 14:11:39 tg Exp $
-.\" $OpenBSD: ksh.1,v 1.147 2013/06/13 19:43:09 millert Exp $
+.\" $MirOS: src/bin/mksh/mksh.1,v 1.336 2014/06/24 20:47:44 tg Exp $
+.\" $OpenBSD: ksh.1,v 1.152 2014/02/12 16:28:13 schwarze Exp $
 .\"-
 .\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
-.\"            2010, 2011, 2012, 2013
+.\"            2010, 2011, 2012, 2013, 2014
 .\"    Thorsten Glaser <tg@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: August 10 2013 $
+.Dd $Mdocdate: June 24 2014 $
 .\"
 .\" Check which macro package we use, and do other -mdoc setup.
 .\"
@@ -247,8 +247,7 @@ below.
 Privileged shell.
 A shell is
 .Dq privileged
-if this option is used
-or if the real user ID or group ID does not match the
+if the real user ID or group ID does not match the
 effective user ID or group ID (see
 .Xr getuid 2
 and
@@ -257,6 +256,9 @@ Clearing the privileged option causes the shell to set
 its effective user ID (group ID) to its real user ID (group ID).
 For further implications, see
 .Sx Startup files .
+If the shell is privileged and this flag is not explicitly set, the
+.Dq privileged
+option is cleared automatically after processing the startup files.
 .It Fl r
 Restricted shell.
 A shell is
@@ -366,6 +368,9 @@ parameter after subjecting it to parameter, command, arithmetic and tilde
 substitution; if unset or empty, the user mkshrc profile is processed;
 otherwise, if a file whose name is the substitution result exists,
 it is processed; non-existence is silently ignored.
+A privileged shell then drops privileges if neither was the
+.Fl p
+option given on the command line nor set during execution of the startup files.
 .Ss Command syntax
 The shell begins parsing its input by removing any backslash-newline
 combinations, then breaking it into
@@ -955,7 +960,7 @@ The second operand of the
 .Sq !=
 and
 .Sq =
-expressions are patterns (e.g. the comparison
+expressions are a subset of patterns (e.g. the comparison
 .Ic \&[[ foobar = f*r ]]
 succeeds).
 This even works indirectly:
@@ -967,6 +972,7 @@ $ [[ $bar = \&"$baz" ]]; echo $?
 .Pp
 Perhaps surprisingly, the first comparison succeeds,
 whereas the second doesn't.
+This does not apply to all extglob metacharacters, currently.
 .El
 .El
 .Ss Quoting
@@ -1123,7 +1129,6 @@ nameref=\*(aqtypeset \-n\*(aq
 nohup=\*(aqnohup \*(aq
 r=\*(aqfc \-e \-\*(aq
 stop=\*(aqkill \-STOP\*(aq
-suspend=\*(aqkill \-STOP $$\*(aq
 type=\*(aqwhence \-v\*(aq
 .Ed
 .Pp
@@ -1685,17 +1690,10 @@ Currently,
 must start with a space, opening parenthesis or digit to be recognised.
 Cannot be applied to a vector.
 .Pp
-.It Xo
-.Pf ${ Ar name
-.Pf @# Ns Oo Ar seed Oc Ns }
-.Xc
-The internal hash of the expansion of
-.Ar name ,
-with an optional (defaulting to zero)
-.Op Ar seed .
-At the moment, this is NZAAT (a 32-bit hash based on
-Bob Jenkins' one-at-a-time hash), but this is not set.
-This is the hash the shell uses internally for its associative arrays.
+.It Pf ${ Ns Ar name Ns @#}
+The hash (using the BAFH algorithm) of the expansion of
+.Ar name .
+This is also used internally for the shell's hashtables.
 .Pp
 .It Pf ${ Ns Ar name Ns @Q}
 A quoted expression safe for re-entry, whose value is the value of the
@@ -2037,7 +2035,7 @@ in reverse video
 in the prompt string:
 .Bd -literal -offset indent
 x=$(print \e\e001)
-PS1="$x$(print \e\er)$x$(tput smso)$x\e$PWD$x$(tput rmso)$x\*(Gt "
+PS1="$x$(print \e\er)$x$(tput so)$x\e$PWD$x$(tput se)$x\*(Gt "
 .Ed
 .Pp
 Due to a strong suggestion from David G. Korn,
@@ -2592,7 +2590,7 @@ in all forms of arithmetic expressions, except as numeric arguments to the
 built-in command.
 Prefixing numbers with a sole digit zero
 .Pq Sq 0
-leads to the shell interpreting it as base-8 integer in
+leads to the shell interpreting it as base-8 (octal) integer in
 .Ic posix
 mode
 .Em only ;
@@ -2953,8 +2951,9 @@ Builtins that are not special:
 .Ic false , fc , fg , getopts ,
 .Ic jobs , kill , let , mknod ,
 .Ic print , pwd , read , realpath ,
-.Ic rename , sleep , test , true ,
-.Ic ulimit , umask , unalias , whence
+.Ic rename , sleep , suspend , test ,
+.Ic true , ulimit , umask , unalias ,
+.Ic whence
 .Pp
 Once the type of command has been determined, any command-line parameter
 assignments are performed and exported for the duration of the command.
@@ -3411,6 +3410,7 @@ and
 .Ar last
 select commands from the history.
 Commands can be selected by history number
+(negative numbers go backwards from the current, most recent, line)
 or a string specifying the most recent command starting with that string.
 The
 .Fl l
@@ -3623,7 +3623,7 @@ Since expressions may need to be quoted,
 is syntactic sugar for
 .No let \&" Ns Ar expr Ns \&" .
 .Pp
-.It let]
+.It Ic let]
 Internally used alias for
 .Ic let .
 .Pp
@@ -4036,6 +4036,12 @@ Only used if job control is enabled
 .It Fl C \*(Ba Fl o Ic noclobber
 Prevent \*(Gt redirection from overwriting existing files.
 Instead, \*(Gt\*(Ba must be used to force an overwrite.
+Note that this is not safe to use for creation of temporary files or
+lockfiles due to a TOCTOU in a check allowing one to redirect output to
+.Pa /dev/null
+or other device files even in
+.Ic noclobber
+mode.
 .It Fl e \*(Ba Fl o Ic errexit
 Exit (after executing the
 .Dv ERR
@@ -4242,6 +4248,9 @@ mode.
 Enable
 .Xr vi 1 Ns -like
 command-line editing (interactive shells only).
+See
+.Sx Vi editing mode
+for documentation and limitations.
 .It Fl o Ic vi\-esccomplete
 In vi command-line editing, do command and file name completion when escape
 (\*(ha[) is entered in command mode.
@@ -4315,6 +4324,16 @@ and
 .Nm mksh ,
 this is implemented as a shell alias instead of a builtin.
 .Pp
+.It Ic suspend
+Stops the shell as if it had received the suspend character from
+the terminal.
+It is not possible to suspend a login shell unless the parent process
+is a member of the same terminal session but is a member of a different
+process group.
+As a general rule, if the shell was started by another shell or via
+.Xr su 1 ,
+it can be suspended.
+.Pp
 .It Ic test Ar expression
 .It Ic \&[ Ar expression Ic \&]
 .Ic test
@@ -4878,7 +4897,7 @@ unless they are also given on the same command line.
 .Pp
 .It Xo
 .Ic ulimit
-.Op Fl aBCcdefHiLlMmnOPpqrSsTtVvw
+.Op Fl aBCcdefHilMmnOPpqrSsTtVvw
 .Op Ar value
 .Xc
 Display or set process limits.
@@ -4929,8 +4948,6 @@ Set the hard limit only (the default is to set both hard and soft limits).
 .It Fl i Ar n
 Set the number of pending signals to
 .Ar n .
-.It Fl L Ar n
-Control flocks; documentation is missing.
 .It Fl l Ar n
 Impose a limit of
 .Ar n
@@ -5673,6 +5690,7 @@ replaces the inserted text string with the next previously killed text string.
 .Ss Vi editing mode
 .Em Note:
 The vi command-line editing mode is orphaned, yet still functional.
+It is 8-bit clean but specifically does not support UTF-8 or MBCS.
 .Pp
 The vi command-line editor in
 .Nm
@@ -6307,15 +6325,15 @@ contains the system and suid profile.
 .%A Stephen G. Kochan
 .%A Patrick H. Wood
 .%B "\\*(tNUNIX\\*(sP Shell Programming"
-.%V "Revised Edition"
-.%D 1990
-.%I "Hayden"
-.%P "xi\ +\ 490 pages"
-.%O "ISBN 978\-0\-672\-48448\-3 (0\-672\-48448\-X)"
+.%V "3rd Edition"
+.%D 2003
+.%I "Sams"
+.%P "xiii\ +\ 437 pages"
+.%O "ISBN 978\-0\-672\-32490\-1 (0\-672\-32490\-3)"
 .Re
 .Rs
 .%A "IEEE Inc."
-.%B "\\*(tNIEEE\\*(sP Standard for Information Technology \*(en Portable Operating System Interface (POSIX)"
+.%T "\\*(tNIEEE\\*(sP Standard for Information Technology \*(en Portable Operating System Interface (POSIX)"
 .%V "Part 2: Shell and Utilities"
 .%D 1993
 .%I "IEEE Press"
@@ -6348,24 +6366,35 @@ contains the system and suid profile.
 .%O "ISBN 978\-0\-201\-56324\-5 (0\-201\-56324\-X)"
 .Re
 .Sh AUTHORS
+.An -nosplit
 .Nm "The MirBSD Korn Shell"
 is developed by
 .An Thorsten Glaser Aq tg@mirbsd.org
 and currently maintained as part of The MirOS Project.
-This shell is based upon the Public Domain Korn SHell.
-The developer of mksh recognises the efforts of the pdksh authors,
-who had dedicated their work into Public Domain, our users, and
-all contributors, such as the Debian and OpenBSD projects.
-.\"
-.\" Charles Forsyth, author of the (Public Domain) Bourne Shell clone,
-.\" which mksh is derived from, agreed to the following:
-.\"
-.\" In countries where the Public Domain status of the work may not be
-.\" valid, its primary author hereby grants a copyright licence to the
-.\" general public to deal in the work without restriction and permis-
-.\" sion to sublicence derivates under the terms of any (OSI approved)
-.\" Open Source licence.
-.\"
+This shell is based on the public domain 7th edition Bourne shell clone by
+.An Charles Forsyth ,
+who kindly agreed to, in countries where the Public Domain status of the work
+may not be valid, grant a copyright licence to the general public to deal in
+the work without restriction and permission to sublicence derivates under the
+terms of any (OSI approved) Open Source licence,
+and parts of the BRL shell by
+.An Doug A. Gwyn ,
+.An Doug Kingston ,
+.An Ron Natalie ,
+.An Arnold Robbins ,
+.An Lou Salkind ,
+and others.
+The first release of
+.Nm pdksh
+was created by
+.An Eric Gisin ,
+and it was subsequently maintained by
+.An John R. MacMillan Aq Mt change!john@sq.sq.com ,
+.An Simon J. Gerraty Aq Mt sjg@zen.void.oz.au ,
+and
+.An Michael Rendell Aq Mt michael@cs.mun.ca .
+The effort of several projects, such as Debian and OpenBSD, and other
+contributors including our users, to improve the shell is appreciated.
 See the documentation, CVS, and web site for details.
 .Pp
 The BSD daemon is Copyright \(co Marshall Kirk McKusick.
@@ -6425,7 +6454,7 @@ $ /bin/sleep 666 && echo fubar
 .Ed
 .Pp
 This document attempts to describe
-.Nm mksh\ R48
+.Nm mksh\ R50
 and up,
 compiled without any options impacting functionality, such as
 .Dv MKSH_SMALL ,
diff --git a/src/rlimits.gen b/src/rlimits.gen
new file mode 100644 (file)
index 0000000..ef71dab
--- /dev/null
@@ -0,0 +1,174 @@
+#ifndef RLIMITS_OPTCS
+#if defined(RLIMITS_DEFNS)
+__RCSID("$MirOS: src/bin/mksh/rlimits.opt,v 1.1 2013/11/17 22:21:18 tg Exp $");
+struct limits {
+       /* limit resource */
+       int resource;
+       /* multiply by to get rlim_{cur,max} values */
+       unsigned int factor;
+       /* getopts char */
+       char optchar;
+       /* limit name */
+       char name[1];
+};
+#define FN(lname,lid,lfac,lopt)                                        static const struct {                                           int resource;                                           unsigned int factor;                                    char optchar;                                           char name[sizeof(lname)];                       } rlimits_ ## lid = {                                           lid, lfac, lopt, lname                          };
+#elif defined(RLIMITS_ITEMS)
+#define FN(lname,lid,lfac,lopt)                                        (const struct limits *)(&rlimits_ ## lid),
+#endif
+#ifndef F0
+#define F0 FN
+#endif
+#ifdef RLIMIT_CPU
+FN("time(cpu-seconds)", RLIMIT_CPU, 1, 't')
+#endif
+#ifdef RLIMIT_FSIZE
+FN("file(blocks)", RLIMIT_FSIZE, 512, 'f')
+#endif
+#ifdef RLIMIT_CORE
+FN("coredump(blocks)", RLIMIT_CORE, 512, 'c')
+#endif
+#ifdef RLIMIT_DATA
+FN("data(KiB)", RLIMIT_DATA, 1024, 'd')
+#endif
+#ifdef RLIMIT_STACK
+FN("stack(KiB)", RLIMIT_STACK, 1024, 's')
+#endif
+#ifdef RLIMIT_MEMLOCK
+FN("lockedmem(KiB)", RLIMIT_MEMLOCK, 1024, 'l')
+#endif
+#ifdef RLIMIT_NOFILE
+FN("nofiles(descriptors)", RLIMIT_NOFILE, 1, 'n')
+#endif
+#ifdef RLIMIT_NPROC
+FN("processes", RLIMIT_NPROC, 1, 'p')
+#endif
+#ifdef RLIMIT_SWAP
+FN("swap(KiB)", RLIMIT_SWAP, 1024, 'w')
+#endif
+#ifdef RLIMIT_TIME
+FN("humantime(seconds)", RLIMIT_TIME, 1, 'T')
+#endif
+#ifdef RLIMIT_NOVMON
+FN("vnodemonitors", RLIMIT_NOVMON, 1, 'V')
+#endif
+#ifdef RLIMIT_SIGPENDING
+FN("sigpending", RLIMIT_SIGPENDING, 1, 'i')
+#endif
+#ifdef RLIMIT_MSGQUEUE
+FN("msgqueue(bytes)", RLIMIT_MSGQUEUE, 1, 'q')
+#endif
+#ifdef RLIMIT_AIO_MEM
+FN("AIOlockedmem(KiB)", RLIMIT_AIO_MEM, 1024, 'M')
+#endif
+#ifdef RLIMIT_AIO_OPS
+FN("AIOoperations", RLIMIT_AIO_OPS, 1, 'O')
+#endif
+#ifdef RLIMIT_TCACHE
+FN("cachedthreads", RLIMIT_TCACHE, 1, 'C')
+#endif
+#ifdef RLIMIT_SBSIZE
+FN("sockbufsiz(KiB)", RLIMIT_SBSIZE, 1024, 'B')
+#endif
+#ifdef RLIMIT_PTHREAD
+FN("threadsperprocess", RLIMIT_PTHREAD, 1, 'P')
+#endif
+#ifdef RLIMIT_NICE
+FN("maxnice", RLIMIT_NICE, 1, 'e')
+#endif
+#ifdef RLIMIT_RTPRIO
+FN("maxrtprio", RLIMIT_RTPRIO, 1, 'r')
+#endif
+#ifdef ULIMIT_M_IS_RSS
+FN("resident-set(KiB)", RLIMIT_RSS, 1024, 'm')
+#endif
+#ifdef ULIMIT_M_IS_VMEM
+FN("memory(KiB)", RLIMIT_VMEM, 1024, 'm')
+#endif
+#ifdef ULIMIT_V_IS_VMEM
+FN("virtual-memory(KiB)", RLIMIT_VMEM, 1024, 'v')
+#endif
+#ifdef ULIMIT_V_IS_AS
+FN("address-space(KiB)", RLIMIT_AS, 1024, 'v')
+#endif
+#undef F0
+#undef FN
+#undef RLIMITS_DEFNS
+#undef RLIMITS_ITEMS
+#else
+"a"
+#ifdef RLIMIT_SBSIZE
+"B"
+#endif
+#ifdef RLIMIT_TCACHE
+"C"
+#endif
+#ifdef RLIMIT_CORE
+"c"
+#endif
+#ifdef RLIMIT_DATA
+"d"
+#endif
+#ifdef RLIMIT_NICE
+"e"
+#endif
+#ifdef RLIMIT_FSIZE
+"f"
+#endif
+"H"
+#ifdef RLIMIT_SIGPENDING
+"i"
+#endif
+#ifdef RLIMIT_MEMLOCK
+"l"
+#endif
+#ifdef RLIMIT_AIO_MEM
+"M"
+#endif
+#ifdef ULIMIT_M_IS_RSS
+"m"
+#endif
+#ifdef ULIMIT_M_IS_VMEM
+"m"
+#endif
+#ifdef RLIMIT_NOFILE
+"n"
+#endif
+#ifdef RLIMIT_AIO_OPS
+"O"
+#endif
+#ifdef RLIMIT_PTHREAD
+"P"
+#endif
+#ifdef RLIMIT_NPROC
+"p"
+#endif
+#ifdef RLIMIT_MSGQUEUE
+"q"
+#endif
+#ifdef RLIMIT_RTPRIO
+"r"
+#endif
+"S"
+#ifdef RLIMIT_STACK
+"s"
+#endif
+#ifdef RLIMIT_TIME
+"T"
+#endif
+#ifdef RLIMIT_CPU
+"t"
+#endif
+#ifdef RLIMIT_NOVMON
+"V"
+#endif
+#ifdef ULIMIT_V_IS_AS
+"v"
+#endif
+#ifdef ULIMIT_V_IS_VMEM
+"v"
+#endif
+#ifdef RLIMIT_SWAP
+"w"
+#endif
+#undef RLIMITS_OPTCS
+#endif
diff --git a/src/rlimits.opt b/src/rlimits.opt
new file mode 100644 (file)
index 0000000..6c3908b
--- /dev/null
@@ -0,0 +1,96 @@
+@RLIMITS_DEFNS
+__RCSID("$MirOS: src/bin/mksh/rlimits.opt,v 1.1 2013/11/17 22:21:18 tg Exp $");
+struct limits {
+       /* limit resource */
+       int resource;
+       /* multiply by to get rlim_{cur,max} values */
+       unsigned int factor;
+       /* getopts char */
+       char optchar;
+       /* limit name */
+       char name[1];
+};
+#define FN(lname,lid,lfac,lopt)                                        static const struct {                                           int resource;                                           unsigned int factor;                                    char optchar;                                           char name[sizeof(lname)];                       } rlimits_ ## lid = {                                           lid, lfac, lopt, lname                          };
+@RLIMITS_ITEMS
+#define FN(lname,lid,lfac,lopt)                                        (const struct limits *)(&rlimits_ ## lid),
+@@
+
+/* generic options for the ulimit builtin */
+
+<a|
+<H|
+<S|
+
+/* do not use options -H, -S or -a or change the order */
+
+>t|RLIMIT_CPU
+FN("time(cpu-seconds)", RLIMIT_CPU, 1
+
+>f|RLIMIT_FSIZE
+FN("file(blocks)", RLIMIT_FSIZE, 512
+
+>c|RLIMIT_CORE
+FN("coredump(blocks)", RLIMIT_CORE, 512
+
+>d|RLIMIT_DATA
+FN("data(KiB)", RLIMIT_DATA, 1024
+
+>s|RLIMIT_STACK
+FN("stack(KiB)", RLIMIT_STACK, 1024
+
+>l|RLIMIT_MEMLOCK
+FN("lockedmem(KiB)", RLIMIT_MEMLOCK, 1024
+
+>n|RLIMIT_NOFILE
+FN("nofiles(descriptors)", RLIMIT_NOFILE, 1
+
+>p|RLIMIT_NPROC
+FN("processes", RLIMIT_NPROC, 1
+
+>w|RLIMIT_SWAP
+FN("swap(KiB)", RLIMIT_SWAP, 1024
+
+>T|RLIMIT_TIME
+FN("humantime(seconds)", RLIMIT_TIME, 1
+
+>V|RLIMIT_NOVMON
+FN("vnodemonitors", RLIMIT_NOVMON, 1
+
+>i|RLIMIT_SIGPENDING
+FN("sigpending", RLIMIT_SIGPENDING, 1
+
+>q|RLIMIT_MSGQUEUE
+FN("msgqueue(bytes)", RLIMIT_MSGQUEUE, 1
+
+>M|RLIMIT_AIO_MEM
+FN("AIOlockedmem(KiB)", RLIMIT_AIO_MEM, 1024
+
+>O|RLIMIT_AIO_OPS
+FN("AIOoperations", RLIMIT_AIO_OPS, 1
+
+>C|RLIMIT_TCACHE
+FN("cachedthreads", RLIMIT_TCACHE, 1
+
+>B|RLIMIT_SBSIZE
+FN("sockbufsiz(KiB)", RLIMIT_SBSIZE, 1024
+
+>P|RLIMIT_PTHREAD
+FN("threadsperprocess", RLIMIT_PTHREAD, 1
+
+>e|RLIMIT_NICE
+FN("maxnice", RLIMIT_NICE, 1
+
+>r|RLIMIT_RTPRIO
+FN("maxrtprio", RLIMIT_RTPRIO, 1
+
+>m|ULIMIT_M_IS_RSS
+FN("resident-set(KiB)", RLIMIT_RSS, 1024
+>m|ULIMIT_M_IS_VMEM
+FN("memory(KiB)", RLIMIT_VMEM, 1024
+
+>v|ULIMIT_V_IS_VMEM
+FN("virtual-memory(KiB)", RLIMIT_VMEM, 1024
+>v|ULIMIT_V_IS_AS
+FN("address-space(KiB)", RLIMIT_AS, 1024
+
+|RLIMITS_OPTCS
index 5a95190..be716ab 100644 (file)
--- a/src/sh.h
+++ b/src/sh.h
@@ -1,16 +1,16 @@
-/*     $OpenBSD: sh.h,v 1.31 2012/09/10 01:25:30 tedu Exp $    */
+/*     $OpenBSD: sh.h,v 1.33 2013/12/18 13:53:12 millert Exp $ */
 /*     $OpenBSD: shf.h,v 1.6 2005/12/11 18:53:51 deraadt Exp $ */
 /*     $OpenBSD: table.h,v 1.8 2012/02/19 07:52:30 otto Exp $  */
 /*     $OpenBSD: tree.h,v 1.10 2005/03/28 21:28:22 deraadt Exp $       */
 /*     $OpenBSD: expand.h,v 1.6 2005/03/30 17:16:37 deraadt Exp $      */
 /*     $OpenBSD: lex.h,v 1.13 2013/03/03 19:11:34 guenther Exp $       */
-/*     $OpenBSD: proto.h,v 1.34 2012/06/27 07:17:19 otto Exp $ */
+/*     $OpenBSD: proto.h,v 1.35 2013/09/04 15:49:19 millert Exp $      */
 /*     $OpenBSD: c_test.h,v 1.4 2004/12/20 11:34:26 otto Exp $ */
 /*     $OpenBSD: tty.h,v 1.5 2004/12/20 11:34:26 otto Exp $    */
 
 /*-
  * Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
- *            2011, 2012, 2013
+ *            2011, 2012, 2013, 2014
  *     Thorsten Glaser <tg@mirbsd.org>
  *
  * Provided that these terms and disclaimer and all copyright notices
 
 #undef __attribute__
 #if HAVE_ATTRIBUTE_BOUNDED
-#define MKSH_A_BOUNDED(x,y,z)  __attribute__((__bounded__ (x, y, z)))
+#define MKSH_A_BOUNDED(x,y,z)  __attribute__((__bounded__(x, y, z)))
 #else
 #define MKSH_A_BOUNDED(x,y,z)  /* nothing */
 #endif
 #if HAVE_ATTRIBUTE_FORMAT
-#define MKSH_A_FORMAT(x,y,z)   __attribute__((__format__ (x, y, z)))
+#define MKSH_A_FORMAT(x,y,z)   __attribute__((__format__(x, y, z)))
 #else
 #define MKSH_A_FORMAT(x,y,z)   /* nothing */
 #endif
 #else
 #define MKSH_A_NORETURN                /* nothing */
 #endif
+#if HAVE_ATTRIBUTE_PURE
+#define MKSH_A_PURE            __attribute__((__pure__))
+#else
+#define MKSH_A_PURE            /* nothing */
+#endif
 #if HAVE_ATTRIBUTE_UNUSED
 #define MKSH_A_UNUSED          __attribute__((__unused__))
 #else
 #endif
 
 #ifdef EXTERN
-__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.667 2013/08/14 20:26:19 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.691 2014/06/29 11:28:28 tg Exp $");
 #endif
-#define MKSH_VERSION "R48 2013/08/14"
+#define MKSH_VERSION "R50 2014/06/29"
 
 /* arithmetic types: C implementation */
 #if !HAVE_CAN_INTTYPES
@@ -298,7 +303,7 @@ struct rusage {
 #define ksh_isupper(c) (((c) >= 'A') && ((c) <= 'Z'))
 #define ksh_tolower(c) (((c) >= 'A') && ((c) <= 'Z') ? (c) - 'A' + 'a' : (c))
 #define ksh_toupper(c) (((c) >= 'a') && ((c) <= 'z') ? (c) - 'a' + 'A' : (c))
-#define ksh_isdash(s)  (((s) != NULL) && ((s)[0] == '-') && ((s)[1] == '\0'))
+#define ksh_isdash(s)  (((s)[0] == '-') && ((s)[1] == '\0'))
 #define ksh_isspace(c) ((((c) >= 0x09) && ((c) <= 0x0D)) || ((c) == 0x20))
 #define ksh_min(x,y)   ((x) < (y) ? (x) : (y))
 #define ksh_max(x,y)   ((x) > (y) ? (x) : (y))
@@ -337,7 +342,17 @@ struct rusage {
 #define NSIG           (SIGMAX+1)
 #elif defined(_SIGMAX)
 #define NSIG           (_SIGMAX+1)
+#else
+# error Please have your platform define NSIG.
+#define NSIG           64
+#endif
 #endif
+
+/* get rid of this (and awk/printf(1) in Build.sh) later */
+#if (NSIG < 1)
+# error Your NSIG value is not positive.
+#unset NSIG
+#define NSIG           64
 #endif
 
 
@@ -396,6 +411,10 @@ extern int __cdecl setegid(gid_t);
 #endif
 #endif
 
+#ifndef O_BINARY
+#define O_BINARY       0
+#endif
+
 #ifdef MKSH__NO_SYMLINK
 #undef S_ISLNK
 #define S_ISLNK(m)     (/* CONSTCOND */ 0)
@@ -414,12 +433,8 @@ extern int __cdecl setegid(gid_t);
 #define mksh_tcset(fd,st) ioctl((fd), TCSETAW, (st))
 #endif
 
-/* remove redundancies */
-
-#if defined(MirBSD) && (MirBSD >= 0x0AB3) && !defined(MKSH_OPTSTATIC)
-#define MKSH_mirbsd_wcwidth
-#define utf_wcwidth(i) wcwidth((__WCHAR_TYPE__)i)
-extern int wcwidth(__WCHAR_TYPE__);
+#ifndef ISTRIP
+#define ISTRIP         0
 #endif
 
 
@@ -518,7 +533,7 @@ char *ucstrstr(char *, const char *);
 #define mkssert(e)     do { } while (/* CONSTCOND */ 0)
 #endif
 
-#if (!defined(MKSH_BUILDMAKEFILE4BSD) && !defined(MKSH_BUILDSH)) || (MKSH_BUILD_R != 481)
+#if (!defined(MKSH_BUILDMAKEFILE4BSD) && !defined(MKSH_BUILDSH)) || (MKSH_BUILD_R != 501)
 #error Must run Build.sh to compile this.
 extern void thiswillneverbedefinedIhope(void);
 int
@@ -660,7 +675,7 @@ EXTERN Area aperm;          /* permanent object space */
  */
 enum sh_flag {
 #define SHFLAGS_ENUMS
-#include "sh_flags.h"
+#include "sh_flags.gen"
        FNFLAGS         /* (place holder: how many flags are there) */
 };
 
@@ -1163,11 +1178,11 @@ EXTERN struct tbl vtemp;
 #define arrayindex(vp) ((unsigned long)((vp)->flag & AINDEX ? \
                            (vp)->ua.index : 0))
 
-EXTERN enum {
+enum namerefflag {
        SRF_NOP,
        SRF_ENABLE,
        SRF_DISABLE
-} set_refflag E_INIT(SRF_NOP);
+};
 
 /* command types */
 #define CNONE          0       /* undefined */
@@ -1380,22 +1395,7 @@ struct ioword {
 #define DOTEMP BIT(8)          /* dito: in word part of ${..[%#=?]..} */
 #define DOVACHECK BIT(9)       /* var assign check (for typeset, set, etc) */
 #define DOMARKDIRS BIT(10)     /* force markdirs behaviour */
-#if !defined(MKSH_SMALL)
 #define DOTCOMEXEC BIT(11)     /* not an eval flag, used by sh -c hack */
-#endif
-
-/*
- * The arguments of [[ .. ]] expressions are kept in t->args[] and flags
- * indicating how the arguments have been munged are kept in t->vars[].
- * The contents of t->vars[] are stuffed strings (so they can be treated
- * like all other t->vars[]) in which the second character is the one that
- * is examined. The DB_* defines are the values for these second characters.
- */
-#define DB_NORM        1       /* normal argument */
-#define DB_OR  2       /* || -> -o conversion */
-#define DB_AND 3       /* && -> -a conversion */
-#define DB_BE  4       /* an inserted -BE */
-#define DB_PAT 5       /* a pattern argument */
 
 #define X_EXTRA        20      /* this many extra bytes in X string */
 
@@ -1426,7 +1426,7 @@ typedef char *XStringP;
 #define XcheckN(xs, xp, n) do {                                        \
        ssize_t more = ((xp) + (n)) - (xs).end;                 \
        if (more > 0)                                           \
-               (xp) = Xcheck_grow(&(xs), (xp), more);          \
+               (xp) = Xcheck_grow(&(xs), (xp), (size_t)more);  \
 } while (/* CONSTCOND */ 0)
 
 /* check for overflow, expand string */
@@ -1526,9 +1526,7 @@ struct source {
 #define SF_ALIASEND    BIT(2)  /* faking space at end of alias */
 #define SF_TTY         BIT(3)  /* type == SSTDIN & it is a tty */
 #define SF_HASALIAS    BIT(4)  /* u.tblp valid (SALIAS, SEOF) */
-#if !defined(MKSH_SMALL)
 #define SF_MAYEXEC     BIT(5)  /* special sh -c optimisation hack */
-#endif
 
 typedef union {
        int i;
@@ -1587,6 +1585,7 @@ typedef union {
 #undef CTRL
 #define        CTRL(x)         ((x) == '?' ? 0x7F : (x) & 0x1F)        /* ASCII */
 #define        UNCTRL(x)       ((x) ^ 0x40)                            /* ASCII */
+#define        ISCTRL(x)       (((signed char)((uint8_t)(x) + 1)) < 33)
 
 #define IDENT          64
 
@@ -1614,48 +1613,6 @@ EXTERN struct timeval j_usrtime, j_systime;
 } while (/* CONSTCOND */ 0)
 
 
-/* NZAAT hash based on Bob Jenkins' one-at-a-time hash */
-
-/* From: src/kern/include/nzat.h,v 1.2 2011/07/18 00:35:40 tg Exp $ */
-
-#define NZATInit(h) do {                                       \
-       (h) = 0;                                                \
-} while (/* CONSTCOND */ 0)
-
-#define NZATUpdateByte(h,b) do {                               \
-       (h) += (uint8_t)(b);                                    \
-       ++(h);                                                  \
-       (h) += (h) << 10;                                       \
-       (h) ^= (h) >> 6;                                        \
-} while (/* CONSTCOND */ 0)
-
-#define NZATUpdateMem(h,p,z) do {                              \
-       register const uint8_t *NZATUpdateMem_p;                \
-       register size_t NZATUpdateMem_z = (z);                  \
-                                                               \
-       NZATUpdateMem_p = (const void *)(p);                    \
-       while (NZATUpdateMem_z--)                               \
-               NZATUpdateByte((h), *NZATUpdateMem_p++);        \
-} while (/* CONSTCOND */ 0)
-
-#define NZATUpdateString(h,s) do {                             \
-       register const char *NZATUpdateString_s;                \
-       register uint8_t NZATUpdateString_c;                    \
-                                                               \
-       NZATUpdateString_s = (const void *)(s);                 \
-       while ((NZATUpdateString_c = *NZATUpdateString_s++))    \
-               NZATUpdateByte((h), NZATUpdateString_c);        \
-} while (/* CONSTCOND */ 0)
-
-#define NZAATFinish(h) do {                                    \
-       (h) += (h) << 10;                                       \
-       (h) ^= (h) >> 6;                                        \
-       (h) += (h) << 3;                                        \
-       (h) ^= (h) >> 11;                                       \
-       (h) += (h) << 15;                                       \
-} while (/* CONSTCOND */ 0)
-
-
 /* lalloc.c */
 void ainit(Area *);
 void afreeall(Area *);
@@ -1706,12 +1663,10 @@ int v_evaluate(struct tbl *, const char *, volatile int, bool);
 size_t utf_mbtowc(unsigned int *, const char *);
 size_t utf_wctomb(char *, unsigned int);
 int utf_widthadj(const char *, const char **);
-size_t utf_mbswidth(const char *);
-const char *utf_skipcols(const char *, int);
-size_t utf_ptradj(const char *);
-#ifndef MKSH_mirbsd_wcwidth
-int utf_wcwidth(unsigned int);
-#endif
+size_t utf_mbswidth(const char *) MKSH_A_PURE;
+const char *utf_skipcols(const char *, int) MKSH_A_PURE;
+size_t utf_ptradj(const char *) MKSH_A_PURE;
+int utf_wcwidth(unsigned int) MKSH_A_PURE;
 int ksh_access(const char *, int);
 struct tbl *tempvar(void);
 /* funcs.c */
@@ -1779,10 +1734,10 @@ void sethistsize(mksh_ari_t);
 void sethistfile(const char *);
 #endif
 #if !defined(MKSH_NO_CMDLINE_EDITING) && !MKSH_S_NOVI
-char **histpos(void);
+char **histpos(void) MKSH_A_PURE;
 int histnum(int);
 #endif
-int findhist(int, int, const char *, int);
+int findhist(int, int, const char *, bool) MKSH_A_PURE;
 char **hist_get_newest(bool);
 void inittraps(void);
 void alarm_init(void);
@@ -1818,6 +1773,9 @@ int j_kill(const char *, int);
 #ifndef MKSH_UNEMPLOYED
 int j_resume(const char *, int);
 #endif
+#if !defined(MKSH_UNEMPLOYED) && HAVE_GETSID
+void j_suspend(void);
+#endif
 int j_jobs(const char *, int, int);
 void j_notify(void);
 pid_t j_async(void);
@@ -1895,15 +1853,15 @@ void DF(const char *, ...)
 /* misc.c */
 void setctypes(const char *, int);
 void initctypes(void);
-size_t option(const char *);
+size_t option(const char *) MKSH_A_PURE;
 char *getoptions(void);
 void change_flag(enum sh_flag, int, bool);
 void change_xtrace(unsigned char, bool);
 int parse_args(const char **, int, bool *);
 int getn(const char *, int *);
 int gmatchx(const char *, const char *, bool);
-int has_globbing(const char *, const char *);
-int xstrcmp(const void *, const void *);
+int has_globbing(const char *, const char *) MKSH_A_PURE;
+int xstrcmp(const void *, const void *) MKSH_A_PURE;
 void ksh_getopt_reset(Getopt *, int);
 int ksh_getopt(const char **, Getopt *, const char *);
 void print_value_quoted(struct shf *, const char *);
@@ -1995,19 +1953,21 @@ void setint(struct tbl *, mksh_ari_t);
 void setint_n(struct tbl *, mksh_ari_t, int);
 struct tbl *typeset(const char *, uint32_t, uint32_t, int, int);
 void unset(struct tbl *, int);
-const char *skip_varname(const char *, int);
-const char *skip_wdvarname(const char *, bool);
-int is_wdvarname(const char *, bool);
-int is_wdvarassign(const char *);
+const char *skip_varname(const char *, bool) MKSH_A_PURE;
+const char *skip_wdvarname(const char *, bool) MKSH_A_PURE;
+int is_wdvarname(const char *, bool) MKSH_A_PURE;
+int is_wdvarassign(const char *) MKSH_A_PURE;
 struct tbl *arraysearch(struct tbl *, uint32_t);
 char **makenv(void);
 void change_winsz(void);
-size_t array_ref_len(const char *);
+size_t array_ref_len(const char *) MKSH_A_PURE;
 char *arrayname(const char *);
 mksh_uari_t set_array(const char *, bool, const char **);
-uint32_t hash(const void *);
+uint32_t hash(const void *) MKSH_A_PURE;
+uint32_t chvt_rndsetup(const void *, size_t) MKSH_A_PURE;
 mksh_ari_t rndget(void);
 void rndset(unsigned long);
+void rndpush(const void *);
 
 enum Test_op {
        /* non-operator */
@@ -2058,10 +2018,11 @@ typedef struct test_env {
 
 extern const char * const dbtest_tokens[];
 
-Test_op        test_isop(Test_meta, const char *);
+Test_op        test_isop(Test_meta, const char *) MKSH_A_PURE;
 int test_eval(Test_env *, Test_op, const char *, const char *, bool);
 int test_parse(Test_env *);
 
+/* tty_fd is not opened O_BINARY, it's thus never read/written */
 EXTERN int tty_fd E_INIT(-1);  /* dup'd tty file descriptor */
 EXTERN bool tty_devtty;                /* true if tty_fd is from /dev/tty */
 EXTERN mksh_ttyst tty_state;   /* saved tty state */
diff --git a/src/sh_flags.gen b/src/sh_flags.gen
new file mode 100644 (file)
index 0000000..cff2e87
--- /dev/null
@@ -0,0 +1,136 @@
+#ifndef SHFLAGS_OPTCS
+#if defined(SHFLAGS_DEFNS)
+__RCSID("$MirOS: src/bin/mksh/sh_flags.opt,v 1.2 2014/06/09 12:28:19 tg Exp $");
+#define FN(sname,cname,flags,ochar)                    static const struct {                                   /* character flag (if any) */                   char c;                                         /* OF_* */                                      unsigned char optflags;                         /* long name of option */                       char name[sizeof(sname)];               } shoptione_ ## cname = {                               ochar, flags, sname                     };
+#elif defined(SHFLAGS_ENUMS)
+#define FN(sname,cname,flags,ochar)    cname,
+#define F0(sname,cname,flags,ochar)    cname = 0,
+#elif defined(SHFLAGS_ITEMS)
+#define FN(sname,cname,flags,ochar)            ((const char *)(&shoptione_ ## cname)) + 2,
+#endif
+#ifndef F0
+#define F0 FN
+#endif
+F0("allexport", FEXPORT, OF_ANY, 'a')
+#if HAVE_NICE
+FN("bgnice", FBGNICE, OF_ANY, 0)
+#endif
+FN("braceexpand", FBRACEEXPAND, OF_ANY, 0)
+#if !defined(MKSH_NO_CMDLINE_EDITING) || defined(MKSH_LEGACY_MODE)
+FN("emacs", FEMACS, OF_ANY, 0)
+#endif
+FN("errexit", FERREXIT, OF_ANY, 'e')
+#if !defined(MKSH_NO_CMDLINE_EDITING) || defined(MKSH_LEGACY_MODE)
+FN("gmacs", FGMACS, OF_ANY, 0)
+#endif
+FN("ignoreeof", FIGNOREEOF, OF_ANY, 0)
+FN("inherit-xtrace", FXTRACEREC, OF_ANY, 0)
+#ifndef SHFLAGS_NOT_CMD
+FN("interactive", FTALKING, OF_CMDLINE, 'i')
+#endif
+FN("keyword", FKEYWORD, OF_ANY, 'k')
+#ifndef SHFLAGS_NOT_CMD
+FN("login", FLOGIN, OF_CMDLINE, 'l')
+#endif
+FN("markdirs", FMARKDIRS, OF_ANY, 'X')
+#ifndef MKSH_UNEMPLOYED
+FN("monitor", FMONITOR, OF_ANY, 'm')
+#endif
+FN("noclobber", FNOCLOBBER, OF_ANY, 'C')
+FN("noexec", FNOEXEC, OF_ANY, 'n')
+FN("noglob", FNOGLOB, OF_ANY, 'f')
+FN("nohup", FNOHUP, OF_ANY, 0)
+FN("nolog", FNOLOG, OF_ANY, 0)
+#ifndef MKSH_UNEMPLOYED
+FN("notify", FNOTIFY, OF_ANY, 'b')
+#endif
+FN("nounset", FNOUNSET, OF_ANY, 'u')
+FN("physical", FPHYSICAL, OF_ANY, 0)
+FN("pipefail", FPIPEFAIL, OF_ANY, 0)
+FN("posix", FPOSIX, OF_ANY, 0)
+FN("privileged", FPRIVILEGED, OF_ANY, 'p')
+#ifndef SHFLAGS_NOT_CMD
+FN("restricted", FRESTRICTED, OF_CMDLINE, 'r')
+#endif
+FN("sh", FSH, OF_ANY, 0)
+#ifndef SHFLAGS_NOT_CMD
+FN("stdin", FSTDIN, OF_CMDLINE, 's')
+#endif
+FN("trackall", FTRACKALL, OF_ANY, 'h')
+FN("utf8-mode", FUNICODE, OF_ANY, 'U')
+FN("verbose", FVERBOSE, OF_ANY, 'v')
+#if !defined(MKSH_NO_CMDLINE_EDITING) || defined(MKSH_LEGACY_MODE)
+FN("vi", FVI, OF_ANY, 0)
+#endif
+#if !defined(MKSH_NO_CMDLINE_EDITING) || defined(MKSH_LEGACY_MODE)
+FN("vi-esccomplete", FVIESCCOMPLETE, OF_ANY, 0)
+#endif
+#if !defined(MKSH_NO_CMDLINE_EDITING) || defined(MKSH_LEGACY_MODE)
+FN("vi-tabcomplete", FVITABCOMPLETE, OF_ANY, 0)
+#endif
+#if !defined(MKSH_NO_CMDLINE_EDITING) || defined(MKSH_LEGACY_MODE)
+FN("viraw", FVIRAW, OF_ANY, 0)
+#endif
+FN("xtrace", FXTRACE, OF_ANY, 'x')
+#ifndef SHFLAGS_NOT_CMD
+FN("", FCOMMAND, OF_CMDLINE, 'c')
+#endif
+FN("", FAS_BUILTIN, OF_INTERNAL, 0)
+FN("", FTALKING_I, OF_INTERNAL, 0)
+#undef F0
+#undef FN
+#undef SHFLAGS_DEFNS
+#undef SHFLAGS_ENUMS
+#undef SHFLAGS_ITEMS
+#else
+#ifndef SHFLAGS_NOT_SET
+"A:"
+#endif
+"a"
+#ifndef MKSH_UNEMPLOYED
+"b"
+#endif
+"C"
+#ifndef SHFLAGS_NOT_CMD
+"c"
+#endif
+"e"
+"f"
+"h"
+#ifndef SHFLAGS_NOT_CMD
+"i"
+#endif
+"k"
+#ifndef SHFLAGS_NOT_CMD
+"l"
+#endif
+#ifndef MKSH_UNEMPLOYED
+"m"
+#endif
+"n"
+#ifndef SHFLAGS_NOT_CMD
+"o:"
+#endif
+#ifndef SHFLAGS_NOT_SET
+"o;"
+#endif
+"p"
+#ifndef SHFLAGS_NOT_CMD
+"r"
+#endif
+#ifndef SHFLAGS_NOT_CMD
+"s"
+#endif
+#ifndef SHFLAGS_NOT_SET
+"s"
+#endif
+#ifndef SHFLAGS_NOT_CMD
+"T:"
+#endif
+"U"
+"u"
+"v"
+"X"
+"x"
+#undef SHFLAGS_OPTCS
+#endif
diff --git a/src/sh_flags.h b/src/sh_flags.h
deleted file mode 100644 (file)
index 3e4cf56..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-#if defined(SHFLAGS_DEFNS)
-__RCSID("$MirOS: src/bin/mksh/sh_flags.h,v 1.16 2013/08/11 14:57:11 tg Exp $");
-#define FN(sname,cname,ochar,flags)            \
-       static const struct {                   \
-               /* character flag (if any) */   \
-               char c;                         \
-               /* OF_* */                      \
-               unsigned char optflags;         \
-               /* long name of option */       \
-               char name[sizeof(sname)];       \
-       } shoptione_ ## cname = {               \
-               ochar, flags, sname             \
-       };
-#elif defined(SHFLAGS_ENUMS)
-#define FN(sname,cname,ochar,flags)    cname,
-#define F0(sname,cname,ochar,flags)    cname = 0,
-#elif defined(SHFLAGS_ITEMS)
-#define FN(sname,cname,ochar,flags)    \
-       ((const char *)(&shoptione_ ## cname)) + 2,
-#endif
-
-#ifndef F0
-#define F0 FN
-#endif
-
-/*
- * special cases (see parse_args()): -A, -o, -s
- *
- * options are sorted by their longnames
- */
-
-/* -a  all new parameters are created with the export attribute */
-F0("allexport", FEXPORT, 'a', OF_ANY)
-
-#if HAVE_NICE
-/* ./. bgnice */
-FN("bgnice", FBGNICE, 0, OF_ANY)
-#endif
-
-/* ./. enable {} globbing (non-standard) */
-FN("braceexpand", FBRACEEXPAND, 0, OF_ANY)
-
-#if !defined(MKSH_NO_CMDLINE_EDITING) || defined(MKSH_LEGACY_MODE)
-/* ./. Emacs command line editing mode */
-FN("emacs", FEMACS, 0, OF_ANY)
-#endif
-
-/* -e  quit on error */
-FN("errexit", FERREXIT, 'e', OF_ANY)
-
-#if !defined(MKSH_NO_CMDLINE_EDITING) || defined(MKSH_LEGACY_MODE)
-/* ./. Emacs command line editing mode, gmacs variant */
-FN("gmacs", FGMACS, 0, OF_ANY)
-#endif
-
-/* ./. reading EOF does not exit */
-FN("ignoreeof", FIGNOREEOF, 0, OF_ANY)
-
-/* ./. inherit -x flag */
-FN("inherit-xtrace", FXTRACEREC, 0, OF_ANY)
-
-/* -i  interactive shell */
-FN("interactive", FTALKING, 'i', OF_CMDLINE)
-
-/* -k  name=value are recognised anywhere */
-FN("keyword", FKEYWORD, 'k', OF_ANY)
-
-/* -l  login shell */
-FN("login", FLOGIN, 'l', OF_CMDLINE)
-
-/* -X  mark dirs with / in file name completion */
-FN("markdirs", FMARKDIRS, 'X', OF_ANY)
-
-#ifndef MKSH_UNEMPLOYED
-/* -m  job control monitoring */
-FN("monitor", FMONITOR, 'm', OF_ANY)
-#endif
-
-/* -C  don't overwrite existing files */
-FN("noclobber", FNOCLOBBER, 'C', OF_ANY)
-
-/* -n  don't execute any commands */
-FN("noexec", FNOEXEC, 'n', OF_ANY)
-
-/* -f  don't do file globbing */
-FN("noglob", FNOGLOB, 'f', OF_ANY)
-
-/* ./. don't kill running jobs when login shell exits */
-FN("nohup", FNOHUP, 0, OF_ANY)
-
-/* ./. don't save functions in history (no effect) */
-FN("nolog", FNOLOG, 0, OF_ANY)
-
-#ifndef MKSH_UNEMPLOYED
-/* -b  asynchronous job completion notification */
-FN("notify", FNOTIFY, 'b', OF_ANY)
-#endif
-
-/* -u  using an unset variable is an error */
-FN("nounset", FNOUNSET, 'u', OF_ANY)
-
-/* ./. don't do logical cds/pwds (non-standard) */
-FN("physical", FPHYSICAL, 0, OF_ANY)
-
-/* ./. errorlevel of a pipeline is the rightmost nonzero value */
-FN("pipefail", FPIPEFAIL, 0, OF_ANY)
-
-/* ./. adhere more closely to POSIX even when undesirable */
-FN("posix", FPOSIX, 0, OF_ANY)
-
-/* -p  use suid_profile; privileged shell */
-FN("privileged", FPRIVILEGED, 'p', OF_ANY)
-
-/* -r  restricted shell */
-FN("restricted", FRESTRICTED, 'r', OF_CMDLINE)
-
-/* ./. kludge mode for better compat with traditional sh (OS-specific) */
-FN("sh", FSH, 0, OF_ANY)
-
-/* -s  (invocation) parse stdin (pseudo non-standard) */
-FN("stdin", FSTDIN, 's', OF_CMDLINE)
-
-/* -h  create tracked aliases for all commands */
-FN("trackall", FTRACKALL, 'h', OF_ANY)
-
-/* -U  enable UTF-8 processing (non-standard) */
-FN("utf8-mode", FUNICODE, 'U', OF_ANY)
-
-/* -v  echo input */
-FN("verbose", FVERBOSE, 'v', OF_ANY)
-
-#if !defined(MKSH_NO_CMDLINE_EDITING) || defined(MKSH_LEGACY_MODE)
-/* ./. Vi command line editing mode */
-FN("vi", FVI, 0, OF_ANY)
-
-/* ./. enable ESC as file name completion character (non-standard) */
-FN("vi-esccomplete", FVIESCCOMPLETE, 0, OF_ANY)
-
-/* ./. enable Tab as file name completion character (non-standard) */
-FN("vi-tabcomplete", FVITABCOMPLETE, 0, OF_ANY)
-
-/* ./. always read in raw mode (no effect) */
-FN("viraw", FVIRAW, 0, OF_ANY)
-#endif
-
-/* -x  execution trace (display commands as they are run) */
-FN("xtrace", FXTRACE, 'x', OF_ANY)
-
-/* -c  (invocation) execute specified command */
-FN("", FCOMMAND, 'c', OF_CMDLINE)
-
-/*
- * anonymous flags: used internally by shell only (not visible to user)
- */
-
-/* ./. direct builtin call (divined from argv[0] multi-call binary) */
-FN("", FAS_BUILTIN, 0, OF_INTERNAL)
-
-/* ./. (internal) initial shell was interactive */
-FN("", FTALKING_I, 0, OF_INTERNAL)
-
-#undef FN
-#undef F0
-#undef SHFLAGS_DEFNS
-#undef SHFLAGS_ENUMS
-#undef SHFLAGS_ITEMS
diff --git a/src/sh_flags.opt b/src/sh_flags.opt
new file mode 100644 (file)
index 0000000..99e4a22
--- /dev/null
@@ -0,0 +1,179 @@
+@SHFLAGS_DEFNS
+__RCSID("$MirOS: src/bin/mksh/sh_flags.opt,v 1.2 2014/06/09 12:28:19 tg Exp $");
+#define FN(sname,cname,flags,ochar)                    static const struct {                                   /* character flag (if any) */                   char c;                                         /* OF_* */                                      unsigned char optflags;                         /* long name of option */                       char name[sizeof(sname)];               } shoptione_ ## cname = {                               ochar, flags, sname                     };
+@SHFLAGS_ENUMS
+#define FN(sname,cname,flags,ochar)    cname,
+#define F0(sname,cname,flags,ochar)    cname = 0,
+@SHFLAGS_ITEMS
+#define FN(sname,cname,flags,ochar)            ((const char *)(&shoptione_ ## cname)) + 2,
+@@
+
+/* special cases */
+
+<o:|!SHFLAGS_NOT_CMD
+<T:|!SHFLAGS_NOT_CMD
+<A:|!SHFLAGS_NOT_SET
+<o;|!SHFLAGS_NOT_SET
+<s|!SHFLAGS_NOT_SET
+
+/*
+ * options are sorted by their longnames
+ */
+
+/* -a  all new parameters are created with the export attribute */
+>a|
+F0("allexport", FEXPORT, OF_ANY
+
+/* ./. bgnice */
+>| HAVE_NICE
+FN("bgnice", FBGNICE, OF_ANY
+
+/* ./. enable {} globbing (non-standard) */
+>|
+FN("braceexpand", FBRACEEXPAND, OF_ANY
+
+/* ./. Emacs command line editing mode */
+>|!defined(MKSH_NO_CMDLINE_EDITING) || defined(MKSH_LEGACY_MODE)
+FN("emacs", FEMACS, OF_ANY
+
+/* -e  quit on error */
+>e|
+FN("errexit", FERREXIT, OF_ANY
+
+/* ./. Emacs command line editing mode, gmacs variant */
+>|!defined(MKSH_NO_CMDLINE_EDITING) || defined(MKSH_LEGACY_MODE)
+FN("gmacs", FGMACS, OF_ANY
+
+/* ./. reading EOF does not exit */
+>|
+FN("ignoreeof", FIGNOREEOF, OF_ANY
+
+/* ./. inherit -x flag */
+>|
+FN("inherit-xtrace", FXTRACEREC, OF_ANY
+
+/* -i  interactive shell */
+>i|!SHFLAGS_NOT_CMD
+FN("interactive", FTALKING, OF_CMDLINE
+
+/* -k  name=value are recognised anywhere */
+>k|
+FN("keyword", FKEYWORD, OF_ANY
+
+/* -l  login shell */
+>l|!SHFLAGS_NOT_CMD
+FN("login", FLOGIN, OF_CMDLINE
+
+/* -X  mark dirs with / in file name completion */
+>X|
+FN("markdirs", FMARKDIRS, OF_ANY
+
+/* -m  job control monitoring */
+>m|!MKSH_UNEMPLOYED
+FN("monitor", FMONITOR, OF_ANY
+
+/* -C  don't overwrite existing files */
+>C|
+FN("noclobber", FNOCLOBBER, OF_ANY
+
+/* -n  don't execute any commands */
+>n|
+FN("noexec", FNOEXEC, OF_ANY
+
+/* -f  don't do file globbing */
+>f|
+FN("noglob", FNOGLOB, OF_ANY
+
+/* ./. don't kill running jobs when login shell exits */
+>|
+FN("nohup", FNOHUP, OF_ANY
+
+/* ./. don't save functions in history (no effect) */
+>|
+FN("nolog", FNOLOG, OF_ANY
+
+/* -b  asynchronous job completion notification */
+>b|!MKSH_UNEMPLOYED
+FN("notify", FNOTIFY, OF_ANY
+
+/* -u  using an unset variable is an error */
+>u|
+FN("nounset", FNOUNSET, OF_ANY
+
+/* ./. don't do logical cds/pwds (non-standard) */
+>|
+FN("physical", FPHYSICAL, OF_ANY
+
+/* ./. errorlevel of a pipeline is the rightmost nonzero value */
+>|
+FN("pipefail", FPIPEFAIL, OF_ANY
+
+/* ./. adhere more closely to POSIX even when undesirable */
+>|
+FN("posix", FPOSIX, OF_ANY
+
+/* -p  privileged shell (suid) */
+>p|
+FN("privileged", FPRIVILEGED, OF_ANY
+
+/* -r  restricted shell */
+>r|!SHFLAGS_NOT_CMD
+FN("restricted", FRESTRICTED, OF_CMDLINE
+
+/* ./. kludge mode for better compat with traditional sh (OS-specific) */
+>|
+FN("sh", FSH, OF_ANY
+
+/* -s  (invocation) parse stdin (pseudo non-standard) */
+>s|!SHFLAGS_NOT_CMD
+FN("stdin", FSTDIN, OF_CMDLINE
+
+/* -h  create tracked aliases for all commands */
+>h|
+FN("trackall", FTRACKALL, OF_ANY
+
+/* -U  enable UTF-8 processing (non-standard) */
+>U|
+FN("utf8-mode", FUNICODE, OF_ANY
+
+/* -v  echo input */
+>v|
+FN("verbose", FVERBOSE, OF_ANY
+
+/* ./. Vi command line editing mode */
+>|!defined(MKSH_NO_CMDLINE_EDITING) || defined(MKSH_LEGACY_MODE)
+FN("vi", FVI, OF_ANY
+
+/* ./. enable ESC as file name completion character (non-standard) */
+>|!defined(MKSH_NO_CMDLINE_EDITING) || defined(MKSH_LEGACY_MODE)
+FN("vi-esccomplete", FVIESCCOMPLETE, OF_ANY
+
+/* ./. enable Tab as file name completion character (non-standard) */
+>|!defined(MKSH_NO_CMDLINE_EDITING) || defined(MKSH_LEGACY_MODE)
+FN("vi-tabcomplete", FVITABCOMPLETE, OF_ANY
+
+/* ./. always read in raw mode (no effect) */
+>|!defined(MKSH_NO_CMDLINE_EDITING) || defined(MKSH_LEGACY_MODE)
+FN("viraw", FVIRAW, OF_ANY
+
+/* -x  execution trace (display commands as they are run) */
+>x|
+FN("xtrace", FXTRACE, OF_ANY
+
+/* -c  (invocation) execute specified command */
+>c|!SHFLAGS_NOT_CMD
+FN("", FCOMMAND, OF_CMDLINE
+
+/*
+ * anonymous flags: used internally by shell only (not visible to user
+ */
+
+/* ./. direct builtin call (divined from argv[0] multi-call binary) */
+>|
+FN("", FAS_BUILTIN, OF_INTERNAL
+
+/* ./. (internal) initial shell was interactive */
+>|
+FN("", FTALKING_I, OF_INTERNAL
+
+|SHFLAGS_OPTCS
index e8ec14a..33e89bd 100644 (file)
--- a/src/shf.c
+++ b/src/shf.c
@@ -25,7 +25,7 @@
 
 #include "sh.h"
 
-__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.61 2013/07/21 18:36:03 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.62 2013/10/09 11:59:30 tg Exp $");
 
 /* flags to shf_emptybuf() */
 #define EB_READSW      0x01    /* about to switch to reading */
@@ -62,7 +62,7 @@ shf_open(const char *name, int oflags, int mode, int sflags)
        shf->flags = SHF_ALLOCS;
        /* Rest filled in by reopen. */
 
-       fd = open(name, oflags, mode);
+       fd = open(name, oflags | O_BINARY, mode);
        if (fd < 0) {
                eno = errno;
                afree(shf, shf->areap);
diff --git a/src/signames.inc b/src/signames.inc
new file mode 100644 (file)
index 0000000..07811fd
--- /dev/null
@@ -0,0 +1,31 @@
+               { "ABRT", 6 },
+               { "FPE", 8 },
+               { "ILL", 4 },
+               { "INT", 2 },
+               { "SEGV", 11 },
+               { "TERM", 15 },
+               { "ALRM", 14 },
+               { "BUS", 7 },
+               { "CHLD", 17 },
+               { "CONT", 18 },
+               { "HUP", 1 },
+               { "KILL", 9 },
+               { "PIPE", 13 },
+               { "QUIT", 3 },
+               { "STOP", 19 },
+               { "TSTP", 20 },
+               { "TTIN", 21 },
+               { "TTOU", 22 },
+               { "USR1", 10 },
+               { "USR2", 12 },
+               { "POLL", 29 },
+               { "PROF", 27 },
+               { "SYS", 31 },
+               { "TRAP", 5 },
+               { "URG", 23 },
+               { "VTALRM", 26 },
+               { "XCPU", 24 },
+               { "XFSZ", 25 },
+               { "WINCH", 28 },
+               { "PWR", 30 },
+               { "STKFLT", 16 },
index 53f9130..c0ebfd5 100644 (file)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2006, 2008, 2009
+ * Copyright (c) 2006, 2008, 2009, 2013
  *     Thorsten Glaser <tg@mirbsd.org>
  * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
  *
 
 #include "sh.h"
 
-__RCSID("$MirOS: src/bin/mksh/strlcpy.c,v 1.7 2009/06/10 18:12:50 tg Rel $");
+__RCSID("$MirOS: src/bin/mksh/strlcpy.c,v 1.8 2013/11/05 22:10:15 tg Exp $");
 
 /*
  * Copy src to string dst of size siz. At most siz-1 characters
  * will be copied. Always NUL terminates (unless siz == 0).
  * Returns strlen(src); if retval >= siz, truncation occurred.
  */
+#undef strlcpy
 size_t
 strlcpy(char *dst, const char *src, size_t siz)
 {
index 5c07d51..6a544df 100644 (file)
--- a/src/syn.c
+++ b/src/syn.c
@@ -2,7 +2,7 @@
 
 /*-
  * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009,
- *              2011, 2012, 2013
+ *              2011, 2012, 2013, 2014
  *     Thorsten Glaser <tg@mirbsd.org>
  *
  * Provided that these terms and disclaimer and all copyright notices
@@ -23,7 +23,7 @@
 
 #include "sh.h"
 
-__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.92 2013/06/03 22:28:17 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.94 2014/01/05 21:57:29 tg Exp $");
 
 struct nesting_state {
        int start_token;        /* token than began nesting (eg, FOR) */
@@ -59,7 +59,7 @@ static void syntaxerr(const char *) MKSH_A_NORETURN;
 static void nesting_push(struct nesting_state *, int);
 static void nesting_pop(struct nesting_state *);
 static int assign_command(const char *);
-static int inalias(struct source *);
+static int inalias(struct source *) MKSH_A_PURE;
 static Test_op dbtestp_isa(Test_env *, Test_meta);
 static const char *dbtestp_getopnd(Test_env *, Test_op, bool);
 static int dbtestp_eval(Test_env *, Test_op, const char *,
@@ -976,7 +976,7 @@ static Test_op
 dbtestp_isa(Test_env *te, Test_meta meta)
 {
        int c = tpeek(ARRAYVAR | (meta == TM_BINOP ? 0 : CONTIN));
-       int uqword;
+       bool uqword;
        char *save = NULL;
        Test_op ret = TO_NONOP;
 
index dcbd7a1..8026f8b 100644 (file)
@@ -23,7 +23,7 @@
 
 #include "sh.h"
 
-__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.71 2013/07/26 20:33:24 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.72 2013/09/24 20:19:45 tg Exp $");
 
 #define INDENT 8
 
@@ -778,15 +778,16 @@ vistree(char *dst, size_t sz, struct op *t)
        if (--sz == 0 || (c = (unsigned char)(*cp++)) == 0)
                /* NUL or not enough free space */
                goto vist_out;
-       if ((c & 0x60) == 0 || (c & 0x7F) == 0x7F) {
+       if (ISCTRL(c & 0x7F)) {
                /* C0 or C1 control character or DEL */
                if (--sz == 0)
                        /* not enough free space for two chars */
                        goto vist_out;
                *dst++ = (c & 0x80) ? '$' : '^';
-               c = (c & 0x7F) ^ 0x40;
+               c = UNCTRL(c & 0x7F);
        } else if (UTFMODE && c > 0x7F) {
                /* better not try to display broken multibyte chars */
+               /* also go easy on the Unicode: no U+FFFD here */
                c = '?';
        }
        *dst++ = c;
@@ -801,10 +802,10 @@ vistree(char *dst, size_t sz, struct op *t)
 void
 dumpchar(struct shf *shf, int c)
 {
-       if (((c & 0x60) == 0) || ((c & 0x7F) == 0x7F)) {
+       if (ISCTRL(c & 0x7F)) {
                /* C0 or C1 control character or DEL */
                shf_putc((c & 0x80) ? '$' : '^', shf);
-               c = (c & 0x7F) ^ 0x40;
+               c = UNCTRL(c & 0x7F);
        }
        shf_putc(c, shf);
 }
index ba8fd82..ef114e1 100644 (file)
--- a/src/var.c
+++ b/src/var.c
@@ -1,8 +1,8 @@
-/*     $OpenBSD: var.c,v 1.35 2013/04/05 01:31:30 tedu Exp $   */
+/*     $OpenBSD: var.c,v 1.38 2013/12/20 17:53:09 zhuk Exp $   */
 
 /*-
  * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
- *              2011, 2012, 2013
+ *              2011, 2012, 2013, 2014
  *     Thorsten Glaser <tg@mirbsd.org>
  *
  * Provided that these terms and disclaimer and all copyright notices
  */
 
 #include "sh.h"
+#include "mirhash.h"
 
 #if defined(__OpenBSD__)
 #include <sys/sysctl.h>
 #endif
 
-__RCSID("$MirOS: src/bin/mksh/var.c,v 1.173 2013/05/31 22:47:14 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/var.c,v 1.180 2014/06/26 20:36:02 tg Exp $");
 
 /*-
  * Variables
@@ -40,7 +41,9 @@ __RCSID("$MirOS: src/bin/mksh/var.c,v 1.173 2013/05/31 22:47:14 tg Exp $");
  */
 
 static struct table specials;
-static uint32_t lcg_state = 5381;
+static uint32_t lcg_state = 5381, qh_state = 4711;
+/* may only be set by typeset() just before call to array_index_calc() */
+static enum namerefflag innermost_refflag = SRF_NOP;
 
 static char *formatstr(struct tbl *, const char *);
 static void exportprep(struct tbl *, const char *);
@@ -164,7 +167,8 @@ varsearch(struct block *l, struct tbl **vpp, const char *vn, uint32_t h)
 /*
  * Used to calculate an array index for global()/local(). Sets *arrayp
  * to true if this is an array, sets *valp to the array index, returns
- * the basename of the array.
+ * the basename of the array. May only be called from global()/local()
+ * and must be their first callee.
  */
 static const char *
 array_index_calc(const char *n, bool *arrayp, uint32_t *valp)
@@ -176,7 +180,7 @@ array_index_calc(const char *n, bool *arrayp, uint32_t *valp)
        *arrayp = false;
  redo_from_ref:
        p = skip_varname(n, false);
-       if (set_refflag == SRF_NOP && (p != n) && ksh_isalphx(n[0])) {
+       if (innermost_refflag == SRF_NOP && (p != n) && ksh_isalphx(n[0])) {
                struct tbl *vp;
                char *vn;
 
@@ -184,8 +188,8 @@ array_index_calc(const char *n, bool *arrayp, uint32_t *valp)
                /* check if this is a reference */
                varsearch(e->loc, &vp, vn, hash(vn));
                afree(vn, ATEMP);
-               if (vp && (vp->flag & (DEFINED|ASSOC|ARRAY)) ==
-                   (DEFINED|ASSOC)) {
+               if (vp && (vp->flag & (DEFINED | ASSOC | ARRAY)) ==
+                   (DEFINED | ASSOC)) {
                        char *cp;
 
                        /* gotcha! */
@@ -195,6 +199,7 @@ array_index_calc(const char *n, bool *arrayp, uint32_t *valp)
                        goto redo_from_ref;
                }
        }
+       innermost_refflag = SRF_NOP;
 
        if (p != n && *p == '[' && (len = array_ref_len(p))) {
                char *sub, *tmp;
@@ -225,10 +230,13 @@ global(const char *n)
        bool array;
        uint32_t h, val;
 
-       /* Check to see if this is an array */
+       /*
+        * check to see if this is an array;
+        * dereference namerefs; must come first
+        */
        n = array_index_calc(n, &array, &val);
        h = hash(n);
-       c = n[0];
+       c = (unsigned char)n[0];
        if (!ksh_isalphx(c)) {
                if (array)
                        errorf("bad substitution");
@@ -238,9 +246,7 @@ global(const char *n)
                vp->areap = ATEMP;
                *vp->name = c;
                if (ksh_isdigit(c)) {
-                       for (c = 0; ksh_isdigit(*n); n++)
-                               c = c*10 + *n-'0';
-                       if (c <= l->argc)
+                       if (getn(n, &c) && (c <= l->argc))
                                /* setstr can't fail here */
                                setstr(vp, l->argv[c], KSH_RETURN_ERROR);
                        vp->flag |= RDONLY;
@@ -297,7 +303,10 @@ local(const char *n, bool copy)
        bool array;
        uint32_t h, val;
 
-       /* check to see if this is an array */
+       /*
+        * check to see if this is an array;
+        * dereference namerefs; must come first
+        */
        n = array_index_calc(n, &array, &val);
        mkssert(n != NULL);
        h = hash(n);
@@ -500,7 +509,7 @@ getint(struct tbl *vp, mksh_ari_u *nump, bool arith)
                base = 8;
                have_base = true;
        }
-       while ((c = *s++)) {
+       while ((c = (unsigned char)*s++)) {
                if (c == '-') {
                        neg = true;
                        continue;
@@ -702,6 +711,16 @@ typeset(const char *var, uint32_t set, uint32_t clr, int field, int base)
        const char *val;
        size_t len;
        bool vappend = false;
+       enum namerefflag new_refflag = SRF_NOP;
+
+       if ((set & (ARRAY | ASSOC)) == ASSOC) {
+               new_refflag = SRF_ENABLE;
+               set &= ~(ARRAY | ASSOC);
+       }
+       if ((clr & (ARRAY | ASSOC)) == ASSOC) {
+               new_refflag = SRF_DISABLE;
+               clr &= ~(ARRAY | ASSOC);
+       }
 
        /* check for valid variable name, search for value */
        val = skip_varname(var, false);
@@ -710,7 +729,7 @@ typeset(const char *var, uint32_t set, uint32_t clr, int field, int base)
                return (NULL);
        }
        if (*val == '[') {
-               if (set_refflag != SRF_NOP)
+               if (new_refflag != SRF_NOP)
                        errorf("%s: %s", var,
                            "reference variable can't be an array");
                len = array_ref_len(val);
@@ -756,18 +775,32 @@ typeset(const char *var, uint32_t set, uint32_t clr, int field, int base)
                        tvar[len - 3] = '\0';
        }
 
-       if (set_refflag == SRF_ENABLE) {
-               const char *qval;
+       if (new_refflag == SRF_ENABLE) {
+               const char *qval, *ccp;
 
                /* bail out on 'nameref foo+=bar' */
                if (vappend)
-                       errorfz();
+                       errorf("appending not allowed for nameref");
                /* find value if variable already exists */
                if ((qval = val) == NULL) {
                        varsearch(e->loc, &vp, tvar, hash(tvar));
                        if (vp != NULL)
                                qval = str_val(vp);
                }
+               /* check target value for being a valid variable name */
+               ccp = skip_varname(qval, false);
+               if (ccp == qval)
+                       errorf("%s: %s", var, "empty nameref target");
+               len = (*ccp == '[') ? array_ref_len(ccp) : 0;
+               if (ccp[len]) {
+                       /*
+                        * works for cases "no array", "valid array with
+                        * junk after it" and "invalid array"; in the
+                        * latter case, len is also 0 and points to '['
+                        */
+                       errorf("%s: %s", qval,
+                           "nameref target not a valid parameter name");
+               }
                /* prevent nameref loops */
                while (qval) {
                        if (!strcmp(qval, tvar))
@@ -775,7 +808,7 @@ typeset(const char *var, uint32_t set, uint32_t clr, int field, int base)
                                    "expression recurses on parameter");
                        varsearch(e->loc, &vp, qval, hash(qval));
                        qval = NULL;
-                       if (vp && ((vp->flag & (ARRAY|ASSOC)) == ASSOC))
+                       if (vp && ((vp->flag & (ARRAY | ASSOC)) == ASSOC))
                                qval = str_val(vp);
                }
        }
@@ -785,11 +818,12 @@ typeset(const char *var, uint32_t set, uint32_t clr, int field, int base)
            strcmp(tvar, "ENV") == 0 || strcmp(tvar, "SHELL") == 0))
                errorf("%s: %s", tvar, "restricted");
 
-       vp = (set&LOCAL) ? local(tvar, tobool(set & LOCAL_COPY)) :
+       innermost_refflag = new_refflag;
+       vp = (set & LOCAL) ? local(tvar, tobool(set & LOCAL_COPY)) :
            global(tvar);
-       if (set_refflag == SRF_DISABLE && (vp->flag & (ARRAY|ASSOC)) == ASSOC)
+       if (new_refflag == SRF_DISABLE && (vp->flag & (ARRAY|ASSOC)) == ASSOC)
                vp->flag &= ~ASSOC;
-       else if (set_refflag == SRF_ENABLE) {
+       else if (new_refflag == SRF_ENABLE) {
                if (vp->flag & ARRAY) {
                        struct tbl *a, *tmp;
 
@@ -809,14 +843,14 @@ typeset(const char *var, uint32_t set, uint32_t clr, int field, int base)
 
        set &= ~(LOCAL|LOCAL_COPY);
 
-       vpbase = (vp->flag & ARRAY) ? global(arrayname(var)) : vp;
+       vpbase = (vp->flag & ARRAY) ? global(arrayname(tvar)) : vp;
 
        /*
         * only allow export flag to be set; AT&T ksh allows any
         * attribute to be changed which means it can be truncated or
         * modified (-L/-R/-Z/-i)
         */
-       if ((vpbase->flag&RDONLY) &&
+       if ((vpbase->flag & RDONLY) &&
            (val || clr || (set & ~EXPORT)))
                /* XXX check calls - is error here ok by POSIX? */
                errorfx(2, "read-only: %s", tvar);
@@ -960,7 +994,7 @@ unset(struct tbl *vp, int flags)
  * the terminating NUL if whole string is legal).
  */
 const char *
-skip_varname(const char *s, int aok)
+skip_varname(const char *s, bool aok)
 {
        size_t alen;
 
@@ -1338,7 +1372,7 @@ arraysearch(struct tbl *vp, uint32_t val)
        struct tbl *prev, *curr, *news;
        size_t len;
 
-       vp->flag = (vp->flag | (ARRAY|DEFINED)) & ~ASSOC;
+       vp->flag = (vp->flag | (ARRAY | DEFINED)) & ~ASSOC;
        /* the table entry is always [0] */
        if (val == 0)
                return (vp);
@@ -1378,6 +1412,8 @@ arraysearch(struct tbl *vp, uint32_t val)
  * Return the length of an array reference (eg, [1+2]) - cp is assumed
  * to point to the open bracket. Returns 0 if there is no matching
  * closing bracket.
+ *
+ * XXX this should parse the actual arithmetic syntax
  */
 size_t
 array_ref_len(const char *cp)
@@ -1458,6 +1494,7 @@ set_array(const char *var, bool reset, const char **vals)
                afree(cp, ATEMP);
        }
        while ((ccp = vals[i])) {
+#if 0 /* temporarily taken out due to regression */
                if (*ccp == '[') {
                        int level = 0;
 
@@ -1478,6 +1515,7 @@ set_array(const char *var, bool reset, const char **vals)
                        } else
                                ccp = vals[i];
                }
+#endif
 
                vq = arraysearch(vp, j);
                /* would be nice to deal with errors here... (see above) */
@@ -1492,6 +1530,11 @@ set_array(const char *var, bool reset, const char **vals)
 void
 change_winsz(void)
 {
+       struct timeval tv;
+
+       mksh_TIME(tv);
+       BAFHUpdateMem_mem(qh_state, &tv, sizeof(tv));
+
 #ifdef TIOCGWINSZ
        /* check if window size has changed */
        if (tty_init_fd() < 2) {
@@ -1522,9 +1565,28 @@ hash(const void *s)
 {
        register uint32_t h;
 
-       NZATInit(h);
-       NZATUpdateString(h, s);
-       NZAATFinish(h);
+       BAFHInit(h);
+       BAFHUpdateStr_reg(h, s);
+       BAFHFinish_reg(h);
+       return (h);
+}
+
+uint32_t
+chvt_rndsetup(const void *bp, size_t sz)
+{
+       register uint32_t h;
+
+       /* use LCG as seed but try to get them to deviate immediately */
+       h = lcg_state;
+       (void)rndget();
+       BAFHFinish_reg(h);
+       /* variation through pid, ppid, and the works */
+       BAFHUpdateMem_reg(h, &rndsetupstate, sizeof(rndsetupstate));
+       /* some variation, some possibly entropy, depending on OE */
+       BAFHUpdateMem_reg(h, bp, sz);
+       /* mix them all up */
+       BAFHFinish_reg(h);
+
        return (h);
 }
 
@@ -1542,28 +1604,67 @@ void
 rndset(unsigned long v)
 {
        register uint32_t h;
+#if defined(arc4random_pushb_fast) || defined(MKSH_A4PB)
+       register uint32_t t;
+#endif
+       struct {
+               struct timeval tv;
+               void *sp;
+               uint32_t qh;
+               pid_t pp;
+               short r;
+       } z;
+
+#ifdef DEBUG
+       /* clear the allocated space, for valgrind */
+       memset(&z, 0, sizeof(z));
+#endif
 
-       NZATInit(h);
-       NZATUpdateMem(h, &lcg_state, sizeof(lcg_state));
-       NZATUpdateMem(h, &v, sizeof(v));
+       h = lcg_state;
+       BAFHFinish_reg(h);
+       BAFHUpdateMem_reg(h, &v, sizeof(v));
+
+       mksh_TIME(z.tv);
+       z.sp = &lcg_state;
+       z.pp = procpid;
+       z.r = (short)rndget();
 
 #if defined(arc4random_pushb_fast) || defined(MKSH_A4PB)
+       t = qh_state;
+       BAFHFinish_reg(t);
+       z.qh = (t & 0xFFFF8000) | rndget();
+       lcg_state = (t << 15) | rndget();
        /*
         * either we have very chap entropy get and push available,
         * with malloc() pulling in this code already anyway, or the
         * user requested us to use the old functions
         */
-       lcg_state = h;
-       NZAATFinish(lcg_state);
+       t = h;
+       BAFHUpdateMem_reg(t, &lcg_state, sizeof(lcg_state));
+       BAFHFinish_reg(t);
+       lcg_state = t;
 #if defined(arc4random_pushb_fast)
        arc4random_pushb_fast(&lcg_state, sizeof(lcg_state));
        lcg_state = arc4random();
 #else
        lcg_state = arc4random_pushb(&lcg_state, sizeof(lcg_state));
 #endif
-       NZATUpdateMem(h, &lcg_state, sizeof(lcg_state));
+       BAFHUpdateMem_reg(h, &lcg_state, sizeof(lcg_state));
+#else
+       z.qh = qh_state;
 #endif
 
-       NZAATFinish(h);
+       BAFHUpdateMem_reg(h, &z, sizeof(z));
+       BAFHFinish_reg(h);
        lcg_state = h;
 }
+
+void
+rndpush(const void *s)
+{
+       register uint32_t h = qh_state;
+
+       BAFHUpdateStr_reg(h, s);
+       BAFHUpdateOctet_reg(h, 0);
+       qh_state = h;
+}