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