xref: /freebsd/bin/sh/eval.c (revision f0adf7f5cdd241db2f2c817683191a6ef64a4e95)
1 /*-
2  * Copyright (c) 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Kenneth Almquist.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 4. Neither the name of the University nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32 
33 #ifndef lint
34 #if 0
35 static char sccsid[] = "@(#)eval.c	8.9 (Berkeley) 6/8/95";
36 #endif
37 #endif /* not lint */
38 #include <sys/cdefs.h>
39 __FBSDID("$FreeBSD$");
40 
41 #include <paths.h>
42 #include <signal.h>
43 #include <stdlib.h>
44 #include <unistd.h>
45 #include <sys/wait.h> /* For WIFSIGNALED(status) */
46 #include <errno.h>
47 
48 /*
49  * Evaluate a command.
50  */
51 
52 #include "shell.h"
53 #include "nodes.h"
54 #include "syntax.h"
55 #include "expand.h"
56 #include "parser.h"
57 #include "jobs.h"
58 #include "eval.h"
59 #include "builtins.h"
60 #include "options.h"
61 #include "exec.h"
62 #include "redir.h"
63 #include "input.h"
64 #include "output.h"
65 #include "trap.h"
66 #include "var.h"
67 #include "memalloc.h"
68 #include "error.h"
69 #include "show.h"
70 #include "mystring.h"
71 #ifndef NO_HISTORY
72 #include "myhistedit.h"
73 #endif
74 
75 
76 /* flags in argument to evaltree */
77 #define EV_EXIT 01		/* exit after evaluating tree */
78 #define EV_TESTED 02		/* exit status is checked; ignore -e flag */
79 #define EV_BACKCMD 04		/* command executing within back quotes */
80 
81 MKINIT int evalskip;		/* set if we are skipping commands */
82 STATIC int skipcount;		/* number of levels to skip */
83 MKINIT int loopnest;		/* current loop nesting level */
84 int funcnest;			/* depth of function calls */
85 
86 
87 char *commandname;
88 struct strlist *cmdenviron;
89 int exitstatus;			/* exit status of last command */
90 int oexitstatus;		/* saved exit status */
91 
92 
93 STATIC void evalloop(union node *);
94 STATIC void evalfor(union node *);
95 STATIC void evalcase(union node *, int);
96 STATIC void evalsubshell(union node *, int);
97 STATIC void expredir(union node *);
98 STATIC void evalpipe(union node *);
99 STATIC void evalcommand(union node *, int, struct backcmd *);
100 STATIC void prehash(union node *);
101 
102 
103 /*
104  * Called to reset things after an exception.
105  */
106 
107 #ifdef mkinit
108 INCLUDE "eval.h"
109 
110 RESET {
111 	evalskip = 0;
112 	loopnest = 0;
113 	funcnest = 0;
114 }
115 
116 SHELLPROC {
117 	exitstatus = 0;
118 }
119 #endif
120 
121 
122 
123 /*
124  * The eval command.
125  */
126 
127 int
128 evalcmd(int argc, char **argv)
129 {
130         char *p;
131         char *concat;
132         char **ap;
133 
134         if (argc > 1) {
135                 p = argv[1];
136                 if (argc > 2) {
137                         STARTSTACKSTR(concat);
138                         ap = argv + 2;
139                         for (;;) {
140                                 while (*p)
141                                         STPUTC(*p++, concat);
142                                 if ((p = *ap++) == NULL)
143                                         break;
144                                 STPUTC(' ', concat);
145                         }
146                         STPUTC('\0', concat);
147                         p = grabstackstr(concat);
148                 }
149                 evalstring(p);
150         }
151         return exitstatus;
152 }
153 
154 
155 /*
156  * Execute a command or commands contained in a string.
157  */
158 
159 void
160 evalstring(char *s)
161 {
162 	union node *n;
163 	struct stackmark smark;
164 
165 	setstackmark(&smark);
166 	setinputstring(s, 1);
167 	while ((n = parsecmd(0)) != NEOF) {
168 		evaltree(n, 0);
169 		popstackmark(&smark);
170 	}
171 	popfile();
172 	popstackmark(&smark);
173 }
174 
175 
176 
177 /*
178  * Evaluate a parse tree.  The value is left in the global variable
179  * exitstatus.
180  */
181 
182 void
183 evaltree(union node *n, int flags)
184 {
185 	if (n == NULL) {
186 		TRACE(("evaltree(NULL) called\n"));
187 		exitstatus = 0;
188 		goto out;
189 	}
190 #ifndef NO_HISTORY
191 	displayhist = 1;	/* show history substitutions done with fc */
192 #endif
193 	TRACE(("evaltree(0x%lx: %d) called\n", (long)n, n->type));
194 	switch (n->type) {
195 	case NSEMI:
196 		evaltree(n->nbinary.ch1, 0);
197 		if (evalskip)
198 			goto out;
199 		evaltree(n->nbinary.ch2, flags);
200 		break;
201 	case NAND:
202 		evaltree(n->nbinary.ch1, EV_TESTED);
203 		if (evalskip || exitstatus != 0) {
204 			goto out;
205 		}
206 		evaltree(n->nbinary.ch2, flags);
207 		break;
208 	case NOR:
209 		evaltree(n->nbinary.ch1, EV_TESTED);
210 		if (evalskip || exitstatus == 0)
211 			goto out;
212 		evaltree(n->nbinary.ch2, flags);
213 		break;
214 	case NREDIR:
215 		expredir(n->nredir.redirect);
216 		redirect(n->nredir.redirect, REDIR_PUSH);
217 		evaltree(n->nredir.n, flags);
218 		popredir();
219 		break;
220 	case NSUBSHELL:
221 		evalsubshell(n, flags);
222 		break;
223 	case NBACKGND:
224 		evalsubshell(n, flags);
225 		break;
226 	case NIF: {
227 		evaltree(n->nif.test, EV_TESTED);
228 		if (evalskip)
229 			goto out;
230 		if (exitstatus == 0)
231 			evaltree(n->nif.ifpart, flags);
232 		else if (n->nif.elsepart)
233 			evaltree(n->nif.elsepart, flags);
234 		else
235 			exitstatus = 0;
236 		break;
237 	}
238 	case NWHILE:
239 	case NUNTIL:
240 		evalloop(n);
241 		break;
242 	case NFOR:
243 		evalfor(n);
244 		break;
245 	case NCASE:
246 		evalcase(n, flags);
247 		break;
248 	case NDEFUN:
249 		defun(n->narg.text, n->narg.next);
250 		exitstatus = 0;
251 		break;
252 	case NNOT:
253 		evaltree(n->nnot.com, EV_TESTED);
254 		exitstatus = !exitstatus;
255 		break;
256 
257 	case NPIPE:
258 		evalpipe(n);
259 		break;
260 	case NCMD:
261 		evalcommand(n, flags, (struct backcmd *)NULL);
262 		break;
263 	default:
264 		out1fmt("Node type = %d\n", n->type);
265 		flushout(&output);
266 		break;
267 	}
268 out:
269 	if (pendingsigs)
270 		dotrap();
271 	if ((flags & EV_EXIT) || (eflag && exitstatus
272 	    && !(flags & EV_TESTED) && (n->type == NCMD ||
273 	    n->type == NSUBSHELL)))
274 		exitshell(exitstatus);
275 }
276 
277 
278 STATIC void
279 evalloop(union node *n)
280 {
281 	int status;
282 
283 	loopnest++;
284 	status = 0;
285 	for (;;) {
286 		evaltree(n->nbinary.ch1, EV_TESTED);
287 		if (evalskip) {
288 skipping:	  if (evalskip == SKIPCONT && --skipcount <= 0) {
289 				evalskip = 0;
290 				continue;
291 			}
292 			if (evalskip == SKIPBREAK && --skipcount <= 0)
293 				evalskip = 0;
294 			break;
295 		}
296 		if (n->type == NWHILE) {
297 			if (exitstatus != 0)
298 				break;
299 		} else {
300 			if (exitstatus == 0)
301 				break;
302 		}
303 		evaltree(n->nbinary.ch2, 0);
304 		status = exitstatus;
305 		if (evalskip)
306 			goto skipping;
307 	}
308 	loopnest--;
309 	exitstatus = status;
310 }
311 
312 
313 
314 STATIC void
315 evalfor(union node *n)
316 {
317 	struct arglist arglist;
318 	union node *argp;
319 	struct strlist *sp;
320 	struct stackmark smark;
321 
322 	setstackmark(&smark);
323 	arglist.lastp = &arglist.list;
324 	for (argp = n->nfor.args ; argp ; argp = argp->narg.next) {
325 		oexitstatus = exitstatus;
326 		expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
327 		if (evalskip)
328 			goto out;
329 	}
330 	*arglist.lastp = NULL;
331 
332 	exitstatus = 0;
333 	loopnest++;
334 	for (sp = arglist.list ; sp ; sp = sp->next) {
335 		setvar(n->nfor.var, sp->text, 0);
336 		evaltree(n->nfor.body, 0);
337 		if (evalskip) {
338 			if (evalskip == SKIPCONT && --skipcount <= 0) {
339 				evalskip = 0;
340 				continue;
341 			}
342 			if (evalskip == SKIPBREAK && --skipcount <= 0)
343 				evalskip = 0;
344 			break;
345 		}
346 	}
347 	loopnest--;
348 out:
349 	popstackmark(&smark);
350 }
351 
352 
353 
354 STATIC void
355 evalcase(union node *n, int flags)
356 {
357 	union node *cp;
358 	union node *patp;
359 	struct arglist arglist;
360 	struct stackmark smark;
361 
362 	setstackmark(&smark);
363 	arglist.lastp = &arglist.list;
364 	oexitstatus = exitstatus;
365 	expandarg(n->ncase.expr, &arglist, EXP_TILDE);
366 	for (cp = n->ncase.cases ; cp && evalskip == 0 ; cp = cp->nclist.next) {
367 		for (patp = cp->nclist.pattern ; patp ; patp = patp->narg.next) {
368 			if (casematch(patp, arglist.list->text)) {
369 				if (evalskip == 0) {
370 					evaltree(cp->nclist.body, flags);
371 				}
372 				goto out;
373 			}
374 		}
375 	}
376 out:
377 	popstackmark(&smark);
378 }
379 
380 
381 
382 /*
383  * Kick off a subshell to evaluate a tree.
384  */
385 
386 STATIC void
387 evalsubshell(union node *n, int flags)
388 {
389 	struct job *jp;
390 	int backgnd = (n->type == NBACKGND);
391 
392 	expredir(n->nredir.redirect);
393 	jp = makejob(n, 1);
394 	if (forkshell(jp, n, backgnd) == 0) {
395 		if (backgnd)
396 			flags &=~ EV_TESTED;
397 		redirect(n->nredir.redirect, 0);
398 		evaltree(n->nredir.n, flags | EV_EXIT);	/* never returns */
399 	}
400 	if (! backgnd) {
401 		INTOFF;
402 		exitstatus = waitforjob(jp, (int *)NULL);
403 		INTON;
404 	}
405 }
406 
407 
408 
409 /*
410  * Compute the names of the files in a redirection list.
411  */
412 
413 STATIC void
414 expredir(union node *n)
415 {
416 	union node *redir;
417 
418 	for (redir = n ; redir ; redir = redir->nfile.next) {
419 		struct arglist fn;
420 		fn.lastp = &fn.list;
421 		oexitstatus = exitstatus;
422 		switch (redir->type) {
423 		case NFROM:
424 		case NTO:
425 		case NFROMTO:
426 		case NAPPEND:
427 		case NCLOBBER:
428 			expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR);
429 			redir->nfile.expfname = fn.list->text;
430 			break;
431 		case NFROMFD:
432 		case NTOFD:
433 			if (redir->ndup.vname) {
434 				expandarg(redir->ndup.vname, &fn, EXP_FULL | EXP_TILDE);
435 				fixredir(redir, fn.list->text, 1);
436 			}
437 			break;
438 		}
439 	}
440 }
441 
442 
443 
444 /*
445  * Evaluate a pipeline.  All the processes in the pipeline are children
446  * of the process creating the pipeline.  (This differs from some versions
447  * of the shell, which make the last process in a pipeline the parent
448  * of all the rest.)
449  */
450 
451 STATIC void
452 evalpipe(union node *n)
453 {
454 	struct job *jp;
455 	struct nodelist *lp;
456 	int pipelen;
457 	int prevfd;
458 	int pip[2];
459 
460 	TRACE(("evalpipe(0x%lx) called\n", (long)n));
461 	pipelen = 0;
462 	for (lp = n->npipe.cmdlist ; lp ; lp = lp->next)
463 		pipelen++;
464 	INTOFF;
465 	jp = makejob(n, pipelen);
466 	prevfd = -1;
467 	for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
468 		prehash(lp->n);
469 		pip[1] = -1;
470 		if (lp->next) {
471 			if (pipe(pip) < 0) {
472 				close(prevfd);
473 				error("Pipe call failed: %s", strerror(errno));
474 			}
475 		}
476 		if (forkshell(jp, lp->n, n->npipe.backgnd) == 0) {
477 			INTON;
478 			if (prevfd > 0) {
479 				dup2(prevfd, 0);
480 				close(prevfd);
481 			}
482 			if (pip[1] >= 0) {
483 				if (!(prevfd >= 0 && pip[0] == 0))
484 					close(pip[0]);
485 				if (pip[1] != 1) {
486 					dup2(pip[1], 1);
487 					close(pip[1]);
488 				}
489 			}
490 			evaltree(lp->n, EV_EXIT);
491 		}
492 		if (prevfd >= 0)
493 			close(prevfd);
494 		prevfd = pip[0];
495 		close(pip[1]);
496 	}
497 	INTON;
498 	if (n->npipe.backgnd == 0) {
499 		INTOFF;
500 		exitstatus = waitforjob(jp, (int *)NULL);
501 		TRACE(("evalpipe:  job done exit status %d\n", exitstatus));
502 		INTON;
503 	}
504 }
505 
506 
507 
508 /*
509  * Execute a command inside back quotes.  If it's a builtin command, we
510  * want to save its output in a block obtained from malloc.  Otherwise
511  * we fork off a subprocess and get the output of the command via a pipe.
512  * Should be called with interrupts off.
513  */
514 
515 void
516 evalbackcmd(union node *n, struct backcmd *result)
517 {
518 	int pip[2];
519 	struct job *jp;
520 	struct stackmark smark;		/* unnecessary */
521 
522 	setstackmark(&smark);
523 	result->fd = -1;
524 	result->buf = NULL;
525 	result->nleft = 0;
526 	result->jp = NULL;
527 	if (n == NULL) {
528 		exitstatus = 0;
529 		goto out;
530 	}
531 	if (n->type == NCMD) {
532 		exitstatus = oexitstatus;
533 		evalcommand(n, EV_BACKCMD, result);
534 	} else {
535 		exitstatus = 0;
536 		if (pipe(pip) < 0)
537 			error("Pipe call failed: %s", strerror(errno));
538 		jp = makejob(n, 1);
539 		if (forkshell(jp, n, FORK_NOJOB) == 0) {
540 			FORCEINTON;
541 			close(pip[0]);
542 			if (pip[1] != 1) {
543 				dup2(pip[1], 1);
544 				close(pip[1]);
545 			}
546 			evaltree(n, EV_EXIT);
547 		}
548 		close(pip[1]);
549 		result->fd = pip[0];
550 		result->jp = jp;
551 	}
552 out:
553 	popstackmark(&smark);
554 	TRACE(("evalbackcmd done: fd=%d buf=%p nleft=%d jp=%p\n",
555 		result->fd, result->buf, result->nleft, result->jp));
556 }
557 
558 
559 
560 /*
561  * Execute a simple command.
562  */
563 
564 STATIC void
565 evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
566 {
567 	struct stackmark smark;
568 	union node *argp;
569 	struct arglist arglist;
570 	struct arglist varlist;
571 	char **argv;
572 	int argc;
573 	char **envp;
574 	int varflag;
575 	struct strlist *sp;
576 	int mode;
577 	int pip[2];
578 	struct cmdentry cmdentry;
579 	struct job *jp;
580 	struct jmploc jmploc;
581 	struct jmploc *volatile savehandler;
582 	char *volatile savecmdname;
583 	volatile struct shparam saveparam;
584 	struct localvar *volatile savelocalvars;
585 	volatile int e;
586 	char *lastarg;
587 	int realstatus;
588 	int do_clearcmdentry;
589 #if __GNUC__
590 	/* Avoid longjmp clobbering */
591 	(void) &argv;
592 	(void) &argc;
593 	(void) &lastarg;
594 	(void) &flags;
595 	(void) &do_clearcmdentry;
596 #endif
597 
598 	/* First expand the arguments. */
599 	TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
600 	setstackmark(&smark);
601 	arglist.lastp = &arglist.list;
602 	varlist.lastp = &varlist.list;
603 	varflag = 1;
604 	do_clearcmdentry = 0;
605 	oexitstatus = exitstatus;
606 	exitstatus = 0;
607 	for (argp = cmd->ncmd.args ; argp ; argp = argp->narg.next) {
608 		char *p = argp->narg.text;
609 		if (varflag && is_name(*p)) {
610 			do {
611 				p++;
612 			} while (is_in_name(*p));
613 			if (*p == '=') {
614 				expandarg(argp, &varlist, EXP_VARTILDE);
615 				continue;
616 			}
617 		}
618 		expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
619 		varflag = 0;
620 	}
621 	*arglist.lastp = NULL;
622 	*varlist.lastp = NULL;
623 	expredir(cmd->ncmd.redirect);
624 	argc = 0;
625 	for (sp = arglist.list ; sp ; sp = sp->next)
626 		argc++;
627 	argv = stalloc(sizeof (char *) * (argc + 1));
628 
629 	for (sp = arglist.list ; sp ; sp = sp->next) {
630 		TRACE(("evalcommand arg: %s\n", sp->text));
631 		*argv++ = sp->text;
632 	}
633 	*argv = NULL;
634 	lastarg = NULL;
635 	if (iflag && funcnest == 0 && argc > 0)
636 		lastarg = argv[-1];
637 	argv -= argc;
638 
639 	/* Print the command if xflag is set. */
640 	if (xflag) {
641 		outc('+', &errout);
642 		for (sp = varlist.list ; sp ; sp = sp->next) {
643 			outc(' ', &errout);
644 			out2str(sp->text);
645 		}
646 		for (sp = arglist.list ; sp ; sp = sp->next) {
647 			outc(' ', &errout);
648 			out2str(sp->text);
649 		}
650 		outc('\n', &errout);
651 		flushout(&errout);
652 	}
653 
654 	/* Now locate the command. */
655 	if (argc == 0) {
656 		cmdentry.cmdtype = CMDBUILTIN;
657 		cmdentry.u.index = BLTINCMD;
658 	} else {
659 		static const char PATH[] = "PATH=";
660 		char *path = pathval();
661 
662 		/*
663 		 * Modify the command lookup path, if a PATH= assignment
664 		 * is present
665 		 */
666 		for (sp = varlist.list ; sp ; sp = sp->next)
667 			if (strncmp(sp->text, PATH, sizeof(PATH) - 1) == 0) {
668 				path = sp->text + sizeof(PATH) - 1;
669 				/*
670 				 * On `PATH=... command`, we need to make
671 				 * sure that the command isn't using the
672 				 * non-updated hash table of the outer PATH
673 				 * setting and we need to make sure that
674 				 * the hash table isn't filled with items
675 				 * from the temporary setting.
676 				 *
677 				 * It would be better to forbit using and
678 				 * updating the table while this command
679 				 * runs, by the command finding mechanism
680 				 * is heavily integrated with hash handling,
681 				 * so we just delete the hash before and after
682 				 * the command runs. Partly deleting like
683 				 * changepatch() does doesn't seem worth the
684 				 * bookinging effort, since most such runs add
685 				 * directories in front of the new PATH.
686 				 */
687 				clearcmdentry(0);
688 				do_clearcmdentry = 1;
689 			}
690 
691 		find_command(argv[0], &cmdentry, 1, path);
692 		if (cmdentry.cmdtype == CMDUNKNOWN) {	/* command not found */
693 			exitstatus = 127;
694 			flushout(&errout);
695 			return;
696 		}
697 		/* implement the bltin builtin here */
698 		if (cmdentry.cmdtype == CMDBUILTIN && cmdentry.u.index == BLTINCMD) {
699 			for (;;) {
700 				argv++;
701 				if (--argc == 0)
702 					break;
703 				if ((cmdentry.u.index = find_builtin(*argv)) < 0) {
704 					outfmt(&errout, "%s: not found\n", *argv);
705 					exitstatus = 127;
706 					flushout(&errout);
707 					return;
708 				}
709 				if (cmdentry.u.index != BLTINCMD)
710 					break;
711 			}
712 		}
713 	}
714 
715 	/* Fork off a child process if necessary. */
716 	if (cmd->ncmd.backgnd
717 	 || (cmdentry.cmdtype == CMDNORMAL
718 	    && ((flags & EV_EXIT) == 0 || Tflag))
719 	 || ((flags & EV_BACKCMD) != 0
720 	    && (cmdentry.cmdtype != CMDBUILTIN
721 		 || cmdentry.u.index == CDCMD
722 		 || cmdentry.u.index == DOTCMD
723 		 || cmdentry.u.index == EVALCMD))
724 	 || (cmdentry.cmdtype == CMDBUILTIN &&
725 	    cmdentry.u.index == COMMANDCMD)) {
726 		jp = makejob(cmd, 1);
727 		mode = cmd->ncmd.backgnd;
728 		if (flags & EV_BACKCMD) {
729 			mode = FORK_NOJOB;
730 			if (pipe(pip) < 0)
731 				error("Pipe call failed: %s", strerror(errno));
732 		}
733 		if (forkshell(jp, cmd, mode) != 0)
734 			goto parent;	/* at end of routine */
735 		if (flags & EV_BACKCMD) {
736 			FORCEINTON;
737 			close(pip[0]);
738 			if (pip[1] != 1) {
739 				dup2(pip[1], 1);
740 				close(pip[1]);
741 			}
742 		}
743 		flags |= EV_EXIT;
744 	}
745 
746 	/* This is the child process if a fork occurred. */
747 	/* Execute the command. */
748 	if (cmdentry.cmdtype == CMDFUNCTION) {
749 #ifdef DEBUG
750 		trputs("Shell function:  ");  trargs(argv);
751 #endif
752 		redirect(cmd->ncmd.redirect, REDIR_PUSH);
753 		saveparam = shellparam;
754 		shellparam.malloc = 0;
755 		shellparam.reset = 1;
756 		shellparam.nparam = argc - 1;
757 		shellparam.p = argv + 1;
758 		shellparam.optnext = NULL;
759 		INTOFF;
760 		savelocalvars = localvars;
761 		localvars = NULL;
762 		INTON;
763 		if (setjmp(jmploc.loc)) {
764 			if (exception == EXSHELLPROC)
765 				freeparam((struct shparam *)&saveparam);
766 			else {
767 				freeparam(&shellparam);
768 				shellparam = saveparam;
769 			}
770 			poplocalvars();
771 			localvars = savelocalvars;
772 			handler = savehandler;
773 			longjmp(handler->loc, 1);
774 		}
775 		savehandler = handler;
776 		handler = &jmploc;
777 		for (sp = varlist.list ; sp ; sp = sp->next)
778 			mklocal(sp->text);
779 		funcnest++;
780 		if (flags & EV_TESTED)
781 			evaltree(cmdentry.u.func, EV_TESTED);
782 		else
783 			evaltree(cmdentry.u.func, 0);
784 		funcnest--;
785 		INTOFF;
786 		poplocalvars();
787 		localvars = savelocalvars;
788 		freeparam(&shellparam);
789 		shellparam = saveparam;
790 		handler = savehandler;
791 		popredir();
792 		INTON;
793 		if (evalskip == SKIPFUNC) {
794 			evalskip = 0;
795 			skipcount = 0;
796 		}
797 		if (flags & EV_EXIT)
798 			exitshell(exitstatus);
799 	} else if (cmdentry.cmdtype == CMDBUILTIN) {
800 #ifdef DEBUG
801 		trputs("builtin command:  ");  trargs(argv);
802 #endif
803 		mode = (cmdentry.u.index == EXECCMD)? 0 : REDIR_PUSH;
804 		if (flags == EV_BACKCMD) {
805 			memout.nleft = 0;
806 			memout.nextc = memout.buf;
807 			memout.bufsize = 64;
808 			mode |= REDIR_BACKQ;
809 		}
810 		redirect(cmd->ncmd.redirect, mode);
811 		savecmdname = commandname;
812 		cmdenviron = varlist.list;
813 		e = -1;
814 		if (setjmp(jmploc.loc)) {
815 			e = exception;
816 			exitstatus = (e == EXINT)? SIGINT+128 : 2;
817 			goto cmddone;
818 		}
819 		savehandler = handler;
820 		handler = &jmploc;
821 		commandname = argv[0];
822 		argptr = argv + 1;
823 		optptr = NULL;			/* initialize nextopt */
824 		exitstatus = (*builtinfunc[cmdentry.u.index])(argc, argv);
825 		flushall();
826 cmddone:
827 		cmdenviron = NULL;
828 		out1 = &output;
829 		out2 = &errout;
830 		freestdout();
831 		if (e != EXSHELLPROC) {
832 			commandname = savecmdname;
833 			if (flags & EV_EXIT) {
834 				exitshell(exitstatus);
835 			}
836 		}
837 		handler = savehandler;
838 		if (e != -1) {
839 			if ((e != EXERROR && e != EXEXEC)
840 			   || cmdentry.u.index == BLTINCMD
841 			   || cmdentry.u.index == DOTCMD
842 			   || cmdentry.u.index == EVALCMD
843 #ifndef NO_HISTORY
844 			   || cmdentry.u.index == HISTCMD
845 #endif
846 			   || cmdentry.u.index == EXECCMD
847 			   || cmdentry.u.index == COMMANDCMD)
848 				exraise(e);
849 			FORCEINTON;
850 		}
851 		if (cmdentry.u.index != EXECCMD)
852 			popredir();
853 		if (flags == EV_BACKCMD) {
854 			backcmd->buf = memout.buf;
855 			backcmd->nleft = memout.nextc - memout.buf;
856 			memout.buf = NULL;
857 		}
858 	} else {
859 #ifdef DEBUG
860 		trputs("normal command:  ");  trargs(argv);
861 #endif
862 		clearredir();
863 		redirect(cmd->ncmd.redirect, 0);
864 		for (sp = varlist.list ; sp ; sp = sp->next)
865 			setvareq(sp->text, VEXPORT|VSTACK);
866 		envp = environment();
867 		shellexec(argv, envp, pathval(), cmdentry.u.index);
868 		/*NOTREACHED*/
869 	}
870 	goto out;
871 
872 parent:	/* parent process gets here (if we forked) */
873 	if (mode == 0) {	/* argument to fork */
874 		INTOFF;
875 		exitstatus = waitforjob(jp, &realstatus);
876 		INTON;
877 		if (iflag && loopnest > 0 && WIFSIGNALED(realstatus)) {
878 			evalskip = SKIPBREAK;
879 			skipcount = loopnest;
880 		}
881 	} else if (mode == 2) {
882 		backcmd->fd = pip[0];
883 		close(pip[1]);
884 		backcmd->jp = jp;
885 	}
886 
887 out:
888 	if (lastarg)
889 		setvar("_", lastarg, 0);
890 	if (do_clearcmdentry)
891 		clearcmdentry(0);
892 	popstackmark(&smark);
893 }
894 
895 
896 
897 /*
898  * Search for a command.  This is called before we fork so that the
899  * location of the command will be available in the parent as well as
900  * the child.  The check for "goodname" is an overly conservative
901  * check that the name will not be subject to expansion.
902  */
903 
904 STATIC void
905 prehash(union node *n)
906 {
907 	struct cmdentry entry;
908 
909 	if (n->type == NCMD && n->ncmd.args)
910 		if (goodname(n->ncmd.args->narg.text))
911 			find_command(n->ncmd.args->narg.text, &entry, 0,
912 				     pathval());
913 }
914 
915 
916 
917 /*
918  * Builtin commands.  Builtin commands whose functions are closely
919  * tied to evaluation are implemented here.
920  */
921 
922 /*
923  * No command given, or a bltin command with no arguments.  Set the
924  * specified variables.
925  */
926 
927 int
928 bltincmd(int argc __unused, char **argv __unused)
929 {
930 	listsetvar(cmdenviron);
931 	/*
932 	 * Preserve exitstatus of a previous possible redirection
933 	 * as POSIX mandates
934 	 */
935 	return exitstatus;
936 }
937 
938 
939 /*
940  * Handle break and continue commands.  Break, continue, and return are
941  * all handled by setting the evalskip flag.  The evaluation routines
942  * above all check this flag, and if it is set they start skipping
943  * commands rather than executing them.  The variable skipcount is
944  * the number of loops to break/continue, or the number of function
945  * levels to return.  (The latter is always 1.)  It should probably
946  * be an error to break out of more loops than exist, but it isn't
947  * in the standard shell so we don't make it one here.
948  */
949 
950 int
951 breakcmd(int argc, char **argv)
952 {
953 	int n = argc > 1 ? number(argv[1]) : 1;
954 
955 	if (n > loopnest)
956 		n = loopnest;
957 	if (n > 0) {
958 		evalskip = (**argv == 'c')? SKIPCONT : SKIPBREAK;
959 		skipcount = n;
960 	}
961 	return 0;
962 }
963 
964 /*
965  * The `command' command.
966  */
967 int
968 commandcmd(int argc, char **argv)
969 {
970 	static char stdpath[] = _PATH_STDPATH;
971 	struct jmploc loc, *old;
972 	struct strlist *sp;
973 	char *path;
974 	int ch;
975 
976 	for (sp = cmdenviron; sp ; sp = sp->next)
977 		setvareq(sp->text, VEXPORT|VSTACK);
978 	path = pathval();
979 
980 	optind = optreset = 1;
981 	opterr = 0;
982 	while ((ch = getopt(argc, argv, "p")) != -1) {
983 		switch (ch) {
984 		case 'p':
985 			path = stdpath;
986 			break;
987 		case '?':
988 		default:
989 			error("unknown option: -%c", optopt);
990 		}
991 	}
992 	argc -= optind;
993 	argv += optind;
994 
995 	if (argc != 0) {
996 		old = handler;
997 		handler = &loc;
998 		if (setjmp(handler->loc) == 0)
999 			shellexec(argv, environment(), path, 0);
1000 		handler = old;
1001 		if (exception == EXEXEC)
1002 			exit(exerrno);
1003 		exraise(exception);
1004 	}
1005 
1006 	/*
1007 	 * Do nothing successfully if no command was specified;
1008 	 * ksh also does this.
1009 	 */
1010 	exit(0);
1011 }
1012 
1013 
1014 /*
1015  * The return command.
1016  */
1017 
1018 int
1019 returncmd(int argc, char **argv)
1020 {
1021 	int ret = argc > 1 ? number(argv[1]) : oexitstatus;
1022 
1023 	if (funcnest) {
1024 		evalskip = SKIPFUNC;
1025 		skipcount = 1;
1026 	} else {
1027 		/* skip the rest of the file */
1028 		evalskip = SKIPFILE;
1029 		skipcount = 1;
1030 	}
1031 	return ret;
1032 }
1033 
1034 
1035 int
1036 falsecmd(int argc __unused, char **argv __unused)
1037 {
1038 	return 1;
1039 }
1040 
1041 
1042 int
1043 truecmd(int argc __unused, char **argv __unused)
1044 {
1045 	return 0;
1046 }
1047 
1048 
1049 int
1050 execcmd(int argc, char **argv)
1051 {
1052 	if (argc > 1) {
1053 		struct strlist *sp;
1054 
1055 		iflag = 0;		/* exit on error */
1056 		mflag = 0;
1057 		optschanged();
1058 		for (sp = cmdenviron; sp ; sp = sp->next)
1059 			setvareq(sp->text, VEXPORT|VSTACK);
1060 		shellexec(argv + 1, environment(), pathval(), 0);
1061 
1062 	}
1063 	return 0;
1064 }
1065