mirror of
https://github.com/Ponce/slackbuilds
synced 2024-11-18 22:06:04 +01:00
4f2c7ddfca
Signed-off-by: Willy Sudiarto Raharjo <willysr@slackbuilds.org>
2371 lines
54 KiB
Diff
2371 lines
54 KiB
Diff
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);
|