From 046bfe52403416c6c40db2c73009dbb360257631 Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Sun, 1 Nov 2015 22:07:40 +0000 Subject: [PATCH] sh: Avoid copying argv for simple commands. Add dummy entries before and after so arglist's array is directly usable as argv. --- bin/sh/eval.c | 18 +++++++++--------- bin/sh/expand.c | 3 +-- bin/sh/expand.h | 1 + 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/bin/sh/eval.c b/bin/sh/eval.c index dfbbc04028f3..46c00de75b99 100644 --- a/bin/sh/eval.c +++ b/bin/sh/eval.c @@ -750,7 +750,7 @@ isdeclarationcmd(struct narg *arg) } static void -xtracecommand(struct arglist *varlist, struct arglist *arglist) +xtracecommand(struct arglist *varlist, int argc, char **argv) { char sep = 0; const char *text, *p, *ps4; @@ -771,8 +771,8 @@ xtracecommand(struct arglist *varlist, struct arglist *arglist) out2qstr(text); sep = ' '; } - for (i = 0; i < arglist->count; i++) { - text = arglist->args[i]; + for (i = 0; i < argc; i++) { + text = argv[i]; if (sep != 0) out2c(' '); out2qstr(text); @@ -849,6 +849,8 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd) do_clearcmdentry = 0; oexitstatus = exitstatus; exitstatus = 0; + /* Add one slot at the beginning for tryexec(). */ + appendarglist(&arglist, nullstr); for (argp = cmd->ncmd.args ; argp ; argp = argp->narg.next) { if (varflag && isassignment(argp->narg.text)) { expandarg(argp, varflag == 1 ? &varlist : &arglist, @@ -858,13 +860,11 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd) varflag = isdeclarationcmd(&argp->narg) ? 2 : 0; expandarg(argp, &arglist, EXP_FULL | EXP_TILDE); } + appendarglist(&arglist, nullstr); expredir(cmd->ncmd.redirect); - argc = arglist.count; - /* Add one slot at the beginning for tryexec(). */ - argv = stalloc(sizeof (char *) * (argc + 2)); - argv++; + argc = arglist.count - 2; + argv = &arglist.args[1]; - memcpy(argv, arglist.args, sizeof(*argv) * argc); argv[argc] = NULL; lastarg = NULL; if (iflag && funcnest == 0 && argc > 0) @@ -872,7 +872,7 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd) /* Print the command if xflag is set. */ if (xflag) - xtracecommand(&varlist, &arglist); + xtracecommand(&varlist, argc, argv); /* Now locate the command. */ if (argc == 0) { diff --git a/bin/sh/expand.c b/bin/sh/expand.c index 567b8a48423a..f7c6735f9e33 100644 --- a/bin/sh/expand.c +++ b/bin/sh/expand.c @@ -114,7 +114,6 @@ static void expmeta(char *, char *, struct arglist *); static int expsortcmp(const void *, const void *); static int patmatch(const char *, const char *, int); static char *cvtnum(int, char *); -static void appendarglist(struct arglist *, char *); static int collate_range_cmp(wchar_t, wchar_t); void @@ -126,7 +125,7 @@ emptyarglist(struct arglist *list) list->capacity = sizeof(list->smallarg) / sizeof(list->smallarg[0]); } -static void +void appendarglist(struct arglist *list, char *str) { char **newargs; diff --git a/bin/sh/expand.h b/bin/sh/expand.h index c377156c9c33..d024e8f6b7af 100644 --- a/bin/sh/expand.h +++ b/bin/sh/expand.h @@ -52,6 +52,7 @@ struct arglist { void emptyarglist(struct arglist *); +void appendarglist(struct arglist *, char *); union node; void expandarg(union node *, struct arglist *, int); void rmescapes(char *);