EXPERIMENTAL optimisation for “sh -c 'foo'” to equal “sh -c 'exit foo'” iff
several conditions are met as outlined below; for more background, refer to http://www.FreeBSD.org/cgi/query-pr.cgi?pr=113860 We don’t yet optimise 「% sh -c '{ echo a; sleep 10;}&'; sleep 1; ps T」 so the FreeBSD® sh approach cannot work for us, but scanning the “sh -c” argu‐ ment for disallowed characters and, if not, setting a flag that enables the shell to exec the tree when parsed as TCOM *and not c_trap()* was possible. Disallowed characters are currently C_QUOTE except space, that is: Tab Newline " # $ & ' ( ) * ; < = > ? [ \ ] ` | This should catch all cases of magic, variables, subshells, pipelines, etc.
This commit is contained in:
parent
1f43cc907d
commit
bebb2d2254
11
exec.c
11
exec.c
@ -23,7 +23,7 @@
|
||||
|
||||
#include "sh.h"
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.101 2012/10/03 17:24:18 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.102 2012/10/21 21:26:39 tg Exp $");
|
||||
|
||||
#ifndef MKSH_DEFAULT_EXECSHELL
|
||||
#define MKSH_DEFAULT_EXECSHELL "/bin/sh"
|
||||
@ -604,11 +604,20 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap,
|
||||
else
|
||||
/* go on, use the builtin */
|
||||
break;
|
||||
#endif
|
||||
#ifndef MKSH_SMALL
|
||||
} else if (tp->val.f == c_trap) {
|
||||
t->u.evalflags &= ~DOTCOMEXEC;
|
||||
break;
|
||||
#endif
|
||||
} else
|
||||
break;
|
||||
tp = findcom(ap[0], fcflags & (FC_BI|FC_FUNC));
|
||||
}
|
||||
#ifndef MKSH_SMALL
|
||||
if (t->u.evalflags & DOTCOMEXEC)
|
||||
flags |= XEXEC;
|
||||
#endif
|
||||
l_expand = e->loc;
|
||||
if (keepasn_ok && (!ap[0] || (tp && (tp->flag & KEEPASN))))
|
||||
type_flags = 0;
|
||||
|
25
main.c
25
main.c
@ -34,7 +34,7 @@
|
||||
#include <locale.h>
|
||||
#endif
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.229 2012/10/21 17:16:45 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.230 2012/10/21 21:26:40 tg Exp $");
|
||||
|
||||
extern char **environ;
|
||||
|
||||
@ -464,6 +464,16 @@ main_init(int argc, const char *argv[], Source **sp, struct block **lp)
|
||||
s = pushs(SSTRINGCMDLINE, ATEMP);
|
||||
if (!(s->start = s->str = argv[argi++]))
|
||||
errorf("%s %s", "-c", "requires an argument");
|
||||
#ifndef MKSH_SMALL
|
||||
while (*s->str) {
|
||||
if (*s->str != ' ' && ctype(*s->str, C_QUOTE))
|
||||
break;
|
||||
s->str++;
|
||||
}
|
||||
if (!*s->str)
|
||||
s->flags |= SF_MAYEXEC;
|
||||
s->str = s->start;
|
||||
#endif
|
||||
#ifdef MKSH_MIDNIGHTBSD01ASH_COMPAT
|
||||
/* compatibility to MidnightBSD 0.1 /bin/sh (kludge) */
|
||||
if (Flag(FSH) && argv[argi] && !strcmp(argv[argi], "--"))
|
||||
@ -818,7 +828,9 @@ shell(Source * volatile s, volatile bool toplevel)
|
||||
}
|
||||
t = compile(s, sfirst);
|
||||
sfirst = false;
|
||||
if (t != NULL && t->type == TEOF) {
|
||||
if (!t)
|
||||
goto source_no_tree;
|
||||
if (t->type == TEOF) {
|
||||
if (wastty && Flag(FIGNOREEOF) && --attempts > 0) {
|
||||
shellf("Use 'exit' to leave mksh\n");
|
||||
s->type = SSTDIN;
|
||||
@ -838,12 +850,17 @@ shell(Source * volatile s, volatile bool toplevel)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (t && (!Flag(FNOEXEC) || (s->flags & SF_TTY)))
|
||||
#ifndef MKSH_SMALL
|
||||
else if ((s->flags & SF_MAYEXEC) && t->type == TCOM)
|
||||
t->u.evalflags |= DOTCOMEXEC;
|
||||
#endif
|
||||
if (!Flag(FNOEXEC) || (s->flags & SF_TTY))
|
||||
exstat = execute(t, 0, NULL);
|
||||
|
||||
if (t != NULL && t->type != TEOF && interactive && really_exit)
|
||||
if (t->type != TEOF && interactive && really_exit)
|
||||
really_exit = false;
|
||||
|
||||
source_no_tree:
|
||||
reclaim();
|
||||
}
|
||||
quitenv(NULL);
|
||||
|
8
sh.h
8
sh.h
@ -157,7 +157,7 @@
|
||||
#endif
|
||||
|
||||
#ifdef EXTERN
|
||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.592 2012/10/03 17:24:23 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.593 2012/10/21 21:26:41 tg Exp $");
|
||||
#endif
|
||||
#define MKSH_VERSION "R40 2012/10/03"
|
||||
|
||||
@ -1343,6 +1343,9 @@ struct ioword {
|
||||
#define DOTEMP BIT(8) /* dito: in word part of ${..[%#=?]..} */
|
||||
#define DOVACHECK BIT(9) /* var assign check (for typeset, set, etc) */
|
||||
#define DOMARKDIRS BIT(10) /* force markdirs behaviour */
|
||||
#ifndef MKSH_SMALL
|
||||
#define DOTCOMEXEC BIT(11) /* not an eval flag, used by sh -c hack */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The arguments of [[ .. ]] expressions are kept in t->args[] and flags
|
||||
@ -1486,6 +1489,9 @@ struct source {
|
||||
#define SF_ALIASEND BIT(2) /* faking space at end of alias */
|
||||
#define SF_TTY BIT(3) /* type == SSTDIN & it is a tty */
|
||||
#define SF_HASALIAS BIT(4) /* u.tblp valid (SALIAS, SEOF) */
|
||||
#ifndef MKSH_SMALL
|
||||
#define SF_MAYEXEC BIT(5) /* special sh -c optimisation hack */
|
||||
#endif
|
||||
|
||||
typedef union {
|
||||
int i;
|
||||
|
Loading…
x
Reference in New Issue
Block a user