summaryrefslogtreecommitdiffstats
path: root/bin/sh/eval.c
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1996-09-01 10:22:36 +0000
committerpeter <peter@FreeBSD.org>1996-09-01 10:22:36 +0000
commit5195be912eb257c05a0c97e561e72f01af2583ff (patch)
treee47ab3981b495c675a987dd1e943d1f4c823f314 /bin/sh/eval.c
parent2fc7d7d1fa299368ccdddede67b31695266698bd (diff)
downloadFreeBSD-src-5195be912eb257c05a0c97e561e72f01af2583ff.zip
FreeBSD-src-5195be912eb257c05a0c97e561e72f01af2583ff.tar.gz
Merge of 4.4-Lite2 sh source, plus some gcc -Wall cleaning. This is a
merge of parallel duplicate work by Steve Price and myself. :-] There are some changes to the build that are my fault... mkinit.c was trying (poorly) to duplicate some of the work that make(1) is designed to do. The Makefile hackery is my fault too, the depend list was incomplete because of some explicit OBJS+= entries, so mkdep wasn't picking up their source file #includes. This closes a pile of /bin/sh PR's, but not all of them.. Submitted by: Steve Price <steve@bonsai.hiwaay.net>, peter
Diffstat (limited to 'bin/sh/eval.c')
-rw-r--r--bin/sh/eval.c220
1 files changed, 144 insertions, 76 deletions
diff --git a/bin/sh/eval.c b/bin/sh/eval.c
index 34417df..cfb0d0b 100644
--- a/bin/sh/eval.c
+++ b/bin/sh/eval.c
@@ -33,13 +33,16 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: eval.c,v 1.3 1995/05/30 00:07:11 rgrimes Exp $
+ * $Id: eval.c,v 1.4 1995/09/20 08:30:56 davidg Exp $
*/
#ifndef lint
-static char sccsid[] = "@(#)eval.c 8.1 (Berkeley) 5/31/93";
+static char sccsid[] = "@(#)eval.c 8.9 (Berkeley) 6/8/95";
#endif /* not lint */
+#include <signal.h>
+#include <unistd.h>
+
/*
* Evaluate a command.
*/
@@ -61,9 +64,11 @@ static char sccsid[] = "@(#)eval.c 8.1 (Berkeley) 5/31/93";
#include "var.h"
#include "memalloc.h"
#include "error.h"
+#include "show.h"
#include "mystring.h"
+#ifndef NO_HISTORY
#include "myhistedit.h"
-#include <signal.h>
+#endif
/* flags in argument to evaltree */
@@ -86,28 +91,17 @@ int funcnest; /* depth of function calls */
char *commandname;
struct strlist *cmdenviron;
int exitstatus; /* exit status of last command */
+int oexitstatus; /* saved exit status */
-#ifdef __STDC__
-STATIC void evalloop(union node *);
-STATIC void evalfor(union node *);
-STATIC void evalcase(union node *, int);
-STATIC void evalsubshell(union node *, int);
-STATIC void expredir(union node *);
-STATIC void evalpipe(union node *);
-STATIC void evalcommand(union node *, int, struct backcmd *);
-STATIC void prehash(union node *);
-#else
-STATIC void evalloop();
-STATIC void evalfor();
-STATIC void evalcase();
-STATIC void evalsubshell();
-STATIC void expredir();
-STATIC void evalpipe();
-STATIC void evalcommand();
-STATIC void prehash();
-#endif
-
+STATIC void evalloop __P((union node *));
+STATIC void evalfor __P((union node *));
+STATIC void evalcase __P((union node *, int));
+STATIC void evalsubshell __P((union node *, int));
+STATIC void expredir __P((union node *));
+STATIC void evalpipe __P((union node *));
+STATIC void evalcommand __P((union node *, int, struct backcmd *));
+STATIC void prehash __P((union node *));
/*
@@ -134,8 +128,10 @@ SHELLPROC {
* The eval commmand.
*/
-evalcmd(argc, argv)
- char **argv;
+int
+evalcmd(argc, argv)
+ int argc;
+ char **argv;
{
char *p;
char *concat;
@@ -193,14 +189,17 @@ evalstring(s)
void
evaltree(n, flags)
union node *n;
- {
+ int flags;
+{
if (n == NULL) {
TRACE(("evaltree(NULL) called\n"));
exitstatus = 0;
goto out;
}
+#ifndef NO_HISTORY
displayhist = 1; /* show history substitutions done with fc */
- TRACE(("evaltree(0x%x: %d) called\n", (int)n, n->type));
+#endif
+ TRACE(("evaltree(0x%lx: %d) called\n", (long)n, n->type));
switch (n->type) {
case NSEMI:
evaltree(n->nbinary.ch1, 0);
@@ -233,19 +232,17 @@ evaltree(n, flags)
evalsubshell(n, flags);
break;
case NIF: {
- int status = 0;
+ int status;
evaltree(n->nif.test, EV_TESTED);
+ status = exitstatus;
+ exitstatus = 0;
if (evalskip)
goto out;
- if (exitstatus == 0) {
+ if (status == 0)
evaltree(n->nif.ifpart, flags);
- status = exitstatus;
- } else if (n->nif.elsepart) {
+ else if (n->nif.elsepart)
evaltree(n->nif.elsepart, flags);
- status = exitstatus;
- }
- exitstatus = status;
break;
}
case NWHILE:
@@ -289,7 +286,7 @@ out:
STATIC void
evalloop(n)
union node *n;
- {
+{
int status;
loopnest++;
@@ -325,8 +322,8 @@ skipping: if (evalskip == SKIPCONT && --skipcount <= 0) {
STATIC void
evalfor(n)
- union node *n;
- {
+ union node *n;
+{
struct arglist arglist;
union node *argp;
struct strlist *sp;
@@ -335,6 +332,7 @@ evalfor(n)
setstackmark(&smark);
arglist.lastp = &arglist.list;
for (argp = n->nfor.args ; argp ; argp = argp->narg.next) {
+ oexitstatus = exitstatus;
expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
if (evalskip)
goto out;
@@ -366,7 +364,8 @@ out:
STATIC void
evalcase(n, flags)
union node *n;
- {
+ int flags;
+{
union node *cp;
union node *patp;
struct arglist arglist;
@@ -374,6 +373,7 @@ evalcase(n, flags)
setstackmark(&smark);
arglist.lastp = &arglist.list;
+ oexitstatus = exitstatus;
expandarg(n->ncase.expr, &arglist, EXP_TILDE);
for (cp = n->ncase.cases ; cp && evalskip == 0 ; cp = cp->nclist.next) {
for (patp = cp->nclist.pattern ; patp ; patp = patp->narg.next) {
@@ -398,7 +398,8 @@ out:
STATIC void
evalsubshell(n, flags)
union node *n;
- {
+ int flags;
+{
struct job *jp;
int backgnd = (n->type == NBACKGND);
@@ -426,17 +427,27 @@ evalsubshell(n, flags)
STATIC void
expredir(n)
union node *n;
- {
+{
register union node *redir;
for (redir = n ; redir ; redir = redir->nfile.next) {
- if (redir->type == NFROM
- || redir->type == NTO
- || redir->type == NAPPEND) {
- struct arglist fn;
- fn.lastp = &fn.list;
+ struct arglist fn;
+ fn.lastp = &fn.list;
+ oexitstatus = exitstatus;
+ switch (redir->type) {
+ case NFROM:
+ case NTO:
+ case NAPPEND:
expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR);
redir->nfile.expfname = fn.list->text;
+ break;
+ case NFROMFD:
+ case NTOFD:
+ if (redir->ndup.vname) {
+ expandarg(redir->ndup.vname, &fn, EXP_FULL | EXP_TILDE);
+ fixredir(redir, fn.list->text, 1);
+ }
+ break;
}
}
}
@@ -453,14 +464,14 @@ expredir(n)
STATIC void
evalpipe(n)
union node *n;
- {
+{
struct job *jp;
struct nodelist *lp;
int pipelen;
int prevfd;
int pip[2];
- TRACE(("evalpipe(0x%x) called\n", (int)n));
+ TRACE(("evalpipe(0x%lx) called\n", (long)n));
pipelen = 0;
for (lp = n->npipe.cmdlist ; lp ; lp = lp->next)
pipelen++;
@@ -520,7 +531,7 @@ void
evalbackcmd(n, result)
union node *n;
struct backcmd *result;
- {
+{
int pip[2];
struct job *jp;
struct stackmark smark; /* unnecessary */
@@ -530,12 +541,15 @@ evalbackcmd(n, result)
result->buf = NULL;
result->nleft = 0;
result->jp = NULL;
- exitstatus = 0;
- if (n == NULL)
+ if (n == NULL) {
+ exitstatus = 0;
goto out;
+ }
if (n->type == NCMD) {
+ exitstatus = oexitstatus;
evalcommand(n, EV_BACKCMD, result);
} else {
+ exitstatus = 0;
if (pipe(pip) < 0)
error("Pipe call failed");
jp = makejob(n, 1);
@@ -568,8 +582,9 @@ out:
STATIC void
evalcommand(cmd, flags, backcmd)
union node *cmd;
+ int flags;
struct backcmd *backcmd;
- {
+{
struct stackmark smark;
union node *argp;
struct arglist arglist;
@@ -579,7 +594,6 @@ evalcommand(cmd, flags, backcmd)
char **envp;
int varflag;
struct strlist *sp;
- register char *p;
int mode;
int pip[2];
struct cmdentry cmdentry;
@@ -591,15 +605,24 @@ evalcommand(cmd, flags, backcmd)
struct localvar *volatile savelocalvars;
volatile int e;
char *lastarg;
+#if __GNUC__
+ /* Avoid longjmp clobbering */
+ (void) &argv;
+ (void) &argc;
+ (void) &lastarg;
+ (void) &flags;
+#endif
/* First expand the arguments. */
- TRACE(("evalcommand(0x%x, %d) called\n", (int)cmd, flags));
+ TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
setstackmark(&smark);
arglist.lastp = &arglist.list;
varlist.lastp = &varlist.list;
varflag = 1;
+ oexitstatus = exitstatus;
+ exitstatus = 0;
for (argp = cmd->ncmd.args ; argp ; argp = argp->narg.next) {
- p = argp->narg.text;
+ char *p = argp->narg.text;
if (varflag && is_name(*p)) {
do {
p++;
@@ -650,9 +673,20 @@ evalcommand(cmd, flags, backcmd)
cmdentry.cmdtype = CMDBUILTIN;
cmdentry.u.index = BLTINCMD;
} else {
- find_command(argv[0], &cmdentry, 1);
+ static const char PATH[] = "PATH=";
+ char *path = pathval();
+
+ /*
+ * Modify the command lookup path, if a PATH= assignment
+ * is present
+ */
+ for (sp = varlist.list ; sp ; sp = sp->next)
+ if (strncmp(sp->text, PATH, sizeof(PATH) - 1) == 0)
+ path = sp->text + sizeof(PATH) - 1;
+
+ find_command(argv[0], &cmdentry, 1, path);
if (cmdentry.cmdtype == CMDUNKNOWN) { /* command not found */
- exitstatus = 2;
+ exitstatus = 1;
flushout(&errout);
return;
}
@@ -664,7 +698,7 @@ evalcommand(cmd, flags, backcmd)
break;
if ((cmdentry.u.index = find_builtin(*argv)) < 0) {
outfmt(&errout, "%s: not found\n", *argv);
- exitstatus = 2;
+ exitstatus = 1;
flushout(&errout);
return;
}
@@ -676,11 +710,11 @@ evalcommand(cmd, flags, backcmd)
/* Fork off a child process if necessary. */
if (cmd->ncmd.backgnd
- || cmdentry.cmdtype == CMDNORMAL && (flags & EV_EXIT) == 0
- || (flags & EV_BACKCMD) != 0
+ || (cmdentry.cmdtype == CMDNORMAL && (flags & EV_EXIT) == 0)
+ || ((flags & EV_BACKCMD) != 0
&& (cmdentry.cmdtype != CMDBUILTIN
|| cmdentry.u.index == DOTCMD
- || cmdentry.u.index == EVALCMD)) {
+ || cmdentry.u.index == EVALCMD))) {
jp = makejob(cmd, 1);
mode = cmd->ncmd.backgnd;
if (flags & EV_BACKCMD) {
@@ -789,7 +823,9 @@ cmddone:
if (e != EXERROR || cmdentry.u.index == BLTINCMD
|| cmdentry.u.index == DOTCMD
|| cmdentry.u.index == EVALCMD
+#ifndef NO_HISTORY
|| cmdentry.u.index == HISTCMD
+#endif
|| cmdentry.u.index == EXECCMD)
exraise(e);
FORCEINTON;
@@ -805,16 +841,10 @@ cmddone:
trputs("normal command: "); trargs(argv);
clearredir();
redirect(cmd->ncmd.redirect, 0);
- if (varlist.list) {
- p = stalloc(strlen(pathval()) + 1);
- scopy(pathval(), p);
- } else {
- p = pathval();
- }
for (sp = varlist.list ; sp ; sp = sp->next)
setvareq(sp->text, VEXPORT|VSTACK);
envp = environment();
- shellexec(argv, envp, p, cmdentry.u.index);
+ shellexec(argv, envp, pathval(), cmdentry.u.index);
/*NOTREACHED*/
}
goto out;
@@ -848,12 +878,13 @@ out:
STATIC void
prehash(n)
union node *n;
- {
+{
struct cmdentry entry;
- if (n->type == NCMD && n->ncmd.args &&
- goodname(n->ncmd.args->narg.text))
- find_command(n->ncmd.args->narg.text, &entry, 0);
+ if (n->type == NCMD && n->ncmd.args)
+ if (goodname(n->ncmd.args->narg.text))
+ find_command(n->ncmd.args->narg.text, &entry, 0,
+ pathval());
}
@@ -868,8 +899,16 @@ prehash(n)
* specified variables.
*/
-bltincmd(argc, argv) char **argv; {
+int
+bltincmd(argc, argv)
+ int argc;
+ char **argv;
+{
listsetvar(cmdenviron);
+ /*
+ * Preserve exitstatus of a previous possible redirection
+ * as POSIX mandates
+ */
return exitstatus;
}
@@ -885,7 +924,11 @@ bltincmd(argc, argv) char **argv; {
* in the standard shell so we don't make it one here.
*/
-breakcmd(argc, argv) char **argv; {
+int
+breakcmd(argc, argv)
+ int argc;
+ char **argv;
+{
int n;
n = 1;
@@ -905,7 +948,11 @@ breakcmd(argc, argv) char **argv; {
* The return command.
*/
-returncmd(argc, argv) char **argv; {
+int
+returncmd(argc, argv)
+ int argc;
+ char **argv;
+{
int ret;
ret = exitstatus;
@@ -919,16 +966,37 @@ returncmd(argc, argv) char **argv; {
}
-truecmd(argc, argv) char **argv; {
+int
+falsecmd(argc, argv)
+ int argc;
+ char **argv;
+{
+ return 1;
+}
+
+
+int
+truecmd(argc, argv)
+ int argc;
+ char **argv;
+{
return 0;
}
-execcmd(argc, argv) char **argv; {
+int
+execcmd(argc, argv)
+ int argc;
+ char **argv;
+{
if (argc > 1) {
+ struct strlist *sp;
+
iflag = 0; /* exit on error */
mflag = 0;
optschanged();
+ for (sp = cmdenviron; sp ; sp = sp->next)
+ setvareq(sp->text, VEXPORT|VSTACK);
shellexec(argv + 1, environment(), pathval(), 0);
}
OpenPOWER on IntegriCloud