svn commit: r262951 - in stable/10: bin bin/date bin/date/tests bin/mv bin/mv/tests bin/pax bin/pax/tests bin/sh bin/sh/tests bin/sh/tests/builtins bin/sh/tests/parameters bin/sh/tests/parser bin/t...
Julio Merino
jmmv at FreeBSD.org
Sun Mar 9 17:04:37 UTC 2014
Author: jmmv
Date: Sun Mar 9 17:04:31 2014
New Revision: 262951
URL: http://svnweb.freebsd.org/changeset/base/262951
Log:
Sync sh(1) in stable/10 to head.
This is a MFC of all the commits listed below.
My original goal of this change was to only merge the move of the tests
from tools/regression/bin/ into the new layout (which include tests for
sh(1) and other tools as well). However, doing so is tricky due to the
ongoing work in sh(1) and, especially, the many changes to its tests
since stable/10 was first branched.
Merging everything is the simplest way to achieve this goal and, as a
bonus point, we get various fixes and miscellaneous improvements into
the branch.
Per jilles' suggestion, I'm avoiding the merge of a couple of changes
(r256850 and r257506) that required depending kernel changes. I'm also
avoiding very recent changes that have not had a long enough time to be
validated in current.
This is "make tinderbox" clean.
r256735 sh: Remove one syscall when waiting for a foreground job.
r257399 sh: Allow trapping SIGINT/SIGQUIT after ignore because of '&'.
r257504 sh: Reorder union node to reduce its size on 64-bit platforms.
r257920 sh: Add a test case for would-be assignments that are not due to quoting.
r257929 sh: Properly quote alias output from command -v.
r258489 sh: Add tests for the </dev/null implicit in a background command.
r258533 sh: Add more tests for the </dev/null implicit in a background command.
r258535 sh: Make <&0 disable the </dev/null implicit in a background command.
r258776 sh: Prefer memcpy() to strcpy() in most cases. Remove the scopy macro.
r259047 sh: Split set -x output into a separate function.
r259210 Migrate tools/regression/bin/ tests to the new layout.
r259844 sh: Remove an unused variable.
r259846 sh: Initialize OPTIND=1 even if it came from the environment.
r259874 sh: Simplify code related to PPID variable.
r259946 sh: Don't check input for non-whitespace if history is disabled.
r260246 sh(1): Discourage use of -e.
r260506 Run the sh(1) and test(1) tests as unprivileged.
r260586 Mark the bin/pax tests as requiring perl.
r260634 Use TAP_TESTS_PERL to register the legacy_test in bin/pax.
r260635 Replace hand-crafted Kyuafiles with automatic generation.
r260654 sh: Remove SIGWINCH handler and just check for resize before every read.
r261121 sh: Add test for nested alias.
r261125 sh: Solve the alias recursion problem in a less hackish way.
r261141 sh: Do not depend on parse/execute split in new alias test.
r261160 sh: Add tests for alias names after another alias.
r261192 sh: Allow aliases to force alias substitution on the following word.
r262533 sh: Make expari() static.
r262565 sh: Do not corrupt internal representation if LINENO inner expansion fails.
r262697 sh: Simplify expari().
Reviewed by: jilles
Added:
stable/10/bin/date/tests/
- copied from r259210, head/bin/date/tests/
stable/10/bin/mv/tests/
- copied from r259210, head/bin/mv/tests/
stable/10/bin/pax/tests/
- copied from r259210, head/bin/pax/tests/
stable/10/bin/pax/tests/legacy_test.pl
- copied unchanged from r260634, head/bin/pax/tests/legacy_test.pl
stable/10/bin/sh/tests/
- copied from r259210, head/bin/sh/tests/
stable/10/bin/sh/tests/builtins/lineno2.0
- copied unchanged from r262565, head/bin/sh/tests/builtins/lineno2.0
stable/10/bin/sh/tests/parameters/optind2.0
- copied unchanged from r259846, head/bin/sh/tests/parameters/optind2.0
stable/10/bin/sh/tests/parser/alias11.0
- copied, changed from r261121, head/bin/sh/tests/parser/alias11.0
stable/10/bin/sh/tests/parser/alias12.0
- copied unchanged from r261160, head/bin/sh/tests/parser/alias12.0
stable/10/bin/sh/tests/parser/alias13.0
- copied unchanged from r261160, head/bin/sh/tests/parser/alias13.0
stable/10/bin/sh/tests/parser/alias14.0
- copied unchanged from r261192, head/bin/sh/tests/parser/alias14.0
stable/10/bin/sh/tests/parser/alias15.0
- copied unchanged from r261192, head/bin/sh/tests/parser/alias15.0
stable/10/bin/sh/tests/parser/alias15.0.stdout
- copied unchanged from r261192, head/bin/sh/tests/parser/alias15.0.stdout
stable/10/bin/test/tests/
- copied from r259210, head/bin/test/tests/
stable/10/bin/tests/
- copied from r259210, head/bin/tests/
Deleted:
stable/10/bin/pax/tests/legacy_test.sh
stable/10/tools/regression/bin/
Modified:
stable/10/bin/Makefile
stable/10/bin/date/Makefile
stable/10/bin/mv/Makefile
stable/10/bin/pax/Makefile
stable/10/bin/pax/tests/Makefile
stable/10/bin/sh/Makefile
stable/10/bin/sh/alias.c
stable/10/bin/sh/cd.c
stable/10/bin/sh/eval.c
stable/10/bin/sh/exec.c
stable/10/bin/sh/expand.c
stable/10/bin/sh/expand.h
stable/10/bin/sh/input.c
stable/10/bin/sh/jobs.c
stable/10/bin/sh/memalloc.c
stable/10/bin/sh/mystring.c
stable/10/bin/sh/mystring.h
stable/10/bin/sh/nodetypes
stable/10/bin/sh/parser.c
stable/10/bin/sh/parser.h
stable/10/bin/sh/redir.c
stable/10/bin/sh/sh.1
stable/10/bin/sh/show.c
stable/10/bin/sh/tests/Makefile
stable/10/bin/sh/tests/builtins/Makefile
stable/10/bin/sh/tests/builtins/command3.0.stdout
stable/10/bin/sh/tests/builtins/command5.0.stdout
stable/10/bin/sh/tests/builtins/command6.0.stdout
stable/10/bin/sh/tests/parameters/Makefile
stable/10/bin/sh/tests/parser/Makefile
stable/10/bin/sh/trap.c
stable/10/bin/sh/trap.h
stable/10/bin/sh/var.c
stable/10/bin/sh/var.h
stable/10/bin/test/Makefile
stable/10/bin/test/tests/Makefile
stable/10/etc/mtree/BSD.tests.dist
Directory Properties:
stable/10/ (props changed)
Modified: stable/10/bin/Makefile
==============================================================================
--- stable/10/bin/Makefile Sun Mar 9 15:36:56 2014 (r262950)
+++ stable/10/bin/Makefile Sun Mar 9 17:04:31 2014 (r262951)
@@ -52,6 +52,10 @@ SUBDIR+= rmail
SUBDIR+= csh
.endif
+.if ${MK_TESTS} != "no"
+SUBDIR+= tests
+.endif
+
.include <bsd.arch.inc.mk>
SUBDIR:= ${SUBDIR:O}
Modified: stable/10/bin/date/Makefile
==============================================================================
--- stable/10/bin/date/Makefile Sun Mar 9 15:36:56 2014 (r262950)
+++ stable/10/bin/date/Makefile Sun Mar 9 17:04:31 2014 (r262951)
@@ -1,7 +1,13 @@
# @(#)Makefile 8.1 (Berkeley) 5/31/93
# $FreeBSD$
+.include <bsd.own.mk>
+
PROG= date
SRCS= date.c netdate.c vary.c
+.if ${MK_TESTS} != "no"
+SUBDIR+= tests
+.endif
+
.include <bsd.prog.mk>
Modified: stable/10/bin/mv/Makefile
==============================================================================
--- stable/10/bin/mv/Makefile Sun Mar 9 15:36:56 2014 (r262950)
+++ stable/10/bin/mv/Makefile Sun Mar 9 17:04:31 2014 (r262951)
@@ -1,6 +1,12 @@
# @(#)Makefile 8.2 (Berkeley) 4/2/94
# $FreeBSD$
+.include <bsd.own.mk>
+
PROG= mv
+.if ${MK_TESTS} != "no"
+SUBDIR+= tests
+.endif
+
.include <bsd.prog.mk>
Modified: stable/10/bin/pax/Makefile
==============================================================================
--- stable/10/bin/pax/Makefile Sun Mar 9 15:36:56 2014 (r262950)
+++ stable/10/bin/pax/Makefile Sun Mar 9 17:04:31 2014 (r262951)
@@ -1,6 +1,8 @@
# @(#)Makefile 8.1 (Berkeley) 5/31/93
# $FreeBSD$
+.include <bsd.own.mk>
+
# To install on versions prior to BSD 4.4 the following may have to be
# defined with CFLAGS +=
#
@@ -30,4 +32,8 @@ SRCS= ar_io.c ar_subs.c buf_subs.c cache
gen_subs.c getoldopt.c options.c pat_rep.c pax.c sel_subs.c \
tables.c tar.c tty_subs.c
+.if ${MK_TESTS} != "no"
+SUBDIR+= tests
+.endif
+
.include <bsd.prog.mk>
Modified: stable/10/bin/pax/tests/Makefile
==============================================================================
--- head/bin/pax/tests/Makefile Wed Dec 11 04:09:17 2013 (r259210)
+++ stable/10/bin/pax/tests/Makefile Sun Mar 9 17:04:31 2014 (r262951)
@@ -4,6 +4,6 @@
TESTSDIR= ${TESTSBASE}/bin/pax
-TAP_TESTS_SH= legacy_test
+TAP_TESTS_PERL= legacy_test
.include <tap.test.mk>
Copied: stable/10/bin/pax/tests/legacy_test.pl (from r260634, head/bin/pax/tests/legacy_test.pl)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ stable/10/bin/pax/tests/legacy_test.pl Sun Mar 9 17:04:31 2014 (r262951, copy of r260634, head/bin/pax/tests/legacy_test.pl)
@@ -0,0 +1,89 @@
+# $FreeBSD$
+
+use strict;
+use warnings;
+
+use Test::More tests => 6;
+use File::Path qw(rmtree mkpath);
+use Cwd;
+
+my $n = 0;
+sub create_file {
+ my $fn = shift;
+
+ $n++;
+ (my $dir = $fn) =~ s,/[^/]+$,,;
+ mkpath $dir;
+ open my $fd, ">", $fn or die "$fn: $!";
+ print $fd "file $n\n";
+}
+
+
+ustar_pathnames: { SKIP: {
+ # Prove that pax breaks up ustar pathnames properly
+
+ my $top = getcwd . "/ustar-pathnames-1";
+ skip "Current path is too long", 6 if length $top > 92;
+ rmtree $top;
+ my $subdir = "x" . "x" x (92 - length $top);
+ my $work94 = "$top/$subdir";
+ mkpath $work94; # $work is 94 characters long
+
+ my $x49 = "x" x 49;
+ my $x50 = "x" x 50;
+ my $x60 = "x" x 60;
+ my $x95 = "x" x 95;
+
+ my @paths = (
+ "$work94/x099", # 99 chars
+ "$work94/xx100", # 100 chars
+ "$work94/xxx101", # 101 chars
+ "$work94/$x49/${x50}x199", # 199 chars
+ "$work94/$x49/${x50}xx200", # 200 chars
+ "$work94/$x49/${x50}xxx201", # 201 chars
+ "$work94/$x60/${x95}254", # 254 chars
+ "$work94/$x60/${x95}x255", # 255 chars
+ );
+
+ my @l = map { length } @paths;
+
+ my $n = 0;
+ create_file $_ for @paths;
+ system "pax -wf ustar.ok $work94";
+ ok($? == 0, "Wrote 'ustar.ok' containing files with lengths @l");
+
+ (my $orig = $top) =~ s,1$,2,;
+ rmtree $orig;
+ rename $top, $orig;
+
+ system "pax -rf ustar.ok";
+ ok($? == 0, "Restored 'ustar.ok' containing files with lengths @l");
+
+ system "diff -ru $orig $top";
+ ok($? == 0, "Restored files are identical");
+
+ rmtree $top;
+ rename $orig, $top;
+
+ # 256 chars (with components < 100 chars) should not work
+ push @paths, "$work94/x$x60/${x95}x256"; # 256 chars
+ push @l, length $paths[-1];
+ create_file $paths[-1];
+ system "pax -wf ustar.fail1 $work94";
+ ok($?, "Failed to write 'ustar.fail1' containing files with lengths @l");
+
+ # Components with 100 chars shouldn't work
+ unlink $paths[-1];
+ $paths[-1] = "$work94/${x95}xc100"; # 100 char filename
+ $l[-1] = length $paths[-1];
+ create_file $paths[-1];
+ system "pax -wf ustar.fail2 $work94";
+ ok($?, "Failed to write 'ustar.fail2' with a 100 char filename");
+
+ unlink $paths[-1];
+ $paths[-1] = "$work94/${x95}xc100/x"; # 100 char component
+ $l[-1] = length $paths[-1];
+ create_file $paths[-1];
+ system "pax -wf ustar.fail3 $work94";
+ ok($?, "Failed to write 'ustar.fail3' with a 100 char component");
+}}
Modified: stable/10/bin/sh/Makefile
==============================================================================
--- stable/10/bin/sh/Makefile Sun Mar 9 15:36:56 2014 (r262950)
+++ stable/10/bin/sh/Makefile Sun Mar 9 17:04:31 2014 (r262951)
@@ -1,6 +1,8 @@
# @(#)Makefile 8.4 (Berkeley) 5/5/95
# $FreeBSD$
+.include <bsd.own.mk>
+
PROG= sh
INSTALLFLAGS= -S
SHSRCS= alias.c arith_yacc.c arith_yylex.c cd.c echo.c error.c eval.c \
@@ -59,7 +61,8 @@ syntax.c syntax.h: mksyntax
token.h: mktokens
sh ${.CURDIR}/mktokens
-regress:
- cd ${.CURDIR}/../../tools/regression/bin/sh && ${MAKE} SH=${.OBJDIR}/sh
+.if ${MK_TESTS} != "no"
+SUBDIR+= tests
+.endif
.include <bsd.prog.mk>
Modified: stable/10/bin/sh/alias.c
==============================================================================
--- stable/10/bin/sh/alias.c Sun Mar 9 15:36:56 2014 (r262950)
+++ stable/10/bin/sh/alias.c Sun Mar 9 17:04:31 2014 (r262951)
@@ -68,18 +68,7 @@ setalias(const char *name, const char *v
if (equal(name, ap->name)) {
INTOFF;
ckfree(ap->val);
- /* See HACK below. */
-#ifdef notyet
ap->val = savestr(val);
-#else
- {
- size_t len = strlen(val);
- ap->val = ckmalloc(len + 2);
- memcpy(ap->val, val, len);
- ap->val[len] = ' ';
- ap->val[len+1] = '\0';
- }
-#endif
INTON;
return;
}
@@ -88,34 +77,7 @@ setalias(const char *name, const char *v
INTOFF;
ap = ckmalloc(sizeof (struct alias));
ap->name = savestr(name);
- /*
- * XXX - HACK: in order that the parser will not finish reading the
- * alias value off the input before processing the next alias, we
- * dummy up an extra space at the end of the alias. This is a crock
- * and should be re-thought. The idea (if you feel inclined to help)
- * is to avoid alias recursions. The mechanism used is: when
- * expanding an alias, the value of the alias is pushed back on the
- * input as a string and a pointer to the alias is stored with the
- * string. The alias is marked as being in use. When the input
- * routine finishes reading the string, it marks the alias not
- * in use. The problem is synchronization with the parser. Since
- * it reads ahead, the alias is marked not in use before the
- * resulting token(s) is next checked for further alias sub. The
- * H A C K is that we add a little fluff after the alias value
- * so that the string will not be exhausted. This is a good
- * idea ------- ***NOT***
- */
-#ifdef notyet
ap->val = savestr(val);
-#else /* hack */
- {
- size_t len = strlen(val);
- ap->val = ckmalloc(len + 2);
- memcpy(ap->val, val, len);
- ap->val[len] = ' '; /* fluff */
- ap->val[len+1] = '\0';
- }
-#endif
ap->flag = 0;
ap->next = *app;
*app = ap;
@@ -207,14 +169,8 @@ comparealiases(const void *p1, const voi
static void
printalias(const struct alias *a)
{
- char *p;
-
out1fmt("%s=", a->name);
- /* Don't print the space added above. */
- p = a->val + strlen(a->val) - 1;
- *p = '\0';
out1qstr(a->val);
- *p = ' ';
out1c('\n');
}
Modified: stable/10/bin/sh/cd.c
==============================================================================
--- stable/10/bin/sh/cd.c Sun Mar 9 15:36:56 2014 (r262950)
+++ stable/10/bin/sh/cd.c Sun Mar 9 17:04:31 2014 (r262951)
@@ -182,6 +182,7 @@ cdlogical(char *dest)
struct stat statb;
int first;
int badstat;
+ size_t len;
/*
* Check each component of the path. If we find a symlink or
@@ -189,8 +190,9 @@ cdlogical(char *dest)
* next time we get the value of the current directory.
*/
badstat = 0;
- cdcomppath = stalloc(strlen(dest) + 1);
- scopy(dest, cdcomppath);
+ len = strlen(dest);
+ cdcomppath = stalloc(len + 1);
+ memcpy(cdcomppath, dest, len + 1);
STARTSTACKSTR(p);
if (*dest == '/') {
STPUTC('/', p);
@@ -275,6 +277,7 @@ findcwd(char *dir)
{
char *new;
char *p;
+ size_t len;
/*
* If our argument is NULL, we don't know the current directory
@@ -283,8 +286,9 @@ findcwd(char *dir)
*/
if (dir == NULL || curdir == NULL)
return getpwd2();
- cdcomppath = stalloc(strlen(dir) + 1);
- scopy(dir, cdcomppath);
+ len = strlen(dir);
+ cdcomppath = stalloc(len + 1);
+ memcpy(cdcomppath, dir, len + 1);
STARTSTACKSTR(new);
if (*dir != '/') {
STPUTS(curdir, new);
Modified: stable/10/bin/sh/eval.c
==============================================================================
--- stable/10/bin/sh/eval.c Sun Mar 9 15:36:56 2014 (r262950)
+++ stable/10/bin/sh/eval.c Sun Mar 9 17:04:31 2014 (r262951)
@@ -750,6 +750,45 @@ isdeclarationcmd(struct narg *arg)
(have_command || !isfunc("local"))));
}
+static void
+xtracecommand(struct arglist *varlist, struct arglist *arglist)
+{
+ struct strlist *sp;
+ char sep = 0;
+ const char *p, *ps4;
+
+ ps4 = expandstr(ps4val());
+ out2str(ps4 != NULL ? ps4 : ps4val());
+ for (sp = varlist->list ; sp ; sp = sp->next) {
+ if (sep != 0)
+ out2c(' ');
+ p = strchr(sp->text, '=');
+ if (p != NULL) {
+ p++;
+ outbin(sp->text, p - sp->text, out2);
+ out2qstr(p);
+ } else
+ out2qstr(sp->text);
+ sep = ' ';
+ }
+ for (sp = arglist->list ; sp ; sp = sp->next) {
+ if (sep != 0)
+ out2c(' ');
+ /* Disambiguate command looking like assignment. */
+ if (sp == arglist->list &&
+ strchr(sp->text, '=') != NULL &&
+ strchr(sp->text, '\'') == NULL) {
+ out2c('\'');
+ out2str(sp->text);
+ out2c('\'');
+ } else
+ out2qstr(sp->text);
+ sep = ' ';
+ }
+ out2c('\n');
+ flushout(&errout);
+}
+
/*
* Check if a builtin can safely be executed in the same process,
* even though it should be in a subshell (command substitution).
@@ -847,40 +886,8 @@ evalcommand(union node *cmd, int flags,
argv -= argc;
/* Print the command if xflag is set. */
- if (xflag) {
- char sep = 0;
- const char *p, *ps4;
- ps4 = expandstr(ps4val());
- out2str(ps4 != NULL ? ps4 : ps4val());
- for (sp = varlist.list ; sp ; sp = sp->next) {
- if (sep != 0)
- out2c(' ');
- p = strchr(sp->text, '=');
- if (p != NULL) {
- p++;
- outbin(sp->text, p - sp->text, out2);
- out2qstr(p);
- } else
- out2qstr(sp->text);
- sep = ' ';
- }
- for (sp = arglist.list ; sp ; sp = sp->next) {
- if (sep != 0)
- out2c(' ');
- /* Disambiguate command looking like assignment. */
- if (sp == arglist.list &&
- strchr(sp->text, '=') != NULL &&
- strchr(sp->text, '\'') == NULL) {
- out2c('\'');
- out2str(sp->text);
- out2c('\'');
- } else
- out2qstr(sp->text);
- sep = ' ';
- }
- out2c('\n');
- flushout(&errout);
- }
+ if (xflag)
+ xtracecommand(&varlist, &arglist);
/* Now locate the command. */
if (argc == 0) {
Modified: stable/10/bin/sh/exec.c
==============================================================================
--- stable/10/bin/sh/exec.c Sun Mar 9 15:36:56 2014 (r262950)
+++ stable/10/bin/sh/exec.c Sun Mar 9 17:04:31 2014 (r262951)
@@ -187,14 +187,15 @@ padvance(const char **path, const char *
{
const char *p, *start;
char *q;
- size_t len;
+ size_t len, namelen;
if (*path == NULL)
return NULL;
start = *path;
for (p = start; *p && *p != ':' && *p != '%'; p++)
; /* nothing */
- len = p - start + strlen(name) + 2; /* "2" is for '/' and '\0' */
+ namelen = strlen(name);
+ len = p - start + namelen + 2; /* "2" is for '/' and '\0' */
STARTSTACKSTR(q);
CHECKSTRSPACE(len, q);
if (p != start) {
@@ -202,7 +203,7 @@ padvance(const char **path, const char *
q += p - start;
*q++ = '/';
}
- strcpy(q, name);
+ memcpy(q, name, namelen + 1);
pathopt = NULL;
if (*p == '%') {
pathopt = ++p;
@@ -527,6 +528,7 @@ cmdlookup(const char *name, int add)
const char *p;
struct tblentry *cmdp;
struct tblentry **pp;
+ size_t len;
p = name;
hashval = *p << 4;
@@ -541,11 +543,11 @@ cmdlookup(const char *name, int add)
}
if (add && cmdp == NULL) {
INTOFF;
- cmdp = *pp = ckmalloc(sizeof (struct tblentry)
- + strlen(name) + 1);
+ len = strlen(name);
+ cmdp = *pp = ckmalloc(sizeof (struct tblentry) + len + 1);
cmdp->next = NULL;
cmdp->cmdtype = CMDUNKNOWN;
- strcpy(cmdp->cmdname, name);
+ memcpy(cmdp->cmdname, name, len + 1);
INTON;
}
lastcmdentry = pp;
@@ -672,9 +674,11 @@ typecmd_impl(int argc, char **argv, int
/* Then look at the aliases */
if ((ap = lookupalias(argv[i], 1)) != NULL) {
- if (cmd == TYPECMD_SMALLV)
- out1fmt("alias %s='%s'\n", argv[i], ap->val);
- else
+ if (cmd == TYPECMD_SMALLV) {
+ out1fmt("alias %s=", argv[i]);
+ out1qstr(ap->val);
+ outcslow('\n', out1);
+ } else
out1fmt("%s is an alias for %s\n", argv[i],
ap->val);
continue;
Modified: stable/10/bin/sh/expand.c
==============================================================================
--- stable/10/bin/sh/expand.c Sun Mar 9 15:36:56 2014 (r262950)
+++ stable/10/bin/sh/expand.c Sun Mar 9 17:04:31 2014 (r262951)
@@ -100,6 +100,7 @@ static struct arglist exparg; /* holds
static void argstr(char *, int);
static char *exptilde(char *, int);
+static char *expari(char *);
static void expbackq(union node *, int, int);
static int subevalvar(char *, char *, int, int, int, int, int);
static char *evalvar(char *, int);
@@ -206,7 +207,7 @@ expandarg(union node *arg, struct arglis
/*
* Perform parameter expansion, command substitution and arithmetic
* expansion, and tilde expansion if requested via EXP_TILDE/EXP_VARTILDE.
- * Processing ends at a CTLENDVAR character as well as '\0'.
+ * Processing ends at a CTLENDVAR or CTLENDARI character as well as '\0'.
* This is used to expand word in ${var+word} etc.
* If EXP_FULL, EXP_CASE or EXP_REDIR are set, keep and/or generate CTLESC
* characters to allow for further processing.
@@ -231,6 +232,7 @@ argstr(char *p, int flag)
switch (c = *p++) {
case '\0':
case CTLENDVAR:
+ case CTLENDARI:
goto breakloop;
case CTLQUOTEMARK:
lit_quoted = 1;
@@ -261,8 +263,8 @@ argstr(char *p, int flag)
expbackq(argbackq->n, c & CTLQUOTE, flag);
argbackq = argbackq->next;
break;
- case CTLENDARI:
- expari(flag);
+ case CTLARI:
+ p = expari(p);
break;
case ':':
case '=':
@@ -387,59 +389,56 @@ removerecordregions(int endoff)
}
/*
- * Expand arithmetic expression. Backup to start of expression,
- * evaluate, place result in (backed up) result, adjust string position.
+ * Expand arithmetic expression.
+ * Note that flag is not required as digits never require CTLESC characters.
*/
-void
-expari(int flag)
+static char *
+expari(char *p)
{
- char *p, *q, *start;
+ char *q, *start;
arith_t result;
int begoff;
- int quotes = flag & (EXP_FULL | EXP_CASE | EXP_REDIR);
int quoted;
+ int c;
+ int nesting;
+ int adj;
- /*
- * This routine is slightly over-complicated for
- * efficiency. First we make sure there is
- * enough space for the result, which may be bigger
- * than the expression. Next we
- * scan backwards looking for the start of arithmetic. If the
- * next previous character is a CTLESC character, then we
- * have to rescan starting from the beginning since CTLESC
- * characters have to be processed left to right.
- */
- CHECKSTRSPACE(DIGITS(result) - 2, expdest);
- USTPUTC('\0', expdest);
- start = stackblock();
- p = expdest - 2;
- while (p >= start && *p != CTLARI)
- --p;
- if (p < start || *p != CTLARI)
- error("missing CTLARI (shouldn't happen)");
- if (p > start && *(p - 1) == CTLESC)
- for (p = start; *p != CTLARI; p++)
- if (*p == CTLESC)
- p++;
-
- if (p[1] == '"')
- quoted=1;
- else
- quoted=0;
- begoff = p - start;
+ quoted = *p++ == '"';
+ begoff = expdest - stackblock();
+ argstr(p, 0);
removerecordregions(begoff);
- if (quotes)
- rmescapes(p+2);
+ STPUTC('\0', expdest);
+ start = stackblock() + begoff;
+
q = grabstackstr(expdest);
- result = arith(p+2);
+ result = arith(start);
ungrabstackstr(q, expdest);
- fmtstr(p, DIGITS(result), ARITH_FORMAT_STR, result);
- while (*p++)
- ;
- if (quoted == 0)
- recordregion(begoff, p - 1 - start, 0);
- result = expdest - p + 1;
- STADJUST(-result, expdest);
+
+ start = stackblock() + begoff;
+ adj = start - expdest;
+ STADJUST(adj, expdest);
+
+ CHECKSTRSPACE((int)(DIGITS(result) + 1), expdest);
+ fmtstr(expdest, DIGITS(result), ARITH_FORMAT_STR, result);
+ adj = strlen(expdest);
+ STADJUST(adj, expdest);
+ if (!quoted)
+ recordregion(begoff, expdest - stackblock(), 0);
+ nesting = 1;
+ while (nesting > 0) {
+ c = *p++;
+ if (c == CTLESC)
+ p++;
+ else if (c == CTLARI)
+ nesting++;
+ else if (c == CTLENDARI)
+ nesting--;
+ else if (c == CTLVAR)
+ p++; /* ignore variable substitution byte */
+ else if (c == '\0')
+ return p - 1;
+ }
+ return p;
}
@@ -671,10 +670,8 @@ evalvar(char *p, int flag)
again: /* jump here after setting a variable with ${var=text} */
if (varflags & VSLINENO) {
set = 1;
- special = 0;
- val = var;
- p[-1] = '\0'; /* temporarily overwrite '=' to have \0
- terminated string */
+ special = 1;
+ val = NULL;
} else if (special) {
set = varisset(var, varflags & VSNUL);
val = NULL;
@@ -703,7 +700,10 @@ again: /* jump here after setting a vari
if (set && subtype != VSPLUS) {
/* insert the value of the variable */
if (special) {
- varvalue(var, varflags & VSQUOTE, subtype, flag);
+ if (varflags & VSLINENO)
+ STPUTBIN(var, p - var - 1, expdest);
+ else
+ varvalue(var, varflags & VSQUOTE, subtype, flag);
if (subtype == VSLENGTH) {
varlenb = expdest - stackblock() - startloc;
varlen = varlenb;
@@ -815,7 +815,6 @@ record:
default:
abort();
}
- p[-1] = '='; /* recover overwritten '=' */
if (subtype != VSNORMAL) { /* skip to end of alternative */
int nesting = 1;
@@ -1307,9 +1306,11 @@ addfname(char *name)
{
char *p;
struct strlist *sp;
+ size_t len;
- p = stalloc(strlen(name) + 1);
- scopy(name, p);
+ len = strlen(name);
+ p = stalloc(len + 1);
+ memcpy(p, name, len + 1);
sp = (struct strlist *)stalloc(sizeof *sp);
sp->text = p;
*exparg.lastp = sp;
Modified: stable/10/bin/sh/expand.h
==============================================================================
--- stable/10/bin/sh/expand.h Sun Mar 9 15:36:56 2014 (r262950)
+++ stable/10/bin/sh/expand.h Sun Mar 9 17:04:31 2014 (r262951)
@@ -58,6 +58,5 @@ struct arglist {
union node;
void expandarg(union node *, struct arglist *, int);
-void expari(int);
void rmescapes(char *);
int casematch(union node *, const char *);
Modified: stable/10/bin/sh/input.c
==============================================================================
--- stable/10/bin/sh/input.c Sun Mar 9 15:36:56 2014 (r262950)
+++ stable/10/bin/sh/input.c Sun Mar 9 17:04:31 2014 (r262951)
@@ -162,20 +162,16 @@ preadfd(void)
int nr;
parsenextc = parsefile->buf;
-#ifndef NO_HISTORY
- if (el != NULL && gotwinch) {
- gotwinch = 0;
- el_resize(el);
- }
-#endif
retry:
#ifndef NO_HISTORY
if (parsefile->fd == 0 && el) {
static const char *rl_cp;
static int el_len;
- if (rl_cp == NULL)
+ if (rl_cp == NULL) {
+ el_resize(el);
rl_cp = el_gets(el, &el_len);
+ }
if (rl_cp == NULL)
nr = el_len == 0 ? 0 : -1;
else {
@@ -228,10 +224,16 @@ preadbuffer(void)
{
char *p, *q;
int more;
- int something;
char savec;
- if (parsefile->strpush) {
+ while (parsefile->strpush) {
+ /*
+ * Add a space to the end of an alias to ensure that the
+ * alias remains in use while parsing its last word.
+ * This avoids alias recursions.
+ */
+ if (parsenleft == -1 && parsefile->strpush->ap != NULL)
+ return ' ';
popstring();
if (--parsenleft >= 0)
return (*parsenextc++);
@@ -252,24 +254,18 @@ again:
q = p = parsefile->buf + (parsenextc - parsefile->buf);
/* delete nul characters */
- something = 0;
for (more = 1; more;) {
switch (*p) {
case '\0':
p++; /* Skip nul */
goto check;
- case '\t':
- case ' ':
- break;
-
case '\n':
parsenleft = q - parsenextc;
more = 0; /* Stop processing here */
break;
default:
- something = 1;
break;
}
@@ -288,7 +284,8 @@ check:
*q = '\0';
#ifndef NO_HISTORY
- if (parsefile->fd == 0 && hist && something) {
+ if (parsefile->fd == 0 && hist &&
+ parsenextc[strspn(parsenextc, " \t\n")] != '\0') {
HistEvent he;
INTOFF;
history(hist, &he, whichprompt == 1 ? H_ENTER : H_ADD,
@@ -370,12 +367,16 @@ popstring(void)
struct strpush *sp = parsefile->strpush;
INTOFF;
+ if (sp->ap) {
+ if (parsenextc != sp->ap->val &&
+ (parsenextc[-1] == ' ' || parsenextc[-1] == '\t'))
+ forcealias();
+ sp->ap->flag &= ~ALIASINUSE;
+ }
parsenextc = sp->prevstring;
parsenleft = sp->prevnleft;
parselleft = sp->prevlleft;
/*out2fmt_flush("*** calling popstring: restoring to '%s'\n", parsenextc);*/
- if (sp->ap)
- sp->ap->flag &= ~ALIASINUSE;
parsefile->strpush = sp->prev;
if (sp != &(parsefile->basestrpush))
ckfree(sp);
Modified: stable/10/bin/sh/jobs.c
==============================================================================
--- stable/10/bin/sh/jobs.c Sun Mar 9 15:36:56 2014 (r262950)
+++ stable/10/bin/sh/jobs.c Sun Mar 9 17:04:31 2014 (r262951)
@@ -978,7 +978,6 @@ int
waitforjob(struct job *jp, int *origstatus)
{
#if JOBS
- pid_t mypgrp = getpgrp();
int propagate_int = jp->jobctl && jp->foreground;
#endif
int status;
@@ -992,7 +991,7 @@ waitforjob(struct job *jp, int *origstat
dotrap();
#if JOBS
if (jp->jobctl) {
- if (tcsetpgrp(ttyfd, mypgrp) < 0)
+ if (tcsetpgrp(ttyfd, rootpid) < 0)
error("tcsetpgrp failed, errno=%d\n", errno);
}
if (jp->state == JOBSTOPPED)
Modified: stable/10/bin/sh/memalloc.c
==============================================================================
--- stable/10/bin/sh/memalloc.c Sun Mar 9 15:36:56 2014 (r262950)
+++ stable/10/bin/sh/memalloc.c Sun Mar 9 17:04:31 2014 (r262951)
@@ -98,9 +98,11 @@ char *
savestr(const char *s)
{
char *p;
+ size_t len;
- p = ckmalloc(strlen(s) + 1);
- scopy(s, p);
+ len = strlen(s);
+ p = ckmalloc(len + 1);
+ memcpy(p, s, len + 1);
return p;
}
Modified: stable/10/bin/sh/mystring.c
==============================================================================
--- stable/10/bin/sh/mystring.c Sun Mar 9 15:36:56 2014 (r262950)
+++ stable/10/bin/sh/mystring.c Sun Mar 9 17:04:31 2014 (r262951)
@@ -42,7 +42,6 @@ __FBSDID("$FreeBSD$");
* String functions.
*
* equal(s1, s2) Return true if strings are equal.
- * scopy(from, to) Copy a string.
* number(s) Convert a string of digits to an integer.
* is_number(s) Return true if s is a string of digits.
*/
@@ -60,10 +59,6 @@ char nullstr[1]; /* zero length string
* equal - #defined in mystring.h
*/
-/*
- * scopy - #defined in mystring.h
- */
-
/*
* prefix -- see if pfx is a prefix of string.
Modified: stable/10/bin/sh/mystring.h
==============================================================================
--- stable/10/bin/sh/mystring.h Sun Mar 9 15:36:56 2014 (r262950)
+++ stable/10/bin/sh/mystring.h Sun Mar 9 17:04:31 2014 (r262951)
@@ -40,4 +40,3 @@ int number(const char *);
int is_number(const char *);
#define equal(s1, s2) (strcmp(s1, s2) == 0)
-#define scopy(s1, s2) ((void)strcpy(s2, s1))
Modified: stable/10/bin/sh/nodetypes
==============================================================================
--- stable/10/bin/sh/nodetypes Sun Mar 9 15:36:56 2014 (r262950)
+++ stable/10/bin/sh/nodetypes Sun Mar 9 17:04:31 2014 (r262951)
@@ -118,16 +118,16 @@ NFROMTO nfile # fd<> fname
NAPPEND nfile # fd>> fname
NCLOBBER nfile # fd>| fname
type int
- next nodeptr # next redirection in list
fd int # file descriptor being redirected
+ next nodeptr # next redirection in list
fname nodeptr # file name, in a NARG node
expfname temp char *expfname # actual file name
NTOFD ndup # fd<&dupfd
NFROMFD ndup # fd>&dupfd
type int
- next nodeptr # next redirection in list
fd int # file descriptor being redirected
+ next nodeptr # next redirection in list
dupfd int # file descriptor to duplicate
vname nodeptr # file name if fd>&$var
@@ -135,8 +135,8 @@ NFROMFD ndup # fd>&dupfd
NHERE nhere # fd<<\!
NXHERE nhere # fd<<!
type int
- next nodeptr # next redirection in list
fd int # file descriptor being redirected
+ next nodeptr # next redirection in list
doc nodeptr # input to command (NARG node)
expdoc temp char *expdoc # actual document (for NXHERE)
Modified: stable/10/bin/sh/parser.c
==============================================================================
--- stable/10/bin/sh/parser.c Sun Mar 9 15:36:56 2014 (r262950)
+++ stable/10/bin/sh/parser.c Sun Mar 9 17:04:31 2014 (r262951)
@@ -683,6 +683,12 @@ makebinary(int type, union node *n1, uni
}
void
+forcealias(void)
+{
+ checkkwd |= CHKALIAS;
+}
+
+void
fixredir(union node *n, const char *text, int err)
{
TRACE(("Fix redir %s %d\n", text, err));
Modified: stable/10/bin/sh/parser.h
==============================================================================
--- stable/10/bin/sh/parser.h Sun Mar 9 15:36:56 2014 (r262950)
+++ stable/10/bin/sh/parser.h Sun Mar 9 17:04:31 2014 (r262951)
@@ -76,6 +76,7 @@ extern const char *const parsekwd[];
union node *parsecmd(int);
+void forcealias(void);
void fixredir(union node *, const char *, int);
int goodname(const char *);
int isassignment(const char *);
Modified: stable/10/bin/sh/redir.c
==============================================================================
--- stable/10/bin/sh/redir.c Sun Mar 9 15:36:56 2014 (r262950)
+++ stable/10/bin/sh/redir.c Sun Mar 9 17:04:31 2014 (r262951)
@@ -69,6 +69,7 @@ __FBSDID("$FreeBSD$");
struct redirtab {
struct redirtab *next;
int renamed[10];
+ int fd0_redirected;
};
@@ -109,11 +110,14 @@ redirect(union node *redir, int flags)
sv = ckmalloc(sizeof (struct redirtab));
for (i = 0 ; i < 10 ; i++)
sv->renamed[i] = EMPTY;
+ sv->fd0_redirected = fd0_redirected;
sv->next = redirlist;
redirlist = sv;
}
for (n = redir ; n ; n = n->nfile.next) {
fd = n->nfile.fd;
+ if (fd == 0)
+ fd0_redirected = 1;
if ((n->nfile.type == NTOFD || n->nfile.type == NFROMFD) &&
n->ndup.dupfd == fd)
continue; /* redirect from/to same file descriptor */
@@ -134,8 +138,6 @@ redirect(union node *redir, int flags)
sv->renamed[fd] = i;
INTON;
}
- if (fd == 0)
- fd0_redirected++;
openredirect(n, memory);
}
if (memory[1])
@@ -303,8 +305,6 @@ popredir(void)
for (i = 0 ; i < 10 ; i++) {
if (rp->renamed[i] != EMPTY) {
- if (i == 0)
- fd0_redirected--;
if (rp->renamed[i] >= 0) {
dup2(rp->renamed[i], i);
close(rp->renamed[i]);
@@ -314,6 +314,7 @@ popredir(void)
}
}
INTOFF;
+ fd0_redirected = rp->fd0_redirected;
redirlist = rp->next;
ckfree(rp);
INTON;
Modified: stable/10/bin/sh/sh.1
==============================================================================
--- stable/10/bin/sh/sh.1 Sun Mar 9 15:36:56 2014 (r262950)
+++ stable/10/bin/sh/sh.1 Sun Mar 9 17:04:31 2014 (r262951)
@@ -32,7 +32,7 @@
.\" from: @(#)sh.1 8.6 (Berkeley) 5/4/95
.\" $FreeBSD$
.\"
-.Dd June 14, 2013
+.Dd January 26, 2014
.Dt SH 1
.Os
.Sh NAME
@@ -235,10 +235,16 @@ or
.Dq Li ||
operator; or if the command is a pipeline preceded by the
.Ic !\&
-operator.
+keyword.
If a shell function is executed and its exit status is explicitly
tested, all commands of the function are considered to be tested as
well.
+.Pp
+It is recommended to check for failures explicitly
+instead of relying on
+.Fl e
+because it tends to behave in unexpected ways,
+particularly in larger scripts.
.It Fl f Li noglob
Disable pathname expansion.
.It Fl h Li trackall
@@ -527,6 +533,20 @@ would become
.Pp
.Dl "ls -F foobar"
.Pp
+Aliases are also recognized after an alias
+whose value ends with a space or tab.
+For example, if there is also an alias called
+.Dq Li nohup
+with the value
+.Dq Li "nohup " ,
+then the input
+.Pp
+.Dl "nohup lf foobar"
+.Pp
+would become
+.Pp
+.Dl "nohup ls -F foobar"
+.Pp
Aliases provide a convenient way for naive users to
create shorthands for commands without having to learn how
to create functions with arguments.
Modified: stable/10/bin/sh/show.c
==============================================================================
--- stable/10/bin/sh/show.c Sun Mar 9 15:36:56 2014 (r262950)
+++ stable/10/bin/sh/show.c Sun Mar 9 17:04:31 2014 (r262951)
@@ -390,11 +390,11 @@ opentrace(void)
else
p = "/tmp";
}
- scopy(p, s);
+ strcpy(s, p);
strcat(s, "/trace");
}
#else
- scopy("./trace", s);
+ strcpy(s, "./trace");
#endif /* not_this_way */
if ((tracefile = fopen(s, "a")) == NULL) {
fprintf(stderr, "Can't open %s: %s\n", s, strerror(errno));
Modified: stable/10/bin/sh/tests/Makefile
==============================================================================
--- head/bin/sh/tests/Makefile Wed Dec 11 04:09:17 2013 (r259210)
+++ stable/10/bin/sh/tests/Makefile Sun Mar 9 17:04:31 2014 (r262951)
@@ -6,6 +6,12 @@ TESTSDIR= ${TESTSBASE}/bin/sh
TAP_TESTS_SH= legacy_test
TAP_TESTS_SH_SED_legacy_test= -e 's,__SH__,/bin/sh,g'
+# Some tests in here are silently not run when the tests are executed as
+# root. Explicitly tell Kyua to drop privileges.
+#
+# TODO(jmmv): Kyua needs to do this by default, not only when explicitly
+# requested. See https://code.google.com/p/kyua/issues/detail?id=6
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-stable
mailing list