diff -Nru mksh-40.4/Build.sh mksh-40.9.20120414/Build.sh --- mksh-40.4/Build.sh 2012-05-01 02:38:29.000000000 +0000 +++ mksh-40.9.20120414/Build.sh 2012-04-14 16:08:07.000000000 +0000 @@ -1,5 +1,5 @@ #!/bin/sh -srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.484.2.10 2012/02/11 15:25:26 tg Exp $' +srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.549 2012/04/14 16:07:43 tg Exp $' #- # Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011, 2012 @@ -28,6 +28,17 @@ LC_ALL=C export LC_ALL +if test -n "${ZSH_VERSION+x}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: +fi + +if test -d /usr/xpg4/bin/. >/dev/null 2>&1; then + # Solaris: some of the tools have weird behaviour, use portable ones + PATH=/usr/xpg4/bin:$PATH + export PATH +fi + v() { $e "$*" eval "$@" @@ -54,17 +65,6 @@ done } -if test -d /usr/xpg4/bin/. >/dev/null 2>&1; then - # Solaris: some of the tools have weird behaviour, use portable ones - PATH=/usr/xpg4/bin:$PATH - export PATH -fi - -if test -n "${ZSH_VERSION+x}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: -fi - allu=QWERTYUIOPASDFGHJKLZXCVBNM alll=qwertyuiopasdfghjklzxcvbnm alln=0123456789 @@ -155,7 +155,7 @@ else fr=0 fi - ac_testinit "$@" || return + ac_testinit "$@" || return 1 cat >conftest.c vv ']' "$CC $CFLAGS $CPPFLAGS $LDFLAGS $NOWARN conftest.c $LIBS $ccpr" test $tcfn = no && test -f a.out && tcfn=a.out @@ -174,9 +174,10 @@ test $ct = sunpro && vscan='-e ignored -e turned.off' fi test -n "$vscan" && grep $vscan vv.out >/dev/null 2>&1 && fv=$fr + return 0 } ac_testn() { - ac_testnnd "$@" + ac_testnnd "$@" || return rmf conftest.c conftest.o ${tcfn}* vv.out ac_testdone } @@ -262,6 +263,7 @@ fi hf=$1; shift hv=`echo "$hf" | tr -d '\012\015' | tr -c $alll$allu$alln $alls` + echo "/* NeXTstep bug workaround */" >x for i do echo "#include <$i>" >>x @@ -274,6 +276,12 @@ } 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 @@ -281,6 +289,13 @@ 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" ;; @@ -292,12 +307,13 @@ echo "$me: Error: ./mksh is a directory!" >&2 exit 1 fi -rmf a.exe* a.out* conftest.c *core lft mksh* no *.bc *.ll *.o \ +rmf a.exe* a.out* conftest.c *core core.* lft mksh* no *.bc *.ll *.o \ Rebuild.sh signames.inc test.sh x vv.out -curdir=`pwd` srcdir=`dirname "$0"` check_categories= -test -n "$srcdir" || srcdir=. +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` +add_cppflags -DMKSH_BUILDSH e=echo r=0 @@ -325,10 +341,6 @@ :-c) last=c ;; - :-combine) - cm=combine - echo "$me: Warning: '$i' is deprecated, use '-c combine' instead!" >&2 - ;; :-g) # checker, debug, valgrind build add_cppflags -DDEBUG @@ -337,16 +349,6 @@ :-j) pm=1 ;; - :-llvm) - cm=llvm - optflags=-std-compile-opts - echo "$me: Warning: '$i' is deprecated, use '-c llvm -O' instead!" >&2 - ;; - :-llvm=*) - cm=llvm - optflags=`echo "x$i" | sed 's/^x-llvm=//'` - echo "$me: Warning: '$i' is deprecated, use '-c llvm -o $llvm' instead!" >&2 - ;; :-M) cm=makefile ;; @@ -390,6 +392,11 @@ else CPPFLAGS="-I. -I'$srcdir' $CPPFLAGS" fi +test -n "$LDSTATIC" && if test -n "$LDFLAGS"; then + LDFLAGS="$LDFLAGS $LDSTATIC" +else + LDFLAGS=$LDSTATIC +fi test x"$TARGET_OS" = x"" && TARGET_OS=`uname -s 2>/dev/null || uname` if test x"$TARGET_OS" = x""; then @@ -408,21 +415,86 @@ TARGET_OS=Linux fi +# Evil OS +if test x"$TARGET_OS" = x"Minix"; then + echo >&2 " +WARNING: additional checks before running Build.sh required! +You can avoid these by calling Build.sh correctly, see below. +" + cat >conftest.c <<'EOF' +#include +const char * +#ifdef _NETBSD_SOURCE +ct="Ninix3" +#else +ct="Minix3" +#endif +; +EOF + ct=unknown + vv ']' "${CC-cc} -E $CFLAGS $CPPFLAGS $NOWARN conftest.c | grep ct= | tr -d \\\\015 >x" + sed 's/^/[ /' x + eval `cat x` + rmf x vv.out + case $ct in + Minix3|Ninix3) + echo >&2 " +Warning: you set TARGET_OS to $TARGET_OS but that is ambiguous. +Please set it to either Minix3 or Ninix3, whereas the latter is +all versions of Minix with even partial NetBSD(R) userland. The +value determined from your compiler for the current compilation +(which may be wrong) is: $ct +" + TARGET_OS=$ct + ;; + *) + echo >&2 " +Warning: you set TARGET_OS to $TARGET_OS but that is ambiguous. +Please set it to either Minix3 or Ninix3, whereas the latter is +all versions of Minix with even partial NetBSD(R) userland. The +proper value couldn't be determined, continue at your own risk. +" + ;; + esac +fi + # Configuration depending on OS revision, on OSes that need them case $TARGET_OS in -QNX) +NEXTSTEP) + test x"$TARGET_OSREV" = x"" && TARGET_OSREV=`hostinfo 2>&1 | sed -n '/^.*NeXT Mach \([0-9.]*\):.*$/s//\1/p'` + ;; +QNX|SCO_SV) test x"$TARGET_OSREV" = x"" && TARGET_OSREV=`uname -r` ;; esac # Configuration depending on OS name case $TARGET_OS in +386BSD) + # required fixes for 386BSD-0.0new are: + # http://groups.google.com/group/comp.unix.bsd/browse_thread/thread/1c6397039f10e76b?hl=en + # http://groups.google.com/group/comp.unix.bsd/browse_thread/thread/cb899f7ccb81550b?hl=en + # from 386BSD-0.1 on, it works out of the box + : ${HAVE_CAN_OTWO=0} + add_cppflags -DMKSH_NO_SIGSETJMP + add_cppflags -DMKSH_TYPEDEF_SIG_ATOMIC_T=int + ;; AIX) add_cppflags -D_ALL_SOURCE : ${HAVE_SETLOCALE_CTYPE=0} ;; BeOS) - oswarn=' and will currently not work' + case $KSH_VERSION in + *MIRBSD\ KSH*) + oswarn="; it has minor issues" + ;; + *) + oswarn="; you must recompile mksh with" + oswarn="$oswarn${nl}itself in a second stage" + ;; + esac + # BeOS has no real tty either + add_cppflags -DMKSH_UNEMPLOYED ;; BSD/OS) : ${HAVE_SETLOCALE_CTYPE=0} @@ -478,9 +550,12 @@ add_cppflags -DSETUID_CAN_FAIL_WITH_EAGAIN : ${HAVE_REVOKE=0} ;; +LynxOS) + oswarn="; it has minor issues" + ;; MidnightBSD) ;; -Minix) +Minix3) add_cppflags -DMKSH_UNEMPLOYED add_cppflags -DMKSH_CONSERVATIVE_FDS add_cppflags -DMKSH_NO_LIMITS @@ -499,6 +574,28 @@ ;; NetBSD) ;; +NEXTSTEP) + add_cppflags -D_NEXT_SOURCE + add_cppflags -D_POSIX_SOURCE + : ${AWK=gawk} ${CC=cc -posix} + add_cppflags -DMKSH_NO_SIGSETJMP + # NeXTstep cannot get a controlling tty + add_cppflags -DMKSH_UNEMPLOYED + case $TARGET_OSREV in + 4.2*) + # OpenStep 4.2 is broken by default + oswarn="; it needs libposix.a" + ;; + esac + ;; +Ninix3) + # similar to Minix3 + add_cppflags -DMKSH_UNEMPLOYED + add_cppflags -DMKSH_CONSERVATIVE_FDS + add_cppflags -DMKSH_NO_LIMITS + # but no idea what else could be needed + oswarn="; it has unknown issues" + ;; OpenBSD) : ${HAVE_SETLOCALE_CTYPE=0} ;; @@ -533,6 +630,25 @@ esac : ${HAVE_SETLOCALE_CTYPE=0} ;; +SCO_SV) + case $TARGET_OSREV in + 3.2*) + # SCO OpenServer 5 + add_cppflags -DMKSH_UNEMPLOYED + ;; + 5*) + # SCO OpenServer 6 + ;; + *) + oswarn='; this is an unknown version of' + oswarn="$oswarn$nl$TARGET_OS ${TARGET_OSREV}, please tell me what to do" + ;; + esac + : ${HAVE_SYS_SIGLIST=0} ${HAVE__SYS_SIGLIST=0} + ;; +skyos) + oswarn="; it has minor issues" + ;; SunOS) add_cppflags -D_BSD_SOURCE add_cppflags -D__EXTENSIONS__ @@ -543,9 +659,13 @@ ;; ULTRIX) : ${CC=cc -YPOSIX} - add_cppflags -Dssize_t=int + add_cppflags -DMKSH_TYPEDEF_SSIZE_T=int : ${HAVE_SETLOCALE_CTYPE=0} ;; +UnixWare|UNIX_SV) + # SCO UnixWare + : ${HAVE_SYS_SIGLIST=0} ${HAVE__SYS_SIGLIST=0} + ;; UWIN*) ccpc='-Yc,' ccpl='-Yl,' @@ -556,12 +676,13 @@ ;; *) oswarn='; it may or may not work' + test x"$TARGET_OSREV" = x"" && TARGET_OSREV=`uname -r` ;; esac : ${HAVE_MKNOD=0} -: ${CC=cc} ${NROFF=nroff} +: ${AWK=awk} ${CC=cc} ${NROFF=nroff} test 0 = $r && echo | $NROFF -v 2>&1 | grep GNU >/dev/null 2>&1 && \ NROFF="$NROFF -c" @@ -584,6 +705,10 @@ vv '|' "uname -a >&2" vv '|' "/usr/sbin/sizer -v >&2" ;; +SCO_SV|UnixWare|UNIX_SV) + vv '|' "uname -a >&2" + vv '|' "uname -X >&2" + ;; *) vv '|' "uname -a >&2" ;; @@ -594,7 +719,7 @@ a shell account to the developer, this may improve; please drop us a success or failure notice or even send in diffs. " -$e "$bi$me: Building the MirBSD Korn Shell$ao $ui$dstversion$ao" +$e "$bi$me: Building the MirBSD Korn Shell$ao $ui$dstversion$ao on $TARGET_OS ${TARGET_OSREV}..." # # Begin of mirtoconf checks @@ -612,62 +737,66 @@ CPP="$CC -E" $e ... which compiler seems to be used cat >conftest.c <<'EOF' +const char * #if defined(__ICC) || defined(__INTEL_COMPILER) -ct=icc +ct="icc" #elif defined(__xlC__) || defined(__IBMC__) -ct=xlc +ct="xlc" #elif defined(__SUNPRO_C) -ct=sunpro +ct="sunpro" #elif defined(__ACK__) -ct=ack +ct="ack" #elif defined(__BORLANDC__) -ct=bcc +ct="bcc" #elif defined(__WATCOMC__) -ct=watcom +ct="watcom" #elif defined(__MWERKS__) -ct=metrowerks +ct="metrowerks" #elif defined(__HP_cc) -ct=hpcc +ct="hpcc" #elif defined(__DECC) || (defined(__osf__) && !defined(__GNUC__)) -ct=dec +ct="dec" #elif defined(__PGI) -ct=pgi +ct="pgi" #elif defined(__DMC__) -ct=dmc +ct="dmc" #elif defined(_MSC_VER) -ct=msc +ct="msc" #elif defined(__ADSPBLACKFIN__) || defined(__ADSPTS__) || defined(__ADSP21000__) -ct=adsp +ct="adsp" #elif defined(__IAR_SYSTEMS_ICC__) -ct=iar +ct="iar" #elif defined(SDCC) -ct=sdcc +ct="sdcc" #elif defined(__PCC__) -ct=pcc +ct="pcc" #elif defined(__TenDRA__) -ct=tendra +ct="tendra" #elif defined(__TINYC__) -ct=tcc +ct="tcc" #elif defined(__llvm__) && defined(__clang__) -ct=clang +ct="clang" #elif defined(__NWCC__) -ct=nwcc +ct="nwcc" #elif defined(__GNUC__) -ct=gcc +ct="gcc" #elif defined(_COMPILER_VERSION) -ct=mipspro +ct="mipspro" #elif defined(__sgi) -ct=mipspro +ct="mipspro" #elif defined(__hpux) || defined(__hpua) -ct=hpcc +ct="hpcc" #elif defined(__ultrix) -ct=ucode +ct="ucode" +#elif defined(__USLC__) +ct="uslc" #else -ct=unknown +ct="unknown" #endif +; EOF -ct=unknown -vv ']' "$CPP $CFLAGS $CPPFLAGS $NOWARN conftest.c | grep ct= | tr -d \\\\015 >x" +ct=untested +vv ']' "$CPP $CFLAGS $CPPFLAGS $NOWARN conftest.c | sed -n '/^ct *= */s//ct=/p' | tr -d \\\\015 >x" sed 's/^/[ /' x eval `cat x` rmf x vv.out @@ -786,6 +915,16 @@ vv '|' "$CC $CFLAGS $CPPFLAGS $LDFLAGS $NOWARN $LIBS -V" vv '|' "$CC $CFLAGS $CPPFLAGS $LDFLAGS $NOWARN -Wl,-V conftest.c $LIBS" ;; +uslc) + case $TARGET_OS:$TARGET_OSREV in + SCO_SV:3.2*) + # SCO OpenServer 5 + CFLAGS="$CFLAGS -g" + : ${HAVE_CAN_OTWO=0} ${HAVE_CAN_OPTIMISE=0} + ;; + esac + vv '|' "$CC $CFLAGS $CPPFLAGS $LDFLAGS $NOWARN -V conftest.c $LIBS" + ;; watcom) echo >&2 'Warning: Watcom C Compiler detected. This compiler has not yet been tested for compatibility with mksh. Continue at your @@ -797,7 +936,11 @@ vv '|' "ld -V" ;; *) + test x"$ct" = x"untested" && $e "!!! detecting preprocessor failed" ct=unknown + vv "$CC --version" + vv '|' "$CC $CFLAGS $CPPFLAGS $LDFLAGS $NOWARN -v conftest.c $LIBS" + vv '|' "$CC $CFLAGS $CPPFLAGS $LDFLAGS $NOWARN -V conftest.c $LIBS" ;; esac case $cm in @@ -844,6 +987,7 @@ 'if this could be tcc'; then ct=tcc CPP='cpp -D__TINYC__' + HAVE_COMPILER_KNOWN=1 fi if test $ct = sunpro; then @@ -924,7 +1068,6 @@ ac_flags 0 wnooverflow -Wno-overflow ac_flags 1 fnostrictaliasing -fno-strict-aliasing ac_flags 1 fstackprotectorall -fstack-protector-all - ac_flags 1 fwrapv -fwrapv test $cm = dragonegg && case " $CC $CFLAGS $LDFLAGS " in *\ -fplugin=*dragonegg*) ;; *) ac_flags 1 fplugin_dragonegg -fplugin=dragonegg ;; @@ -1021,6 +1164,7 @@ # flags common to a subset of compilers (run with -Werror on gcc) if test 1 = $i; then ac_flags 1 wall -Wall + ac_flags 1 fwrapv -fwrapv fi phase=x @@ -1115,24 +1259,6 @@ # if ac_ifcpp 'ifdef MKSH_SMALL' isset_MKSH_SMALL '' \ "if a reduced-feature mksh is requested"; then - #XXX this sucks; fix it for *all* compilers - case $ct in - clang|icc|nwcc) - ac_flags 1 fnoinline -fno-inline - ;; - gcc) - NOWARN=$DOWARN; phase=u - ac_flags 1 fnoinline -fno-inline - NOWARN=$save_NOWARN; phase=x - ;; - sunpro) - ac_flags 1 fnoinline -xinline= - ;; - xlc) - ac_flags 1 fnoinline -qnoinline - ;; - esac - : ${HAVE_NICE=0} : ${HAVE_PERSISTENT_HISTORY=0} check_categories="$check_categories smksh" @@ -1152,9 +1278,9 @@ ac_ifcpp 'ifdef MKSH_CONSERVATIVE_FDS' isset_MKSH_CONSERVATIVE_FDS '' \ 'if traditional/conservative fd use is requested' && \ check_categories="$check_categories convfds" -ac_ifcpp 'ifdef MKSH_DISABLE_DEPRECATED' isset_MKSH_DISABLE_DEPRECATED '' \ - "if deprecated features are to be omitted" && \ - check_categories="$check_categories nodeprecated" +#ac_ifcpp 'ifdef MKSH_DISABLE_DEPRECATED' isset_MKSH_DISABLE_DEPRECATED '' \ +# "if deprecated features are to be omitted" && \ +# check_categories="$check_categories nodeprecated" # # Environment: headers @@ -1276,7 +1402,7 @@ #define EXTERN #define MKSH_INCLUDES_ONLY #include "sh.h" - __RCSID("$MirOS: src/bin/mksh/Build.sh,v 1.484.2.10 2012/02/11 15:25:26 tg Exp $"); + __RCSID("$MirOS: src/bin/mksh/Build.sh,v 1.549 2012/04/14 16:07:43 tg Exp $"); int main(void) { printf("Hello, World!\n"); return (0); } EOF case $cm in @@ -1340,19 +1466,20 @@ # # Environment: library functions # -ac_testn flock_ex '' 'flock and mmap' <<-'EOF' - #include - #if HAVE_SYS_FILE_H - #include - #endif - #if HAVE_SYS_MMAN_H - #include - #endif +ac_test flock <<-'EOF' #include - #include - int main(void) { return ((void *)mmap(NULL, (size_t)flock(0, LOCK_EX), - PROT_READ, MAP_PRIVATE, 0, (off_t)0) == (void *)NULL ? 1 : - munmap(NULL, 0)); } + #undef flock + int main(void) { return (flock(0, LOCK_EX | LOCK_UN)); } +EOF + +ac_test lock_fcntl '!' flock 1 'whether we can lock files with fcntl' <<-'EOF' + #include + #undef flock + int main(void) { + struct flock lks; + lks.l_type = F_WRLCK | F_UNLCK; + return (fcntl(0, F_SETLKW, &lks)); + } EOF ac_test getrusage <<-'EOF' @@ -1381,10 +1508,19 @@ } EOF -ac_test mkstemp <<-'EOF' +ac_test mmap lock_fcntl 0 'for mmap and munmap' <<-'EOF' + #include + #if HAVE_SYS_FILE_H + #include + #endif + #if HAVE_SYS_MMAN_H + #include + #endif + #include #include - #include - int main(void) { char tmpl[] = "X"; return (mkstemp(tmpl)); } + int main(void) { return ((void *)mmap(NULL, (size_t)0, + PROT_READ, MAP_PRIVATE, 0, (off_t)0) == (void *)NULL ? 1 : + munmap(NULL, 0)); } EOF ac_test nice <<-'EOF' @@ -1454,18 +1590,6 @@ int main(void) { gid_t gid = 0; return (setgroups(0, &gid)); } EOF -ac_test strcasestr <<-'EOF' - #include - #include - #include - #if HAVE_STRINGS_H - #include - #endif - int main(int ac, char *av[]) { - return ((int)(ptrdiff_t)(void *)strcasestr(*av, av[ac])); - } -EOF - ac_test strlcpy <<-'EOF' #include int main(int ac, char *av[]) { return (strlcpy(*av, av[1], @@ -1477,7 +1601,7 @@ # save_CC=$CC; save_LDFLAGS=$LDFLAGS; save_LIBS=$LIBS CC="$CC -c -o $tcfn"; LDFLAGS=; LIBS= -ac_test '!' flock_decl flock_ex 1 'if flock() does not need to be declared' <<-'EOF' +ac_test '!' flock_decl flock 1 'if flock() does not need to be declared' <<-'EOF' #define MKSH_INCLUDES_ONLY #include "sh.h" long flock(void); /* this clashes if defined before */ @@ -1489,10 +1613,11 @@ long revoke(void); /* this clashes if defined before */ int main(void) { return ((int)revoke()); } EOF -ac_test sys_siglist_decl sys_siglist 1 'if sys_siglist[] does not need to be declared' <<-'EOF' +ac_test '!' sys_siglist_decl sys_siglist 1 'if sys_siglist[] does not need to be declared' <<-'EOF' #define MKSH_INCLUDES_ONLY #include "sh.h" - int main(void) { return (sys_siglist[0][0]); } + extern int sys_siglist[5][5][5][5][5]; /* this clashes happily */ + int main(void) { return (sys_siglist[0][0][0][0][0]); } EOF CC=$save_CC; LDFLAGS=$save_LDFLAGS; LIBS=$save_LIBS @@ -1500,7 +1625,9 @@ # other checks # fd='if to use persistent history' -ac_cache PERSISTENT_HISTORY || test 0 = $HAVE_FLOCK_EX || fv=1 +ac_cache PERSISTENT_HISTORY || case $HAVE_MMAP$HAVE_FLOCK$HAVE_LOCK_FCNTL in +11*|101) fv=1 ;; +esac test 1 = $fv || check_categories="$check_categories no-histfile" ac_testdone ac_cppflags @@ -1561,7 +1688,7 @@ # $e "${bi}run-time checks follow$ao, please ignore any weird errors" -ac_testnnd silent_idivwrapv '' '(run-time) whether signed integer division overflows wrap silently' <<-'EOF' +if ac_testnnd silent_idivwrapv '' '(run-time) whether signed integer division overflows wrap silently' <<-'EOF' #define MKSH_INCLUDES_ONLY #include "sh.h" #ifdef SIGFPE @@ -1581,7 +1708,8 @@ printf("si"); return (0); } - printf("no %d %d %d %d %s", o1, o2, r1, r2, av[0]); + printf("no %d %d %d %d %s", (int)o1, (int)o2, (int)r1, + (int)r2, av[0]); return (1); } #ifdef SIGFPE @@ -1592,19 +1720,21 @@ } #endif EOF -if test $fv = 0; then - echo "| hrm, compiling this failed, but we will just failback" -else - echo "| running test programme; this will fail if cross-compiling" - echo "| in which case we will gracefully degrade to the default" - ./$tcfn >vv.out 2>&1 - rv=$? - echo "| result: `cat vv.out`" - fv=0 - test $rv = 0 && test x"`cat vv.out`" = x"si" && fv=1 +then + if test $fv = 0; then + echo "| hrm, compiling this failed, but we will just failback" + else + echo "| running test programme; this will fail if cross-compiling" + echo "| in which case we will gracefully degrade to the default" + ./$tcfn >vv.out 2>&1 + rv=$? + echo "| result: `cat vv.out`" + fv=0 + test $rv = 0 && test x"`cat vv.out`" = x"si" && fv=1 + fi + rmf conftest.c conftest.o ${tcfn}* vv.out + ac_testdone fi -rmf conftest.c conftest.o ${tcfn}* vv.out -ac_testdone ac_cppflags $e "${bi}end of run-time checks$ao" @@ -1639,7 +1769,8 @@ else $e No list of signal names available via cpp. Falling back... fi - sigseen=: + sigseenone=: + sigseentwo=: echo '#include #ifndef NSIG #if defined(_NSIG) @@ -1648,18 +1779,20 @@ #define NSIG (SIGMAX+1) #endif #endif -mksh_cfg: NSIG' >conftest.c +int +mksh_cfg= NSIG +;' >conftest.c NSIG=`vq "$CPP $CFLAGS $CPPFLAGS $NOWARN conftest.c" | \ - grep mksh_cfg: | sed 's/^mksh_cfg:[ ]*\([0-9x ()+-]*\).*$/\1/'` + sed -n '/^mksh_cfg *=[ ]*\([0-9x ()+-]*\).*$/s//\1/p'` case $NSIG in - *[\ \(\)+-]*) NSIG=`awk "BEGIN { print $NSIG }"` ;; + *[\ \(\)+-]*) NSIG=`"$AWK" "BEGIN { print $NSIG }"` ;; esac printf=printf (printf hallo) >/dev/null 2>&1 || printf=echo test $printf = echo || NSIG=`printf %d "$NSIG" 2>/dev/null` $printf "NSIG=$NSIG ... " - sigs="ABRT ALRM BUS CHLD CLD CONT DIL EMT FPE HUP ILL INFO INT IO IOT" - sigs="$sigs KILL LOST PIPE PROF PWR QUIT RESV SAK SEGV STOP SYS TERM" + 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" test 1 = $HAVE_CPP_DD && test $NSIG -gt 1 && sigs="$sigs "`vq \ "$CPP $CFLAGS $CPPFLAGS $NOWARN -dD conftest.c" | \ @@ -1667,18 +1800,23 @@ sed 's/^\(.*[ ]SIG\)\([A-Z0-9]*\)\([ ].*\)$/\2/' | sort` test $NSIG -gt 1 || sigs= for name in $sigs; do + case $sigseenone in + *:$name:*) continue ;; + esac + sigseenone=$sigseenone$name: echo '#include ' >conftest.c - echo mksh_cfg: SIG$name >>conftest.c + echo int >>conftest.c + echo mksh_cfg= SIG$name >>conftest.c + echo ';' >>conftest.c vq "$CPP $CFLAGS $CPPFLAGS $NOWARN conftest.c" | \ - grep mksh_cfg: | \ - sed 's/^mksh_cfg:[ ]*\([0-9x]*\).*$/\1:'$name/ - done | grep -v '^:' | sed 's/:/ /g' | while read nr name; do + sed -n '/^mksh_cfg *=[ ]*\([0-9x]*\).*$/s//\1:'$name/p + done | sed -e '/^:/d' -e 's/:/ /g' | while read nr name; do test $printf = echo || nr=`printf %d "$nr" 2>/dev/null` test $nr -gt 0 && test $nr -le $NSIG || continue - case $sigseen in + case $sigseentwo in *:$nr:*) ;; *) echo " { \"$name\", $nr }," - sigseen=$sigseen$nr: + sigseentwo=$sigseentwo$nr: $printf "$name=$nr " >&2 ;; esac @@ -1687,10 +1825,12 @@ $e done. fi -addsrcs '!' HAVE_STRLCPY strlcpy.c +addsrcs -s '!' 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=409 $e $bi$me: Finished configuration testing, now producing output.$ao @@ -1702,10 +1842,11 @@ *) mkshexe=mksh ;; esac case $curdir in -*\ *) echo "#!./$mkshexe" >test.sh ;; -*) echo "#!$curdir/$mkshexe" >test.sh ;; +*\ *) mkshshebang="#!./$mkshexe" ;; +*) mkshshebang="#!$curdir/$mkshexe" ;; esac -cat >>test.sh <<-EOF +cat >test.sh <<-EOF + $mkshshebang LC_ALL=C PATH='$PATH'; export LC_ALL PATH test -n "\$KSH_VERSION" || exit 1 set -A check_categories -- $check_categories @@ -1780,7 +1921,8 @@ else emitbc=-c fi -echo set -x >Rebuild.sh +echo "# work around NeXTstep bug" >Rebuild.sh +echo set -x >>Rebuild.sh for file in $SRCS; do op=`echo x"$file" | sed 's/^x\(.*\)\.c$/\1./'` test -f $file || file=$srcdir/$file @@ -1914,11 +2056,13 @@ === Environment used === ==== build environment ==== +AWK default: awk CC default: cc CFLAGS if empty, defaults to -xO2 or +O2 or -O3 -qstrict or -O2, per compiler CPPFLAGS default empty LDFLAGS default empty; added before sources +LDSTATIC set this to '-static'; default unset LIBS default empty; added after sources [Interix] default: -lcrypt (XXX still needed?) NOWARN -Wno-error or similar @@ -1951,8 +2095,11 @@ MKSH_NO_DEPRECATED_WARNING omit warning when deprecated stuff is run MKSH_NO_EXTERNAL_CAT omit hack to skip cat builtin when flags passed MKSH_NO_LIMITS omit ulimit code +MKSH_NO_SIGSETJMP define if sigsetjmp is broken or not available MKSH_SMALL omit some code, optimise hard for size (slower) -MKSH_S_NOVI disable Vi editing mode (default if MKSH_SMALL) +MKSH_S_NOVI=1 disable Vi editing mode (default if MKSH_SMALL) +MKSH_TYPEDEF_SIG_ATOMIC_T define to e.g. 'int' if sig_atomic_t is missing +MKSH_TYPEDEF_SSIZE_T define to e.g. 'long' if your OS has no ssize_t MKSH_UNEMPLOYED disable job control (but not jobs/co-processes) === generic installation instructions === diff -Nru mksh-40.4/check.pl mksh-40.9.20120414/check.pl --- mksh-40.4/check.pl 2011-05-29 02:19:35.000000000 +0000 +++ mksh-40.9.20120414/check.pl 2012-04-06 12:22:38.000000000 +0000 @@ -1,7 +1,7 @@ -# $MirOS: src/bin/mksh/check.pl,v 1.27 2011/05/29 02:18:47 tg Exp $ +# $MirOS: src/bin/mksh/check.pl,v 1.31 2012/04/06 12:22:14 tg Exp $ # $OpenBSD: th,v 1.13 2006/05/18 21:27:23 miod Exp $ #- -# Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011 +# Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 # Thorsten Glaser # # Provided that these terms and disclaimer and all copyright notices @@ -75,6 +75,7 @@ # USER # (values taken from the environment of # the test harness). +# CYGWIN is set to nodosfilewarning. # ENV is set to /nonexistant. # __progname is set to the -p argument. # __perlname is set to $^X (perlexe). @@ -150,7 +151,24 @@ # p tag takes parameters (used with m). # s tag can be used several times. -use POSIX qw(EINTR); +# pull EINTR from POSIX.pm or Errno.pm if they exist +# otherwise just skip it +BEGIN { + $EINTR = 0; + eval { + require POSIX; + $EINTR = POSIX::EINTR(); + }; + if ($@) { + eval { + require Errno; + $EINTR = Errno::EINTR(); + } or do { + $EINTR = 0; + }; + } +}; + use Getopt::Std; use Config; @@ -262,6 +280,7 @@ 'PATH', 'SHELL', 'UNIXMODE', 'USER')) { $new_env{$env} = $ENV{$env} if defined $ENV{$env}; } +$new_env{'CYGWIN'} = 'nodosfilewarning'; $new_env{'ENV'} = '/nonexistant'; if (($os eq 'VMS') || ($Config{perlpath} =~ m/$Config{_exe}$/i)) { $new_env{'__perlname'} = $Config{perlpath}; @@ -555,7 +574,9 @@ $xpid = waitpid($pid, 0); $child_kill_ok = 0; if ($xpid < 0) { - next if $! == EINTR; + if ($EINTR) { + next if $! == $EINTR; + } print STDERR "$prog: error waiting for child - $!\n"; return undef; } diff -Nru mksh-40.4/check.t mksh-40.9.20120414/check.t --- mksh-40.4/check.t 2012-05-01 02:38:29.000000000 +0000 +++ mksh-40.9.20120414/check.t 2012-04-14 16:08:08.000000000 +0000 @@ -1,4 +1,4 @@ -# $MirOS: src/bin/mksh/check.t,v 1.474.2.12 2012/02/11 15:25:29 tg Exp $ +# $MirOS: src/bin/mksh/check.t,v 1.532 2012/04/14 16:07:44 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 $ @@ -29,7 +29,7 @@ # http://www.freebsd.org/cgi/cvsweb.cgi/src/tools/regression/bin/test/regress.sh?rev=HEAD expected-stdout: - @(#)MIRBSD KSH R40 2012/02/11 + @(#)MIRBSD KSH R40 2012/04/14 description: Check version of shell. stdin: @@ -298,9 +298,11 @@ description: Check division overflow wraps around silently stdin: - echo :$((-2147483648 / -1))_$((-2147483648 % -1)). + echo signed:$((-2147483648 / -1))r$((-2147483648 % -1)). + echo unsigned:$((# -2147483648 / -1))r$((# -2147483648 % -1)). expected-stdout: - :-2147483648_0. + signed:-2147483648r0. + unsigned:0r2147483648. --- name: arith-assop-assoc-1 description: @@ -1089,11 +1091,14 @@ description: Check that weird ${foo+bar} constructs are parsed correctly stdin: + print '#!'"$__progname"'\nfor x in "$@"; do print -r -- "$x"; done' >pfn + print '#!'"$__progname"'\nfor x in "$@"; do print -nr -- "<$x> "; done' >pfs + chmod +x pfn pfs (echo 1 ${IFS+'}'z}) 2>&- || echo failed in 1 (echo 2 "${IFS+'}'z}") 2>&- || echo failed in 2 (echo 3 "foo ${IFS+'bar} baz") 2>&- || echo failed in 3 - (echo -n '4 '; printf '%s\n' "foo ${IFS+"b c"} baz") 2>&- || echo failed in 4 - (echo -n '5 '; printf '%s\n' "foo ${IFS+b c} baz") 2>&- || echo failed in 5 + (echo -n '4 '; ./pfn "foo ${IFS+"b c"} baz") 2>&- || echo failed in 4 + (echo -n '5 '; ./pfn "foo ${IFS+b c} baz") 2>&- || echo failed in 5 (echo 6 ${IFS+"}"z}) 2>&- || echo failed in 6 (echo 7 "${IFS+"}"z}") 2>&- || echo failed in 7 (echo 8 "${IFS+\"}\"z}") 2>&- || echo failed in 8 @@ -1103,7 +1108,7 @@ (echo 12 "$(echo ${IFS+'}'z})") 2>&- || echo failed in 12 (echo 13 ${IFS+\}z}) 2>&- || echo failed in 13 (echo 14 "${IFS+\}z}") 2>&- || echo failed in 14 - u=x; (echo -n '15 '; printf '<%s> ' "foo ${IFS+a"b$u{ {"{{\}b} c ${IFS+d{}} bar" ${IFS-e{}} baz; echo .) 2>&- || echo failed in 15 + u=x; (echo -n '15 '; ./pfs "foo ${IFS+a"b$u{ {"{{\}b} c ${IFS+d{}} bar" ${IFS-e{}} baz; echo .) 2>&- || echo failed in 15 l=t; (echo 16 ${IFS+h`echo -n i ${IFS+$l}h`ere}) 2>&- || echo failed in 16 l=t; (echo 17 ${IFS+h$(echo -n i ${IFS+$l}h)ere}) 2>&- || echo failed in 17 l=t; (echo 18 "${IFS+h`echo -n i ${IFS+$l}h`ere}") 2>&- || echo failed in 18 @@ -1112,26 +1117,26 @@ l=t; (echo 21 ${IFS+h$(echo -n i "${IFS+$l}"h)ere}) 2>&- || echo failed in 21 l=t; (echo 22 "${IFS+h`echo -n i "${IFS+$l}"h`ere}") 2>&- || echo failed in 22 l=t; (echo 23 "${IFS+h$(echo -n i "${IFS+$l}"h)ere}") 2>&- || echo failed in 23 - key=value; (echo -n '24 '; printf '%s\n' "${IFS+'$key'}") 2>&- || echo failed in 24 - key=value; (echo -n '25 '; printf '%s\n' "${IFS+"'$key'"}") 2>&- || echo failed in 25 # ksh93: “'$key'” - key=value; (echo -n '26 '; printf '%s\n' ${IFS+'$key'}) 2>&- || echo failed in 26 - key=value; (echo -n '27 '; printf '%s\n' ${IFS+"'$key'"}) 2>&- || echo failed in 27 - (echo -n '28 '; printf '%s\n' "${IFS+"'"x ~ x'}'x"'}"x}" #') 2>&- || echo failed in 28 - u=x; (echo -n '29 '; printf '<%s> ' foo ${IFS+a"b$u{ {"{ {\}b} c ${IFS+d{}} bar ${IFS-e{}} baz; echo .) 2>&- || echo failed in 29 - (echo -n '30 '; printf '<%s> ' ${IFS+foo 'b\ + key=value; (echo -n '24 '; ./pfn "${IFS+'$key'}") 2>&- || echo failed in 24 + key=value; (echo -n '25 '; ./pfn "${IFS+"'$key'"}") 2>&- || echo failed in 25 # ksh93: “'$key'” + key=value; (echo -n '26 '; ./pfn ${IFS+'$key'}) 2>&- || echo failed in 26 + key=value; (echo -n '27 '; ./pfn ${IFS+"'$key'"}) 2>&- || echo failed in 27 + (echo -n '28 '; ./pfn "${IFS+"'"x ~ x'}'x"'}"x}" #') 2>&- || echo failed in 28 + u=x; (echo -n '29 '; ./pfs foo ${IFS+a"b$u{ {"{ {\}b} c ${IFS+d{}} bar ${IFS-e{}} baz; echo .) 2>&- || echo failed in 29 + (echo -n '30 '; ./pfs ${IFS+foo 'b\ ar' baz}; echo .) 2>&- || (echo failed in 30; echo failed in 31) - (echo -n '32 '; printf '<%s> ' ${IFS+foo "b\ + (echo -n '32 '; ./pfs ${IFS+foo "b\ ar" baz}; echo .) 2>&- || echo failed in 32 - (echo -n '33 '; printf '<%s> ' "${IFS+foo 'b\ + (echo -n '33 '; ./pfs "${IFS+foo 'b\ ar' baz}"; echo .) 2>&- || echo failed in 33 - (echo -n '34 '; printf '<%s> ' "${IFS+foo "b\ + (echo -n '34 '; ./pfs "${IFS+foo "b\ ar" baz}"; echo .) 2>&- || echo failed in 34 - (echo -n '35 '; printf '<%s> ' ${v=a\ b} x ${v=c\ d}; echo .) 2>&- || echo failed in 35 - (echo -n '36 '; printf '<%s> ' "${v=a\ b}" x "${v=c\ d}"; echo .) 2>&- || echo failed in 36 - (echo -n '37 '; printf '<%s> ' ${v-a\ b} x ${v-c\ d}; echo .) 2>&- || echo failed in 37 + (echo -n '35 '; ./pfs ${v=a\ b} x ${v=c\ d}; echo .) 2>&- || echo failed in 35 + (echo -n '36 '; ./pfs "${v=a\ b}" x "${v=c\ d}"; echo .) 2>&- || echo failed in 36 + (echo -n '37 '; ./pfs ${v-a\ b} x ${v-c\ d}; echo .) 2>&- || echo failed in 37 (echo 38 ${IFS+x'a'y} / "${IFS+x'a'y}" .) 2>&- || echo failed in 38 foo="x'a'y"; (echo 39 ${foo%*'a'*} / "${foo%*'a'*}" .) 2>&- || echo failed in 39 - foo="a b c"; (echo -n '40 '; printf '<%s> ' "${foo#a}"; echo .) 2>&- || echo failed in 40 + foo="a b c"; (echo -n '40 '; ./pfs "${foo#a}"; echo .) 2>&- || echo failed in 40 expected-stdout: 1 }z 2 ''z} @@ -1889,7 +1894,8 @@ Check that symbolic links aren't stat()'d # breaks on FreeMiNT (cannot unlink dangling symlinks) # breaks on MSYS (does not support symlinks) -category: !os:mint,!os:msys +# breaks on Dell UNIX 4.0 R2.2 (SVR4) where unlink also fails +category: !os:mint,!os:msys,!os:svr4.0 file-setup: dir 755 "dir" file-setup: symlink 644 "dir/abc" non-existent-file @@ -3620,20 +3626,10 @@ 64 64 --- -name: integer-base-check-flat-posix -description: - Check behaviour of POSuX bases -category: !nodeprecated -stdin: - echo :$((10)).$((010)).$((0x10)). -expected-stdout: - :10.8.16. ---- -name: integer-base-check-flat-right +name: integer-base-check-flat description: Check behaviour does not match POSuX, because a not type-safe scripting language has *no* business interpreting "010" as octal -category: nodeprecated stdin: echo :$((10)).$((010)).$((0x10)). expected-stdout: @@ -3937,7 +3933,7 @@ Check read with delimiters stdin: emit() { - printf 'foo bar\tbaz\nblah \0blub\tblech\nmyok meck \0' + print -n 'foo bar\tbaz\nblah \0blub\tblech\nmyok meck \0' } emit | while IFS= read -d "" foo; do print -r -- "<$foo>"; done emit | while read -d "" foo; do print -r -- "<$foo>"; done @@ -4502,12 +4498,15 @@ description: Can't use command line assignments to assign readonly parameters. stdin: + print '#!'"$__progname"'\nunset RANDOM\nexport | while IFS= read -r' \ + 'RANDOM; do eval '\''print -r -- "$RANDOM=$'\''"$RANDOM"'\'\"\'\; \ + done >env; chmod +x env; PATH=.:$PATH foo=bar readonly foo foo=stuff env | grep '^foo' expected-exit: e != 0 expected-stderr-pattern: - /.*read *only.*/ + /read-only/ --- name: regression-43 description: @@ -4617,10 +4616,10 @@ description: Check that aliases do not use continuation prompt after trailing semi-colon. -file-setup: file 644 "env" +file-setup: file 644 "envf" PS1=Y PS2=X -env-setup: !ENV=./env! +env-setup: !ENV=./envf! need-ctty: yes arguments: !-i! stdin: @@ -4647,11 +4646,11 @@ name: regression-52 description: Check that globbing works in pipelined commands -file-setup: file 644 "env" +file-setup: file 644 "envf" PS1=P file-setup: file 644 "abc" stuff -env-setup: !ENV=./env! +env-setup: !ENV=./envf! need-ctty: yes arguments: !-i! stdin: @@ -5002,7 +5001,6 @@ name: regression-66 description: Check that quoting is sane - XXX not really in R40-stable stdin: ac_space=' ' ac_newline=' @@ -5021,7 +5019,7 @@ done expected-stdout: ac_space=' ' - ac_newline=' + ac_newline=$'\n' --- name: readonly-0 description: @@ -5039,7 +5037,7 @@ = 1 x . expected-stderr-pattern: - /read *only/ + /read-only/ --- name: readonly-1 description: @@ -5049,7 +5047,7 @@ expected-stdout: aborted, 2 expected-stderr-pattern: - /read *only/ + /read-only/ --- name: readonly-2a description: @@ -5068,7 +5066,7 @@ expected-stdout: 2 . expected-stderr-pattern: - /read *only/ + /read-only/ --- name: readonly-3 description: @@ -5080,7 +5078,7 @@ 0 x . 2 . expected-stderr-pattern: - /read *only/ + /read-only/ --- name: syntax-1 description: @@ -5185,6 +5183,9 @@ description: Check to see if exec sets it's environment correctly stdin: + print '#!'"$__progname"'\nunset RANDOM\nexport | while IFS= read -r' \ + 'RANDOM; do eval '\''print -r -- "$RANDOM=$'\''"$RANDOM"'\'\"\'\; \ + done >env; chmod +x env; PATH=.:$PATH FOO=bar exec env expected-stdout-pattern: /(^|.*\n)FOO=bar\n/ @@ -5194,9 +5195,11 @@ Check to make sure exec doesn't change environment if a program isn't exec-ed stdin: - sortprog=$(whence -p sort) || sortprog=cat - env | $sortprog | grep -v '^RANDOM=' >bar1 - FOO=bar exec; env | $sortprog | grep -v '^RANDOM=' >bar2 + print '#!'"$__progname"'\nunset RANDOM\nexport | while IFS= read -r' \ + 'RANDOM; do eval '\''print -r -- "$RANDOM=$'\''"$RANDOM"'\'\"\'\; \ + done >env; chmod +x env; PATH=.:$PATH + env >bar1 + FOO=bar exec; env >bar2 cmp -s bar1 bar2 --- name: exec-function-environment-1 @@ -5416,6 +5419,10 @@ description: Check some "exit on error" conditions stdin: + print '#!'"$__progname"'\nexec "$1"' >env + print '#!'"$__progname"'\nexit 1' >false + chmod +x env false + PATH=.:$PATH set -ex env false && echo something echo END @@ -5429,6 +5436,11 @@ description: Check some "exit on error" edge conditions (POSIXly) stdin: + print '#!'"$__progname"'\nexec "$1"' >env + print '#!'"$__progname"'\nexit 1' >false + print '#!'"$__progname"'\nexit 0' >true + chmod +x env false + PATH=.:$PATH set -ex if env true; then env false && echo something @@ -6367,23 +6379,25 @@ description: Check if bash-style arrays work as expected, with newlines stdin: + print '#!'"$__progname"'\nfor x in "$@"; do print -nr -- "$x|"; done' >pfp + chmod +x pfp test -n "$ZSH_VERSION" && setopt KSH_ARRAYS v="e f" foo=(a bc d \$v "$v" '$v' g ) - printf '%s|' "${#foo[*]}" "${foo[0]}" "${foo[1]}" "${foo[2]}" "${foo[3]}" "${foo[4]}" "${foo[5]}" "${foo[6]}"; echo + ./pfp "${#foo[*]}" "${foo[0]}" "${foo[1]}" "${foo[2]}" "${foo[3]}" "${foo[4]}" "${foo[5]}" "${foo[6]}"; echo foo=(a\ bc d \$v "$v" '$v' g ) - printf '%s|' "${#foo[*]}" "${foo[0]}" "${foo[1]}" "${foo[2]}" "${foo[3]}" "${foo[4]}" "${foo[5]}" "${foo[6]}"; echo + ./pfp "${#foo[*]}" "${foo[0]}" "${foo[1]}" "${foo[2]}" "${foo[3]}" "${foo[4]}" "${foo[5]}" "${foo[6]}"; echo foo=(a\ bc\\ d \$v "$v" '$v' g) - printf '%s|' "${#foo[*]}" "${foo[0]}" "${foo[1]}" "${foo[2]}" "${foo[3]}" "${foo[4]}" "${foo[5]}" "${foo[6]}"; echo + ./pfp "${#foo[*]}" "${foo[0]}" "${foo[1]}" "${foo[2]}" "${foo[3]}" "${foo[4]}" "${foo[5]}" "${foo[6]}"; echo expected-stdout: 7|a|bc|d|$v|e f|$v|g| 7|a|bc|d|$v|e f|$v|g| @@ -7070,9 +7084,14 @@ 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: - E76664C2 57F1BA9A 04808901 . + D50219A0 20E5DB5B 00000001 . + 554A1C76 004A212E CB209562 . + 6B21CF91 20E5DB5B 124EA49D . --- name: varexpand-null-1 description: @@ -7090,7 +7109,9 @@ description: Ensure empty strings, when quoted, are expanded as empty strings stdin: - printf '<%s> ' 1 "${a}" 2 "${a#?}" + "${b%?}" 3 "${a=}" + "${b/c/d}" + print '#!'"$__progname"'\nfor x in "$@"; do print -nr -- "<$x> "; done' >pfs + chmod +x pfs + ./pfs 1 "${a}" 2 "${a#?}" + "${b%?}" 3 "${a=}" + "${b/c/d}" echo . expected-stdout: <1> <> <2> <> <+> <> <3> <> <+> <> . @@ -7113,16 +7134,13 @@ --- name: print-nul-chars description: - Check handling of NUL characters for print and read - note: second line should output “4 3” but we cannot - handle NUL characters in strings yet + Check handling of NUL characters for print and COMSUB stdin: - print $(($(print '<\0>' | wc -c))) x=$(print '<\0>') - print $(($(print "$x" | wc -c))) ${#x} -expected-stdout: - 4 - 3 2 + print $(($(print '<\0>' | wc -c))) $(($(print "$x" | wc -c))) \ + ${#x} "$x" '<\0>' +expected-stdout-pattern: + /^4 3 2 <> <\0>$/ --- name: print-escapes description: @@ -7199,7 +7217,9 @@ description: Check backslash expansion by $'…' strings stdin: - printf '%s\n' $'\ \!\"\#\$\%\&\'\(\)\*\+\,\-\.\/ \1\2\3\4\5\6' \ + print '#!'"$__progname"'\nfor x in "$@"; do print -r -- "$x"; done' >pfn + chmod +x pfn + ./pfn $'\ \!\"\#\$\%\&\'\(\)\*\+\,\-\.\/ \1\2\3\4\5\6' \ $'a\0b' $'a\01b' $'\7\8\9\:\;\<\=\>\?\@\A\B\C\D\E\F\G\H\I' \ $'\J\K\L\M\N\O\P\Q\R\S\T\U1\V\W\X\Y\Z\[\\\]\^\_\`\a\b\d\e' \ $'\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u1\v\w\x1\y\z\{\|\}\~ $x' \ @@ -7856,6 +7876,7 @@ name: ulimit-1 description: Check if we can use a specific syntax idiom for ulimit +category: !os:syllable stdin: if ! x=$(ulimit -d) || [[ $x = unknown ]]; then #echo expected to fail on this OS @@ -8074,6 +8095,9 @@ global environment. Inspired by PR 2450. stdin: + print '#!'"$__progname"'\nunset RANDOM\nexport | while IFS= read -r' \ + 'RANDOM; do eval '\''print -r -- "$RANDOM=$'\''"$RANDOM"'\'\"\'\; \ + done >env; chmod +x env; PATH=.:$PATH function k { if [ x$FOO != xbar ]; then echo 1 @@ -8220,6 +8244,7 @@ is a must (a non-recursive parser cannot pass all three of these test cases, especially the ‘#’ is difficult) stdin: + print '#!'"$__progname"'\necho 1234' >id; chmod +x id; PATH=.:$PATH echo $(typeset -i10 x=16#20; echo $x) echo $(typeset -Uui16 x=16#$(id -u) ) . @@ -8255,16 +8280,18 @@ description: Check COMSUB works with aliases (does not expand them twice) stdin: + print '#!'"$__progname"'\nfor x in "$@"; do print -r -- "$x"; done' >pfn + chmod +x pfn alias echo='echo a' foo() { - printf '%s\n' "$(echo foo)" + ./pfn "$(echo foo)" } - printf '%s\n' "$(echo b)" + ./pfn "$(echo b)" typeset -f foo expected-stdout: a b foo() { - printf "%s\\n" "$(echo foo )" + ./pfn "$(echo foo )" } --- name: comsub-torture @@ -9376,99 +9403,6 @@ 11 0 12 0 --- -name: event-subst-1a -description: - Check that '!' substitution in interactive mode works -category: !smksh,!nodeprecated -file-setup: file 755 "falsetto" - #! /bin/sh - echo molto bene - exit 42 -file-setup: file 755 "!false" - #! /bin/sh - echo si -need-ctty: yes -arguments: !-i! -stdin: - export PATH=.:$PATH - falsetto - echo yeap - !false -expected-exit: 42 -expected-stdout: - molto bene - yeap - molto bene -expected-stderr-pattern: - /.*/ ---- -name: event-subst-1b -description: - Check that '!' substitution in interactive mode works - even when a space separates it from the search command, - which is not what GNU bash provides but required for the - other regression tests below to check -category: !smksh,!nodeprecated -file-setup: file 755 "falsetto" - #! /bin/sh - echo molto bene - exit 42 -file-setup: file 755 "!" - #! /bin/sh - echo si -need-ctty: yes -arguments: !-i! -stdin: - export PATH=.:$PATH - falsetto - echo yeap - ! false -expected-exit: 42 -expected-stdout: - molto bene - yeap - molto bene -expected-stderr-pattern: - /.*/ ---- -name: event-subst-2 -description: - Check that '!' substitution in interactive mode - does not break things -category: !smksh,!nodeprecated -file-setup: file 755 "falsetto" - #! /bin/sh - echo molto bene - exit 42 -file-setup: file 755 "!" - #! /bin/sh - echo si -need-ctty: yes -arguments: !-i! -env-setup: !ENV=./Env! -file-setup: file 644 "Env" - PS1=X -stdin: - export PATH=.:$PATH - falsetto - echo yeap - !false - echo meow - ! false - echo = $? - if - ! false; then echo foo; else echo bar; fi -expected-stdout: - molto bene - yeap - molto bene - meow - molto bene - = 42 - foo -expected-stderr-pattern: - /.*/ ---- name: event-subst-3 description: Check that '!' substitution in noninteractive mode is ignored @@ -9501,7 +9435,6 @@ name: event-subst-0 description: Check that '!' substitution in interactive mode is ignored -category: nodeprecated need-ctty: yes arguments: !-i! file-setup: file 755 "falsetto" @@ -10191,6 +10124,10 @@ (( u )) || set -U } - s=$("$__perlname" -e 'print "a"x12120;') + i=-1 + s= + while (( ++i < 12120 )); do + s+=a + done Lb64decode $s >/dev/null --- diff -Nru mksh-40.4/debian/changelog mksh-40.9.20120414/debian/changelog --- mksh-40.4/debian/changelog 2012-05-01 02:38:29.000000000 +0000 +++ mksh-40.9.20120414/debian/changelog 2012-04-14 18:52:25.000000000 +0000 @@ -1,3 +1,100 @@ +mksh (40.9.20120414-2) unstable; urgency=low + + * The “still more buggy than I had hoped” upload + * When running mtests, time-limit every test to prevent hanging builds + * Add back ppc64, packages.d.o brokenness had me fooled + * m68k specific klibc workaround: -g but no -O are needed (gcc bug?) + + -- Thorsten Glaser Sat, 14 Apr 2012 18:48:37 +0000 + +mksh (40.9.20120414-1) unstable; urgency=low + + * The “ziek zijn zuigt” upload + * d/source/format 3.0 (quilt), with local single-debian-patch + * Honour DevRef §6.7.8.2.(4) wrt. top-level directory name + * Base on mksh-current HEAD of today: + - [tg] New Build.sh environment configurable: LDSTATIC (empty) + - [tg] Improve LTO effect by always adding our copies of distributed + utility function sources when linking statically (i.e. LDSTATIC is + not empty) + - [tg] Drop deprecated hack for lines beginning with an exclamation mark + - [tg] No longer interpret numbers beginning with a 0 digit as octal + - [tg] Attempt to use -fwrapv on more compilers + - [tg, RT] Better portability to 386BSD + - [tg] No longer use mkstemp(3) or tempnam(3) functions, do our own + - [tg] Fix some bugs in the manual page + * Try klibc and fix missing optimisation for size with it + * Note klibc and dietlibc both disable ProPolice SSP + + -- Thorsten Glaser Sat, 14 Apr 2012 16:58:58 +0000 + +mksh (40.5-3) unstable; urgency=low + + * The “Basti” intermediate upload + * Add a minitest that select(2) works (fails on dietlibc/ppc64) + * Patch up to mksh-current HEAD of today: + - [tg, RT] Implement fcntl(2)-based advisory locking as an + alternative iff flock(2) is not found (LP: #912691); keep + trying to lock in the face of EINTR on OSes that throw it + - [tg] Improve testsuite, build-time checks and debugging output + - [tg, RT, winstonw] Improve portability to BeOS (broken), + Cygwin (good), SCO OpenServer (good), SCO UnixWare (good), + USL C, Plan 9 (broken), … + - [tg] rlim_t is supposed to be unsigned + - [tg] Some code and warning cleanup + * Revert the 40.5-2 dietlibc test change as promised + + -- Thorsten Glaser Thu, 29 Mar 2012 19:35:09 +0000 + +mksh (40.5-2) unstable; urgency=low + + * The “meow korn shell” upload + * We build on DEB_BUILD_ARCH for DEB_HOST_ARCH, not the other way round, + take this in mind when deciding based on the target system (DEB_HOST) + * Add hotfix for regression in 40.5 wrt. tty initialisation handling + - [tg] Fix severe regression wrt. initialising tty(4) states + * Build-Depend on newer dietlibc upload for testing that (will be + removed in the next upload when 40.6 is out); if needed, we can + always block the 40.5-1 upload from entering testing + * Build with --as-needed + + -- Thorsten Glaser Sun, 25 Mar 2012 20:34:46 +0000 + +mksh (40.5-1) unstable; urgency=low + + * The “amused” upload + * Patch up to mksh R40-stable branch of today: + - [tg, RT, lewellyn] Better support for SkyOS, Minix 3, Ninix 3, + QNX and various BSD/OS versions + - [tg] Fix regression in mirtoconf output wrt. cached values (introduced + with check if divmod fixup was needed) + - [tg] Drop some Android-specific unused code (lsmod builtin) + - [tg] More code cleanup and new developer-only debugging functions + - [tg, Andrew Kudryashov] Fix some tab completion related escaping bugs + - [tg, draenog] Honour COLUMNS and LINES from the environment in scripts + - [tg, winstonw] The sleep built-in utility now blocks more signals + - [tg] Warn when using another deprecated function that will be removed + * New upstream distfile from the above + * Patch up to mksh-current HEAD of today: + - [tg] Drop “set ±o arc4random” (deprecated in R40) + - [tg] Drop old Build.sh -long-options (deprecated in R40) + - [tg] Change the internal hash algorithm from Bob Jenkins’ one-at-a-time + to its NUL-counting, always-changing, never-zero, better-avalanching + MirOS variant NZAT + - [tg] Use $'…' for non-ASCII parameters for re-entry printing + - [tg] Use sane spelling of “read-only” consistently + - [tg] Improve tree -DDEBUG functions (internal/developer use) + - [tg] Reduce stack usage a bit; speed up hash tables at size cost + - [tg] MKSH_SMALL no longer implies -fno-inline + - [tg] Support optional seed in ${parameter@#seed} for security + * Consider yourself warned about the following things: + - once klibc ships mkstemp() we will build mksh-static against it + - soon, probably before the wheezy freeze even, we will disable + deprecated code (which users of are warned about, at the moment) + * Policy 3.9.3 (no relevant changes) + + -- Thorsten Glaser Sat, 24 Mar 2012 23:30:11 +0000 + mksh (40.4-3) unstable; urgency=low * The “sleepy” upload diff -Nru mksh-40.4/debian/control mksh-40.9.20120414/debian/control --- mksh-40.4/debian/control 2012-05-01 02:38:29.000000000 +0000 +++ mksh-40.9.20120414/debian/control 2012-04-14 18:33:08.000000000 +0000 @@ -1,4 +1,4 @@ -# $MirOS: contrib/hosted/tg/deb/mksh/debian/control,v 1.65 2012/02/11 17:00:59 tg Exp $ +# $MirOS: contrib/hosted/tg/deb/mksh/debian/control,v 1.71 2012/04/14 18:32:44 tg Exp $ # Source: mksh Section: shells @@ -10,11 +10,15 @@ # note to porters: dropping the dietlibc-dev B-D is fine, will use eglibc then # but do not unversion the B-D where it is versioned, older versions are buggy # (not all buggy versions are excluded - but caught by the testsuite, run it!) +# same applies to klibc Build-Depends: bsdmainutils, debhelper (>= 5), ed, - locales [!avr32] | belocs-locales-bin [!avr32], +#XXX klibc on powerpcspe and hppa aren't built yet + libklibc-dev (>= 2.0~) [alpha amd64 armel armhf i386 ia64 m68k mips mipsel powerpc ppc64 s390 s390x sh4 sparc sparc64], +#XXX dietlibc on hppa isn't built yet (needs versioning) dietlibc-dev [alpha amd64 arm armeb i386 ia64 mips mipsel powerpc ppc64 sparc], - dietlibc-dev (>= 0.33~cvs20111108-5~) [armel armhf s390 s390x sparc64] -Standards-Version: 3.9.2 + dietlibc-dev (>= 0.33~cvs20111108-5~) [armel armhf s390 s390x sparc64], + locales [!avr32] | belocs-locales-bin [!avr32] +Standards-Version: 3.9.3 # First word is the $CVSROOT (-d arg) string, second word the module. # Upstream is on the same server, in the "mksh" module. Vcs-CVS: :ext:_anoncvs@anoncvs.mirbsd.org:/cvs contrib/hosted/tg/deb/mksh @@ -39,10 +43,11 @@ This shell is Debian Policy 10.4 compliant and may be used as /bin/sh on Debian systems, in both /bin/mksh and /bin/mksh-static flavours. . - The mksh-static binary is a version of mksh, linked against dietlibc - (if dietlibc exists for that Debian architecture), and optimised for - small code size, for example for use on initrd or initramfs images, - installation or rescue systems, or /bin/sh on slow architectures. + The mksh-static binary is a version of mksh, linked against klibc or + dietlibc (if they exist for that Debian architecture and are usable) + and optimised for small code size, for example for use on initrd or + initramfs images, installation or rescue systems, or /bin/sh on slow + architectures. It omits some leaf features to be even smaller. . A sample ~/.mkshrc is included in /usr/share/doc/mksh/examples and diff -Nru mksh-40.4/debian/copyright mksh-40.9.20120414/debian/copyright --- mksh-40.4/debian/copyright 2012-05-01 02:38:29.000000000 +0000 +++ mksh-40.9.20120414/debian/copyright 2012-04-14 16:45:52.000000000 +0000 @@ -1,7 +1,7 @@ This package was debianised by Thorsten Glaser on Sat, 28 May 2005 22:02:17 +0000. -$MirOS: contrib/hosted/tg/deb/mksh/debian/copyright,v 1.26 2012/02/11 17:00:59 tg Exp $ +$MirOS: contrib/hosted/tg/deb/mksh/debian/copyright,v 1.28 2012/04/14 16:45:28 tg Exp $ It was downloaded via "debian/rules get-orig-source". This both makes using CVS snapshots easier and is needed because upstream @@ -14,9 +14,9 @@ is OSI approved, as reproduced below. Binaries of the MirBSD Korn Shell on systems whose libc does -not provide a strlcpy function will additionally contain an -implementation under the ISC Licence, which is OSI approved -and also reproduced below. +not provide a strlcpy function, as well as mksh-static, will +additionally contain an implementation under the ISC Licence +which is OSI approved and also reproduced below. All Debian binaries of mksh R39 and up also pull in the UCB code SLOB printf.c to have a printf(1) builtin (also OSI approved). @@ -28,14 +28,14 @@ The MirBSD Korn Shell (mksh) is Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 - Thorsten "mirabilos" Glaser + Thorsten “mirabilos” Glaser All rights reserved. The mksh logo is Copyright © 2008, 2009 Lukas U. Copyright © 2008, 2009 - Thorsten "mirabilos" Glaser + Thorsten “mirabilos” Glaser Provided that these terms and disclaimer and all copyright notices are retained or reproduced in an accompanying document, permission diff -Nru mksh-40.4/debian/meat mksh-40.9.20120414/debian/meat --- mksh-40.4/debian/meat 2012-05-01 02:38:29.000000000 +0000 +++ mksh-40.9.20120414/debian/meat 2012-04-14 18:46:49.000000000 +0000 @@ -1,11 +1,11 @@ -# $MirOS: contrib/hosted/tg/deb/mksh/debian/meat,v 1.33 2012/02/11 17:01:00 tg Exp $ +# $MirOS: contrib/hosted/tg/deb/mksh/debian/meat,v 1.40 2012/04/14 18:46:25 tg Exp $ #- # Design: this thing is intended to build two mksh binaries, # mksh-full and mksh-static (with the latter being statical- # ly linked) according to DEB_BUILD_OPTIONS set: # - nocheck: do not run mksh's regression test suite # - noopt: build mksh with -O0, for eglibc builds only -# - nodbg: do not build with debugging info (for eglibc builds) +# - nodbg: do not build with debugging info # - nostrip: handled by dh_strip, so ignored here # - parallel=n: currently ignored, maybe -flto=jobserver could use it # - mksh-firstbuilt: do not run a simple test for operational @@ -15,8 +15,9 @@ # - nomksh-small: do not build mksh-static with -DMKSH_SMALL # # Default values are: -# - mksh-static=dietlibc,eglibc +# - mksh-static=klibc,dietlibc,eglibc # if mksh-firstbuilt is set: +# - mksh-static=dietlibc,eglibc on certain targets (see below for details) # - mksh-static=eglibc on certain targets (see below for details) # # If we are cross-building, mksh-firstbuilt will be set. @@ -47,7 +48,7 @@ echo "$resultest" | sed 's/^/| /' fi echo "Variables used:" - for v in CC CFLAGS CPPFLAGS LDFLAGS LIBS; do + for v in CC CFLAGS CPPFLAGS LDFLAGS LDSTATIC LIBS; do eval x=\$$v echo "| $v='$x'" done @@ -64,11 +65,12 @@ normalise CFLAGS normalise CPPFLAGS normalise LDFLAGS + # do not normalise LDSTATIC normalise LIBS cd builddir/$where echo "Attempting compilation of mksh in $where with CC='$CC'" echo "CFLAGS='$CFLAGS' CPPFLAGS='$CPPFLAGS'" - echo "LDFLAGS='$LDFLAGS' LIBS='$LIBS'" + echo "LDFLAGS='$LDFLAGS' LDSTATIC='$LDSTATIC' LIBS='$LIBS'" buildok=0 arg='-r -c lto' @@ -77,7 +79,8 @@ startdate=$(date -u) set -x CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" LDFLAGS="$LDFLAGS" \ - LIBS="$LIBS" sh ../../Build.sh $arg && test -f mksh && gotbin=1 + LDSTATIC="$LDSTATIC" LIBS="$LIBS" sh ../../Build.sh $arg && \ + test -f mksh && gotbin=1 set +x test -f Rebuild.sh && test x"$HAVE_CAN_COMBINE" != x"0" && \ if test $gotbin = 0; then @@ -138,7 +141,7 @@ return fi buildinfo=regressed - resultest=$(grep '^[FPT]' utest.log 2>&1 | fgrep -v \ + resultest=$(grep -a '^[FPT]' utest.log 2>&1 | fgrep -a -v \ -e 'Testing mksh for conformance' \ -e 'This shell is actually') fi @@ -156,17 +159,13 @@ export DEB_BUILD_MAINT_OPTIONS # pull environment configuration -for varname in DEB_BUILD_ARCH DEB_BUILD_GNU_TYPE DEB_HOST_GNU_TYPE; do - eval x=\$$varname - test x"$x" = x"" || continue - x=$(dpkg-architecture -q$varname) - eval $varname=\$x -done +eval $(dpkg-architecture -s) rm -rf builddir mkdir builddir builddir/full builddir/static -echo "Building the mksh package on '$DEB_BUILD_ARCH' with DEB_BUILD_OPTIONS '$DEB_BUILD_OPTIONS'" +echo "Building the package 'mksh' on '$DEB_BUILD_ARCH' for '$DEB_HOST_ARCH'" \ + "with DEB_BUILD_OPTIONS '$DEB_BUILD_OPTIONS'" echo "Values (not used) from environment: CFLAGS='$CFLAGS' CPPFLAGS='$CPPFLAGS' LDFLAGS='$LDFLAGS'" # parse options @@ -177,7 +176,7 @@ static=unset small=1 -if test x"$DEB_BUILD_GNU_TYPE" = x"$DEB_HOST_GNU_TYPE"; then +if test x"$DEB_HOST_ARCH" = x"$DEB_BUILD_ARCH"; then firstbuilt=0 else echo Using first built binary because we are cross-compiling @@ -210,6 +209,7 @@ dLDFLAGS=$(dpkg-buildflags --get LDFLAGS 2>/dev/null) echo "Values from dpkg-buildflags: CFLAGS='$dCFLAGS' CPPFLAGS='$dCPPFLAGS' LDFLAGS='$dLDFLAGS'" dCFLAGS="$dCFLAGS -Wall -Wextra" +dLDFLAGS="$dLDFLAGS -Wl,--as-needed" HAVE_CAN_WALL=0; export HAVE_CAN_WALL # Debian #499139 dCPPFLAGS="$dCPPFLAGS -DMKSH_BINSHREDUCED" @@ -219,19 +219,28 @@ HAVE_LIBUTIL_H=0; export HAVE_LIBUTIL_H # avr32 currently has no locales -if test x"$DEB_BUILD_ARCH" = x"avr32"; then +if test x"$DEB_HOST_ARCH" = x"avr32"; then HAVE_SETLOCALE_CTYPE=0; export HAVE_SETLOCALE_CTYPE fi # set mksh-static default values if none given if test x"$static" = x"unset"; then - static=dietlibc,eglibc - case $firstbuilt$static:$DEB_BUILD_ARCH in - (*:hppa) + static=klibc,dietlibc,eglibc + case $firstbuilt$static:$DEB_HOST_ARCH in + (1*:hppa) # revisit once dietlibc and lsb-release are built # and this arch has caught up (meat,v 1.32 e.g.) + # or of course if klibc has gotten usable on hppa static=eglibc ;; + (0*:hppa) + # let's see whether... + static=klibc,eglibc + ;; + (1*) + # revisit once klibc results are in + static=dietlibc,eglibc + ;; esac fi @@ -262,6 +271,7 @@ CFLAGS=$dCFLAGS CPPFLAGS=$dCPPFLAGS LDFLAGS=$dLDFLAGS +unset LDSTATIC LIBS= echo Building mksh-full... trybuild full @@ -301,9 +311,14 @@ continue fi CC=klcc - CFLAGS="$sCFLAGS -fno-stack-protector -g" + CFLAGS="$sCFLAGS -fno-stack-protector -Os" + test $nodbg = 1 || CFLAGS="$CFLAGS -g" + # -g with no -O is the only way to get it working, toolchain bug? + test x"$DEB_HOST_ARCH" = x"m68k" && \ + CFLAGS="$sCFLAGS -fno-stack-protector -g" CPPFLAGS="$sCPPFLAGS -DMKSH_NO_LIMITS" - LDFLAGS="$sLDFLAGS -static" + LDFLAGS="$sLDFLAGS" + LDSTATIC="-static" LIBS=$sLIBS HAVE_CAN_COMBINE=0; export HAVE_CAN_COMBINE trybuild static @@ -316,8 +331,10 @@ fi CC="diet -v -Os $sCC" CFLAGS=$sCFLAGS + # debug builds are too fragile here, IIRC CPPFLAGS=$sCPPFLAGS LDFLAGS=$sLDFLAGS + LDSTATIC=" " LIBS=$sLIBS echo "Note: all warning: dereferencing pointer 'p' does break" \ "strict-aliasing rules come from dietlibc, not mksh!" @@ -326,8 +343,10 @@ (eglibc) CC=$sCC CFLAGS="-Os $sCFLAGS" + test $nodbg = 1 || CFLAGS="$CFLAGS -g" CPPFLAGS=$sCPPFLAGS - LDFLAGS="$sLDFLAGS -static" + LDFLAGS="$sLDFLAGS" + LDSTATIC="-static" LIBS=$sLIBS trybuild static ;; diff -Nru mksh-40.4/debian/mtest.t mksh-40.9.20120414/debian/mtest.t --- mksh-40.4/debian/mtest.t 2012-05-01 02:38:29.000000000 +0000 +++ mksh-40.9.20120414/debian/mtest.t 2012-04-14 18:00:22.000000000 +0000 @@ -1,6 +1,7 @@ -# $MirOS: contrib/hosted/tg/deb/mksh/debian/mtest.t,v 1.5 2011/12/10 14:26:33 tg Exp $ +# $MirOS: contrib/hosted/tg/deb/mksh/debian/mtest.t,v 1.7 2012/04/14 17:59:58 tg Exp $ #- -# Catch the most basic failures to run (broken ABI, signals, dietlibc bug) +# Catch the most basic failures to run (broken ABI, signals, dietlibc bug, +# select not implemented) # Failures to pass these leads to the binary being thrown away, if run name: mtest-builtin @@ -26,6 +27,7 @@ name: mtest-ascii1 description: Part of dollar-quoted-strings +time-limit: 3 stdin: printf '<\1\n'|while read x;do while [[ -n $x ]];do typeset -i16 hv=1#${x::1};x=${x:1};echo -n "$hv ";done;done;echo . expected-stdout: @@ -35,6 +37,7 @@ description: Check that break and continue work; used by test.sh itself and broken at least once on *buntu +time-limit: 3 stdin: for x in "echo 1" false "echo 2"; do $x && continue; echo 3; break; done; echo 4 expected-stdout: @@ -42,3 +45,16 @@ 3 4 --- +name: mtest-select-works +description: + Check that we correctly detect our host system has select(2) + and that it is actually implemented, exported from libc and working +time-limit: 3 +stdin: + print foo | while read -t 1 bar; do print ${bar}bar; done + sleep 1 + print baz +expected-stdout: + foobar + baz +--- diff -Nru mksh-40.4/debian/README.Debian mksh-40.9.20120414/debian/README.Debian --- mksh-40.4/debian/README.Debian 2012-05-01 02:38:29.000000000 +0000 +++ mksh-40.9.20120414/debian/README.Debian 2012-04-14 17:00:40.000000000 +0000 @@ -1,4 +1,4 @@ -$MirOS: contrib/hosted/tg/deb/mksh/debian/README.Debian,v 1.19 2012/02/11 17:00:58 tg Exp $ +$MirOS: contrib/hosted/tg/deb/mksh/debian/README.Debian,v 1.21 2012/04/14 17:00:16 tg Exp $ ___________________________________________________________________________________________ Notes for the mksh binary package @@ -33,8 +33,10 @@ * /bin/mksh-static is built with the following options: - extra hardening flags: +all but no PIE (position independent code), as this is a static executable - - dietlibc, if available, eglibc otherwise (statically linked) - + klibc might be a viable choice some day; patches in progress + - eglibc, if cross-built or running the testsuite is disabled; + otherwise klibc if available and working, otherwise dietlibc + if available and working, otherwise eglibc + - note that the stack protector is disabled on dietlibc, klibc - the printf builtin - calling as sh or -sh invokes "set -o sh" - -DMKSH_SMALL diff -Nru mksh-40.4/debian/rules mksh-40.9.20120414/debian/rules --- mksh-40.4/debian/rules 2012-05-01 02:38:29.000000000 +0000 +++ mksh-40.9.20120414/debian/rules 2012-04-14 17:00:41.000000000 +0000 @@ -1,18 +1,18 @@ #!/usr/bin/make -f -# $MirOS: contrib/hosted/tg/deb/mksh/debian/rules,v 1.85 2011/12/11 18:54:16 tg Exp $ +# $MirOS: contrib/hosted/tg/deb/mksh/debian/rules,v 1.89 2012/04/14 17:00:17 tg Exp $ LC_ALL:=C export LC_ALL # for "debian/rules get-orig-source" -#ORIGTGZ_SOURCE:= -D'2011/06/05 20:00' -#ORIGTGZ_DESTINATION:= 40~0.20110605 +ORIGTGZ_SOURCE:= -D'2012/04/14 16:30' +ORIGTGZ_DESTINATION:= 40.9.20120414 # built from R40-stable branch: R40c+ #ORIGTGZ_SOURCE:= -rmksh-R40stable -D'2011-11-26 18:30' -# build from R40d tag -ORIGTGZ_SOURCE:= -rmksh-R40d -ORIGTGZ_PRINTF:= -rmksh-R40 -ORIGTGZ_DESTINATION:= 40.4 +# built from R40e tag +#ORIGTGZ_SOURCE:= -rmksh-R40e +ORIGTGZ_PRINTF:= -rmksh-R40e +#ORIGTGZ_DESTINATION:= 40.5 # shut up build log checkers that don’t know what they are doing # Debian #492377, #572252; as well *buntu @@ -41,7 +41,6 @@ binary-arch: build-arch dh_testdir dh_testroot - # a build log checker may be nice but not backport-friendly; honestly if test -x "$$(which dh_prep)"; then dh_prep; else dh_clean -k; fi dh_installchangelogs dh_installdocs @@ -82,9 +81,9 @@ cd $@.tmp; ${_CVSEXPORT} ${ORIGTGZ_PRINTF} src/usr.bin/printf/printf.c # then mix those together, rename and pack it up mv $@.tmp/src/usr.bin/printf/printf.c $@.tmp/mksh/ - mv $@.tmp/mksh $@.tmp/mksh-${ORIGTGZ_DESTINATION} - cd $@.tmp; find mksh-${ORIGTGZ_DESTINATION} -type f | sort | \ - mircpio -oC512 -Hustar -Mdist | gzip -n9 \ + mv $@.tmp/mksh $@.tmp/mksh-${ORIGTGZ_DESTINATION}.orig + cd $@.tmp; find mksh-${ORIGTGZ_DESTINATION}.orig -type f | sort | \ + paxcpio -oC512 -Hustar -Mdist | gzip -n9 \ >../mksh_${ORIGTGZ_DESTINATION}.orig.tar.gz rm -rf $@.tmp # there we are... diff -Nru mksh-40.4/debian/source/format mksh-40.9.20120414/debian/source/format --- mksh-40.4/debian/source/format 2012-05-01 02:38:29.000000000 +0000 +++ mksh-40.9.20120414/debian/source/format 2012-05-01 02:38:29.000000000 +0000 @@ -1 +1 @@ -1.0 +3.0 (quilt) diff -Nru mksh-40.4/debian/source.lintian-overrides mksh-40.9.20120414/debian/source.lintian-overrides --- mksh-40.4/debian/source.lintian-overrides 2012-05-01 02:38:29.000000000 +0000 +++ mksh-40.9.20120414/debian/source.lintian-overrides 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ -# $MirOS: contrib/hosted/tg/deb/mksh/debian/source.lintian-overrides,v 1.9 2011/12/31 02:54:17 tg Exp $ - -# desired method of keeping changes is CVS -# as long as etch backports are required -mksh source: direct-changes-in-diff-but-no-patch-system * diff -Nru mksh-40.4/edit.c mksh-40.9.20120414/edit.c --- mksh-40.4/edit.c 2012-05-01 02:38:29.000000000 +0000 +++ mksh-40.9.20120414/edit.c 2012-04-06 15:07:06.000000000 +0000 @@ -4,7 +4,8 @@ /* $OpenBSD: vi.c,v 1.26 2009/06/29 22:50:19 martynas Exp $ */ /*- - * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 + * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, + * 2011, 2012 * Thorsten Glaser * * Provided that these terms and disclaimer and all copyright notices @@ -25,7 +26,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.226 2011/12/29 23:36:10 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.234 2012/04/06 15:06:42 tg Exp $"); /* * in later versions we might use libtermcap for this, but since external @@ -288,28 +289,38 @@ static int x_file_glob(int flags MKSH_A_UNUSED, char *toglob, char ***wordsp) { - char **words; - int nwords, i, idx; + char ch, **words; + int nwords, i = 0, idx = 0; bool escaping; XPtrV w; struct source *s, *sold; /* remove all escaping backward slashes */ escaping = false; - for (i = 0, idx = 0; toglob[i]; i++) { - if (toglob[i] == '\\' && !escaping) { + while ((ch = toglob[i++])) { + if (ch == '\\' && !escaping) { escaping = true; continue; } - /* specially escape escaped [ or $ or ` for globbing */ - if (escaping && (toglob[i] == '[' || - toglob[i] == '$' || toglob[i] == '`')) - toglob[idx++] = QCHAR; - - toglob[idx] = toglob[i]; - idx++; - if (escaping) + if (escaping) { + /* + * empirically made list of chars to escape + * for globbing; ASCII 0x02 probably too as + * that's what QCHAR is, but... + */ + switch (ch) { + case '$': + case '*': + case '?': + case '[': + case '\\': + case '`': + toglob[idx++] = QCHAR; + break; + } escaping = false; + } + toglob[idx++] = ch; } toglob[idx] = '\0'; @@ -336,6 +347,15 @@ if (nwords == 1) { struct stat statb; + /* Drop all QCHAR from toglob for strcmp below */ + i = 0; + idx = 0; + while ((ch = toglob[i++])) { + if (ch != QCHAR) + toglob[idx++] = ch; + } + toglob[idx] = '\0'; + /* * Check if globbing failed (returned glob pattern), * but be careful (e.g. toglob == "ab*" when the file @@ -847,12 +867,12 @@ static char *xep; /* current end */ static char *xbp; /* start of visible portion of input buffer */ static char *xlp; /* last char visible on screen */ -static int x_adj_ok; +static bool x_adj_ok; /* * we use x_adj_done so that functions can tell * whether x_adjust() has been called while they are active. */ -static int x_adj_done; +static bool x_adj_done; static int x_col; static int x_displen; @@ -890,7 +910,7 @@ static int lastref; /* argument to last refresh() */ static int holdlen; /* length of holdbuf */ #endif -static int prompt_redraw; /* 0 if newline forced after prompt */ +static bool prompt_redraw; /* false if newline forced after prompt */ static int x_ins(const char *); static void x_delete(int, int); @@ -1101,19 +1121,19 @@ x_init_prompt(void) { x_col = promptlen(prompt); - x_adj_ok = 1; - prompt_redraw = 1; + x_adj_ok = true; + prompt_redraw = true; if (x_col >= xx_cols) x_col %= xx_cols; x_displen = xx_cols - 2 - x_col; - x_adj_done = 0; + x_adj_done = false; pprompt(prompt, 0); if (x_displen < 1) { x_col = 0; x_displen = xx_cols - 2; x_e_putc2('\n'); - prompt_redraw = 0; + prompt_redraw = false; } } @@ -1279,7 +1299,7 @@ x_ins(const char *s) { char *cp = xcp; - int adj = x_adj_done; + bool adj = x_adj_done; if (x_do_ins(s, strlen(s)) < 0) return (-1); @@ -1289,7 +1309,7 @@ */ xlp_valid = false; x_lastcp(); - x_adj_ok = (xcp >= xlp); + x_adj_ok = tobool(xcp >= xlp); x_zots(cp); /* has x_adjust() been called? */ if (adj == x_adj_done) { @@ -1300,7 +1320,7 @@ } if (xlp == xep - 1) x_redraw(xx_cols); - x_adj_ok = 1; + x_adj_ok = true; return (0); } @@ -1384,7 +1404,7 @@ /* Copies the NUL */ memmove(xcp, xcp + nb, xep - xcp + 1); /* don't redraw */ - x_adj_ok = 0; + x_adj_ok = false; xlp_valid = false; x_zots(xcp); /* @@ -1404,7 +1424,7 @@ x_e_putc2('\b'); } /*x_goto(xcp);*/ - x_adj_ok = 1; + x_adj_ok = true; xlp_valid = false; cp = x_lastcp(); while (cp > xcp) @@ -1494,7 +1514,9 @@ static void x_goto(char *cp) { - if (UTFMODE) + if (cp >= xep) + cp = xep; + else if (UTFMODE) while ((cp > xbuf) && ((*cp & 0xC0) == 0x80)) --cp; if (cp < xbp || cp >= utf_skipcols(xbp, x_displen)) { @@ -1557,7 +1579,7 @@ static void x_zots(char *str) { - int adj = x_adj_done; + bool adj = x_adj_done; x_lastcp(); while (*str && str < xlp && adj == x_adj_done) @@ -1802,7 +1824,7 @@ x_search_hist(int c) { int offset = -1; /* offset of match in xbuf, else -1 */ - char pat[256 + 1]; /* pattern buffer */ + char pat[80 + 1]; /* pattern buffer */ char *p = pat; unsigned char f; @@ -2014,7 +2036,7 @@ int i, j, x_trunc = 0; char *cp; - x_adj_ok = 0; + x_adj_ok = false; if (limit == -1) x_e_putc2('\n'); else @@ -2075,7 +2097,7 @@ cp = xlp; while (cp > xcp) x_bs3(&cp); - x_adj_ok = 1; + x_adj_ok = true; return; } @@ -2702,14 +2724,14 @@ } olen = end - start; nlen = x_longest_prefix(nwords, words); - /* complete */ - if (nwords == 1 || nlen > olen) { - x_goto(xbuf + start); - x_delete(olen, false); - x_escape(words[0], nlen, x_do_ins); - x_adjust(); + /* always complete */ + x_goto(xbuf + start); + x_delete(olen, false); + x_escape(words[0], nlen, x_do_ins); + x_adjust(); + /* check if we did add something */ + if (xcp - (xbuf + start) > olen) completed = true; - } /* * append a space if this is a single non-directory match * and not a parameter or homedir substitution @@ -2748,7 +2770,7 @@ x_adjust(void) { /* flag the fact that we were called. */ - x_adj_done++; + x_adj_done = true; /* * we had a problem if the prompt length > xx_cols / 2 */ @@ -2870,7 +2892,7 @@ static void x_e_puts(const char *s) { - int adj = x_adj_done; + bool adj = x_adj_done; while (*s && adj == x_adj_done) x_e_putc3(&s); @@ -3094,7 +3116,7 @@ return (x_fold_case('L')); } -/* Lowercase N(1) words */ +/* Titlecase N(1) words */ static int x_fold_capitalise(int c MKSH_A_UNUSED) { @@ -3106,8 +3128,8 @@ * x_fold_case - convert word to UPPER/lower/Capital case * * DESCRIPTION: - * This function is used to implement M-U,M-u,M-L,M-l,M-C and M-c - * to UPPER case, lower case or Capitalise words. + * This function is used to implement M-U/M-u, M-L/M-l, M-C/M-c + * to UPPER CASE, lower case or Capitalise Words. * * RETURN VALUE: * None @@ -3453,10 +3475,11 @@ pprompt(prompt, 0); if (cur_col > x_cols - 3 - MIN_EDIT_SPACE) { - prompt_redraw = cur_col = 0; + prompt_redraw = false; + cur_col = 0; x_putc('\n'); } else - prompt_redraw = 1; + prompt_redraw = true; pwidth = cur_col; if (!wbuf_len || wbuf_len != x_cols - 3) { diff -Nru mksh-40.4/eval.c mksh-40.9.20120414/eval.c --- mksh-40.4/eval.c 2012-05-01 02:38:29.000000000 +0000 +++ mksh-40.9.20120414/eval.c 2012-04-06 14:08:16.000000000 +0000 @@ -1,7 +1,8 @@ /* $OpenBSD: eval.c,v 1.37 2011/10/11 14:32:43 otto Exp $ */ /*- - * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 + * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, + * 2011, 2012 * Thorsten Glaser * * Provided that these terms and disclaimer and all copyright notices @@ -22,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.111 2011/12/16 20:03:12 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.116 2012/04/06 14:07:52 tg Exp $"); /* * string expansion @@ -375,9 +376,27 @@ 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)); + NZATFinish(h); x.str = shf_smprintf("%08X", - (unsigned int)hash(str_val(st->var))); + (unsigned int)h); break; + } case '0': { char *beg, *mid, *end, *stg; mksh_ari_t from = 0, num = -1, flen, finc = 0; @@ -896,7 +915,7 @@ if (!quote) switch (c) { case '[': - case NOT: + case '!': case '-': case ']': /* @@ -918,10 +937,10 @@ *dp++ = MAGIC; } break; - case OBRACE: + case '{': + case '}': case ',': - case CBRACE: - if ((f & DOBRACE) && (c == OBRACE || + if ((f & DOBRACE) && (c == '{' /*}*/ || (fdo & DOBRACE))) { fdo |= DOBRACE|DOMAGIC; *dp++ = MAGIC; @@ -1646,7 +1665,7 @@ char *p; /* search for open brace */ - for (p = exp_start; (p = strchr(p, MAGIC)) && p[1] != OBRACE; p += 2) + for (p = exp_start; (p = strchr(p, MAGIC)) && p[1] != '{' /*}*/; p += 2) ; brace_start = p; @@ -1656,9 +1675,9 @@ count = 1; for (p += 2; *p && count; p++) { if (ISMAGIC(*p)) { - if (*++p == OBRACE) + if (*++p == '{' /*}*/) count++; - else if (*p == CBRACE) + else if (*p == /*{*/ '}') --count; else if (*p == ',' && count == 1) comma = p; @@ -1689,9 +1708,9 @@ count = 1; for (p = brace_start + 2; p != brace_end; p++) { if (ISMAGIC(*p)) { - if (*++p == OBRACE) + if (*++p == '{' /*}*/) count++; - else if ((*p == CBRACE && --count == 0) || + else if ((*p == /*{*/ '}' && --count == 0) || (*p == ',' && count == 1)) { char *news; int l1, l2, l3; diff -Nru mksh-40.4/exec.c mksh-40.9.20120414/exec.c --- mksh-40.4/exec.c 2011-09-07 15:25:02.000000000 +0000 +++ mksh-40.9.20120414/exec.c 2012-04-14 16:08:10.000000000 +0000 @@ -1,7 +1,8 @@ /* $OpenBSD: exec.c,v 1.49 2009/01/29 23:27:26 jaredy Exp $ */ /*- - * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 + * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, + * 2011, 2012 * Thorsten Glaser * * Provided that these terms and disclaimer and all copyright notices @@ -22,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.96 2011/09/07 15:24:14 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.98 2012/04/14 16:07:46 tg Exp $"); #ifndef MKSH_DEFAULT_EXECSHELL #define MKSH_DEFAULT_EXECSHELL "/bin/sh" @@ -234,8 +235,7 @@ */ sigprocmask(SIG_BLOCK, &sm_sigchld, &omask); e->type = E_ERRH; - i = sigsetjmp(e->jbuf, 0); - if (i) { + if ((i = kshsetjmp(e->jbuf))) { sigprocmask(SIG_SETMASK, &omask, NULL); quitenv(NULL); unwind(i); @@ -337,10 +337,7 @@ (const char **)eval((const char **)t->vars, DOBLANK | DOGLOB | DOTILDE); e->type = E_LOOP; - while (/* CONSTCOND */ 1) { - i = sigsetjmp(e->jbuf, 0); - if (!i) - break; + while ((i = kshsetjmp(e->jbuf))) { if ((e->flags&EF_BRKCONT_PASS) || (i != LBREAK && i != LCONTIN)) { quitenv(NULL); @@ -375,10 +372,7 @@ case TWHILE: case TUNTIL: e->type = E_LOOP; - while (/* CONSTCOND */ 1) { - i = sigsetjmp(e->jbuf, 0); - if (!i) - break; + while ((i = kshsetjmp(e->jbuf))) { if ((e->flags&EF_BRKCONT_PASS) || (i != LBREAK && i != LCONTIN)) { quitenv(NULL); @@ -733,8 +727,7 @@ tp->flag |= FINUSE; e->type = E_FUNC; - i = sigsetjmp(e->jbuf, 0); - if (i == 0) { + if (!(i = kshsetjmp(e->jbuf))) { /* seems odd to pass XERROK here, but AT&T ksh does */ exstat = execute(tp->val.t, flags & XERROK, xerrok); i = LRETURN; @@ -1424,7 +1417,7 @@ osource = source; newenv(E_ERRH); - if (sigsetjmp(e->jbuf, 0)) { + if (kshsetjmp(e->jbuf)) { source = osource; quitenv(shf); /* special to iosetup(): don't print error */ @@ -1475,10 +1468,10 @@ * so temp doesn't get removed too soon). */ h = maketemp(ATEMP, TT_HEREDOC_EXP, &e->temps); - if (!(shf = h->shf) || (fd = open(h->name, O_RDONLY, 0)) < 0) { + if (!(shf = h->shf) || (fd = open(h->tffn, O_RDONLY, 0)) < 0) { i = errno; warningf(true, "can't %s temporary file %s: %s", - !shf ? "create" : "open", h->name, strerror(i)); + !shf ? "create" : "open", h->tffn, strerror(i)); if (shf) shf_close(shf); /* special to iosetup(): don't print error */ @@ -1494,7 +1487,8 @@ if (shf_close(shf) == EOF) { i = errno; close(fd); - warningf(true, "%s: %s: %s", "write", h->name, strerror(i)); + warningf(true, "can't %s temporary file %s: %s", + "write", h->tffn, strerror(i)); /* special to iosetup(): don't print error */ return (-2); } diff -Nru mksh-40.4/expr.c mksh-40.9.20120414/expr.c --- mksh-40.4/expr.c 2012-05-01 02:38:29.000000000 +0000 +++ mksh-40.9.20120414/expr.c 2012-03-31 17:52:57.000000000 +0000 @@ -1,7 +1,8 @@ /* $OpenBSD: expr.c,v 1.21 2009/06/01 19:00:57 deraadt Exp $ */ /*- - * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 + * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, + * 2011, 2012 * Thorsten Glaser * * Provided that these terms and disclaimer and all copyright notices @@ -22,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.51.2.1 2011/12/31 02:25:28 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.56 2012/03/31 17:52:33 tg Exp $"); /* The order of these enums is constrained by the order of opinfo[] */ enum token { @@ -198,8 +199,7 @@ curstate.natural = false; newenv(E_ERRH); - i = sigsetjmp(e->jbuf, 0); - if (i) { + if ((i = kshsetjmp(e->jbuf))) { /* Clear EXPRINEVAL in of any variables we were playing with */ if (curstate.evaling) curstate.evaling->flag &= ~EXPRINEVAL; @@ -284,7 +284,7 @@ case ET_RDONLY: warningf(true, "%s: %s %s", - es->expression, str, "applied to read only variable"); + es->expression, str, "applied to read-only variable"); break; default: /* keep gcc happy */ @@ -367,11 +367,19 @@ case O_DIV: case O_DIVASN: #if !HAVE_SILENT_IDIVWRAPV - if (!es->natural && vr->val.i == -1 && - vl->val.i == ((mksh_ari_t)1 << 31)) { + /* + * we are doing the comparisons here for the + * signed arithmetics (!es->natural) case, + * but the exact value checks and the bypass + * case assignments are done unsignedly as + * several compilers bitch around otherwise + */ + if (!es->natural && + vl->val.u == (mksh_uari_t)0x80000000UL && + vr->val.u == (mksh_uari_t)0xFFFFFFFFUL) { /* -2147483648 / -1 = 2147483648 */ - /* 80000000 / FFFFFFFF = 80000000 */ - res = ((mksh_ari_t)1 << 31); + /* this ^ is really (1 << 31) though */ + res = (mksh_ari_t)(mksh_uari_t)0x80000000UL; } else #endif res = bivui(vl, /, vr); @@ -379,8 +387,10 @@ case O_MOD: case O_MODASN: #if !HAVE_SILENT_IDIVWRAPV - if (!es->natural && vr->val.i == -1 && - vl->val.i == ((mksh_ari_t)1 << 31)) { + /* see O_DIV / O_DIVASN for the reason behind this */ + if (!es->natural && + vl->val.u == (mksh_uari_t)0x80000000UL && + vr->val.u == (mksh_uari_t)0xFFFFFFFFUL) { /* -2147483648 % -1 = 0 */ res = 0; } else diff -Nru mksh-40.4/funcs.c mksh-40.9.20120414/funcs.c --- mksh-40.4/funcs.c 2011-12-09 20:41:13.000000000 +0000 +++ mksh-40.9.20120414/funcs.c 2012-04-06 13:29:23.000000000 +0000 @@ -5,7 +5,7 @@ /*- * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, - * 2010, 2011 + * 2010, 2011, 2012 * Thorsten Glaser * * 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.204 2011/12/09 20:40:25 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.212 2012/04/06 13:28:59 tg Exp $"); #if HAVE_KILLPG /* @@ -60,10 +60,6 @@ #define c_ulimit c_true #endif -#if defined(ANDROID) -static int c_android_lsmod(const char **); -#endif - static int c_true(const char **wp MKSH_A_UNUSED) { @@ -146,9 +142,6 @@ /* alias to "true" for historical reasons */ {"domainname", c_true}, #endif -#if defined(ANDROID) - {"lsmod", c_android_lsmod}, -#endif {NULL, (int (*)(const char **))NULL} }; @@ -547,7 +540,7 @@ Talias); if (!iam_whence && !vflag) shprintf("%s %s=", Talias, id); - print_value_quoted(tp->val.s); + print_value_quoted(shl_stdout, tp->val.s); break; case CFUNC: if (vflag) { @@ -921,7 +914,7 @@ INTEGER) shf_puts(s, shl_stdout); else - print_value_quoted(s); + print_value_quoted(shl_stdout, s); } shf_putc('\n', shl_stdout); if (vp->flag & ARRAY) @@ -953,7 +946,7 @@ INTEGER) shf_puts(s, shl_stdout); else - print_value_quoted(s); + print_value_quoted(shl_stdout, s); } shf_putc('\n', shl_stdout); } @@ -1053,7 +1046,7 @@ shf_puts(ap->name, shl_stdout); if (prefix != '+') { shf_putc('=', shl_stdout); - print_value_quoted(ap->val.s); + print_value_quoted(shl_stdout, ap->val.s); } shf_putc('\n', shl_stdout); } @@ -1078,7 +1071,7 @@ shf_puts(ap->name, shl_stdout); if (prefix != '+') { shf_putc('=', shl_stdout); - print_value_quoted(ap->val.s); + print_value_quoted(shl_stdout, ap->val.s); } shf_putc('\n', shl_stdout); } else { @@ -1282,7 +1275,7 @@ /* assume old style options if -digits or -UPPERCASE */ if ((p = wp[1]) && *p == '-' && (ksh_isdigit(p[1]) || ksh_isupper(p[1]))) { - if (!(t = gettrap(p + 1, true))) { + if (!(t = gettrap(p + 1, false))) { bi_errorf("bad signal '%s'", p + 1); return (1); } @@ -1759,11 +1752,11 @@ return (rv); } +static char REPLY[] = "REPLY"; int c_read(const char **wp) { #define is_ifsws(c) (ctype((c), C_IFS) && ctype((c), C_IFSWS)) - static char REPLY[] = "REPLY"; int c, fd = 0, rv = 0, lastparm = 0; bool savehist = false, intoarray = false, aschars = false; bool rawmode = false, expanding = false; @@ -2021,7 +2014,7 @@ vp = global(*wp); if (vp->flag & RDONLY) { c_read_splitro: - bi_errorf("%s: %s", *wp, "is read only"); + bi_errorf("read-only: %s", *wp); c_read_spliterr: rv = 2; afree(cp, ATEMP); @@ -2225,7 +2218,7 @@ for (p = sigtraps, i = NSIG+1; --i >= 0; p++) if (p->trap != NULL) { shf_puts("trap -- ", shl_stdout); - print_value_quoted(p->trap); + print_value_quoted(shl_stdout, p->trap); shprintf(" %s\n", p->name); } return (0); @@ -2260,7 +2253,7 @@ const char *arg; if (ksh_getopt(wp, &builtin_opt, null) == '?') - return (1); + goto c_exitreturn_err; arg = wp[builtin_opt.optind]; if (arg) { @@ -2295,6 +2288,9 @@ quitenv(NULL); unwind(how); /* NOTREACHED */ + + c_exitreturn_err: + return (1); } int @@ -2305,19 +2301,19 @@ const char *arg; if (ksh_getopt(wp, &builtin_opt, null) == '?') - return (1); + goto c_brkcont_err; arg = wp[builtin_opt.optind]; if (!arg) n = 1; else if (!bi_getn(arg, &n)) - return (1); - quit = n; - if (quit <= 0) { + goto c_brkcont_err; + if (n <= 0) { /* AT&T ksh does this for non-interactive shells only - weird */ bi_errorf("%s: %s", arg, "bad value"); - return (1); + goto c_brkcont_err; } + quit = n; /* Stop at E_NONE, E_PARSE, E_FUNC, or E_INCL */ for (ep = e; ep && !STOP_BRKCONT(ep->type); ep = ep->oenv) @@ -2351,6 +2347,9 @@ unwind(*wp[0] == 'b' ? LBREAK : LCONTIN); /* NOTREACHED */ + + c_brkcont_err: + return (1); } int @@ -2434,8 +2433,7 @@ afree(cp, ATEMP); if ((vp->flag&RDONLY)) { - warningf(true, "%s: %s", vp->name, - "is read only"); + warningf(true, "read-only: %s", vp->name); rv = 1; } else unset(vp, optc); @@ -2982,7 +2980,7 @@ /* -s */ case TO_FILGZ: - return (stat(opnd1, &b1) == 0 && b1.st_size > 0L); + return (stat(opnd1, &b1) == 0 && (off_t)b1.st_size > (off_t)0); /* -t */ case TO_FILTT: @@ -3259,7 +3257,7 @@ struct limits { const char *name; int resource; /* resource to get/set */ - int factor; /* multiply by to get rlim_{cur,max} values */ + unsigned int factor; /* multiply by to get rlim_{cur,max} values */ char option; }; @@ -3455,9 +3453,9 @@ if (strcmp(v, "unlimited") == 0) val = (rlim_t)RLIM_INFINITY; else { - mksh_ari_t rval; + mksh_uari_t rval; - if (!evaluate(v, &rval, KSH_RETURN_ERROR, false)) + if (!evaluate(v, (mksh_ari_t *)&rval, KSH_RETURN_ERROR, false)) return (1); /* * Avoid problems caused by typos that evaluate misses due @@ -3507,7 +3505,7 @@ if (val == (rlim_t)RLIM_INFINITY) shf_puts("unlimited\n", shl_stdout); else - shprintf("%ld\n", (long)(val / l->factor)); + shprintf("%lu\n", (unsigned long)(val / l->factor)); } #endif @@ -3668,10 +3666,25 @@ bi_errorf("%s: %s '%s'", Tsynerr, strerror(errno), wp[0]); else { #ifndef MKSH_NOPROSPECTOFWORK - sigset_t omask; + sigset_t omask, bmask; - /* block SIGCHLD from interrupting us, though */ - sigprocmask(SIG_BLOCK, &sm_sigchld, &omask); + /* block a number of signals from interrupting us, though */ + (void)sigemptyset(&bmask); + (void)sigaddset(&bmask, SIGPIPE); + (void)sigaddset(&bmask, SIGCHLD); +#ifdef SIGWINCH + (void)sigaddset(&bmask, SIGWINCH); +#endif +#ifdef SIGINFO + (void)sigaddset(&bmask, SIGINFO); +#endif +#ifdef SIGUSR1 + (void)sigaddset(&bmask, SIGUSR1); +#endif +#ifdef SIGUSR2 + (void)sigaddset(&bmask, SIGUSR2); +#endif + sigprocmask(SIG_BLOCK, &bmask, &omask); #endif if (select(1, NULL, NULL, NULL, &tv) == 0 || errno == EINTR) /* @@ -3682,20 +3695,10 @@ else bi_errorf("%s: %s", Tselect, strerror(errno)); #ifndef MKSH_NOPROSPECTOFWORK + /* this will re-schedule signal delivery */ sigprocmask(SIG_SETMASK, &omask, NULL); #endif } return (rv); } #endif - -#if defined(ANDROID) -static int -c_android_lsmod(const char **wp MKSH_A_UNUSED) -{ - const char *cwp[3] = { "cat", "/proc/modules", NULL }; - - builtin_argv0 = cwp[0]; - return (c_cat(cwp)); -} -#endif diff -Nru mksh-40.4/histrap.c mksh-40.9.20120414/histrap.c --- mksh-40.4/histrap.c 2012-05-01 02:38:29.000000000 +0000 +++ mksh-40.9.20120414/histrap.c 2012-04-14 16:08:11.000000000 +0000 @@ -2,7 +2,8 @@ /* $OpenBSD: trap.c,v 1.23 2010/05/19 17:36:08 jasper Exp $ */ /*- - * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 + * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, + * 2011, 2012 * Thorsten Glaser * * Provided that these terms and disclaimer and all copyright notices @@ -26,7 +27,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.117 2011/12/31 00:47:45 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.123 2012/04/14 16:07:47 tg Exp $"); Trap sigtraps[NSIG + 1]; static struct sigaction Sigact_ign; @@ -296,7 +297,7 @@ tf = maketemp(ATEMP, TT_HIST_EDIT, &e->temps); if (!(shf = tf->shf)) { bi_errorf("can't %s temporary file %s: %s", - "create", tf->name, strerror(errno)); + "create", tf->tffn, strerror(errno)); return (1); } for (hp = rflag ? hlast : hfirst; @@ -304,12 +305,12 @@ shf_fprintf(shf, "%s\n", *hp); if (shf_close(shf) == EOF) { bi_errorf("can't %s temporary file %s: %s", - "write", tf->name, strerror(errno)); + "write", tf->tffn, strerror(errno)); return (1); } /* Ignore setstr errors here (arbitrary) */ - setstr(local("_", false), tf->name, KSH_RETURN_ERROR); + setstr(local("_", false), tf->tffn, KSH_RETURN_ERROR); /* XXX: source should not get trashed by this.. */ { @@ -328,20 +329,20 @@ char *xp; ssize_t n; - if (!(shf = shf_open(tf->name, O_RDONLY, 0, 0))) { + if (!(shf = shf_open(tf->tffn, O_RDONLY, 0, 0))) { bi_errorf("can't %s temporary file %s: %s", - "open", tf->name, strerror(errno)); + "open", tf->tffn, strerror(errno)); return (1); } - if (stat(tf->name, &statb) < 0) + if (stat(tf->tffn, &statb) < 0) n = 128; else if ((off_t)statb.st_size > MKSH_MAXHISTFSIZE) { bi_errorf("%s %s too large: %lu", Thistory, "file", (unsigned long)statb.st_size); goto errout; } else - n = statb.st_size + 1; + n = (size_t)statb.st_size + 1; Xinit(xs, xp, n, hist_source->areap); while ((n = shf_read(xp, Xnleft(xs, xp), shf)) > 0) { xp += n; @@ -350,7 +351,7 @@ } if (n < 0) { bi_errorf("can't %s temporary file %s: %s", - "read", tf->name, strerror(shf_errno(shf))); + "read", tf->tffn, strerror(shf_errno(shf))); errout: shf_close(shf); return (1); @@ -691,7 +692,9 @@ #define HMAGIC2 0xCD #define COMMAND 0xFF +#if HAVE_PERSISTENT_HISTORY static const unsigned char sprinkle[2] = { HMAGIC1, HMAGIC2 }; +#endif void hist_init(Source *s) @@ -723,7 +726,7 @@ if (histfd != fd) close(fd); - (void)flock(histfd, LOCK_EX); + mksh_lockfd(histfd); histfsize = lseek(histfd, (off_t)0, SEEK_END); if (histfsize > MKSH_MAXHISTFSIZE || hs == hist_init_restore) { @@ -815,7 +818,7 @@ } histfsize = lseek(histfd, (off_t)0, SEEK_END); hist_init_tail: - (void)flock(histfd, LOCK_UN); + mksh_unlkfd(histfd); #endif } @@ -880,7 +883,7 @@ size_t bytes; unsigned char *base, *news; - (void)flock(histfd, LOCK_EX); + mksh_lockfd(histfd); sizenow = lseek(histfd, (off_t)0, SEEK_END); if (sizenow < histfsize) { /* the file has shrunk; give up */ @@ -917,7 +920,7 @@ return; } histfsize = lseek(histfd, (off_t)0, SEEK_END); - (void)flock(histfd, LOCK_UN); + mksh_unlkfd(histfd); } static int @@ -938,7 +941,7 @@ void hist_finish(void) { - (void)flock(histfd, LOCK_UN); + mksh_unlkfd(histfd); (void)close(histfd); histfd = -1; } @@ -984,8 +987,14 @@ else { char *s; - if (!strncasecmp(cs, "SIG", 3)) + /* this is not optimal, what about SIGSIG1? */ + if ((cs[0] & 0xDF) == 'S' && + (cs[1] & 0xDF) == 'I' && + (cs[2] & 0xDF) == 'G' && + cs[3] != '\0') { + /* skip leading "SIG" */ cs += 3; + } strdupx(s, cs, APERM); sigtraps[i].name = s; while ((*s = ksh_toupper(*s))) @@ -1053,27 +1062,45 @@ } Trap * -gettrap(const char *name, int igncase) +gettrap(const char *cs, bool igncase) { - int n = NSIG + 1; + int i; Trap *p; - const char *n2; - int (*cmpfunc)(const char *, const char *) = strcmp; + char *as; - if (ksh_isdigit(*name)) { - if (getn(name, &n) && 0 <= n && n < NSIG) - return (&sigtraps[n]); - else - return (NULL); - } + if (ksh_isdigit(*cs)) { + return ((getn(cs, &i) && 0 <= i && i < NSIG) ? + (&sigtraps[i]) : NULL); + } + + /* this breaks SIGSIG1, but we do that above anyway */ + if ((cs[0] & 0xDF) == 'S' && + (cs[1] & 0xDF) == 'I' && + (cs[2] & 0xDF) == 'G' && + cs[3] != '\0') { + /* skip leading "SIG" */ + cs += 3; + } + if (igncase) { + char *s; + + strdupx(as, cs, ATEMP); + cs = s = as; + while ((*s = ksh_toupper(*s))) + ++s; + } else + as = NULL; - n2 = strncasecmp(name, "SIG", 3) ? NULL : name + 3; - if (igncase) - cmpfunc = strcasecmp; - for (p = sigtraps; --n >= 0; p++) - if (!cmpfunc(p->name, name) || (n2 && !cmpfunc(p->name, n2))) - return (p); - return (NULL); + p = sigtraps; + for (i = 0; i <= NSIG; i++) { + if (!strcmp(p->name, cs)) + goto found; + ++p; + } + p = NULL; + found: + afree(as, ATEMP); + return (p); } /* @@ -1419,3 +1446,56 @@ break; } } + +#if HAVE_PERSISTENT_HISTORY || defined(DF) +/* + * File descriptor locking and unlocking functions. + * Could use some error handling, but hey, this is only + * advisory locking anyway, will often not work over NFS, + * and you are SOL if this fails... + */ + +void +mksh_lockfd(int fd) +{ +#if defined(__OpenBSD__) + /* flock is not interrupted by signals */ + (void)flock(fd, LOCK_EX); +#elif HAVE_FLOCK + int rv; + + /* e.g. on Linux */ + do { + rv = flock(fd, LOCK_EX); + } while (rv == 1 && errno == EINTR); +#elif HAVE_LOCK_FCNTL + int rv; + struct flock lks; + + memset(&lks, 0, sizeof(lks)); + lks.l_type = F_WRLCK; + do { + rv = fcntl(fd, F_SETLKW, &lks); + } while (rv == 1 && errno == EINTR); +#endif +} + +/* designed to not define mksh_unlkfd if none triggered */ +#if HAVE_FLOCK +void +mksh_unlkfd(int fd) +{ + (void)flock(fd, LOCK_UN); +} +#elif HAVE_LOCK_FCNTL +void +mksh_unlkfd(int fd) +{ + struct flock lks; + + memset(&lks, 0, sizeof(lks)); + lks.l_type = F_UNLCK; + (void)fcntl(fd, F_SETLKW, &lks); +} +#endif +#endif diff -Nru mksh-40.4/lex.c mksh-40.9.20120414/lex.c --- mksh-40.4/lex.c 2011-11-26 17:57:18.000000000 +0000 +++ mksh-40.9.20120414/lex.c 2012-04-07 11:20:13.000000000 +0000 @@ -22,7 +22,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.158 2011/11/26 17:56:30 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.161 2012/04/07 11:19:49 tg Exp $"); /* * states while lexing word @@ -1440,25 +1440,6 @@ alarm(0); } cp = Xstring(s->xs, xp); -#if !defined(MKSH_SMALL) && !defined(MKSH_DISABLE_DEPRECATED) - if (interactive && *cp == '!' && cur_prompt == PS1) { - int linelen; - - linelen = Xlength(s->xs, xp); - XcheckN(s->xs, xp, Zfc_e_dash + /* NUL */ 1); - /* reload after potential realloc */ - cp = Xstring(s->xs, xp); - /* change initial '!' into space */ - *cp = ' '; - /* NUL terminate the current string */ - *xp = '\0'; - /* move the actual string forward */ - memmove(cp + Zfc_e_dash, cp, linelen + /* NUL */ 1); - xp += Zfc_e_dash; - /* prepend it with "fc -e -" */ - memcpy(cp, Tfc_e_dash, Zfc_e_dash); - } -#endif 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 */ @@ -1514,7 +1495,7 @@ ps1 = shf_sclose(shf); saved_atemp = ATEMP; newenv(E_ERRH); - if (sigsetjmp(e->jbuf, 0)) { + if (kshsetjmp(e->jbuf)) { prompt = safe_prompt; /* * Don't print an error - assume it has already @@ -1633,7 +1614,7 @@ c2 = getsc(); ungetsc(c2); - if (c2 != '}') { + if (c2 != /*{*/ '}') { ungetsc(c); goto out; } diff -Nru mksh-40.4/main.c mksh-40.9.20120414/main.c --- mksh-40.4/main.c 2011-11-08 22:08:09.000000000 +0000 +++ mksh-40.9.20120414/main.c 2012-04-14 16:08:11.000000000 +0000 @@ -1,10 +1,11 @@ /* $OpenBSD: main.c,v 1.47 2011/09/07 11:33:25 otto 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: table.c,v 1.13 2009/01/17 22:06:44 millert 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 + * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, + * 2011, 2012 * Thorsten Glaser * * Provided that these terms and disclaimer and all copyright notices @@ -33,7 +34,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/main.c,v 1.195.2.4 2011/11/08 22:07:21 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/main.c,v 1.216 2012/04/14 16:07:47 tg Exp $"); extern char **environ; @@ -45,6 +46,8 @@ #define MKSH_DEFAULT_TMPDIR "/tmp" #endif +static uint8_t isuc(const char *); +static int main_init(int, const char *[], Source **, struct block **); void chvt_reinit(void); static void reclaim(void); static void remove_temps(struct temp *); @@ -94,7 +97,7 @@ Ttypeset, "-r", "PATH", "ENV", "SHELL", NULL }; -static int initio_done; +static bool initio_done; /* top-level parsing and execution environment */ static struct env env; @@ -107,9 +110,10 @@ struct { ALLOC_ITEM alloc_INT; void *dataptr, *stkptr, *mallocptr; +#if defined(__GLIBC__) && (__GLIBC__ >= 2) sigjmp_buf jbuf; +#endif struct timeval tv; - struct timezone tz; } *bufptr; char *cp; @@ -126,17 +130,19 @@ bufptr->stkptr = &bufptr; /* randomised malloc in BSD (and possibly others) */ bufptr->mallocptr = bufptr; +#if defined(__GLIBC__) && (__GLIBC__ >= 2) /* glibc pointer guard */ sigsetjmp(bufptr->jbuf, 1); - /* introduce variation */ - gettimeofday(&bufptr->tv, &bufptr->tz); +#endif + /* introduce variation (and yes, second arg MBZ for portability) */ + gettimeofday(&bufptr->tv, NULL); - oaat1_init_impl(h); + NZATInit(h); /* variation through pid, ppid, and the works */ - oaat1_addmem_impl(h, &rndsetupstate, sizeof(rndsetupstate)); + NZATUpdateMem(h, &rndsetupstate, sizeof(rndsetupstate)); /* some variation, some possibly entropy, depending on OE */ - oaat1_addmem_impl(h, bufptr, sizeof(*bufptr)); - oaat1_fini_impl(h); + NZATUpdateMem(h, bufptr, sizeof(*bufptr)); + NZAATFinish(h); afree(cp, APERM); return ((mksh_uari_t)h); @@ -155,8 +161,31 @@ "mksh", NULL }; -int -main(int argc, const char *argv[]) +static uint8_t +isuc(const char *cx) { + char *cp, *x; + uint8_t rv = 0; + + if (!cx || !*cx) + return (0); + + /* uppercase a string duplicate */ + strdupx(x, cx, ATEMP); + cp = x; + while ((*cp = ksh_toupper(*cp))) + ++cp; + + /* check for UTF-8 */ + if (strstr(x, "UTF-8") || strstr(x, "UTF8")) + rv = 1; + + /* free copy and out */ + afree(x, ATEMP); + return (rv); +} + +static int +main_init(int argc, const char *argv[], Source **sp, struct block **lp) { int argi, i; Source *s = NULL; @@ -209,8 +238,8 @@ /* define built-in commands and see if we were called as one */ ktinit(APERM, &builtins, - /* currently 50 builtins -> 80% of 64 (2^6) */ - 6); + /* currently up to 50 builtins */ + /* 80% of 64 = 2^6 */ 6, /* 66% of 128 = 2^7 */ 7); for (i = 0; mkshbuiltins[i].name != NULL; i++) if (!strcmp(ccp, builtin(mkshbuiltins[i].name, mkshbuiltins[i].func))) @@ -238,10 +267,10 @@ coproc_init(); /* set up variable and command dictionaries */ - ktinit(APERM, &taliases, 0); - ktinit(APERM, &aliases, 0); + ktinit(APERM, &taliases, 0, 0); + ktinit(APERM, &aliases, 0, 0); #ifndef MKSH_NOPWNAM - ktinit(APERM, &homedirs, 0); + ktinit(APERM, &homedirs, 0, 0); #endif /* define shell keywords */ @@ -249,6 +278,13 @@ init_histvec(); +#ifdef TIOCGWINSZ + /* try to initialise tty size before importing environment */ + tty_init(false, false); + change_winsz(); + tty_close(); +#endif + #ifdef _PATH_DEFPATH def_path = _PATH_DEFPATH; #else @@ -503,8 +539,6 @@ } /* divine the initial state of the utf8-mode Flag */ -#define isuc(x) (((x) != NULL) && \ - (stristr((x), "UTF-8") || stristr((x), "utf8"))) ccp = null; switch (utf_flag) { @@ -546,7 +580,6 @@ UTFMODE = utf_flag; break; } -#undef isuc /* Disable during .profile/ENV reading */ restricted = Flag(FRESTRICTED); @@ -594,15 +627,31 @@ alarm_init(); - if (Flag(FAS_BUILTIN)) - return (shcomexec(l->argv)); - - /* doesn't return */ - shell(s, true); - /* NOTREACHED */ + *sp = s; + *lp = l; return (0); } +/* this indirection barrier reduces stack usage during normal operation */ + +int +main(int argc, const char *argv[]) +{ + int rv; + Source *s; + struct block *l; + + if ((rv = main_init(argc, argv, &s, &l)) == 0) { + if (Flag(FAS_BUILTIN)) { + rv = shcomexec(l->argv); + } else { + shell(s, true); + /* NOTREACHED */ + } + } + return (rv); +} + int include(const char *name, int argc, const char **argv, int intr_ok) { @@ -624,8 +673,7 @@ old_argc = 0; } newenv(E_INCL); - i = sigsetjmp(e->jbuf, 0); - if (i) { + if ((i = kshsetjmp(e->jbuf))) { quitenv(s ? s->u.shf : NULL); if (old_argv) { e->loc->argv = old_argv; @@ -700,49 +748,47 @@ newenv(E_PARSE); if (interactive) really_exit = 0; - i = sigsetjmp(e->jbuf, 0); - if (i) { - switch (i) { - case LINTR: - /* we get here if SIGINT not caught or ignored */ - case LERROR: - case LSHELL: - if (interactive) { - if (i == LINTR) - shellf("\n"); - /* - * Reset any eof that was read as part of a - * multiline command. - */ - if (Flag(FIGNOREEOF) && s->type == SEOF && - wastty) - s->type = SSTDIN; - /* - * Used by exit command to get back to - * top level shell. Kind of strange since - * interactive is set if we are reading from - * a tty, but to have stopped jobs, one only - * needs FMONITOR set (not FTALKING/SF_TTY)... - */ - /* toss any input we have so far */ - s->start = s->str = null; - break; - } - /* FALLTHROUGH */ - case LEXIT: - case LLEAVE: - case LRETURN: - source = old_source; - quitenv(NULL); - /* keep on going */ - unwind(i); - /* NOTREACHED */ - default: - source = old_source; - quitenv(NULL); - internal_errorf("%s %d", "shell", i); - /* NOTREACHED */ + switch ((i = kshsetjmp(e->jbuf))) { + case 0: + break; + case LINTR: + /* we get here if SIGINT not caught or ignored */ + case LERROR: + case LSHELL: + if (interactive) { + if (i == LINTR) + shellf("\n"); + /* + * Reset any eof that was read as part of a + * multiline command. + */ + if (Flag(FIGNOREEOF) && s->type == SEOF && wastty) + s->type = SSTDIN; + /* + * Used by exit command to get back to + * top level shell. Kind of strange since + * interactive is set if we are reading from + * a tty, but to have stopped jobs, one only + * needs FMONITOR set (not FTALKING/SF_TTY)... + */ + /* toss any input we have so far */ + s->start = s->str = null; + break; } + /* FALLTHROUGH */ + case LEXIT: + case LLEAVE: + case LRETURN: + source = old_source; + quitenv(NULL); + /* keep on going */ + unwind(i); + /* NOTREACHED */ + default: + source = old_source; + quitenv(NULL); + internal_errorf("%s %d", "shell", i); + /* NOTREACHED */ } while (/* CONSTCOND */ 1) { if (trap) @@ -817,7 +863,7 @@ case E_INCL: case E_LOOP: case E_ERRH: - siglongjmp(e->jbuf, i); + kshlongjmp(e->jbuf, i); /* NOTREACHED */ case E_NONE: if (i == LINTR) @@ -969,7 +1015,7 @@ { for (; tp != NULL; tp = tp->next) if (tp->pid == procpid) - unlink(tp->name); + unlink(tp->tffn); } /* @@ -1217,7 +1263,13 @@ SHF_UNBUF : 0); } -struct shf shf_iob[3]; +#ifdef DF +int shl_dbg_fd; +#define NSHF_IOB 4 +#else +#define NSHF_IOB 3 +#endif +struct shf shf_iob[NSHF_IOB]; void initio(void) @@ -1225,9 +1277,23 @@ /* force buffer allocation */ shf_fdopen(1, SHF_WR, shl_stdout); shf_fdopen(2, SHF_WR, shl_out); - /* force buffer allocation */ shf_fdopen(2, SHF_WR, shl_spare); - initio_done = 1; +#ifdef DF + if ((shl_dbg_fd = open("/tmp/mksh-dbg.txt", + O_WRONLY | O_APPEND | O_CREAT, 0600)) == -1) + errorf("cannot open debug output file"); + if (shl_dbg_fd < FDBASE) { + int nfd; + + nfd = fcntl(shl_dbg_fd, F_DUPFD, FDBASE); + close(shl_dbg_fd); + if ((shl_dbg_fd = nfd) == -1) + errorf("cannot dup debug output file"); + } + shf_fdopen(shl_dbg_fd, SHF_WR, shl_dbg); + DF("=== open ==="); +#endif + initio_done = true; } /* A dup2() with error checking */ @@ -1433,42 +1499,61 @@ struct temp * maketemp(Area *ap, Temp_type type, struct temp **tlist) { - struct temp *tp; + char *cp; size_t len; - int fd; - char *pathname; + int i; + struct temp *tp; const char *dir; + struct stat sb; dir = tmpdir ? tmpdir : MKSH_DEFAULT_TMPDIR; -#if HAVE_MKSTEMP - len = strlen(dir) + 6 + 10 + 1; -#else - pathname = tempnam(dir, "mksh."); - len = ((pathname == NULL) ? 0 : strlen(pathname)) + 1; -#endif - /* reasonably sure that this will not overflow */ - tp = alloc(sizeof(struct temp) + len, ap); - tp->name = (char *)&tp[1]; -#if !HAVE_MKSTEMP - if (pathname == NULL) - tp->name[0] = '\0'; - else { - memcpy(tp->name, pathname, len); - free_ostempnam(pathname); - } -#endif - pathname = tp->name; + /* add "/shXXXXXX.tmp" plus NUL */ + len = strlen(dir); + checkoktoadd(len, offsetof(struct temp, tffn[0]) + 14); + tp = alloc(offsetof(struct temp, tffn[0]) + 14 + len, ap); + tp->shf = NULL; - tp->type = type; -#if HAVE_MKSTEMP - shf_snprintf(pathname, len, "%s%s", dir, "/mksh.XXXXXXXXXX"); - if ((fd = mkstemp(pathname)) >= 0) -#else - if (tp->name[0] && (fd = open(tp->name, O_CREAT | O_RDWR, 0600)) >= 0) -#endif - tp->shf = shf_fdopen(fd, SHF_WR, NULL); tp->pid = procpid; + tp->type = type; + if (stat(dir, &sb) || !S_ISDIR(sb.st_mode)) { + tp->tffn[0] = '\0'; + goto maketemp_out; + } + + cp = (void *)tp; + cp += offsetof(struct temp, tffn[0]); + memcpy(cp, dir, len); + cp += len; + memcpy(cp, "/shXXXXXX.tmp", 14); + /* point to the first of six Xes */ + cp += 3; + /* generate random part of filename */ + len = -1; + do { + i = rndget() % 36; + cp[++len] = i < 26 ? 'a' + i : '0' + i - 26; + } while (len < 5); + + /* cyclically attempt to open a temporary file */ + while ((i = open(tp->tffn, O_CREAT | O_EXCL | O_RDWR, 0600)) == -1) { + if (errno != EEXIST) + goto maketemp_out; + /* count down from z to a then from 9 to 0 */ + while (cp[len] == '0') + if (!len--) + goto maketemp_out; + if (cp[len] == 'a') + cp[len] = '9'; + else + --cp[len]; + /* do another cycle */ + } + + /* shf_fdopen cannot fail, so no fd leak */ + tp->shf = shf_fdopen(i, SHF_WR, NULL); + + maketemp_out: tp->next = *tlist; *tlist = tp; return (tp); @@ -1503,8 +1588,15 @@ /* multiplication cannot overflow: alloc2 checked that */ memset(ntblp, 0, i * sizeof(struct tbl *)); - /* table can get 80% full except when reaching its limit */ - tp->nfree = (tp->tshift == 30) ? 0x3FFF0000UL : ((i * 4) / 5); + /* table can get very full when reaching its size limit */ + tp->nfree = (tp->tshift == 30) ? 0x3FFF0000UL : + /* but otherwise, only 80% (MKSH_SMALL) or 66% (normal) */ +#ifdef MKSH_SMALL + ((i * 4) / 5) +#else + ((i * 2) / 3) +#endif + ; tp->tbls = ntblp; if (otblp == NULL) return; @@ -1534,7 +1626,7 @@ } void -ktinit(Area *ap, struct table *tp, uint8_t initshift) +ktinit_real(Area *ap, struct table *tp, uint8_t initshift) { tp->areap = ap; tp->tbls = NULL; @@ -1662,3 +1754,23 @@ got_winch = 1; } #endif + +#ifdef DF +void +DF(const char *fmt, ...) +{ + va_list args; + struct timeval tv; + + mksh_lockfd(shl_dbg_fd); + gettimeofday(&tv, NULL); + shf_fprintf(shl_dbg, "[%d.%06d:%d] ", (int)tv.tv_sec, (int)tv.tv_usec, + (int)getpid()); + va_start(args, fmt); + shf_vfprintf(shl_dbg, fmt, args); + va_end(args); + shf_putc('\n', shl_dbg); + shf_flush(shl_dbg); + mksh_unlkfd(shl_dbg_fd); +} +#endif diff -Nru mksh-40.4/misc.c mksh-40.9.20120414/misc.c --- mksh-40.4/misc.c 2011-12-04 20:00:35.000000000 +0000 +++ mksh-40.9.20120414/misc.c 2012-04-06 12:59:51.000000000 +0000 @@ -2,7 +2,8 @@ /* $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 + * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, + * 2011, 2012 * Thorsten Glaser * * Provided that these terms and disclaimer and all copyright notices @@ -29,7 +30,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.167.2.3 2011/12/04 19:59:47 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.187 2012/04/06 12:59:27 tg Exp $"); /* type bits for unsigned char */ unsigned char chtypes[UCHAR_MAX + 1]; @@ -249,9 +250,16 @@ DO_SETUID(setresuid, (ksheuid, ksheuid, ksheuid)); #else /* seteuid, setegid, setgid don't EAGAIN on Linux */ - seteuid(ksheuid = kshuid = getuid()); + ksheuid = kshuid = getuid(); +#ifndef __BEOS__ + /* BeOS doesn't have different UIDs */ + seteuid(ksheuid); +#endif DO_SETUID(setuid, (ksheuid)); +#ifndef __BEOS__ + /* BeOS doesn't have different GIDs */ setegid(kshegid); +#endif setgid(kshegid); #endif } else if ((f == FPOSIX || f == FSH) && newval) { @@ -356,14 +364,6 @@ break; } i = option(go.optarg); -#if !defined(MKSH_NO_DEPRECATED_WARNING) && !defined(MKSH_DISABLE_DEPRECATED) - if ((enum sh_flag)i == FARC4RANDOM) { - warningf(true, "Do not use set ±o arc4random," - " it will be removed in the next version" - " of mksh!"); - return (0); - } -#endif if ((i != (size_t)-1) && set == Flag(i)) /* * Don't check the context if the flag @@ -652,7 +652,7 @@ if (!in_bracket) { saw_glob = true; in_bracket = true; - if (ISMAGIC(p[1]) && p[2] == NOT) + if (ISMAGIC(p[1]) && p[2] == '!') p += 2; if (ISMAGIC(p[1]) && p[2] == ']') p += 2; @@ -831,7 +831,7 @@ int c, d, notp, found = 0; const unsigned char *orig_p = p; - if ((notp = (ISMAGIC(*p) && *++p == NOT))) + if ((notp = (ISMAGIC(*p) && *++p == '!'))) p++; do { c = *p++; @@ -1038,41 +1038,116 @@ * No trailing newline is printed. */ void -print_value_quoted(const char *s) +print_value_quoted(struct shf *shf, const char *s) { - const char *p; - bool inquote = false; + unsigned char c; + const unsigned char *p = (const unsigned char *)s; + bool inquote = true; /* first, check whether any quotes are needed */ - for (p = s; *p; p++) - if (ctype(*p, C_QUOTE)) - break; - if (!*p) { - /* nope, use the shortcut */ - shf_puts(s, shl_stdout); - return; - } + while ((c = *p++) >= 32) + if (ctype(c, C_QUOTE)) + inquote = false; + + p = (const unsigned char *)s; + if (c == 0) { + if (inquote) { + /* nope, use the shortcut */ + shf_puts(s, shf); + return; + } - /* quote via state machine */ - for (p = s; *p; p++) { - if (*p == '\'') { - /* - * multiple '''s or any ' at beginning of string - * look nicer this way than when simply substituting - */ - if (inquote) { - shf_putc('\'', shl_stdout); - inquote = false; - } - shf_putc('\\', shl_stdout); - } else if (!inquote) { - shf_putc('\'', shl_stdout); - inquote = true; + /* otherwise, quote nicely via state machine */ + while ((c = *p++) != 0) { + if (c == '\'') { + /* + * multiple single quotes or any of them + * at the beginning of a string look nicer + * this way than when simply substituting + */ + if (inquote) { + shf_putc('\'', shf); + inquote = false; + } + shf_putc('\\', shf); + } else if (!inquote) { + shf_putc('\'', shf); + inquote = true; + } + shf_putc(c, shf); } - shf_putc(*p, shl_stdout); + } else { + unsigned int wc; + size_t n; + + /* use $'...' quote format */ + shf_putc('$', shf); + shf_putc('\'', shf); + while ((c = *p) != 0) { + if (c >= 0xC2) { + n = utf_mbtowc(&wc, (const char *)p); + if (n != (size_t)-1) { + p += n; + shf_fprintf(shf, "\\u%04X", wc); + continue; + } + } + ++p; + switch (c) { + /* see unbksl() in this file for comments */ + case 7: + c = 'a'; + if (0) + /* FALLTHROUGH */ + case '\b': + c = 'b'; + if (0) + /* FALLTHROUGH */ + case '\f': + c = 'f'; + if (0) + /* FALLTHROUGH */ + case '\n': + c = 'n'; + if (0) + /* FALLTHROUGH */ + case '\r': + c = 'r'; + if (0) + /* FALLTHROUGH */ + case '\t': + c = 't'; + if (0) + /* FALLTHROUGH */ + case 11: + c = 'v'; + if (0) + /* FALLTHROUGH */ + case '\033': + /* take E not e because \e is \ in *roff */ + c = 'E'; + /* FALLTHROUGH */ + case '\\': + shf_putc('\\', shf); + + if (0) + /* FALLTHROUGH */ + default: + if (c < 32 || c > 0x7E) { + /* FALLTHROUGH */ + case '\'': + shf_fprintf(shf, "\\x%02X", c); + break; + } + + shf_putc(c, shf); + break; + } + } + inquote = true; } if (inquote) - shf_putc('\'', shl_stdout); + shf_putc('\'', shf); } /* @@ -1106,10 +1181,6 @@ ++max_oct; str = alloc(max_oct, ATEMP); - /* ensure x_cols is valid first */ - if (x_cols < MIN_COLS) - change_winsz(); - /* * We use (max_col + 1) to consider the space separator. * Note that no space is printed after the last column @@ -1247,6 +1318,10 @@ return (rv); } +#ifndef ELOOP +#define ELOOP E2BIG +#endif + char * do_realpath(const char *upath) { @@ -1884,9 +1959,9 @@ { register uint32_t h; - oaat1_init_impl(h); - oaat1_addmem_impl(h, &rndsetupstate, sizeof(rndsetupstate)); - oaat1_fini_impl(h); + NZATInit(h); + NZATUpdateMem(h, &rndsetupstate, sizeof(rndsetupstate)); + NZAATFinish(h); rndset((long)h); } chvt_reinit(); @@ -1925,26 +2000,6 @@ } #endif -#if !HAVE_STRCASESTR -const char * -stristr(const char *b, const char *l) -{ - char first, c; - size_t n; - - if ((first = *l++), ((first = ksh_tolower(first)) == '\0')) - return (b); - n = strlen(l); - stristr_look: - while ((c = *b++), ((c = ksh_tolower(c)) != first)) - if (c == '\0') - return (NULL); - if (strncasecmp(b, l, n)) - goto stristr_look; - return (b - 1); -} -#endif - #ifdef MKSH_SMALL char * strndup_i(const char *src, size_t len, Area *ap) diff -Nru mksh-40.4/mksh.1 mksh-40.9.20120414/mksh.1 --- mksh-40.4/mksh.1 2012-05-01 02:38:29.000000000 +0000 +++ mksh-40.9.20120414/mksh.1 2012-04-14 12:51:58.000000000 +0000 @@ -1,8 +1,8 @@ -.\" $MirOS: src/bin/mksh/mksh.1,v 1.269.2.9 2011/12/31 02:25:29 tg Exp $ +.\" $MirOS: src/bin/mksh/mksh.1,v 1.284 2012/04/14 12:51:34 tg Exp $ .\" $OpenBSD: ksh.1,v 1.141 2011/09/03 22:59:08 jmc Exp $ .\"- .\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, -.\" 2010, 2011 +.\" 2010, 2011, 2012 .\" Thorsten Glaser .\" .\" Provided that these terms and disclaimer and all copyright notices @@ -28,6 +28,8 @@ .\" * ~ is size-reduced and placed atop in groff, so use \*(TI .\" * ^ is size-reduced and placed atop in groff, so use \*(ha .\" * \(en does not work in nroff, so use \*(en +.\" * <>| are problematic, so redefine and use \*(Lt\*(Gt\*(Ba +.\" Also make sure to use \& especially with two-letter words. .\" The section after the "doc" macropackage has been loaded contains .\" additional code to convene between the UCB mdoc macropackage (and .\" its variant as BSD mdoc in groff) and the GNU mdoc macropackage. @@ -72,11 +74,13 @@ .\" with -mandoc, it might implement .Mx itself, but we want to .\" use our own definition. And .Dd must come *first*, always. .\" -.Dd $Mdocdate: December 31 2011 $ +.Dd $Mdocdate: April 14 2012 $ .\" -.\" Check which macro package we use +.\" Check which macro package we use, and do other -mdoc setup. .\" .ie \n(.g \{\ +. if \*[.T]utf8 .tr \[la]\*(Lt +. if \*[.T]utf8 .tr \[ra]\*(Gt . ie d volume-ds-1 .ds tT gnu . el .ds tT bsd .\} @@ -153,7 +157,7 @@ .Nm .Bk -words .Op Fl +abCefhiklmnprUuvXx -.Op Fl T Ar /dev/ttyCn | \- +.Op Fl T Ar /dev/ttyCn \*(Ba \- .Op Fl +o Ar option .Oo .Fl c Ar string \*(Ba @@ -1614,12 +1618,16 @@ must start with a space, opening parenthesis or digit to be recognised. Cannot be applied to a vector. .Pp -.It Pf ${ Ns Ar name Ns @#} +.It Xo +.Pf ${ Ar name +.Pf @# Ns Oo Ar seed Oc Ns } +.Xc The internal hash of the expansion of -.Ar name . -At the moment, this is OAAT1 (Bob Jenkins' one-at-a-time hash with -an initialisation value of 0x00000100), this will change for R41, -which will also introduce an explicit initial value. +.Ar name , +with an optional (defaulting to zero) +.Ar seed . +At the moment, this is NZAT (a never-zero 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. .El .Pp @@ -2476,14 +2484,14 @@ .Ar number is a number in the specified base. Additionally, base-16 integers may be specified by prefixing them with -.Sq 0x Pq case-insensitive +.Sq 0x +.Pq case-insensitive in all forms of arithmetic expressions, except as numeric arguments to the .Ic test built-in command. -Base-8 integers may be specified by prefixing them with -.Sq 0 , -but this is deprecated and will be removed in the next version of -.Nm . +It is discouraged to prefix numbers with a sole zero +.Pq Sq 0 , +because some shells may interpret them as base-8 integers. As a special .Nm mksh extension, numbers to the base of one are treated as either (8-bit @@ -3349,11 +3357,8 @@ and .Fl s is identical: re-execute the selected command without invoking an editor. -This command is usually accessed with the predefined +This command is usually accessed with the predefined: .Ic alias r=\*(aqfc \-e \-\*(aq -or (deprecated; will be removed RSN) by prefixing an interactive mode input line with -.Sq \&! -.Pq wbx extension . .Pp .It Ic fg Op Ar job ... Resume the specified job(s) in the foreground. @@ -3639,7 +3644,7 @@ .Pp .It Xo .Ic read -.Op Fl A | Fl a +.Op Fl A \*(Ba Fl a .Op Fl d Ar x .Oo Fl N Ar z \*(Ba .Fl n Ar z Oc @@ -3758,7 +3763,7 @@ .Bd -literal -offset indent find . \-type f \-print0 \*(Ba \e while IFS= read \-d \*(aq\*(aq \-r filename; do - print \-r \-\- "found <${filename#./}>" + print \-r \-\- "found \*(Lt${filename#./}\*(Gt" done .Ed .Pp @@ -4030,11 +4035,6 @@ Print commands and parameter assignments when they are executed, preceded by the value of .Ev PS4 . -.It Fl o Ic arc4random -Deprecated, will be removed in -.Nm -R41. -Do not use, emits a warning to stderr. .It Fl o Ic bgnice Background jobs are run with lower priority. .It Fl o Ic braceexpand @@ -6265,7 +6265,7 @@ .Ed .Pp This document attempts to describe -.Nm mksh\ R40d +.Nm mksh\ R40+CVS and up, compiled without any options impacting functionality, such as .Dv MKSH_SMALL , diff -Nru mksh-40.4/printf.c mksh-40.9.20120414/printf.c --- mksh-40.4/printf.c 2011-03-13 15:10:57.000000000 +0000 +++ mksh-40.9.20120414/printf.c 2011-08-17 20:54:48.000000000 +0000 @@ -47,7 +47,7 @@ #define vstrchr strchr #endif -__RCSID("$MirOS: src/usr.bin/printf/printf.c,v 1.17 2011/03/13 15:10:09 tg Exp $"); +__RCSID("$MirOS: src/usr.bin/printf/printf.c,v 1.18 2011/08/17 20:54:24 tg Exp $"); static int print_escape_str(const char *); static int print_escape(const char *); @@ -481,12 +481,13 @@ mklong(const char *str, int ch) { static char *copy; - static int copysize; - int len; + static size_t copysize; + size_t len; len = strlen(str) + 2; if (copysize < len) { char *newcopy; + copysize = len + 256; newcopy = realloc(copy, copysize); @@ -634,7 +635,7 @@ ts[0] = c; c = 1; } else - c = utf_wctomb(ts, c - 0x100); + c = (int)utf_wctomb(ts, c - 0x100); shf_write(ts, c, shl_stdout); } diff -Nru mksh-40.4/sh_flags.h mksh-40.9.20120414/sh_flags.h --- mksh-40.4/sh_flags.h 2011-11-26 18:24:14.000000000 +0000 +++ mksh-40.9.20120414/sh_flags.h 2011-06-12 15:37:34.000000000 +0000 @@ -1,5 +1,5 @@ #if defined(SHFLAGS_DEFNS) -__RCSID("$MirOS: src/bin/mksh/sh_flags.h,v 1.8.2.1 2011/11/26 18:23:26 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/sh_flags.h,v 1.9 2011/06/12 15:37:10 tg Exp $"); #define FN(sname,cname,ochar,flags) /* nothing */ #elif defined(SHFLAGS_ENUMS) #define FN(sname,cname,ochar,flags) cname, @@ -21,11 +21,6 @@ /* -a all new parameters are created with the export attribute */ F0("allexport", FEXPORT, 'a', OF_ANY) -#ifndef MKSH_DISABLE_DEPRECATED -/* ./. backwards compat: dummy, emits a warning */ -FN("arc4random", FARC4RANDOM, 0, OF_ANY) -#endif - #if HAVE_NICE /* ./. bgnice */ FN("bgnice", FBGNICE, 0, OF_ANY) diff -Nru mksh-40.4/sh.h mksh-40.9.20120414/sh.h --- mksh-40.4/sh.h 2012-05-01 02:38:29.000000000 +0000 +++ mksh-40.9.20120414/sh.h 2012-04-14 16:08:12.000000000 +0000 @@ -1,6 +1,6 @@ /* $OpenBSD: sh.h,v 1.30 2010/01/04 18:07:11 deraadt Exp $ */ /* $OpenBSD: shf.h,v 1.6 2005/12/11 18:53:51 deraadt Exp $ */ -/* $OpenBSD: table.h,v 1.7 2005/12/11 20:31:21 otto 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.11 2006/05/29 18:22:24 otto Exp $ */ @@ -152,9 +152,9 @@ #endif #ifdef EXTERN -__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.484.2.14 2012/02/11 15:25:33 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.549 2012/04/14 16:07:48 tg Exp $"); #endif -#define MKSH_VERSION "R40 2012/02/11" +#define MKSH_VERSION "R40 2012/04/14" /* arithmetic types: C implementation */ #if !HAVE_CAN_INTTYPES @@ -167,6 +167,14 @@ #endif /* arithmetic types: shell arithmetics */ +/* + * NOTE: these are currently hard-coded to exactly 32 bit, do not change + * + * TODO: make these configurable, or add 64-bit arithmetic, somehow + * (on some operating environments, 64-bit types are needed for some + * things, such as the ulimit builtin, to work proper), except mksh + * must still be able to run on systems with no native 64-bit integers + */ typedef int32_t mksh_ari_t; typedef uint32_t mksh_uari_t; @@ -196,7 +204,7 @@ /* other standard types */ #if !HAVE_RLIM_T -typedef long rlim_t; +typedef unsigned long rlim_t; #endif #if !HAVE_SIG_T @@ -204,6 +212,21 @@ typedef void (*sig_t)(int); #endif +#ifdef MKSH_TYPEDEF_SIG_ATOMIC_T +typedef MKSH_TYPEDEF_SIG_ATOMIC_T sig_atomic_t; +#endif + +#ifdef MKSH_TYPEDEF_SSIZE_T +typedef MKSH_TYPEDEF_SSIZE_T ssize_t; +#endif + +/* un-do vendor damage */ + +#undef BAD /* AIX defines that somewhere */ +#undef PRINT /* LynxOS defines that somewhere */ +#undef flock /* SCO UnixWare defines that to flock64 but ENOENT */ + + #ifndef MKSH_INCLUDES_ONLY /* extra types */ @@ -296,7 +319,6 @@ #endif #endif -#undef BAD /* AIX defines that somewhere */ /* OS-dependent additions (functions, variables, by OS) */ @@ -312,15 +334,6 @@ extern int revoke(const char *); #endif -#ifdef __ultrix -/* XXX imake style */ -int strcasecmp(const char *, const char *); -#endif - -#if !HAVE_STRCASESTR -const char *stristr(const char *, const char *); -#endif - #if !HAVE_STRLCPY size_t strlcpy(char *, const char *, size_t); #endif @@ -336,9 +349,9 @@ extern int __cdecl setegid(gid_t); #endif -/* remove redundances */ +/* remove redundancies */ -#if defined(MirBSD) && (MirBSD >= 0x08A8) +#if defined(MirBSD) && (MirBSD >= 0x08A8) && !defined(MKSH_OPTSTATIC) #define MKSH_mirbsd_wcwidth #define utf_wcwidth(i) wcwidth((__WCHAR_TYPE__)i) extern int wcwidth(__WCHAR_TYPE__); @@ -370,11 +383,10 @@ /* * Make MAGIC a char that might be printed to make bugs more obvious, but * not a char that is used often. Also, can't use the high bit as it causes - * portability problems (calling strchr(x, 0x80|'x') is error prone). + * portability problems (calling strchr(x, 0x80 | 'x') is error prone). */ #define MAGIC (7) /* prefix for *?[!{,} during expand */ #define ISMAGIC(c) ((unsigned char)(c) == MAGIC) -#define NOT '!' /* might use ^ (ie, [!...] vs [^..]) */ #define LINE 4096 /* input line size */ @@ -430,6 +442,16 @@ #define mkssert(e) ((void)0) #endif +#if (!defined(MKSH_BUILDMAKEFILE4BSD) && !defined(MKSH_BUILDSH)) || (MKSH_BUILD_R != 409) +#error Must run Build.sh to compile this. +int +im_sorry_dave(void) +{ + /* I’m sorry, Dave. I’m afraid I can’t do that. */ + return (thiswillneverbedefinedIhope()); +} +#endif + /* use this ipv strchr(s, 0) but no side effects in s! */ #define strnul(s) ((s) + strlen(s)) @@ -471,10 +493,6 @@ } while (/* CONSTCOND */ 0) #endif -#if HAVE_STRCASESTR -#define stristr(b,l) ((const char *)strcasestr((b), (l))) -#endif - #ifdef MKSH_SMALL #ifndef MKSH_CONSERVATIVE_FDS #define MKSH_CONSERVATIVE_FDS /* defined */ @@ -517,11 +535,6 @@ #define free_ossetmode(p) free(p) #endif -#if !HAVE_MKSTEMP -/* tempnam(3) -> free(3) */ -#define free_ostempnam(p) free(p) -#endif - #ifdef NO_PATH_MAX /* GNU libc: get_current_dir_name(3) -> free(3) */ #define free_gnu_gcdn(p) free(p) @@ -560,6 +573,16 @@ /* * parsing & execution environment */ +#ifdef MKSH_NO_SIGSETJMP +#define kshjmp_buf jmp_buf +#define kshsetjmp(jbuf) _setjmp(jbuf) +#define kshlongjmp _longjmp +#else +#define kshjmp_buf sigjmp_buf +#define kshsetjmp(jbuf) sigsetjmp((jbuf), 0) +#define kshlongjmp siglongjmp +#endif + extern struct env { ALLOC_ITEM alloc_INT; /* internal, do not touch */ Area area; /* temporary allocation area */ @@ -567,9 +590,9 @@ struct block *loc; /* local variables and functions */ short *savefd; /* original redirected fds */ struct temp *temps; /* temp files */ - sigjmp_buf jbuf; /* long jump back to env creator */ - short type; /* environment type - see below */ - short flags; /* EF_* */ + kshjmp_buf jbuf; /* long jump back to env creator */ + uint8_t type; /* environment type - see below */ + uint8_t flags; /* EF_* */ } *e; /* struct env.type values */ @@ -588,12 +611,12 @@ #define EF_FAKE_SIGDIE BIT(2) /* hack to get info from unwind to quitenv */ /* Do breaks/continues stop at env type e? */ -#define STOP_BRKCONT(t) ((t) == E_NONE || (t) == E_PARSE \ - || (t) == E_FUNC || (t) == E_INCL) +#define STOP_BRKCONT(t) ((t) == E_NONE || (t) == E_PARSE || \ + (t) == E_FUNC || (t) == E_INCL) /* Do returns stop at env type e? */ #define STOP_RETURN(t) ((t) == E_FUNC || (t) == E_INCL) -/* values for siglongjmp(e->jbuf, 0) */ +/* values for kshlongjmp(e->jbuf, i) */ #define LRETURN 1 /* return statement */ #define LEXIT 2 /* exit statement */ #define LERROR 3 /* errorf() called */ @@ -676,18 +699,21 @@ EXTERN const char T_function[] E_INIT(" function"); #define Tfunction (T_function + 1) /* "function" */ -enum temp_type { - TT_HEREDOC_EXP, /* expanded heredoc */ - TT_HIST_EDIT /* temp file used for history editing (fc -e) */ -}; -typedef enum temp_type Temp_type; +typedef uint8_t Temp_type; +/* expanded heredoc */ +#define TT_HEREDOC_EXP 0 +/* temp file used for history editing (fc -e) */ +#define TT_HIST_EDIT 1 + /* temp/heredoc files. The file is removed when the struct is freed. */ struct temp { struct temp *next; struct shf *shf; - char *name; - int pid; /* pid of process parsed here-doc */ + /* pid of process parsed here-doc */ + pid_t pid; Temp_type type; + /* actually longer: name (variable length) */ + char tffn[3]; }; /* @@ -697,6 +723,9 @@ #define shl_spare (&shf_iob[0]) /* for c_read()/c_print() */ #define shl_stdout (&shf_iob[1]) #define shl_out (&shf_iob[2]) +#ifdef DF +#define shl_dbg (&shf_iob[3]) /* for DF() */ +#endif EXTERN bool shl_stdout_ok; /* @@ -856,15 +885,7 @@ #define MIN_COLS (2 + MIN_EDIT_SPACE + 3) #define MIN_LINS 3 EXTERN mksh_ari_t x_cols E_INIT(80); /* tty columns */ -EXTERN mksh_ari_t x_lins E_INIT(-1); /* tty lines */ - -/* These to avoid bracket matching problems */ -#define OPAREN '(' -#define CPAREN ')' -#define OBRACK '[' -#define CBRACK ']' -#define OBRACE '{' -#define CBRACE '}' +EXTERN mksh_ari_t x_lins E_INIT(24); /* tty lines */ /* Determine the location of the system (common) profile */ @@ -881,7 +902,7 @@ /* Used by v_evaluate() and setstr() to control action when error occurs */ -#define KSH_UNWIND_ERROR 0 /* unwind the stack (longjmp) */ +#define KSH_UNWIND_ERROR 0 /* unwind the stack (kshlongjmp) */ #define KSH_RETURN_ERROR 1 /* return 1/0 for success/failure */ /* @@ -1470,34 +1491,54 @@ } while (/* CONSTCOND */ 0) -/* Bob Jenkins' one-at-a-time hash, with better start value */ -#define oaat1_init_impl(h) do { \ - (h) = 0x100; \ +/* NZAT/NZAAT hashes 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 oaat1_addmem_impl(h, buf, len) do { \ - register const uint8_t *oaat1_addmem_p = (const void *)(buf); \ - register size_t oaat1_addmem_n = (len); \ - \ - while (oaat1_addmem_n--) { \ - (h) += *oaat1_addmem_p++; \ - (h) += (h) << 10; \ - (h) ^= (h) >> 6; \ - } \ + +#define NZATUpdateByte(h,b) do { \ + (h) += (uint8_t)(b); \ + ++(h); \ + (h) += (h) << 10; \ + (h) ^= (h) >> 6; \ } while (/* CONSTCOND */ 0) -#define oaat1_addstr_impl(h, s) do { \ - register const uint8_t *oaat1_addstr_p = (const void *)(s); \ - register uint8_t oaat1_addstr_c; \ - \ - while ((oaat1_addstr_c = *oaat1_addstr_p++)) { \ - h += oaat1_addstr_c; \ - (h) += (h) << 10; \ - (h) ^= (h) >> 6; \ - } \ + +#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 oaat1_fini_impl(h) do { \ - (h) += (h) << 3; \ - (h) ^= (h) >> 11; \ - (h) += (h) << 15; \ + +/* not zero after termination */ +#define NZATFinish(h) do { \ + if ((h) == 0) \ + ++(h); \ + else \ + NZAATFinish(h); \ +} while (/* CONSTCOND */ 0) + +/* NULs zählen an allen Teilen */ +#define NZAATFinish(h) do { \ + (h) += (h) << 10; \ + (h) ^= (h) >> 6; \ + (h) += (h) << 3; \ + (h) ^= (h) >> 11; \ + (h) += (h) << 15; \ } while (/* CONSTCOND */ 0) @@ -1622,7 +1663,7 @@ char **hist_get_newest(bool); void inittraps(void); void alarm_init(void); -Trap *gettrap(const char *, int); +Trap *gettrap(const char *, bool); void trapsig(int); void intrcheck(void); int fatal_trap_check(void); @@ -1636,6 +1677,10 @@ void restore_pipe(int); int setsig(Trap *, sig_t, int); void setexecsig(Trap *, int); +#if HAVE_FLOCK || HAVE_LOCK_FCNTL +void mksh_lockfd(int); +void mksh_unlkfd(int); +#endif /* jobs.c */ void j_init(void); void j_exit(void); @@ -1710,7 +1755,12 @@ int coproc_getfd(int, const char **); void coproc_cleanup(int); struct temp *maketemp(Area *, Temp_type, struct temp **); -void ktinit(Area *, struct table *, uint8_t); +void ktinit_real(Area *, struct table *, uint8_t); +#ifdef MKSH_SMALL +#define ktinit(ap, tp, s80, s66) ktinit_real((ap), (tp), (s80)) +#else +#define ktinit(ap, tp, s80, s66) ktinit_real((ap), (tp), (s66)) +#endif struct tbl *ktscan(struct table *, const char *, uint32_t, struct tbl ***); /* table, name (key) to search for, hash(n) */ #define ktsearch(tp, s, h) ktscan((tp), (s), (h), NULL) @@ -1719,6 +1769,10 @@ void ktwalk(struct tstate *, struct table *); struct tbl *ktnext(struct tstate *); struct tbl **ktsort(struct table *); +#ifdef DF +void DF(const char *, ...) + MKSH_A_FORMAT(__printf__, 1, 2); +#endif /* misc.c */ void setctypes(const char *, int); void initctypes(void); @@ -1733,7 +1787,7 @@ int xstrcmp(const void *, const void *); void ksh_getopt_reset(Getopt *, int); int ksh_getopt(const char **, Getopt *, const char *); -void print_value_quoted(const char *); +void print_value_quoted(struct shf *, const char *); char *quote_value(const char *); void print_columns(struct shf *, int, char *(*)(char *, size_t, int, const void *), @@ -1832,6 +1886,7 @@ char *arrayname(const char *); mksh_uari_t set_array(const char *, bool, const char **); uint32_t hash(const void *); +mksh_ari_t rndget(void); void rndset(long); enum Test_op { diff -Nru mksh-40.4/syn.c mksh-40.9.20120414/syn.c --- mksh-40.4/syn.c 2012-05-01 02:38:29.000000000 +0000 +++ mksh-40.9.20120414/syn.c 2012-03-03 21:31:22.000000000 +0000 @@ -23,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.73 2012/01/03 15:32:08 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.74 2012/03/03 21:30:58 tg Exp $"); extern short subshell_nesting_level; extern void yyskiputf8bom(void); @@ -794,8 +794,8 @@ struct tbl *p; ktinit(APERM, &keywords, - /* currently 28 keywords -> 80% of 64 (2^6) */ - 6); + /* currently 28 keywords */ + /* 80% of 64 = 2^6 */ 6, /* 66% of 64 = 2^6 */ 6); for (tt = tokentab; tt->name; tt++) { if (tt->reserved) { p = ktenter(&keywords, tt->name, hash(tt->name)); diff -Nru mksh-40.4/tree.c mksh-40.9.20120414/tree.c --- mksh-40.4/tree.c 2012-05-01 02:38:29.000000000 +0000 +++ mksh-40.9.20120414/tree.c 2012-04-07 11:19:54.000000000 +0000 @@ -23,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.52.4.2 2012/02/11 15:25:36 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.58 2012/04/07 11:19:30 tg Exp $"); #define INDENT 8 @@ -127,7 +127,7 @@ } fptreef(shf, indent, "%Nesac "); break; -#ifndef MKSH_NO_DEPRECATED_WARNING +#ifdef DEBUG case TELIF: internal_errorf("TELIF in tree.c:ptree() unexpected"); /* FALLTHROUGH */ @@ -291,7 +291,7 @@ case CHAR: c = *wp++; if ((opmode & WDS_MAGIC) && - (ISMAGIC(c) || c == '[' || c == NOT || + (ISMAGIC(c) || c == '[' || c == '!' || c == '-' || c == ']' || c == '*' || c == '?')) shf_putc(MAGIC, shf); shf_putc(c, shf); @@ -850,12 +850,71 @@ } void +dumpioact(struct shf *shf, struct op *t) +{ + struct ioword **ioact, *iop; + + if ((ioact = t->ioact) == NULL) + return; + + shf_puts("{IOACT", shf); + while ((iop = *ioact++) != NULL) { + int type = iop->flag & IOTYPE; +#define DT(x) case x: shf_puts(#x, shf); break; +#define DB(x) if (iop->flag & x) shf_puts("|" #x, shf); + + shf_putc(';', shf); + switch (type) { + DT(IOREAD) + DT(IOWRITE) + DT(IORDWR) + DT(IOHERE) + DT(IOCAT) + DT(IODUP) + default: + shf_fprintf(shf, "unk%d", type); + } + DB(IOEVAL) + DB(IOSKIP) + DB(IOCLOB) + DB(IORDUP) + DB(IONAMEXP) + DB(IOBASH) + DB(IOHERESTR) + DB(IONDELIM) + shf_fprintf(shf, ",unit=%d", iop->unit); + if (iop->delim) { + shf_puts(",delim<", shf); + dumpwdvar(shf, iop->delim); + shf_putc('>', shf); + } + if (iop->name) { + if (iop->flag & IONAMEXP) { + shf_puts(",name=", shf); + print_value_quoted(shf, iop->name); + } else { + shf_puts(",name<", shf); + dumpwdvar(shf, iop->name); + shf_putc('>', shf); + } + } + if (iop->heredoc) { + shf_puts(",heredoc=", shf); + print_value_quoted(shf, iop->heredoc); + } +#undef DT +#undef DB + } + shf_putc('}', shf); +} + +void dumptree(struct shf *shf, struct op *t) { int i; const char **w, *name; struct op *t1; - static int nesting = 0; + static int nesting; for (i = 0; i < nesting; ++i) shf_putc('\t', shf); @@ -865,6 +924,7 @@ name = "(null)"; goto out; } + dumpioact(shf, t); switch (t->type) { #define OPEN(x) case x: name = #x; shf_puts(" {" #x ":", shf); /*}*/ @@ -968,6 +1028,7 @@ ++w; } shf_putc(')', shf); + dumpioact(shf, t); shf_putc('\n', shf); dumptree(shf, t1->left); shf_fprintf(shf, " ;%c/%d]", t1->u.charflag, i++); @@ -994,6 +1055,7 @@ shf_putc('\n', shf); dumptree(shf, t->left); t = t->right; + dumpioact(shf, t); if (t->left != NULL) { shf_puts(" /TTHEN:\n", shf); dumptree(shf, t->left); @@ -1001,6 +1063,7 @@ if (t->right && t->right->type == TELIF) { shf_puts(" /TELIF:", shf); t = t->right; + dumpioact(shf, t); goto dumpif; } if (t->right != NULL) { diff -Nru mksh-40.4/var.c mksh-40.9.20120414/var.c --- mksh-40.4/var.c 2012-05-01 02:38:29.000000000 +0000 +++ mksh-40.9.20120414/var.c 2012-04-14 14:35:37.000000000 +0000 @@ -1,7 +1,8 @@ /* $OpenBSD: var.c,v 1.34 2007/10/15 02:16:35 deraadt Exp $ */ /*- - * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 + * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, + * 2011, 2012 * Thorsten Glaser * * Provided that these terms and disclaimer and all copyright notices @@ -26,7 +27,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/var.c,v 1.130.2.7 2011/12/31 02:25:36 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/var.c,v 1.146 2012/04/14 14:35:13 tg Exp $"); /*- * Variables @@ -74,8 +75,8 @@ l->argv = e->loc->argv; } l->exit = l->error = NULL; - ktinit(&l->area, &l->vars, 0); - ktinit(&l->area, &l->funs, 0); + ktinit(&l->area, &l->vars, 0, 0); + ktinit(&l->area, &l->funs, 0, 0); l->next = e->loc; e->loc = l; } @@ -130,8 +131,8 @@ struct tbl *tp; ktinit(APERM, &specials, - /* currently 12 specials -> 80% of 16 (2^4) */ - 4); + /* currently 12 specials */ + /* 80% of 16 = 2^4 */ 4, /* 66% of 32 = 2^5 */ 5); while (i < V_MAX - 1) { tp = ktenter(&specials, initvar_names[i], hash(initvar_names[i])); @@ -409,7 +410,7 @@ error_ok &= ~0x4; if ((vq->flag & RDONLY) && !no_ro_check) { - warningf(true, "%s: %s", vq->name, "is read only"); + warningf(true, "read-only: %s", vq->name); if (!error_ok) errorfxz(2); return (0); @@ -487,26 +488,11 @@ base = 10; num = 0; neg = 0; -#ifdef MKSH_DISABLE_DEPRECATED if (arith && s[0] == '0' && (s[1] | 0x20) == 'x') { s += 2; base = 16; have_base = true; } -#else - if (arith && *s == '0' && *(s+1)) { - s++; - if (*s == 'x' || *s == 'X') { - s++; - base = 16; - } else if (vp->flag & ZEROFIL) { - while (*s == '0') - s++; - } else - base = 8; - have_base = true; - } -#endif while ((c = *s++)) { if (c == '-') { neg++; @@ -809,7 +795,7 @@ if ((vpbase->flag&RDONLY) && (val || clr || (set & ~EXPORT))) /* XXX check calls - is error here ok by POSIX? */ - errorfx(2, "%s: %s", tvar, "is read only"); + errorfx(2, "read-only: %s", tvar); afree(tvar, ATEMP); /* most calls are with set/clr == 0 */ @@ -1108,11 +1094,7 @@ return; break; case V_RANDOM: - /* - * this is the same Linear Congruential PRNG as Borland - * C/C++ allegedly uses in its built-in rand() function - */ - i = ((lcg_state = 22695477 * lcg_state + 1) >> 16) & 0x7FFF; + i = rndget(); break; case V_HISTSIZE: i = histsize; @@ -1132,7 +1114,6 @@ * and the window is then resized, the app won't * see the change cause the environ doesn't change. */ - change_winsz(); i = st == V_COLUMNS ? x_cols : x_lins; break; default: @@ -1400,7 +1381,7 @@ /* Note: AT&T ksh allows set -A but not set +A of a read-only var */ if ((vp->flag&RDONLY)) - errorfx(2, "%s: %s", ccp, "is read only"); + errorfx(2, "read-only: %s", ccp); /* This code is quite non-optimal */ if (reset) { /* trash existing values and attributes */ @@ -1458,16 +1439,6 @@ void change_winsz(void) { - if (x_lins < 0) { - /* first time initialisation */ -#ifdef TIOCGWINSZ - if (tty_fd < 0) - /* non-FTALKING, try to get an fd anyway */ - tty_init(true, false); -#endif - x_cols = -1; - } - #ifdef TIOCGWINSZ /* check if window size has changed */ if (tty_fd >= 0) { @@ -1498,20 +1469,30 @@ { register uint32_t h; - oaat1_init_impl(h); - oaat1_addstr_impl(h, s); - oaat1_fini_impl(h); + NZATInit(h); + NZATUpdateString(h, s); + NZATFinish(h); return (h); } +mksh_ari_t +rndget(void) +{ + /* + * this is the same Linear Congruential PRNG as Borland + * C/C++ allegedly uses in its built-in rand() function + */ + return (((lcg_state = 22695477 * lcg_state + 1) >> 16) & 0x7FFF); +} + void rndset(long v) { register uint32_t h; - oaat1_init_impl(h); - oaat1_addmem_impl(h, &lcg_state, sizeof(lcg_state)); - oaat1_addmem_impl(h, &v, sizeof(v)); + NZATInit(h); + NZATUpdateMem(h, &lcg_state, sizeof(lcg_state)); + NZATUpdateMem(h, &v, sizeof(v)); #if defined(arc4random_pushb_fast) || defined(MKSH_A4PB) /* @@ -1520,16 +1501,16 @@ * user requested us to use the old functions */ lcg_state = h; - oaat1_fini_impl(lcg_state); + NZAATFinish(lcg_state); #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 - oaat1_addmem_impl(h, &lcg_state, sizeof(lcg_state)); + NZATUpdateMem(h, &lcg_state, sizeof(lcg_state)); #endif - oaat1_fini_impl(h); + NZAATFinish(h); lcg_state = h; }