diff options
-rw-r--r-- | system/dash/README | 17 | ||||
-rw-r--r-- | system/dash/dash.SlackBuild | 24 | ||||
-rw-r--r-- | system/dash/dash.info | 10 | ||||
-rw-r--r-- | system/dash/patches/dash-0.5.8-git_d7582e6.diff | 2371 |
4 files changed, 18 insertions, 2404 deletions
diff --git a/system/dash/README b/system/dash/README index 4daf9c0301..4f1ca583a5 100644 --- a/system/dash/README +++ b/system/dash/README @@ -1,13 +1,4 @@ -DASH is a POSIX-compliant implementation of /bin/sh that aims to be as -small as possible. It does this without sacrificing speed where possible. -In fact, it is significantly faster than bash (the GNU Bourne-Again SHell) -for most tasks. - -To patch in fixes from current git, add 'USE_GIT_PATCH=yes' to the command -line when building, like this: - -# USE_GIT_PATCH=yes sh dash.Slackbuild - -or, if you use fakeroot to build: - -$ fakeroot env USE_GIT_PATCH=yes sh dash.SlackBuild +DASH is a POSIX-compliant implementation of /bin/sh that aims to be as +small as possible. It does this without sacrificing speed where +possible. In fact, it is significantly faster than bash (the GNU +Bourne-Again SHell) for most tasks. diff --git a/system/dash/dash.SlackBuild b/system/dash/dash.SlackBuild index f0c362a7d5..61c42279a9 100644 --- a/system/dash/dash.SlackBuild +++ b/system/dash/dash.SlackBuild @@ -3,17 +3,16 @@ # Slackware build script for dash # Written by Vincent Batts, http://hashbangbash.com/ +# Copyright 2017 Donald Cooley South Haven, Indiana USA PRGNAM=dash -VERSION=${VERSION:-0.5.8} -_PATCH_VERS=${PATCH_VERS:-git_d7582e6} +VERSION=${VERSION:-0.5.9.1} BUILD=${BUILD:-1} TAG=${TAG:-_SBo} -USE_GIT_PATCH=${USE_GIT_PATCH:-no} if [ -z "$ARCH" ]; then case "$( uname -m )" in - i?86) ARCH=i486 ;; + i?86) ARCH=i586 ;; arm*) ARCH=arm ;; *) ARCH=$( uname -m ) ;; esac @@ -24,8 +23,8 @@ TMP=${TMP:-/tmp/SBo} PKG=$TMP/package-$PRGNAM OUTPUT=${OUTPUT:-/tmp} -if [ "$ARCH" = "i486" ]; then - SLKCFLAGS="-O2 -march=i486 -mtune=i686" +if [ "$ARCH" = "i586" ]; then + SLKCFLAGS="-O2 -march=i586 -mtune=i686" LIBDIRSUFFIX="" elif [ "$ARCH" = "i686" ]; then SLKCFLAGS="-O2 -march=i686 -mtune=i686" @@ -47,13 +46,6 @@ rm -rf $PRGNAM-$VERSION tar xvf $CWD/$PRGNAM-$VERSION.tar.gz cd $PRGNAM-$VERSION -# add fixes from upstream devel, if requested -if [ "$USE_GIT_PATCH" = "yes" ] && \ - [ -f $CWD/patches/dash-${VERSION}-${_PATCH_VERS}.diff ]; then - patch -p1 < $CWD/patches/dash-${VERSION}-${_PATCH_VERS}.diff - VERSION="${VERSION}.${_PATCH_VERS}" -fi - chown -R root:root . find -L . \ \( -perm 777 -o -perm 775 -o -perm 750 -o -perm 711 -o -perm 555 -o -perm 511 \) \ @@ -78,14 +70,16 @@ make install DESTDIR=$PKG mkdir -p $PKG/usr/bin ( cd $PKG/usr/bin ; ln -s /bin/dash dash ) -find $PKG | xargs file | grep -e "executable" -e "shared object" | grep ELF \ +find $PKG -print0 | xargs -0 file | grep -e "executable" -e "shared object" | grep ELF \ | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null || true find $PKG/usr/man -type f -exec gzip -9 {} \; for i in $( find $PKG/usr/man -type l ) ; do ln -s $( readlink $i ).gz $i.gz ; rm $i ; done mkdir -p $PKG/usr/doc/$PRGNAM-$VERSION -cp -a COPYING ChangeLog $PKG/usr/doc/$PRGNAM-$VERSION +cp -a \ + COPYING ChangeLog \ + $PKG/usr/doc/$PRGNAM-$VERSION cat $CWD/$PRGNAM.SlackBuild > $PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.SlackBuild mkdir -p $PKG/install diff --git a/system/dash/dash.info b/system/dash/dash.info index 6d206c8caa..5603cdd0bc 100644 --- a/system/dash/dash.info +++ b/system/dash/dash.info @@ -1,10 +1,10 @@ PRGNAM="dash" -VERSION="0.5.8" +VERSION="0.5.9.1" HOMEPAGE="http://gondor.apana.org.au/~herbert/dash/" -DOWNLOAD="http://gondor.apana.org.au/~herbert/dash/files/dash-0.5.8.tar.gz" -MD5SUM="5c152209680dab3c319e8923f6c51378" +DOWNLOAD="https://sourceforge.net/projects/slackbuildsdirectlinks/files/dash/dash-0.5.9.1.tar.gz" +MD5SUM="6472702a8d9760d166ef8333dcb527a6" DOWNLOAD_x86_64="" MD5SUM_x86_64="" REQUIRES="" -MAINTAINER="John Vogel" -EMAIL="jvogel4@stny.rr.com" +MAINTAINER="Donald Cooley" +EMAIL="chytraeu@sdf.org" diff --git a/system/dash/patches/dash-0.5.8-git_d7582e6.diff b/system/dash/patches/dash-0.5.8-git_d7582e6.diff deleted file mode 100644 index ac5c6903d5..0000000000 --- a/system/dash/patches/dash-0.5.8-git_d7582e6.diff +++ /dev/null @@ -1,2371 +0,0 @@ -diff -Naur dash-0.5.8/ChangeLog dash-0.5.8-git_d7582e6/ChangeLog ---- dash-0.5.8/ChangeLog 2014-09-28 04:19:32.000000000 -0400 -+++ dash-0.5.8-git_d7582e6/ChangeLog 2015-08-05 13:55:25.055358032 -0400 -@@ -1,3 +1,73 @@ -+2014-11-17 Stéphane Aulery <saulery@free.fr> -+ -+ * Correct typo in manual page. -+ * Document redirection file descriptor limitation. -+ -+2014-10-30 Herbert Xu <herbert@gondor.apana.org.au> -+ -+ * Catch variable length expansions on non-existant specials. -+ -+2014-10-28 Herbert Xu <herbert@gondor.apana.org.au> -+ -+ * Removed unnecessary pungetc on EOF from parser. -+ * Simplify EOF/newline handling in list parser. -+ -+2014-10-27 Herbert Xu <herbert@gondor.apana.org.au> -+ -+ * Add printf support for format string a, A, and F. -+ * Handle embedded NULs correctly in printf. -+ * Replace open-coded flushall in preadbuffer. -+ * Add likely tag in outmem. -+ * Add ifdefs around MEM_OUT handling in outmem. -+ * Remove unnecessary restoration of format string in printf. -+ * Remove getintmax in printf. -+ * Use error instead of warnx for fatal errors in printf. -+ * Optimise handling of backslash octals in printf. -+ * Simplify echo command. -+ * Handle -- in dotcmd. -+ -+2014-10-13 Eric Blake <eblake@redhat.com> -+ -+ * cd: support drive letters on Cygwin. -+ -+2014-10-08 Herbert Xu <herbert@gondor.apana.org.au> -+ -+ * Split unquoted $@/$* correctly when IFS is set but empty. -+ * Do not split quoted VSLENGTH and VSTRIM. -+ * Optimise nulonly away and just use quoted as before. -+ -+2014-10-07 Herbert Xu <herbert@gondor.apana.org.au> -+ -+ * Use setvareq to set OPTIND initially. -+ -+2014-10-06 Herbert Xu <herbert@gondor.apana.org.au> -+ -+ * Exit without arguments in a trap should use status outside traps. -+ * Do not allow break to break across function calls. -+ * Move common skipcount logic into skiploop. -+ * Allow return in loop conditional to set exit status. -+ * Return without arguments in a trap should use status outside traps. -+ -+2014-10-03 Herbert Xu <herbert@gondor.apana.org.au> -+ -+ * Do not clobber exitstatus in evalcommand. -+ -+2014-10-02 Herbert Xu <herbert@gondor.apana.org.au> -+ -+ * Fix use-after-free in dotrap/evalstring. -+ * Make sure evalskip is zero before running traps. -+ * Set exitstatus in onint. -+ -+2014-09-29 Herbert Xu <herbert@gondor.apana.org.au> -+ -+ * Kill pgetc_macro. -+ * Handle backslash newlines properly after dollar sign. -+ * Add nlprompt/nlnoprompt helpers. -+ -+2014-09-28 Herbert Xu <herbert@gondor.apana.org.au> -+ -+ * Correctly handle test ! ! = !. -+ - 2014-09-26 Herbert Xu <herbert@gondor.apana.org.au> - - * Small optimisation of command -pv change. -diff -Naur dash-0.5.8/Makefile.in dash-0.5.8-git_d7582e6/Makefile.in ---- dash-0.5.8/Makefile.in 2014-09-28 04:19:40.000000000 -0400 -+++ dash-0.5.8-git_d7582e6/Makefile.in 2015-08-05 13:57:40.555361584 -0400 -@@ -1,4 +1,4 @@ --# Makefile.in generated by automake 1.11.6 from Makefile.am. -+# Makefile.in generated by automake 1.11.5 from Makefile.am. - # @configure_input@ - - # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -@@ -527,7 +527,7 @@ - *.zip*) \ - unzip $(distdir).zip ;;\ - esac -- chmod -R a-w $(distdir); chmod u+w $(distdir) -+ chmod -R a-w $(distdir); chmod a+w $(distdir) - mkdir $(distdir)/_build - mkdir $(distdir)/_inst - chmod a-w $(distdir) -diff -Naur dash-0.5.8/aclocal.m4 dash-0.5.8-git_d7582e6/aclocal.m4 ---- dash-0.5.8/aclocal.m4 2014-09-28 04:19:39.000000000 -0400 -+++ dash-0.5.8-git_d7582e6/aclocal.m4 2015-08-05 13:57:39.728694896 -0400 -@@ -1,4 +1,4 @@ --# generated automatically by aclocal 1.11.6 -*- Autoconf -*- -+# generated automatically by aclocal 1.11.5 -*- Autoconf -*- - - # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, - # 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, -@@ -38,7 +38,7 @@ - [am__api_version='1.11' - dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to - dnl require some minimum version. Point them to the right macro. --m4_if([$1], [1.11.6], [], -+m4_if([$1], [1.11.5], [], - [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl - ]) - -@@ -54,7 +54,7 @@ - # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. - # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. - AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], --[AM_AUTOMAKE_VERSION([1.11.6])dnl -+[AM_AUTOMAKE_VERSION([1.11.5])dnl - m4_ifndef([AC_AUTOCONF_VERSION], - [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl - _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) -diff -Naur dash-0.5.8/config.h.in dash-0.5.8-git_d7582e6/config.h.in ---- dash-0.5.8/config.h.in 2014-09-28 04:19:39.000000000 -0400 -+++ dash-0.5.8-git_d7582e6/config.h.in 2015-08-05 13:57:40.062028238 -0400 -@@ -88,6 +88,9 @@ - /* Define to 1 if you have the <sys/types.h> header file. */ - #undef HAVE_SYS_TYPES_H - -+/* Define if your faccessat tells root all files are executable */ -+#undef HAVE_TRADITIONAL_FACCESSAT -+ - /* Define to 1 if you have the <unistd.h> header file. */ - #undef HAVE_UNISTD_H - -diff -Naur dash-0.5.8/configure dash-0.5.8-git_d7582e6/configure ---- dash-0.5.8/configure 2014-09-28 04:19:40.000000000 -0400 -+++ dash-0.5.8-git_d7582e6/configure 2015-08-05 13:57:40.772028257 -0400 -@@ -714,6 +714,7 @@ - enable_static - enable_fnmatch - enable_glob -+enable_test_workaround - with_libedit - enable_lineno - ' -@@ -1347,6 +1348,9 @@ - --enable-static Build statical linked program - --enable-fnmatch Use fnmatch(3) from libc - --enable-glob Use glob(3) from libc -+ --enable-test-workaround -+ Guard against faccessat(2) that tells root all files -+ are executable - --disable-lineno Disable LINENO support - - Optional Packages: -@@ -4614,6 +4618,29 @@ - done - - -+ -+# Check whether --enable-test-workaround was given. -+if test "${enable_test_workaround+set}" = set; then : -+ enableval=$enable_test_workaround; -+else -+ enable_test_workaround=auto -+fi -+ -+ -+if test "enable_test_workaround" = "auto" && -+ test "$ac_cv_func_faccessat" = yes; then -+ case `uname -s 2>/dev/null` in -+ GNU/kFreeBSD | \ -+ FreeBSD) -+ enable_test_workaround=yes -+ esac -+fi -+if test "$enable_test_workaround" = "yes"; then -+ -+$as_echo "#define HAVE_TRADITIONAL_FACCESSAT 1" >>confdefs.h -+ -+fi -+ - if test "$enable_fnmatch" = yes; then - use_fnmatch= - for ac_func in fnmatch -diff -Naur dash-0.5.8/configure.ac dash-0.5.8-git_d7582e6/configure.ac ---- dash-0.5.8/configure.ac 2014-09-28 04:19:32.000000000 -0400 -+++ dash-0.5.8-git_d7582e6/configure.ac 2015-08-05 13:55:25.055358032 -0400 -@@ -90,6 +90,37 @@ - sigsetmask stpcpy strchrnul strsignal strtod strtoimax \ - strtoumax sysconf) - -+dnl Check whether it's worth working around FreeBSD PR kern/125009. -+dnl The traditional behavior of access/faccessat is crazy, but -+dnl POSIX.1-2008 explicitly allows those functions to misbehave. -+dnl -+dnl Unaffected kernels: -+dnl -+dnl - all versions of Linux -+dnl - NetBSD sys/kern/vfs_subr.c 1.64, 1997-04-23 -+dnl - FreeBSD 9 (r212002), 2010-09-10 -+dnl - OpenBSD sys/kern/vfs_subr.c 1.166, 2008-06-09 -+dnl -+dnl Also worked around in Debian's libc0.1 2.13-19 when using -+dnl kFreeBSD 8. -+ -+AC_ARG_ENABLE(test-workaround, AS_HELP_STRING(--enable-test-workaround, \ -+ [Guard against faccessat(2) that tells root all files are executable]),, -+ [enable_test_workaround=auto]) -+ -+if test "enable_test_workaround" = "auto" && -+ test "$ac_cv_func_faccessat" = yes; then -+ case `uname -s 2>/dev/null` in -+ GNU/kFreeBSD | \ -+ FreeBSD) -+ enable_test_workaround=yes -+ esac -+fi -+if test "$enable_test_workaround" = "yes"; then -+ AC_DEFINE([HAVE_TRADITIONAL_FACCESSAT], [1], -+ [Define if your faccessat tells root all files are executable]) -+fi -+ - if test "$enable_fnmatch" = yes; then - use_fnmatch= - AC_CHECK_FUNCS(fnmatch, use_fnmatch=yes) -diff -Naur dash-0.5.8/src/Makefile.am dash-0.5.8-git_d7582e6/src/Makefile.am ---- dash-0.5.8/src/Makefile.am 2014-09-28 04:19:32.000000000 -0400 -+++ dash-0.5.8-git_d7582e6/src/Makefile.am 2015-08-05 13:55:25.058691365 -0400 -@@ -26,7 +26,7 @@ - dash_SOURCES = \ - $(dash_CFILES) \ - alias.h arith_yacc.h bltin/bltin.h cd.h error.h eval.h exec.h \ -- expand.h hetio.h \ -+ expand.h \ - init.h input.h jobs.h machdep.h mail.h main.h memalloc.h miscbltin.h \ - myhistedit.h mystring.h options.h output.h parser.h redir.h shell.h \ - show.h system.h trap.h var.h -diff -Naur dash-0.5.8/src/Makefile.in dash-0.5.8-git_d7582e6/src/Makefile.in ---- dash-0.5.8/src/Makefile.in 2014-09-28 04:19:40.000000000 -0400 -+++ dash-0.5.8-git_d7582e6/src/Makefile.in 2015-08-05 13:57:40.525361584 -0400 -@@ -1,4 +1,4 @@ --# Makefile.in generated by automake 1.11.6 from Makefile.am. -+# Makefile.in generated by automake 1.11.5 from Makefile.am. - # @configure_input@ - - # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -@@ -236,7 +236,7 @@ - dash_SOURCES = \ - $(dash_CFILES) \ - alias.h arith_yacc.h bltin/bltin.h cd.h error.h eval.h exec.h \ -- expand.h hetio.h \ -+ expand.h \ - init.h input.h jobs.h machdep.h mail.h main.h memalloc.h miscbltin.h \ - myhistedit.h mystring.h options.h output.h parser.h redir.h shell.h \ - show.h system.h trap.h var.h -diff -Naur dash-0.5.8/src/bltin/printf.c dash-0.5.8-git_d7582e6/src/bltin/printf.c ---- dash-0.5.8/src/bltin/printf.c 2014-09-28 04:19:32.000000000 -0400 -+++ dash-0.5.8-git_d7582e6/src/bltin/printf.c 2015-08-05 13:55:25.058691365 -0400 -@@ -40,12 +40,11 @@ - #include <string.h> - #include <unistd.h> - --static int conv_escape_str(char *); -+static int conv_escape_str(char *, char **); - static char *conv_escape(char *, int *); - static int getchr(void); - static double getdouble(void); --static intmax_t getintmax(void); --static uintmax_t getuintmax(void); -+static uintmax_t getuintmax(int); - static char *getstr(void); - static char *mklong(const char *, const char *); - static void check_conversion(const char *, const char *); -@@ -73,6 +72,53 @@ - } \ - } - -+#define ASPF(sp, f, func) ({ \ -+ int ret; \ -+ switch ((char *)param - (char *)array) { \ -+ default: \ -+ ret = xasprintf(sp, f, array[0], array[1], func); \ -+ break; \ -+ case sizeof(*param): \ -+ ret = xasprintf(sp, f, array[0], func); \ -+ break; \ -+ case 0: \ -+ ret = xasprintf(sp, f, func); \ -+ break; \ -+ } \ -+ ret; \ -+}) -+ -+ -+static int print_escape_str(const char *f, int *param, int *array, char *s) -+{ -+ struct stackmark smark; -+ char *p, *q; -+ int done; -+ int len; -+ int total; -+ -+ setstackmark(&smark); -+ done = conv_escape_str(s, &p); -+ q = stackblock(); -+ len = p - q; -+ -+ p = makestrspace(len, p); -+ memset(p, 'X', len - 1); -+ p[len - 1] = 0; -+ -+ q = stackblock(); -+ total = ASPF(&p, f, p); -+ -+ len = strchrnul(p, 'X') - p; -+ memcpy(p + len, q, strchrnul(p + len, ' ') - (p + len)); -+ -+ out1mem(p, total); -+ -+ popstackmark(&smark); -+ return done; -+} -+ -+ - int printfcmd(int argc, char *argv[]) - { - char *fmt; -@@ -86,10 +132,8 @@ - argv = argptr; - format = *argv; - -- if (!format) { -- warnx("usage: printf format [arg ...]"); -- goto err; -- } -+ if (!format) -+ error("usage: printf format [arg ...]"); - - gargv = ++argv; - -@@ -132,39 +176,33 @@ - /* skip to field width */ - fmt += strspn(fmt, SKIP1); - if (*fmt == '*') -- *param++ = getintmax(); -+ *param++ = getuintmax(1); - - /* skip to possible '.', get following precision */ - fmt += strspn(fmt, SKIP2); - if (*fmt == '.') - ++fmt; - if (*fmt == '*') -- *param++ = getintmax(); -+ *param++ = getuintmax(1); - - fmt += strspn(fmt, SKIP2); - - ch = *fmt; -- if (!ch) { -- warnx("missing format character"); -- goto err; -- } -+ if (!ch) -+ error("missing format character"); - /* null terminate format string to we can use it - as an argument to printf. */ - nextch = fmt[1]; - fmt[1] = 0; - switch (ch) { - -- case 'b': { -- int done = conv_escape_str(getstr()); -- char *p = stackblock(); -+ case 'b': - *fmt = 's'; -- PF(start, p); - /* escape if a \c was encountered */ -- if (done) -+ if (print_escape_str(start, param, array, -+ getstr())) - goto out; -- *fmt = 'b'; - break; -- } - case 'c': { - int p = getchr(); - PF(start, p); -@@ -177,23 +215,26 @@ - } - case 'd': - case 'i': { -- intmax_t p = getintmax(); -- char *f = mklong(start, fmt); -- PF(f, p); -+ uintmax_t p = getuintmax(1); -+ start = mklong(start, fmt); -+ PF(start, p); - break; - } - case 'o': - case 'u': - case 'x': - case 'X': { -- uintmax_t p = getuintmax(); -- char *f = mklong(start, fmt); -- PF(f, p); -+ uintmax_t p = getuintmax(0); -+ start = mklong(start, fmt); -+ PF(start, p); - break; - } -+ case 'a': -+ case 'A': - case 'e': - case 'E': - case 'f': -+ case 'F': - case 'g': - case 'G': { - double p = getdouble(); -@@ -201,8 +242,7 @@ - break; - } - default: -- warnx("%s: invalid directive", start); -- goto err; -+ error("%s: invalid directive", start); - } - *++fmt = nextch; - } -@@ -210,8 +250,6 @@ - - out: - return rval; --err: -- return 1; - } - - -@@ -220,8 +258,9 @@ - * Halts processing string if a \c escape is encountered. - */ - static int --conv_escape_str(char *str) -+conv_escape_str(char *str, char **sp) - { -+ int c; - int ch; - char *cp; - -@@ -229,16 +268,14 @@ - STARTSTACKSTR(cp); - - do { -- int c; -- -- ch = *str++; -+ c = ch = *str++; - if (ch != '\\') - continue; - -- ch = *str++; -- if (ch == 'c') { -+ c = *str++; -+ if (c == 'c') { - /* \c as in SYSV echo - abort all processing.... */ -- ch = 0x100; -+ c = ch = 0x100; - continue; - } - -@@ -247,25 +284,14 @@ - * They start with a \0, and are followed by 0, 1, 2, - * or 3 octal digits. - */ -- if (ch == '0') { -- unsigned char i; -- i = 3; -- ch = 0; -- do { -- unsigned k = octtobin(*str); -- if (k > 7) -- break; -- str++; -- ch <<= 3; -- ch += k; -- } while (--i); -- continue; -- } -+ if (c == '0' && isodigit(*str)) -+ str++; - - /* Finally test for sequences valid in the format string */ - str = conv_escape(str - 1, &c); -- ch = c; -- } while (STPUTC(ch, cp), (char)ch); -+ } while (STPUTC(c, cp), (char)ch); -+ -+ *sp = cp; - - return ch; - } -@@ -283,12 +309,11 @@ - - switch (ch) { - default: -- case 0: -- value = '\\'; -- goto out; -+ if (!isodigit(*str)) { -+ value = '\\'; -+ goto out; -+ } - -- case '0': case '1': case '2': case '3': -- case '4': case '5': case '6': case '7': - ch = 3; - value = 0; - do { -@@ -357,30 +382,8 @@ - return val; - } - --static intmax_t --getintmax(void) --{ -- intmax_t val = 0; -- char *cp, *ep; -- -- cp = *gargv; -- if (cp == NULL) -- goto out; -- gargv++; -- -- val = (unsigned char) cp[1]; -- if (*cp == '\"' || *cp == '\'') -- goto out; -- -- errno = 0; -- val = strtoimax(cp, &ep, 0); -- check_conversion(cp, ep); --out: -- return val; --} -- - static uintmax_t --getuintmax(void) -+getuintmax(int sign) - { - uintmax_t val = 0; - char *cp, *ep; -@@ -395,7 +398,7 @@ - goto out; - - errno = 0; -- val = strtoumax(cp, &ep, 0); -+ val = sign ? strtoimax(cp, &ep, 0) : strtoumax(cp, &ep, 0); - check_conversion(cp, ep); - out: - return val; -@@ -439,34 +442,21 @@ - int - echocmd(int argc, char **argv) - { -- int nonl = 0; -- struct output *outs = out1; -+ int nonl; - -- if (!*++argv) -- goto end; -- if (equal(*argv, "-n")) { -- nonl = ~nonl; -- if (!*++argv) -- goto end; -- } -+ nonl = *++argv ? equal(*argv, "-n") : 0; -+ argv += nonl; - - do { - int c; - -- nonl += conv_escape_str(*argv); -- outstr(stackblock(), outs); -+ if (likely(*argv)) -+ nonl += print_escape_str("%s", NULL, NULL, *argv++); - if (nonl > 0) - break; - -- c = ' '; -- if (!*++argv) { --end: -- if (nonl) { -- break; -- } -- c = '\n'; -- } -- outc(c, outs); -+ c = *argv ? ' ' : '\n'; -+ out1c(c); - } while (*argv); - return 0; - } -diff -Naur dash-0.5.8/src/bltin/test.c dash-0.5.8-git_d7582e6/src/bltin/test.c ---- dash-0.5.8/src/bltin/test.c 2014-09-28 04:19:32.000000000 -0400 -+++ dash-0.5.8-git_d7582e6/src/bltin/test.c 2015-08-05 13:55:25.058691365 -0400 -@@ -155,6 +155,14 @@ - static int bash_group_member(gid_t); - #endif - -+#ifdef HAVE_FACCESSAT -+# ifdef HAVE_TRADITIONAL_FACCESSAT -+static inline int faccessat_confused_about_superuser(void) { return 1; } -+# else -+static inline int faccessat_confused_about_superuser(void) { return 0; } -+# endif -+#endif -+ - static inline intmax_t getn(const char *s) - { - return atomax10(s); -@@ -177,7 +185,7 @@ - { - const struct t_op *op; - enum token n; -- int res; -+ int res = 1; - - if (*argv[0] == '[') { - if (*argv[--argc] != ']') -@@ -185,11 +193,12 @@ - argv[argc] = NULL; - } - -+recheck: - argv++; - argc--; - - if (argc < 1) -- return 1; -+ return res; - - /* - * POSIX prescriptions: he who wrote this deserves the Nobel -@@ -209,6 +218,9 @@ - argv[--argc] = NULL; - argv++; - argc--; -+ } else if (!strcmp(argv[0], "!")) { -+ res = 0; -+ goto recheck; - } - } - -@@ -216,7 +228,7 @@ - - eval: - t_wp = argv; -- res = !oexpr(n); -+ res ^= oexpr(n); - argv = t_wp; - - if (argv[0] != NULL && argv[1] != NULL) -@@ -489,8 +501,20 @@ - } - - #ifdef HAVE_FACCESSAT -+static int has_exec_bit_set(const char *path) -+{ -+ struct stat64 st; -+ -+ if (stat64(path, &st)) -+ return 0; -+ return st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH); -+} -+ - static int test_file_access(const char *path, int mode) - { -+ if (faccessat_confused_about_superuser() && -+ mode == X_OK && geteuid() == 0 && !has_exec_bit_set(path)) -+ return 0; - return !faccessat(AT_FDCWD, path, mode, AT_EACCESS); - } - #else /* HAVE_FACCESSAT */ -diff -Naur dash-0.5.8/src/cd.c dash-0.5.8-git_d7582e6/src/cd.c ---- dash-0.5.8/src/cd.c 2014-09-28 04:19:32.000000000 -0400 -+++ dash-0.5.8-git_d7582e6/src/cd.c 2015-08-05 13:55:25.058691365 -0400 -@@ -38,6 +38,9 @@ - #include <string.h> - #include <unistd.h> - #include <limits.h> -+#ifdef __CYGWIN__ -+#include <sys/cygwin.h> -+#endif - - /* - * The cd and pwd commands. -@@ -194,6 +197,17 @@ - char *cdcomppath; - const char *lim; - -+#ifdef __CYGWIN__ -+ /* On cygwin, thanks to drive letters, some absolute paths do -+ not begin with slash; but cygwin includes a function that -+ forces normalization to the posix form */ -+ char pathbuf[PATH_MAX]; -+ if (cygwin_conv_path(CCP_WIN_A_TO_POSIX | CCP_RELATIVE, dir, pathbuf, -+ sizeof(pathbuf)) < 0) -+ sh_error("can't normalize %s", dir); -+ dir = pathbuf; -+#endif -+ - cdcomppath = sstrdup(dir); - STARTSTACKSTR(new); - if (*dir != '/') { -diff -Naur dash-0.5.8/src/dash.1 dash-0.5.8-git_d7582e6/src/dash.1 ---- dash-0.5.8/src/dash.1 2014-09-28 04:19:32.000000000 -0400 -+++ dash-0.5.8-git_d7582e6/src/dash.1 2015-08-05 13:55:25.058691365 -0400 -@@ -385,7 +385,7 @@ - Following is a list of the possible redirections. - The - .Bq n --is an optional number, as in -+is an optional number between 0 and 9, as in - .Sq 3 - (not - .Sq Bq 3 ) , -@@ -402,11 +402,13 @@ - .It [n] Ns \*[Lt] file - Redirect standard input (or n) from file. - .It [n1] Ns \*[Lt]& Ns n2 --Duplicate standard input (or n1) from file descriptor n2. -+Copy file descriptor n2 as stdout (or fd n1). -+fd n2. - .It [n] Ns \*[Lt]&- - Close standard input (or n). - .It [n1] Ns \*[Gt]& Ns n2 --Duplicate standard output (or n1) to n2. -+Copy file descriptor n2 as stdin (or fd n1). -+fd n2. - .It [n] Ns \*[Gt]&- - Close standard output (or n). - .It [n] Ns \*[Lt]\*[Gt] file -@@ -596,7 +598,7 @@ - characters. - The commands in a list are executed in the order they are written. - If command is followed by an ampersand, the shell starts the --command and immediately proceed onto the next command; otherwise it waits -+command and immediately proceeds onto the next command; otherwise it waits - for the command to terminate before proceeding to the next one. - .Ss Short-Circuit List Operators - .Dq && -@@ -1400,14 +1402,9 @@ - .Va optstring - all errors will be ignored. - .Pp --A nonzero value is returned when the last option is reached. --If there are no remaining arguments, -+After the last option - .Ic getopts --will set --.Va var --to the special option, --.Dq -- , --otherwise, it will set -+will return a non-zero value and set - .Va var - to - .Dq \&? . -diff -Naur dash-0.5.8/src/error.c dash-0.5.8-git_d7582e6/src/error.c ---- dash-0.5.8/src/error.c 2014-09-28 04:19:32.000000000 -0400 -+++ dash-0.5.8-git_d7582e6/src/error.c 2015-08-05 13:55:25.058691365 -0400 -@@ -105,6 +105,7 @@ - signal(SIGINT, SIG_DFL); - raise(SIGINT); - } -+ exitstatus = SIGINT + 128; - exraise(EXINT); - /* NOTREACHED */ - } -diff -Naur dash-0.5.8/src/eval.c dash-0.5.8-git_d7582e6/src/eval.c ---- dash-0.5.8/src/eval.c 2014-09-28 04:19:32.000000000 -0400 -+++ dash-0.5.8-git_d7582e6/src/eval.c 2015-08-05 13:55:25.058691365 -0400 -@@ -74,6 +74,7 @@ - char *commandname; - int exitstatus; /* exit status of last command */ - int back_exitstatus; /* exit status of backquoted command */ -+int savestatus = -1; /* exit status of last command outside traps */ - - - #if !defined(__alpha__) || (defined(__GNUC__) && __GNUC__ >= 3) -@@ -114,6 +115,10 @@ - RESET { - evalskip = 0; - loopnest = 0; -+ if (savestatus >= 0) { -+ exitstatus = savestatus; -+ savestatus = -1; -+ } - } - #endif - -@@ -160,6 +165,7 @@ - struct stackmark smark; - int status; - -+ s = sstrdup(s); - setinputstring(s); - setstackmark(&smark); - -@@ -171,7 +177,9 @@ - if (evalskip) - break; - } -+ popstackmark(&smark); - popfile(); -+ stunalloc(s); - - return status; - } -@@ -194,6 +202,9 @@ - TRACE(("evaltree(NULL) called\n")); - goto out; - } -+ -+ dotrap(); -+ - #ifndef SMALL - displayhist = 1; /* show history substitutions done with fc */ - #endif -@@ -305,8 +316,7 @@ - if (checkexit & exitstatus) - goto exexit; - -- if (pendingsigs) -- dotrap(); -+ dotrap(); - - if (flags & EV_EXIT) { - exexit: -@@ -329,27 +339,45 @@ - #endif - - -+static int skiploop(void) -+{ -+ int skip = evalskip; -+ -+ switch (skip) { -+ case 0: -+ break; -+ -+ case SKIPBREAK: -+ case SKIPCONT: -+ if (likely(--skipcount <= 0)) { -+ evalskip = 0; -+ break; -+ } -+ -+ skip = SKIPBREAK; -+ break; -+ } -+ -+ return skip; -+} -+ -+ - STATIC void - evalloop(union node *n, int flags) - { -+ int skip; - int status; - - loopnest++; - status = 0; - flags &= EV_TESTED; -- for (;;) { -+ do { - int i; - - evaltree(n->nbinary.ch1, EV_TESTED); -- if (evalskip) { --skipping: if (evalskip == SKIPCONT && --skipcount <= 0) { -- evalskip = 0; -- continue; -- } -- if (evalskip == SKIPBREAK && --skipcount <= 0) -- evalskip = 0; -- break; -- } -+ skip = skiploop(); -+ if (skip) -+ continue; - i = exitstatus; - if (n->type != NWHILE) - i = !i; -@@ -357,11 +385,11 @@ - break; - evaltree(n->nbinary.ch2, flags); - status = exitstatus; -- if (evalskip) -- goto skipping; -- } -+ skip = skiploop(); -+ } while (!(skip & ~SKIPCONT)); -+ if (skip != SKIPFUNC) -+ exitstatus = status; - loopnest--; -- exitstatus = status; - } - - -@@ -382,9 +410,6 @@ - arglist.lastp = &arglist.list; - for (argp = n->nfor.args ; argp ; argp = argp->narg.next) { - expandarg(argp, &arglist, EXP_FULL | EXP_TILDE); -- /* XXX */ -- if (evalskip) -- goto out; - } - *arglist.lastp = NULL; - -@@ -394,18 +419,10 @@ - for (sp = arglist.list ; sp ; sp = sp->next) { - setvar(n->nfor.var, sp->text, 0); - evaltree(n->nfor.body, flags); -- if (evalskip) { -- if (evalskip == SKIPCONT && --skipcount <= 0) { -- evalskip = 0; -- continue; -- } -- if (evalskip == SKIPBREAK && --skipcount <= 0) -- evalskip = 0; -+ if (skiploop() & ~SKIPCONT) - break; -- } - } - loopnest--; --out: - popstackmark(&smark); - } - -@@ -848,21 +865,12 @@ - listsetvar(varlist.list, VEXPORT); - } - if (evalbltin(cmdentry.u.cmd, argc, argv, flags)) { -- int status; -- int i; -- -- i = exception; -- if (i == EXEXIT) -- goto raise; -- -- status = (i == EXINT) ? SIGINT + 128 : 2; -- exitstatus = status; -- -- if (i == EXINT || spclbltin > 0) { --raise: -- longjmp(handler->loc, 1); -+ if (exception == EXERROR && spclbltin <= 0) { -+ FORCEINTON; -+ break; - } -- FORCEINTON; -+raise: -+ longjmp(handler->loc, 1); - } - break; - -@@ -927,9 +935,11 @@ - struct jmploc jmploc; - int e; - int savefuncline; -+ int saveloopnest; - - saveparam = shellparam; - savefuncline = funcline; -+ saveloopnest = loopnest; - savehandler = handler; - if ((e = setjmp(jmploc.loc))) { - goto funcdone; -@@ -939,6 +949,7 @@ - shellparam.malloc = 0; - func->count++; - funcline = func->n.ndefun.linno; -+ loopnest = 0; - INTON; - shellparam.nparam = argc - 1; - shellparam.p = argv + 1; -@@ -949,13 +960,14 @@ - poplocalvars(0); - funcdone: - INTOFF; -+ loopnest = saveloopnest; - funcline = savefuncline; - freefunc(func); - freeparam(&shellparam); - shellparam = saveparam; - handler = savehandler; - INTON; -- evalskip &= ~SKIPFUNC; -+ evalskip &= ~(SKIPFUNC | SKIPFUNCDEF); - return e; - } - -@@ -1035,12 +1047,23 @@ - int - returncmd(int argc, char **argv) - { -+ int skip; -+ int status; -+ - /* - * If called outside a function, do what ksh does; - * skip the rest of the file. - */ -- evalskip = SKIPFUNC; -- return argv[1] ? number(argv[1]) : exitstatus; -+ if (argv[1]) { -+ skip = SKIPFUNC; -+ status = number(argv[1]); -+ } else { -+ skip = SKIPFUNCDEF; -+ status = exitstatus; -+ } -+ evalskip = skip; -+ -+ return status; - } - - -diff -Naur dash-0.5.8/src/eval.h dash-0.5.8-git_d7582e6/src/eval.h ---- dash-0.5.8/src/eval.h 2014-09-28 04:19:32.000000000 -0400 -+++ dash-0.5.8-git_d7582e6/src/eval.h 2015-08-05 13:55:25.058691365 -0400 -@@ -37,6 +37,7 @@ - extern char *commandname; /* currently executing command */ - extern int exitstatus; /* exit status of last command */ - extern int back_exitstatus; /* exit status of backquoted command */ -+extern int savestatus; /* exit status of last command outside traps */ - - - struct backcmd { /* result of evalbackcmd */ -@@ -61,3 +62,4 @@ - #define SKIPBREAK (1 << 0) - #define SKIPCONT (1 << 1) - #define SKIPFUNC (1 << 2) -+#define SKIPFUNCDEF (1 << 3) -diff -Naur dash-0.5.8/src/expand.c dash-0.5.8-git_d7582e6/src/expand.c ---- dash-0.5.8/src/expand.c 2014-09-28 04:19:32.000000000 -0400 -+++ dash-0.5.8-git_d7582e6/src/expand.c 2015-08-05 13:55:25.058691365 -0400 -@@ -116,7 +116,7 @@ - STATIC char *evalvar(char *, int); - STATIC size_t strtodest(const char *, const char *, int); - STATIC void memtodest(const char *, size_t, const char *, int); --STATIC ssize_t varvalue(char *, int, int); -+STATIC ssize_t varvalue(char *, int, int, int *); - STATIC void expandmeta(struct strlist *, int); - #ifdef HAVE_GLOB - STATIC void addglob(const glob_t *); -@@ -736,7 +736,7 @@ - p = strchr(p, '=') + 1; - - again: -- varlen = varvalue(var, varflags, flag); -+ varlen = varvalue(var, varflags, flag, "ed); - if (varflags & VSNUL) - varlen--; - -@@ -751,28 +751,22 @@ - argstr(p, flag | EXP_TILDE | EXP_WORD); - goto end; - } -- if (easy) -- goto record; -- goto end; -+ goto record; - } - - if (subtype == VSASSIGN || subtype == VSQUESTION) { -- if (varlen < 0) { -- if (subevalvar(p, var, 0, subtype, startloc, -- varflags, flag & ~QUOTES_ESC)) { -- varflags &= ~VSNUL; -- /* -- * Remove any recorded regions beyond -- * start of variable -- */ -- removerecordregions(startloc); -- goto again; -- } -- goto end; -- } -- if (easy) -+ if (varlen >= 0) - goto record; -- goto end; -+ -+ subevalvar(p, var, 0, subtype, startloc, varflags, -+ flag & ~QUOTES_ESC); -+ varflags &= ~VSNUL; -+ /* -+ * Remove any recorded regions beyond -+ * start of variable -+ */ -+ removerecordregions(startloc); -+ goto again; - } - - if (varlen < 0 && uflag) -@@ -784,9 +778,9 @@ - } - - if (subtype == VSNORMAL) { -+record: - if (!easy) - goto end; --record: - recordregion(startloc, expdest - (char *)stackblock(), quoted); - goto end; - } -@@ -892,7 +886,7 @@ - */ - - STATIC ssize_t --varvalue(char *name, int varflags, int flags) -+varvalue(char *name, int varflags, int flags, int *quotedp) - { - int num; - char *p; -@@ -901,13 +895,13 @@ - char sepc; - char **ap; - char const *syntax; -- int quoted = flags & EXP_QUOTED; -+ int quoted = *quotedp; - int subtype = varflags & VSTYPE; - int discard = subtype == VSPLUS || subtype == VSLENGTH; - int quotes = (discard ? 0 : (flags & QUOTES_ESC)) | QUOTES_KEEPNUL; - ssize_t len = 0; - -- sep = quoted ? ((flags & EXP_FULL) << CHAR_BIT) : 0; -+ sep = (flags & EXP_FULL) << CHAR_BIT; - syntax = quoted ? DQSYNTAX : BASESYNTAX; - - switch (*name) { -@@ -938,15 +932,18 @@ - expdest = p; - break; - case '@': -- if (sep) -+ if (quoted && sep) - goto param; - /* fall through */ - case '*': -- sep = ifsset() ? ifsval()[0] : ' '; -+ if (quoted) -+ sep = 0; -+ sep |= ifsset() ? ifsval()[0] : ' '; - param: -+ sepc = sep; -+ *quotedp = !sepc; - if (!(ap = shellparam.p)) - return -1; -- sepc = sep; - while ((p = *ap++)) { - len += strtodest(p, syntax, quotes); - -diff -Naur dash-0.5.8/src/hetio.h dash-0.5.8-git_d7582e6/src/hetio.h ---- dash-0.5.8/src/hetio.h 2014-09-28 04:19:32.000000000 -0400 -+++ dash-0.5.8-git_d7582e6/src/hetio.h 1969-12-31 19:00:00.000000000 -0500 -@@ -1,22 +0,0 @@ --/* -- * Termios command line History and Editting for NetBSD sh (ash) -- * Copyright (c) 1999 -- * Main code: Adam Rogoyski <rogoyski@cs.utexas.edu> -- * Etc: Dave Cinege <dcinege@psychosis.com> -- * -- * You may use this code as you wish, so long as the original author(s) -- * are attributed in any redistributions of the source code. -- * This code is 'as is' with no warranty. -- * This code may safely be consumed by a BSD or GPL license. -- * -- * v 0.5 19990328 Initial release -- * -- * Future plans: Simple file and path name completion. (like BASH) -- * -- */ -- --void hetio_init(void); --int hetio_read_input(int fd); --void hetio_reset_term(void); -- --extern int hetio_inter; -diff -Naur dash-0.5.8/src/histedit.c dash-0.5.8-git_d7582e6/src/histedit.c ---- dash-0.5.8/src/histedit.c 2014-09-28 04:19:32.000000000 -0400 -+++ dash-0.5.8-git_d7582e6/src/histedit.c 2015-08-05 13:55:25.062024698 -0400 -@@ -372,8 +372,7 @@ - out2str(s); - } - -- evalstring(strcpy(stalloc(strlen(s) + 1), s), -- 0); -+ evalstring(s, 0); - if (displayhist && hist) { - /* - * XXX what about recursive and -diff -Naur dash-0.5.8/src/input.c dash-0.5.8-git_d7582e6/src/input.c ---- dash-0.5.8/src/input.c 2014-09-28 04:19:32.000000000 -0400 -+++ dash-0.5.8-git_d7582e6/src/input.c 2015-08-05 13:55:25.062024698 -0400 -@@ -58,45 +58,10 @@ - #include "myhistedit.h" - #endif - --#ifdef HETIO --#include "hetio.h" --#endif -- - #define EOF_NLEFT -99 /* value of parsenleft when EOF pushed back */ - #define IBUFSIZ (BUFSIZ + 1) - --MKINIT --struct strpush { -- struct strpush *prev; /* preceding string on stack */ -- char *prevstring; -- int prevnleft; -- struct alias *ap; /* if push was associated with an alias */ -- char *string; /* remember the string since it may change */ --}; -- --/* -- * The parsefile structure pointed to by the global variable parsefile -- * contains information about the current file being read. -- */ - --MKINIT --struct parsefile { -- struct parsefile *prev; /* preceding file on stack */ -- int linno; /* current line */ -- int fd; /* file descriptor (or -1 if string) */ -- int nleft; /* number of chars left in this line */ -- int lleft; /* number of chars left in this buffer */ -- char *nextc; /* next char in buffer */ -- char *buf; /* input buffer */ -- struct strpush *strpush; /* for pushing strings at this level */ -- struct strpush basestrpush; /* so pushing one is fast */ --}; -- -- --int plinno = 1; /* input line number */ --int parsenleft; /* copy of parsefile->nleft */ --MKINIT int parselleft; /* copy of parsefile->lleft */ --char *parsenextc; /* copy of parsefile->nextc */ - MKINIT struct parsefile basepf; /* top level input file */ - MKINIT char basebuf[IBUFSIZ]; /* buffer for top level input file */ - struct parsefile *parsefile = &basepf; /* current input file */ -@@ -109,6 +74,7 @@ - STATIC void pushfile(void); - static int preadfd(void); - static void setinputfd(int fd, int push); -+static int preadbuffer(void); - - #ifdef mkinit - INCLUDE <stdio.h> -@@ -117,10 +83,12 @@ - - INIT { - basepf.nextc = basepf.buf = basebuf; -+ basepf.linno = 1; - } - - RESET { -- parselleft = parsenleft = 0; /* clear input buffer */ -+ /* clear input buffer */ -+ basepf.lleft = basepf.nleft = 0; - popallfiles(); - } - #endif -@@ -134,7 +102,20 @@ - int - pgetc(void) - { -- return pgetc_macro(); -+ int c; -+ -+ if (parsefile->unget) -+ return parsefile->lastc[--parsefile->unget]; -+ -+ if (--parsefile->nleft >= 0) -+ c = (signed char)*parsefile->nextc++; -+ else -+ c = preadbuffer(); -+ -+ parsefile->lastc[1] = parsefile->lastc[0]; -+ parsefile->lastc[0] = c; -+ -+ return c; - } - - -@@ -147,7 +128,7 @@ - { - int c; - do { -- c = pgetc_macro(); -+ c = pgetc(); - } while (c == PEOA); - return c; - } -@@ -158,7 +139,7 @@ - { - int nr; - char *buf = parsefile->buf; -- parsenextc = buf; -+ parsefile->nextc = buf; - - retry: - #ifndef SMALL -@@ -184,11 +165,6 @@ - - } else - #endif -- --#ifdef HETIO -- nr = hetio_read_input(parsefile->fd); -- if (nr == -255) --#endif - nr = read(parsefile->fd, buf, IBUFSIZ - 1); - - -@@ -219,8 +195,7 @@ - * 4) Process input up to the next newline, deleting nul characters. - */ - --int --preadbuffer(void) -+static int preadbuffer(void) - { - char *q; - int more; -@@ -229,34 +204,33 @@ - #endif - char savec; - -- while (unlikely(parsefile->strpush)) { -+ if (unlikely(parsefile->strpush)) { - if ( -- parsenleft == -1 && parsefile->strpush->ap && -- parsenextc[-1] != ' ' && parsenextc[-1] != '\t' -+ parsefile->nleft == -1 && -+ parsefile->strpush->ap && -+ parsefile->nextc[-1] != ' ' && -+ parsefile->nextc[-1] != '\t' - ) { - return PEOA; - } - popstring(); -- if (--parsenleft >= 0) -- return (signed char)*parsenextc++; -+ return pgetc(); - } -- if (unlikely(parsenleft == EOF_NLEFT || parsefile->buf == NULL)) -+ if (unlikely(parsefile->nleft == EOF_NLEFT || -+ parsefile->buf == NULL)) - return PEOF; -- flushout(&output); --#ifdef FLUSHERR -- flushout(&errout); --#endif -+ flushall(); - -- more = parselleft; -+ more = parsefile->lleft; - if (more <= 0) { - again: - if ((more = preadfd()) <= 0) { -- parselleft = parsenleft = EOF_NLEFT; -+ parsefile->lleft = parsefile->nleft = EOF_NLEFT; - return PEOF; - } - } - -- q = parsenextc; -+ q = parsefile->nextc; - - /* delete nul characters */ - #ifndef SMALL -@@ -274,7 +248,7 @@ - q++; - - if (c == '\n') { -- parsenleft = q - parsenextc - 1; -+ parsefile->nleft = q - parsefile->nextc - 1; - break; - } - -@@ -291,13 +265,13 @@ - } - - if (more <= 0) { -- parsenleft = q - parsenextc - 1; -- if (parsenleft < 0) -+ parsefile->nleft = q - parsefile->nextc - 1; -+ if (parsefile->nleft < 0) - goto again; - break; - } - } -- parselleft = more; -+ parsefile->lleft = more; - - savec = *q; - *q = '\0'; -@@ -307,13 +281,13 @@ - HistEvent he; - INTOFF; - history(hist, &he, whichprompt == 1? H_ENTER : H_APPEND, -- parsenextc); -+ parsefile->nextc); - INTON; - } - #endif - - if (vflag) { -- out2str(parsenextc); -+ out2str(parsefile->nextc); - #ifdef FLUSHERR - flushout(out2); - #endif -@@ -321,19 +295,18 @@ - - *q = savec; - -- return (signed char)*parsenextc++; -+ return (signed char)*parsefile->nextc++; - } - - /* -- * Undo the last call to pgetc. Only one character may be pushed back. -+ * Undo a call to pgetc. Only two characters may be pushed back. - * PEOF may be pushed back. - */ - - void - pungetc(void) - { -- parsenleft++; -- parsenextc--; -+ parsefile->unget++; - } - - /* -@@ -355,15 +328,18 @@ - parsefile->strpush = sp; - } else - sp = parsefile->strpush = &(parsefile->basestrpush); -- sp->prevstring = parsenextc; -- sp->prevnleft = parsenleft; -+ sp->prevstring = parsefile->nextc; -+ sp->prevnleft = parsefile->nleft; -+ sp->unget = parsefile->unget; -+ memcpy(sp->lastc, parsefile->lastc, sizeof(sp->lastc)); - sp->ap = (struct alias *)ap; - if (ap) { - ((struct alias *)ap)->flag |= ALIASINUSE; - sp->string = s; - } -- parsenextc = s; -- parsenleft = len; -+ parsefile->nextc = s; -+ parsefile->nleft = len; -+ parsefile->unget = 0; - INTON; - } - -@@ -374,7 +350,8 @@ - - INTOFF; - if (sp->ap) { -- if (parsenextc[-1] == ' ' || parsenextc[-1] == '\t') { -+ if (parsefile->nextc[-1] == ' ' || -+ parsefile->nextc[-1] == '\t') { - checkkwd |= CHKALIAS; - } - if (sp->string != sp->ap->val) { -@@ -385,8 +362,10 @@ - unalias(sp->ap->name); - } - } -- parsenextc = sp->prevstring; -- parsenleft = sp->prevnleft; -+ parsefile->nextc = sp->prevstring; -+ parsefile->nleft = sp->prevnleft; -+ parsefile->unget = sp->unget; -+ memcpy(parsefile->lastc, sp->lastc, sizeof(sp->lastc)); - /*dprintf("*** calling popstring: restoring to '%s'\n", parsenextc);*/ - parsefile->strpush = sp->prev; - if (sp != &(parsefile->basestrpush)) -@@ -435,7 +414,7 @@ - parsefile->fd = fd; - if (parsefile->buf == NULL) - parsefile->buf = ckmalloc(IBUFSIZ); -- parselleft = parsenleft = 0; -+ parsefile->lleft = parsefile->nleft = 0; - plinno = 1; - } - -@@ -449,8 +428,8 @@ - { - INTOFF; - pushfile(); -- parsenextc = string; -- parsenleft = strlen(string); -+ parsefile->nextc = string; -+ parsefile->nleft = strlen(string); - parsefile->buf = NULL; - plinno = 1; - INTON; -@@ -468,15 +447,12 @@ - { - struct parsefile *pf; - -- parsefile->nleft = parsenleft; -- parsefile->lleft = parselleft; -- parsefile->nextc = parsenextc; -- parsefile->linno = plinno; - pf = (struct parsefile *)ckmalloc(sizeof (struct parsefile)); - pf->prev = parsefile; - pf->fd = -1; - pf->strpush = NULL; - pf->basestrpush.prev = NULL; -+ pf->unget = 0; - parsefile = pf; - } - -@@ -495,10 +471,6 @@ - popstring(); - parsefile = pf->prev; - ckfree(pf); -- parsenleft = parsefile->nleft; -- parselleft = parsefile->lleft; -- parsenextc = parsefile->nextc; -- plinno = parsefile->linno; - INTON; - } - -diff -Naur dash-0.5.8/src/input.h dash-0.5.8-git_d7582e6/src/input.h ---- dash-0.5.8/src/input.h 2014-09-28 04:19:32.000000000 -0400 -+++ dash-0.5.8-git_d7582e6/src/input.h 2015-08-05 13:55:25.062024698 -0400 -@@ -41,18 +41,56 @@ - INPUT_NOFILE_OK = 2, - }; - -+struct alias; -+ -+struct strpush { -+ struct strpush *prev; /* preceding string on stack */ -+ char *prevstring; -+ int prevnleft; -+ struct alias *ap; /* if push was associated with an alias */ -+ char *string; /* remember the string since it may change */ -+ -+ /* Remember last two characters for pungetc. */ -+ int lastc[2]; -+ -+ /* Number of outstanding calls to pungetc. */ -+ int unget; -+}; -+ -+/* -+ * The parsefile structure pointed to by the global variable parsefile -+ * contains information about the current file being read. -+ */ -+ -+struct parsefile { -+ struct parsefile *prev; /* preceding file on stack */ -+ int linno; /* current line */ -+ int fd; /* file descriptor (or -1 if string) */ -+ int nleft; /* number of chars left in this line */ -+ int lleft; /* number of chars left in this buffer */ -+ char *nextc; /* next char in buffer */ -+ char *buf; /* input buffer */ -+ struct strpush *strpush; /* for pushing strings at this level */ -+ struct strpush basestrpush; /* so pushing one is fast */ -+ -+ /* Remember last two characters for pungetc. */ -+ int lastc[2]; -+ -+ /* Number of outstanding calls to pungetc. */ -+ int unget; -+}; -+ -+extern struct parsefile *parsefile; -+ - /* - * The input line number. Input.c just defines this variable, and saves - * and restores it when files are pushed and popped. The user of this - * package must set its value. - */ --extern int plinno; --extern int parsenleft; /* number of characters left in input buffer */ --extern char *parsenextc; /* next character in input buffer */ -+#define plinno (parsefile->linno) - - int pgetc(void); - int pgetc2(void); --int preadbuffer(void); - void pungetc(void); - void pushstring(char *, void *); - void popstring(void); -@@ -61,6 +99,3 @@ - void popfile(void); - void popallfiles(void); - void closescript(void); -- --#define pgetc_macro() \ -- (--parsenleft >= 0 ? (signed char)*parsenextc++ : preadbuffer()) -diff -Naur dash-0.5.8/src/main.c dash-0.5.8-git_d7582e6/src/main.c ---- dash-0.5.8/src/main.c 2014-09-28 04:19:32.000000000 -0400 -+++ dash-0.5.8-git_d7582e6/src/main.c 2015-08-05 13:55:25.062024698 -0400 -@@ -60,10 +60,6 @@ - #include "exec.h" - #include "cd.h" - --#ifdef HETIO --#include "hetio.h" --#endif -- - #define PROFILE 0 - - int rootpid; -@@ -206,10 +202,6 @@ - int numeof = 0; - - TRACE(("cmdloop(%d) called\n", top)); --#ifdef HETIO -- if(iflag && top) -- hetio_init(); --#endif - for (;;) { - int skip; - -@@ -242,7 +234,7 @@ - - skip = evalskip; - if (skip) { -- evalskip &= ~SKIPFUNC; -+ evalskip &= ~(SKIPFUNC | SKIPFUNCDEF); - break; - } - } -@@ -321,15 +313,19 @@ - { - int status = 0; - -- if (argc >= 2) { /* That's what SVR2 does */ -+ nextopt(nullstr); -+ argv = argptr; -+ -+ if (*argv) { - char *fullname; - -- fullname = find_dot_file(argv[1]); -+ fullname = find_dot_file(*argv); - setinputfile(fullname, INPUT_PUSH_FILE); - commandname = fullname; - status = cmdloop(0); - popfile(); - } -+ - return status; - } - -@@ -339,8 +335,15 @@ - { - if (stoppedjobs()) - return 0; -- if (argc > 1) -- exitstatus = number(argv[1]); -+ -+ if (argc > 1) { -+ int status = number(argv[1]); -+ -+ exitstatus = status; -+ if (savestatus >= 0) -+ savestatus = status; -+ } -+ - exraise(EXEXIT); - /* NOTREACHED */ - } -diff -Naur dash-0.5.8/src/mkbuiltins dash-0.5.8-git_d7582e6/src/mkbuiltins ---- dash-0.5.8/src/mkbuiltins 2014-09-28 04:19:32.000000000 -0400 -+++ dash-0.5.8-git_d7582e6/src/mkbuiltins 2015-08-05 13:55:25.062024698 -0400 -@@ -69,7 +69,7 @@ - #include "builtins.h" - - ! --< $builtins sed '/^#/d; /^$/d' > $temp -+< $builtins sed '/^#/d; /^ *$/d' > $temp - awk '{ printf "int %s(int, char **);\n", $1}' $temp - echo ' - const struct builtincmd builtincmd[] = {' -@@ -78,7 +78,7 @@ - if ($i ~ /^-/) - line = $(++i) "\t" line - print line -- }}' $temp | LC_COLLATE=C sort -k 1,1 | tee $temp2 | awk '{ -+ }}' $temp | LC_ALL= LC_COLLATE=C sort -k 1,1 | tee $temp2 | awk '{ - opt = "" - if (NF > 2) { - opt = substr($2, 2) -@@ -97,8 +97,9 @@ - */ - - ! --sed 's/ -[a-z]*//' $temp2 | nl -b a -v 0 | LC_COLLATE=C sort -u -k 3,3 | --tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ | -+sed 's/ -[a-z]*//' $temp2 | nl -b a -v 0 | -+ LC_ALL= LC_COLLATE=C sort -u -k 3,3 | -+ tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ | - awk '{ printf "#define %s (builtincmd + %d)\n", $3, $1}' - printf '\n#define NUMBUILTINS %d\n' $(wc -l < $temp2) - echo ' -diff -Naur dash-0.5.8/src/output.c dash-0.5.8-git_d7582e6/src/output.c ---- dash-0.5.8/src/output.c 2014-09-28 04:19:32.000000000 -0400 -+++ dash-0.5.8-git_d7582e6/src/output.c 2015-08-05 13:55:25.062024698 -0400 -@@ -99,9 +99,6 @@ - struct output *out2 = &errout; - - --#ifndef USE_GLIBC_STDIO --static void __outstr(const char *, size_t, struct output *); --#endif - static int xvsnprintf(char *, size_t, const char *, va_list); - - -@@ -134,16 +131,20 @@ - #endif - - --#ifndef USE_GLIBC_STDIO --static void --__outstr(const char *p, size_t len, struct output *dest) -+void -+outmem(const char *p, size_t len, struct output *dest) - { -+#ifdef USE_GLIBC_STDIO -+ INTOFF; -+ fwrite(p, 1, len, dest->stream); -+ INTON; -+#else - size_t bufsize; - size_t offset; - size_t nleft; - - nleft = dest->end - dest->nextc; -- if (nleft >= len) { -+ if (likely(nleft >= len)) { - buffered: - dest->nextc = mempcpy(dest->nextc, p, len); - return; -@@ -153,10 +154,13 @@ - if (!bufsize) { - ; - } else if (dest->buf == NULL) { -+#ifdef notyet - if (dest->fd == MEM_OUT && len > bufsize) { - bufsize = len; - } -+#endif - offset = 0; -+#ifdef notyet - goto alloc; - } else if (dest->fd == MEM_OUT) { - offset = bufsize; -@@ -168,6 +172,7 @@ - if (bufsize < offset) - goto err; - alloc: -+#endif - INTOFF; - dest->buf = ckrealloc(dest->buf, bufsize); - dest->bufsize = bufsize; -@@ -183,11 +188,13 @@ - goto buffered; - - if ((xwrite(dest->fd, p, len))) { -+#ifdef notyet - err: -+#endif - dest->flags |= OUTPUT_ERR; - } --} - #endif -+} - - - void -@@ -201,7 +208,7 @@ - size_t len; - - len = strlen(p); -- __outstr(p, len, file); -+ outmem(p, len, file); - #endif - } - -@@ -213,7 +220,7 @@ - outcslow(int c, struct output *dest) - { - char buf = c; -- __outstr(&buf, 1, dest); -+ outmem(&buf, 1, dest); - } - #endif - -@@ -283,35 +290,58 @@ - } - - -+static int xvasprintf(char **sp, size_t size, const char *f, va_list ap) -+{ -+ char *s; -+ int len; -+ va_list ap2; -+ -+ va_copy(ap2, ap); -+ len = xvsnprintf(*sp, size, f, ap2); -+ va_end(ap2); -+ if (len < 0) -+ sh_error("xvsnprintf failed"); -+ if (len < size) -+ return len; -+ -+ s = stalloc((len >= stackblocksize() ? len : stackblocksize()) + 1); -+ *sp = s; -+ len = xvsnprintf(s, len + 1, f, ap); -+ return len; -+} -+ -+ -+int xasprintf(char **sp, const char *f, ...) -+{ -+ va_list ap; -+ int ret; -+ -+ va_start(ap, f); -+ ret = xvasprintf(sp, 0, f, ap); -+ va_end(ap); -+ return ret; -+} -+ -+ - #ifndef USE_GLIBC_STDIO - void - doformat(struct output *dest, const char *f, va_list ap) - { - struct stackmark smark; - char *s; -- int len, ret; -- size_t size; -- va_list ap2; -+ int len; -+ int olen; - -- va_copy(ap2, ap); -- size = dest->end - dest->nextc; -- len = xvsnprintf(dest->nextc, size, f, ap2); -- va_end(ap2); -- if (len < 0) { -- dest->flags |= OUTPUT_ERR; -- return; -- } -- if (len < size) { -+ setstackmark(&smark); -+ s = dest->nextc; -+ olen = dest->end - dest->nextc; -+ len = xvasprintf(&s, olen, f, ap); -+ if (likely(olen > len)) { - dest->nextc += len; -- return; -+ goto out; - } -- setstackmark(&smark); -- s = stalloc((len >= stackblocksize() ? len : stackblocksize()) + 1); -- ret = xvsnprintf(s, len + 1, f, ap); -- if (ret == len) -- __outstr(s, len, dest); -- else -- dest->flags |= OUTPUT_ERR; -+ outmem(s, len, dest); -+out: - popstackmark(&smark); - } - #endif -diff -Naur dash-0.5.8/src/output.h dash-0.5.8-git_d7582e6/src/output.h ---- dash-0.5.8/src/output.h 2014-09-28 04:19:32.000000000 -0400 -+++ dash-0.5.8-git_d7582e6/src/output.h 2015-08-05 13:55:25.062024698 -0400 -@@ -63,6 +63,7 @@ - extern struct output *out1; - extern struct output *out2; - -+void outmem(const char *, size_t, struct output *); - void outstr(const char *, struct output *); - #ifndef USE_GLIBC_STDIO - void outcslow(int, struct output *); -@@ -75,6 +76,7 @@ - __attribute__((__format__(__printf__,1,2))); - int fmtstr(char *, size_t, const char *, ...) - __attribute__((__format__(__printf__,3,4))); -+int xasprintf(char **, const char *, ...); - #ifndef USE_GLIBC_STDIO - void doformat(struct output *, const char *, va_list); - #endif -@@ -115,6 +117,7 @@ - #endif - #define out1c(c) outc((c), out1) - #define out2c(c) outcslow((c), out2) -+#define out1mem(s, l) outmem((s), (l), out1) - #define out1str(s) outstr((s), out1) - #define out2str(s) outstr((s), out2) - #define outerr(f) (f)->flags -diff -Naur dash-0.5.8/src/parser.c dash-0.5.8-git_d7582e6/src/parser.c ---- dash-0.5.8/src/parser.c 2014-09-28 04:19:32.000000000 -0400 -+++ dash-0.5.8-git_d7582e6/src/parser.c 2015-08-05 13:55:25.062024698 -0400 -@@ -135,19 +135,13 @@ - union node * - parsecmd(int interact) - { -- int t; -- - tokpushback = 0; -+ checkkwd = 0; -+ heredoclist = 0; - doprompt = interact; - if (doprompt) - setprompt(doprompt); - needprompt = 0; -- t = readtoken(); -- if (t == TEOF) -- return NEOF; -- if (t == TNL) -- return NULL; -- tokpushback++; - return list(1); - } - -@@ -158,11 +152,27 @@ - union node *n1, *n2, *n3; - int tok; - -- checkkwd = CHKNL | CHKKWD | CHKALIAS; -- if (nlflag == 2 && tokendlist[peektoken()]) -- return NULL; - n1 = NULL; - for (;;) { -+ switch (peektoken()) { -+ case TNL: -+ if (!(nlflag & 1)) -+ break; -+ parseheredoc(); -+ return n1; -+ -+ case TEOF: -+ if (!n1 && (nlflag & 1)) -+ n1 = NEOF; -+ parseheredoc(); -+ return n1; -+ } -+ -+ checkkwd = CHKNL | CHKKWD | CHKALIAS; -+ if (nlflag == 2 && tokendlist[peektoken()]) -+ return n1; -+ nlflag |= 2; -+ - n2 = andor(); - tok = readtoken(); - if (tok == TBACKGND) { -@@ -189,31 +199,15 @@ - n1 = n3; - } - switch (tok) { -- case TBACKGND: -- case TSEMI: -- tok = readtoken(); -- /* fall through */ - case TNL: -- if (tok == TNL) { -- parseheredoc(); -- if (nlflag == 1) -- return n1; -- } else { -- tokpushback++; -- } -- checkkwd = CHKNL | CHKKWD | CHKALIAS; -- if (tokendlist[peektoken()]) -- return n1; -- break; - case TEOF: -- if (heredoclist) -- parseheredoc(); -- else -- pungetc(); /* push back EOF on input */ - tokpushback++; -- return n1; -+ /* fall through */ -+ case TBACKGND: -+ case TSEMI: -+ break; - default: -- if (nlflag == 1) -+ if ((nlflag & 1)) - synexpect(-1); - tokpushback++; - return n1; -@@ -743,6 +737,19 @@ - return (t); - } - -+static void nlprompt(void) -+{ -+ plinno++; -+ if (doprompt) -+ setprompt(2); -+} -+ -+static void nlnoprompt(void) -+{ -+ plinno++; -+ needprompt = doprompt; -+} -+ - - /* - * Read the next input token. -@@ -775,7 +782,7 @@ - setprompt(2); - } - for (;;) { /* until token or start of word found */ -- c = pgetc_macro(); -+ c = pgetc(); - switch (c) { - case ' ': case '\t': - case PEOA: -@@ -786,16 +793,13 @@ - continue; - case '\\': - if (pgetc() == '\n') { -- plinno++; -- if (doprompt) -- setprompt(2); -+ nlprompt(); - continue; - } - pungetc(); - goto breakloop; - case '\n': -- plinno++; -- needprompt = doprompt; -+ nlnoprompt(); - RETURN(TNL); - case PEOF: - RETURN(TEOF); -@@ -827,6 +831,22 @@ - #undef RETURN - } - -+static int pgetc_eatbnl(void) -+{ -+ int c; -+ -+ while ((c = pgetc()) == '\\') { -+ if (pgetc() != '\n') { -+ pungetc(); -+ break; -+ } -+ -+ nlprompt(); -+ } -+ -+ return c; -+} -+ - - - /* -@@ -895,9 +915,7 @@ - if (syntax == BASESYNTAX) - goto endword; /* exit outer loop */ - USTPUTC(c, out); -- plinno++; -- if (doprompt) -- setprompt(2); -+ nlprompt(); - c = pgetc(); - goto loop; /* continue outer loop */ - case CWORD: -@@ -916,9 +934,7 @@ - USTPUTC('\\', out); - pungetc(); - } else if (c == '\n') { -- plinno++; -- if (doprompt) -- setprompt(2); -+ nlprompt(); - } else { - if ( - dblquote && -@@ -1009,7 +1025,7 @@ - USTPUTC(c, out); - } - } -- c = pgetc_macro(); -+ c = pgetc(); - } - } - endword: -@@ -1074,8 +1090,7 @@ - - if (c == '\n' || c == PEOF) { - c = PEOF; -- plinno++; -- needprompt = doprompt; -+ nlnoprompt(); - } else { - int len; - -@@ -1179,7 +1194,7 @@ - char *p; - static const char types[] = "}-+?="; - -- c = pgetc(); -+ c = pgetc_eatbnl(); - if ( - (checkkwd & CHKEOFMARK) || - c <= PEOA || -@@ -1188,7 +1203,7 @@ - USTPUTC('$', out); - pungetc(); - } else if (c == '(') { /* $(command) or $((arith)) */ -- if (pgetc() == '(') { -+ if (pgetc_eatbnl() == '(') { - PARSEARITH(); - } else { - pungetc(); -@@ -1200,25 +1215,24 @@ - STADJUST(1, out); - subtype = VSNORMAL; - if (likely(c == '{')) { -- c = pgetc(); -+ c = pgetc_eatbnl(); - subtype = 0; - } - varname: - if (is_name(c)) { - do { - STPUTC(c, out); -- c = pgetc(); -+ c = pgetc_eatbnl(); - } while (is_in_name(c)); - } else if (is_digit(c)) { - do { - STPUTC(c, out); -- c = pgetc(); -+ c = pgetc_eatbnl(); - } while (is_digit(c)); -- } -- else if (is_special(c)) { -+ } else { - int cc = c; - -- c = pgetc(); -+ c = pgetc_eatbnl(); - - if (!subtype && cc == '#') { - subtype = VSLENGTH; -@@ -1227,7 +1241,7 @@ - goto varname; - - cc = c; -- c = pgetc(); -+ c = pgetc_eatbnl(); - if (cc == '}' || c != '}') { - pungetc(); - subtype = 0; -@@ -1236,16 +1250,20 @@ - } - } - -+ if (!is_special(cc)) { -+ if (subtype == VSLENGTH) -+ subtype = 0; -+ goto badsub; -+ } -+ - USTPUTC(cc, out); - } -- else -- goto badsub; - - if (subtype == 0) { - switch (c) { - case ':': - subtype = VSNUL; -- c = pgetc(); -+ c = pgetc_eatbnl(); - /*FALLTHROUGH*/ - default: - p = strchr(types, c); -@@ -1259,7 +1277,7 @@ - int cc = c; - subtype = c == '#' ? VSTRIMLEFT : - VSTRIMRIGHT; -- c = pgetc(); -+ c = pgetc_eatbnl(); - if (c == cc) - subtype++; - else -@@ -1324,9 +1342,7 @@ - - case '\\': - if ((pc = pgetc()) == '\n') { -- plinno++; -- if (doprompt) -- setprompt(2); -+ nlprompt(); - /* - * If eating a newline, avoid putting - * the newline into the new character -@@ -1348,8 +1364,7 @@ - synerror("EOF in backquote substitution"); - - case '\n': -- plinno++; -- needprompt = doprompt; -+ nlnoprompt(); - break; - - default: -@@ -1427,10 +1442,6 @@ - - #ifdef mkinit - INCLUDE "parser.h" --RESET { -- tokpushback = 0; -- checkkwd = 0; --} - #endif - - -diff -Naur dash-0.5.8/src/trap.c dash-0.5.8-git_d7582e6/src/trap.c ---- dash-0.5.8/src/trap.c 2014-09-28 04:19:32.000000000 -0400 -+++ dash-0.5.8-git_d7582e6/src/trap.c 2015-08-05 13:55:25.062024698 -0400 -@@ -51,10 +51,6 @@ - #include "trap.h" - #include "mystring.h" - --#ifdef HETIO --#include "hetio.h" --#endif -- - /* - * Sigmode records the current value of the signal handlers for the various - * modes. A value of zero means that the current handler is not known. -@@ -314,25 +310,40 @@ - char *p; - char *q; - int i; -- int savestatus; -+ int status, last_status; - -- savestatus = exitstatus; -+ if (!pendingsigs) -+ return; -+ -+ status = savestatus; -+ last_status = status; -+ if (likely(status < 0)) { -+ status = exitstatus; -+ savestatus = status; -+ } - pendingsigs = 0; - barrier(); - - for (i = 0, q = gotsig; i < NSIG - 1; i++, q++) { - if (!*q) - continue; -+ -+ if (evalskip) { -+ pendingsigs = i + 1; -+ break; -+ } -+ - *q = 0; - - p = trap[i + 1]; - if (!p) - continue; - evalstring(p, 0); -- exitstatus = savestatus; -- if (evalskip) -- break; -+ if (evalskip != SKIPFUNC) -+ exitstatus = status; - } -+ -+ savestatus = last_status; - } - - -@@ -366,18 +377,11 @@ - { - struct jmploc loc; - char *p; -- volatile int status; - --#ifdef HETIO -- hetio_reset_term(); --#endif -- status = exitstatus; -- TRACE(("pid %d, exitshell(%d)\n", getpid(), status)); -- if (setjmp(loc.loc)) { -- if (exception == EXEXIT) -- status = exitstatus; -+ savestatus = exitstatus; -+ TRACE(("pid %d, exitshell(%d)\n", getpid(), savestatus)); -+ if (setjmp(loc.loc)) - goto out; -- } - handler = &loc; - if ((p = trap[0])) { - trap[0] = NULL; -@@ -392,7 +396,7 @@ - if (likely(!setjmp(loc.loc))) - setjobctl(0); - flushall(); -- _exit(status); -+ _exit(savestatus); - /* NOTREACHED */ - } - -diff -Naur dash-0.5.8/src/var.c dash-0.5.8-git_d7582e6/src/var.c ---- dash-0.5.8/src/var.c 2014-09-28 04:19:32.000000000 -0400 -+++ dash-0.5.8-git_d7582e6/src/var.c 2015-08-05 13:55:25.065358031 -0400 -@@ -80,6 +80,7 @@ - #else - const char defifs[] = " \t\n"; - #endif -+MKINIT char defoptindvar[] = "OPTIND=1"; - - int lineno; - char linenovar[sizeof("LINENO=")+sizeof(int)*CHAR_BIT/3+1] = "LINENO="; -@@ -100,7 +101,7 @@ - { 0, VSTRFIXED|VTEXTFIXED, "PS1=$ ", 0 }, - { 0, VSTRFIXED|VTEXTFIXED, "PS2=> ", 0 }, - { 0, VSTRFIXED|VTEXTFIXED, "PS4=+ ", 0 }, -- { 0, VSTRFIXED|VTEXTFIXED, "OPTIND=1", getoptsreset }, -+ { 0, VSTRFIXED|VTEXTFIXED, defoptindvar, getoptsreset }, - #ifdef WITH_LINENO - { 0, VSTRFIXED|VTEXTFIXED, linenovar, 0 }, - #endif -@@ -142,7 +143,7 @@ - } - } - -- setvarint("OPTIND", 1, 0); -+ setvareq(defoptindvar, VTEXTFIXED); - - fmtstr(ppid + 5, sizeof(ppid) - 5, "%ld", (long) getppid()); - setvareq(ppid, VTEXTFIXED); |