Группа :: Интерпретаторы команд
Пакет: mksh
Главная Изменения Спек Патчи Sources Загрузить Gear Bugs and FR Repocop
Патч: cvs.patch
Скачать
Скачать
Index: check.t
===================================================================
RCS file: /cvs/src/bin/mksh/check.t,v
retrieving revision 1.661
retrieving revision 1.667
diff -u -p -r1.661 -r1.667
--- check.t 7 Oct 2014 15:22:14 -0000 1.661
+++ check.t 19 Oct 2014 22:26:13 -0000 1.667
@@ -1,4 +1,4 @@
-# $MirOS: src/bin/mksh/check.t,v 1.661 2014/10/07 15:22:14 tg Exp $
+# $MirOS: src/bin/mksh/check.t,v 1.667 2014/10/19 22:26:13 tg Exp $
# OpenBSD src/regress/bin/ksh updated: 2013/12/02 20:39:44
#-
# Copyright б╘ 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
@@ -24,10 +24,10 @@
# http://www.research.att.com/~gsf/public/ifs.sh
#
# More testsuites at:
-# http://www.freebsd.org/cgi/cvsweb.cgi/src/tools/regression/bin/test/regress.sh?rev=HEAD
+# http://svnweb.freebsd.org/base/head/bin/test/tests/legacy_test.sh?view=co&content-type=text%2Fplain
expected-stdout:
- @(#)MIRBSD KSH R50 2014/10/07
+ @(#)MIRBSD KSH R50 2014/10/19
description:
Check version of shell.
stdin:
@@ -36,7 +36,7 @@ name: KSH_VERSION
category: shell:legacy-no
---
expected-stdout:
- @(#)LEGACY KSH R50 2014/10/07
+ @(#)LEGACY KSH R50 2014/10/19
description:
Check version of legacy shell.
stdin:
@@ -2389,6 +2389,14 @@ stdin:
vf=<<<$'=f $x \x40='
# now check
print -r -- "| va={$va} vb={$vb} vc={$vc} vd={$vd} ve={$ve} vf={$vf} |"
+ # check append
+ v=<<-EOF
+ vapp1
+ EOF
+ v+=<<-EOF
+ vapp2
+ EOF
+ print -r -- "| ${v//$'\n'/^} |"
expected-stdout:
function foo {
vc=<<-EOF
@@ -2404,6 +2412,7 @@ expected-stdout:
} ve={=e $x \x40=
} vf={=f $x @=
} |
+ | vapp1^vapp2^ |
---
name: heredoc-11
description:
@@ -2433,6 +2442,14 @@ stdin:
eval "$fnd"
foo
print -r -- "| va={$va} vb={$vb} vc={$vc} vd={$vd} |"
+ # check append
+ v=<<-
+ vapp1
+ <<
+ v+=<<-''
+ vapp2
+
+ print -r -- "| ${v//$'\n'/^} |"
expected-stdout:
function foo {
vc=<<-
@@ -2450,6 +2467,7 @@ expected-stdout:
} vc={=c u \x40=
} vd={=d $x \x40=
} |
+ | vapp1^vapp2^ |
---
name: heredoc-comsub-1
description:
@@ -3733,7 +3751,7 @@ stdin:
expected-stdout:
<1> <shift> <1> <2>
---
-name: IFS-subst-3
+name: IFS-subst-3-arr
description:
Check leading IFS non-whitespace after trim does make a field
but leading IFS whitespace does not, nor empty replacements
@@ -3749,6 +3767,32 @@ expected-stdout:
<1> <> <foo> <bar>
<2> <foo> <bar>
---
+name: IFS-subst-3-ass
+description:
+ Check non-field semantics
+stdin:
+ showargs() { for i; do echo -n " <$i>"; done; echo; }
+ showargs 0 x=${-+}
+ IFS=:
+ showargs 1 x=${-+:foo:bar}
+ IFS=' '
+ showargs 2 x=${-+ foo bar}
+expected-stdout:
+ <0> <x=>
+ <1> <x=> <foo> <bar>
+ <2> <x=> <foo> <bar>
+---
+name: IFS-subst-3-lcl
+description:
+ Check non-field semantics, smaller corner case (LP#1381965)
+stdin:
+ set -x
+ local regex=${2:-}
+ exit 1
+expected-exit: e != 0
+expected-stderr-pattern:
+ /regex=/
+---
name: IFS-subst-4-1
description:
reported by mikeserv
@@ -4133,6 +4177,30 @@ expected-stdout:
<A B C>
=b8iqa
---
+name: IFS-subst-6
+description:
+ Regression wrt. vector expansion in trim
+stdin:
+ showargs() { for x in "$@"; do echo -n "<$x> "; done; echo .; }
+ IFS=
+ x=abc
+ set -- a b
+ showargs ${x#$*}
+expected-stdout:
+ <c> .
+---
+name: IFS-subst-7
+description:
+ ksh93 bug wrt. vector expansion in trim
+stdin:
+ showargs() { for x in "$@"; do echo -n "<$x> "; done; echo .; }
+ IFS="*"
+ a=abcd
+ set -- '' c
+ showargs "$*" ${a##"$*"}
+expected-stdout:
+ <*c> <abcd> .
+---
name: IFS-arith-1
description:
http://austingroupbugs.net/view.php?id=832
@@ -8013,6 +8081,66 @@ expected-stdout:
.fnr:f:
.f2r:f:
---
+name: unset-fnc-local-ksh
+description:
+ Check that Б─°unsetБ─² removes a previous Б─°localБ─²
+ (ksh93 syntax compatible version); apparently,
+ there are shells which fail this?
+stdin:
+ function f {
+ echo f0: $x
+ typeset x
+ echo f1: $x
+ x=fa
+ echo f2: $x
+ unset x
+ echo f3: $x
+ x=fb
+ echo f4: $x
+ }
+ x=o
+ echo before: $x
+ f
+ echo after: $x
+expected-stdout:
+ before: o
+ f0: o
+ f1:
+ f2: fa
+ f3: o
+ f4: fb
+ after: fb
+---
+name: unset-fnc-local-sh
+description:
+ Check that Б─°unsetБ─² removes a previous Б─°localБ─²
+ (Debian Policy б╖10.4 sh version); apparently,
+ there are shells which fail this?
+stdin:
+ f() {
+ echo f0: $x
+ local x
+ echo f1: $x
+ x=fa
+ echo f2: $x
+ unset x
+ echo f3: $x
+ x=fb
+ echo f4: $x
+ }
+ x=o
+ echo before: $x
+ f
+ echo after: $x
+expected-stdout:
+ before: o
+ f0: o
+ f1:
+ f2: fa
+ f3: o
+ f4: fb
+ after: fb
+---
name: varexpand-substr-1
description:
Check if bash-style substring expansion works
Index: eval.c
===================================================================
RCS file: /cvs/src/bin/mksh/eval.c,v
retrieving revision 1.153
retrieving revision 1.158
diff -u -p -r1.153 -r1.158
--- eval.c 7 Oct 2014 15:22:16 -0000 1.153
+++ eval.c 19 Oct 2014 21:53:07 -0000 1.158
@@ -23,7 +23,7 @@
#include "sh.h"
-__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.153 2014/10/07 15:22:16 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.158 2014/10/19 21:53:07 tg Exp $");
/*
* string expansion
@@ -246,7 +246,7 @@ expand(
/* for alias, readonly, set, typeset commands */
if ((f & DOVACHECK) && is_wdvarassign(ccp)) {
f &= ~(DOVACHECK | DOBLANK | DOGLOB | DOTILDE);
- f |= DOASNTILDE | DOASNFIELD;
+ f |= DOASNTILDE | DOSCALAR;
}
if (Flag(FNOGLOB))
f &= ~DOGLOB;
@@ -622,7 +622,7 @@ expand(
case '%':
/* ! DOBLANK,DOBRACE,DOTILDE */
f = (f & DONTRUNCOMMAND) |
- DOPAT | DOTEMP;
+ DOPAT | DOTEMP | DOSCALAR;
st->quotew = quote = 0;
/*
* Prepend open pattern (so |
@@ -631,7 +631,7 @@ expand(
*/
if (!Flag(FSH)) {
*dp++ = MAGIC;
- *dp++ = '@' | 0x80;
+ *dp++ = 0x80 | '@';
}
break;
case '=':
@@ -664,7 +664,11 @@ expand(
f |= DOTEMP;
/* FALLTHROUGH */
default:
- word = quote ? IFS_WORD : IFS_IWS;
+ /* '-' '+' '?' */
+ if (quote)
+ word = IFS_WORD;
+ else if (dp == Xstring(ds, dp))
+ word = IFS_IWS;
/* Enable tilde expansion */
tilde_ok = 1;
f |= DOTILDE;
@@ -704,7 +708,7 @@ expand(
x.str = trimsub(str_val(st->var),
dp, st->stype);
if (x.str[0] != '\0') {
- word = IFS_WS;
+ word = IFS_IWS;
type = XSUB;
} else
type = quote ? XSUB : XNULLSUB;
@@ -743,7 +747,7 @@ expand(
if (f & DOBLANK)
doblank++;
st = st->prev;
- word = quote || (!*x.str && (f & DOASNFIELD)) ? IFS_WORD : IFS_WS;
+ word = quote || (!*x.str && (f & DOSCALAR)) ? IFS_WORD : IFS_IWS;
continue;
case '?': {
char *s = Xrestpos(ds, dp, st->base);
@@ -759,11 +763,12 @@ expand(
case 0x100 | 'Q':
dp = Xrestpos(ds, dp, st->base);
type = XSUB;
- word = quote || (!*x.str && (f & DOASNFIELD)) ? IFS_WORD : IFS_WS;
+ word = quote || (!*x.str && (f & DOSCALAR)) ? IFS_WORD : IFS_IWS;
if (f & DOBLANK)
doblank++;
st = st->prev;
continue;
+ /* default: '-' '+' */
}
st = st->prev;
type = XBASE;
@@ -800,7 +805,7 @@ expand(
if (f & DOBLANK) {
doblank--;
if (dp == Xstring(ds, dp))
- word = IFS_WS;
+ word = IFS_IWS;
}
continue;
@@ -834,8 +839,8 @@ expand(
continue;
}
c = ifs0;
- if ((f & DOASNFIELD)) {
- /* assignment, do not field-split */
+ if ((f & DOSCALAR)) {
+ /* do not field-split */
if (x.split) {
c = ' ';
break;
Index: exec.c
===================================================================
RCS file: /cvs/src/bin/mksh/exec.c,v
retrieving revision 1.133
retrieving revision 1.137
diff -u -p -r1.133 -r1.137
--- exec.c 3 Oct 2014 17:32:11 -0000 1.133
+++ exec.c 19 Oct 2014 21:53:07 -0000 1.137
@@ -23,7 +23,7 @@
#include "sh.h"
-__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.133 2014/10/03 17:32:11 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.137 2014/10/19 21:53:07 tg Exp $");
#ifndef MKSH_DEFAULT_EXECSHELL
#define MKSH_DEFAULT_EXECSHELL "/bin/sh"
@@ -32,7 +32,7 @@ __RCSID("$MirOS: src/bin/mksh/exec.c,v 1
static int comexec(struct op *, struct tbl * volatile, const char **,
int volatile, volatile int *);
static void scriptexec(struct op *, const char **) MKSH_A_NORETURN;
-static int call_builtin(struct tbl *, const char **, const char *);
+static int call_builtin(struct tbl *, const char **, const char *, bool);
static int iosetup(struct ioword *, struct tbl *);
static int herein(struct ioword *, char **);
static const char *do_selectargs(const char **, bool);
@@ -81,6 +81,8 @@ execute(struct op * volatile t,
/* we want to run an executable, do some variance checks */
if (t->type == TCOM) {
/* check if this is 'var=<<EOF' */
+ /*XXX this is broken, donБ─≥t use! */
+ /*XXX https://bugs.launchpad.net/mksh/+bug/1380389 */
if (
/* we have zero arguments, i.e. no programme to run */
t->args[0] == NULL &&
@@ -94,20 +96,23 @@ execute(struct op * volatile t,
/* the variable assignment begins with a valid varname */
(ccp = skip_wdvarname(t->vars[0], true)) != t->vars[0] &&
/* and has no right-hand side (i.e. "varname=") */
- ccp[0] == CHAR && ccp[1] == '=' && ccp[2] == EOS &&
+ ccp[0] == CHAR && ((ccp[1] == '=' && ccp[2] == EOS) ||
+ /* or "varname+=" */ (ccp[1] == '+' && ccp[2] == CHAR &&
+ ccp[3] == '=' && ccp[4] == EOS)) &&
/* plus we can have a here document content */
herein(t->ioact[0], &cp) == 0 && cp && *cp) {
char *sp = cp, *dp;
- size_t n = ccp - t->vars[0] + 2, z;
+ size_t n = ccp - t->vars[0] + (ccp[1] == '+' ? 4 : 2);
+ size_t z;
/* drop redirection (will be garbage collected) */
t->ioact = NULL;
/* set variable to its expanded value */
- z = strlen(cp) + 1;
- if (notoktomul(z, 2) || notoktoadd(z * 2, n))
+ z = strlen(cp);
+ if (notoktomul(z, 2) || notoktoadd(z * 2, n + 1))
internal_errorf(Toomem, (size_t)-1);
- dp = alloc(z * 2 + n, ATEMP);
+ dp = alloc(z * 2 + n + 1, APERM);
memcpy(dp, t->vars[0], n);
t->vars[0] = dp;
dp += n;
@@ -500,7 +505,7 @@ comexec(struct op *t, struct tbl * volat
/* Must be static (XXX but why?) */
static struct op texec;
int type_flags;
- bool keepasn_ok;
+ bool resetspec;
int fcflags = FC_BI|FC_FUNC|FC_PATH;
bool bourne_function_call = false;
struct block *l_expand, *l_assign;
@@ -532,7 +537,7 @@ comexec(struct op *t, struct tbl * volat
* FOO=bar command FOO is neither kept nor exported
* PATH=... foobar use new PATH in foobar search
*/
- keepasn_ok = true;
+ resetspec = false;
while (tp && tp->type == CSHELL) {
/* undo effects of command */
fcflags = FC_BI|FC_FUNC|FC_PATH;
@@ -579,7 +584,7 @@ comexec(struct op *t, struct tbl * volat
* POSIX says special builtins lose their status
* if accessed using command.
*/
- keepasn_ok = false;
+ resetspec = true;
if (!ap[0]) {
/* ensure command with no args exits with 0 */
subst_exstat = 0;
@@ -614,13 +619,13 @@ comexec(struct op *t, struct tbl * volat
if (t->u.evalflags & DOTCOMEXEC)
flags |= XEXEC;
l_expand = e->loc;
- if (keepasn_ok && (!ap[0] || (tp && (tp->flag & KEEPASN))))
+ if (!resetspec && (!ap[0] || (tp && (tp->flag & KEEPASN))))
type_flags = 0;
else {
/* create new variable/function block */
newblock();
/* ksh functions don't keep assignments, POSIX functions do. */
- if (keepasn_ok && tp && tp->type == CFUNC &&
+ if (!resetspec && tp && tp->type == CFUNC &&
!(tp->flag & FKSH)) {
bourne_function_call = true;
type_flags = EXPORT;
@@ -635,7 +640,7 @@ comexec(struct op *t, struct tbl * volat
for (i = 0; t->vars[i]; i++) {
/* do NOT lookup in the new var/fn block just created */
e->loc = l_expand;
- cp = evalstr(t->vars[i], DOASNTILDE | DOASNFIELD);
+ cp = evalstr(t->vars[i], DOASNTILDE | DOSCALAR);
e->loc = l_assign;
if (Flag(FXTRACE)) {
const char *ccp;
@@ -684,8 +689,8 @@ comexec(struct op *t, struct tbl * volat
/* shell built-in */
case CSHELL:
- rv = call_builtin(tp, (const char **)ap, null);
- if (!keepasn_ok && tp->val.f == c_shift) {
+ rv = call_builtin(tp, (const char **)ap, null, resetspec);
+ if (resetspec && tp->val.f == c_shift) {
l_expand->argc = l_assign->argc;
l_expand->argv = l_assign->argv;
}
@@ -952,7 +957,7 @@ shcomexec(const char **wp)
struct tbl *tp;
tp = ktsearch(&builtins, *wp, hash(*wp));
- return (call_builtin(tp, wp, "shcomexec"));
+ return (call_builtin(tp, wp, "shcomexec", false));
}
/*
@@ -1265,22 +1270,22 @@ search_path(const char *name, const char
}
static int
-call_builtin(struct tbl *tp, const char **wp, const char *where)
+call_builtin(struct tbl *tp, const char **wp, const char *where, bool resetspec)
{
int rv;
if (!tp)
internal_errorf("%s: %s", where, wp[0]);
builtin_argv0 = wp[0];
- builtin_flag = tp->flag;
+ builtin_spec = tobool(!resetspec && (tp->flag & SPEC_BI));
shf_reopen(1, SHF_WR, shl_stdout);
shl_stdout_ok = true;
ksh_getopt_reset(&builtin_opt, GF_ERROR);
rv = (*tp->val.f)(wp);
shf_flush(shl_stdout);
shl_stdout_ok = false;
- builtin_flag = 0;
builtin_argv0 = NULL;
+ builtin_spec = false;
return (rv);
}
@@ -1559,7 +1564,8 @@ do_selectargs(const char **ap, bool prin
if (print_menu || !*str_val(global("REPLY")))
pr_menu(ap);
shellf("%s", str_val(global("PS3")));
- if (call_builtin(findcom("read", FC_BI), read_args, Tselect))
+ if (call_builtin(findcom("read", FC_BI), read_args, Tselect,
+ false))
return (NULL);
s = str_val(global("REPLY"));
if (*s && getn(s, &i))
Index: funcs.c
===================================================================
RCS file: /cvs/src/bin/mksh/funcs.c,v
retrieving revision 1.258
retrieving revision 1.259
diff -u -p -r1.258 -r1.259
--- funcs.c 3 Sep 2014 19:55:51 -0000 1.258
+++ funcs.c 12 Oct 2014 21:58:51 -0000 1.259
@@ -38,7 +38,7 @@
#endif
#endif
-__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.258 2014/09/03 19:55:51 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.259 2014/10/12 21:58:51 tg Exp $");
#if HAVE_KILLPG
/*
@@ -1587,12 +1587,16 @@ c_shift(const char **wp)
return (1);
arg = wp[builtin_opt.optind];
- if (arg) {
- evaluate(arg, &val, KSH_UNWIND_ERROR, false);
- n = val;
- } else
+ if (!arg)
n = 1;
- if (n < 0) {
+ else if (!evaluate(arg, &val, KSH_RETURN_ERROR, false)) {
+ /* error already printed */
+ bi_errorfz();
+ return (1);
+ } else if (!(n = val)) {
+ /* nothing to do */
+ return (0);
+ } else if (n < 0) {
bi_errorf("%s: %s", arg, "bad number");
return (1);
}
@@ -2417,9 +2421,8 @@ c_set(const char **wp)
return (c_typeset(args));
}
- argi = parse_args(wp, OF_SET, &setargs);
- if (argi < 0)
- return (1);
+ if ((argi = parse_args(wp, OF_SET, &setargs)) < 0)
+ return (2);
/* set $# and $* */
if (setargs) {
wp += argi - 1;
Index: main.c
===================================================================
RCS file: /cvs/src/bin/mksh/main.c,v
retrieving revision 1.284
retrieving revision 1.285
diff -u -p -r1.284 -r1.285
--- main.c 3 Oct 2014 17:19:27 -0000 1.284
+++ main.c 12 Oct 2014 21:58:52 -0000 1.285
@@ -34,7 +34,7 @@
#include <locale.h>
#endif
-__RCSID("$MirOS: src/bin/mksh/main.c,v 1.284 2014/10/03 17:19:27 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/main.c,v 1.285 2014/10/12 21:58:52 tg Exp $");
extern char **environ;
@@ -1244,7 +1244,7 @@ bi_errorf(const char *fmt, ...)
* non-interactive shells to exit.
* XXX odd use of KEEPASN; also may not want LERROR here
*/
- if (builtin_flag & SPEC_BI) {
+ if (builtin_spec) {
builtin_argv0 = NULL;
unwind(LERROR);
}
Index: sh.h
===================================================================
RCS file: /cvs/src/bin/mksh/sh.h,v
retrieving revision 1.697
retrieving revision 1.701
diff -u -p -r1.697 -r1.701
--- sh.h 7 Oct 2014 15:22:17 -0000 1.697
+++ sh.h 19 Oct 2014 21:53:08 -0000 1.701
@@ -169,9 +169,9 @@
#endif
#ifdef EXTERN
-__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.697 2014/10/07 15:22:17 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.701 2014/10/19 21:53:08 tg Exp $");
#endif
-#define MKSH_VERSION "R50 2014/10/07"
+#define MKSH_VERSION "R50 2014/10/19"
/* arithmetic types: C implementation */
#if !HAVE_CAN_INTTYPES
@@ -992,8 +992,8 @@ EXTERN sigset_t sm_default, sm_sigchld;
/* name of called builtin function (used by error functions) */
EXTERN const char *builtin_argv0;
-/* flags of called builtin (SPEC_BI, etc.) */
-EXTERN uint32_t builtin_flag;
+/* is called builtin SPEC_BI? */
+EXTERN bool builtin_spec;
/* current working directory */
EXTERN char *current_wd;
@@ -1396,7 +1396,7 @@ struct ioword {
#define DOVACHECK BIT(9) /* var assign check (for typeset, set, etc) */
#define DOMARKDIRS BIT(10) /* force markdirs behaviour */
#define DOTCOMEXEC BIT(11) /* not an eval flag, used by sh -c hack */
-#define DOASNFIELD BIT(12) /* is assignment, change field handling */
+#define DOSCALAR BIT(12) /* change field handling to non-list context */
#define X_EXTRA 20 /* this many extra bytes in X string */