summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bin/sh/eval.c19
-rw-r--r--bin/sh/eval.h5
-rw-r--r--bin/sh/input.c17
-rw-r--r--bin/sh/input.h1
-rw-r--r--bin/sh/main.c2
5 files changed, 35 insertions, 9 deletions
diff --git a/bin/sh/eval.c b/bin/sh/eval.c
index 8554943..5cee55e 100644
--- a/bin/sh/eval.c
+++ b/bin/sh/eval.c
@@ -74,11 +74,6 @@ __FBSDID("$FreeBSD$");
#endif
-/* flags in argument to evaltree */
-#define EV_EXIT 01 /* exit after evaluating tree */
-#define EV_TESTED 02 /* exit status is checked; ignore -e flag */
-#define EV_BACKCMD 04 /* command executing within back quotes */
-
MKINIT int evalskip; /* set if we are skipping commands */
STATIC int skipcount; /* number of levels to skip */
MKINIT int loopnest; /* current loop nesting level */
@@ -163,20 +158,28 @@ evalstring(char *s, int flags)
{
union node *n;
struct stackmark smark;
+ int flags_exit;
+ flags_exit = flags & EV_EXIT;
+ flags &= ~EV_EXIT;
setstackmark(&smark);
setinputstring(s, 1);
while ((n = parsecmd(0)) != NEOF) {
- if (n != NULL)
- evaltree(n, flags);
+ if (n != NULL) {
+ if (flags_exit && preadateof())
+ evaltree(n, flags | EV_EXIT);
+ else
+ evaltree(n, flags);
+ }
popstackmark(&smark);
}
popfile();
popstackmark(&smark);
+ if (flags_exit)
+ exitshell(exitstatus);
}
-
/*
* Evaluate a parse tree. The value is left in the global variable
* exitstatus.
diff --git a/bin/sh/eval.h b/bin/sh/eval.h
index 11f7470..c82585e 100644
--- a/bin/sh/eval.h
+++ b/bin/sh/eval.h
@@ -45,6 +45,11 @@ struct backcmd { /* result of evalbackcmd */
struct job *jp; /* job structure for command */
};
+/* flags in argument to evaltree/evalstring */
+#define EV_EXIT 01 /* exit after evaluating tree */
+#define EV_TESTED 02 /* exit status is checked; ignore -e flag */
+#define EV_BACKCMD 04 /* command executing within back quotes */
+
int evalcmd(int, char **);
void evalstring(char *, int);
union node; /* BLETCH for ansi C */
diff --git a/bin/sh/input.c b/bin/sh/input.c
index 81c1f0b..c97c496 100644
--- a/bin/sh/input.c
+++ b/bin/sh/input.c
@@ -321,6 +321,23 @@ check:
}
/*
+ * Returns if we are certain we are at EOF. Does not cause any more input
+ * to be read from the outside world.
+ */
+
+int
+preadateof(void)
+{
+ if (parsenleft > 0)
+ return 0;
+ if (parsefile->strpush)
+ return 0;
+ if (parsenleft == EOF_NLEFT || parsefile->buf == NULL)
+ return 1;
+ return 0;
+}
+
+/*
* Undo the last call to pgetc. Only one character may be pushed back.
* PEOF may be pushed back.
*/
diff --git a/bin/sh/input.h b/bin/sh/input.h
index 0d188c5..4d57b3b 100644
--- a/bin/sh/input.h
+++ b/bin/sh/input.h
@@ -48,6 +48,7 @@ extern int init_editline; /* 0 == not setup, 1 == OK, -1 == failed */
char *pfgets(char *, int);
int pgetc(void);
int preadbuffer(void);
+int preadateof(void);
void pungetc(void);
void pushstring(char *, int, void *);
void popstring(void);
diff --git a/bin/sh/main.c b/bin/sh/main.c
index 77526b5..85a6d20 100644
--- a/bin/sh/main.c
+++ b/bin/sh/main.c
@@ -178,7 +178,7 @@ state2:
state3:
state = 4;
if (minusc) {
- evalstring(minusc, 0);
+ evalstring(minusc, sflag ? 0 : EV_EXIT);
}
if (sflag || minusc == NULL) {
state4: /* XXX ??? - why isn't this before the "if" statement */
OpenPOWER on IntegriCloud