xref: /netbsd-src/bin/sh/eval.c (revision d909946ca08dceb44d7d0f22ec9488679695d976)
1 /*	$NetBSD: eval.c,v 1.128 2016/06/01 05:10:41 kre Exp $	*/
2 
3 /*-
4  * Copyright (c) 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * This code is derived from software contributed to Berkeley by
8  * Kenneth Almquist.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of the University nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34 
35 #include <sys/cdefs.h>
36 #ifndef lint
37 #if 0
38 static char sccsid[] = "@(#)eval.c	8.9 (Berkeley) 6/8/95";
39 #else
40 __RCSID("$NetBSD: eval.c,v 1.128 2016/06/01 05:10:41 kre Exp $");
41 #endif
42 #endif /* not lint */
43 
44 #include <stdbool.h>
45 #include <stdlib.h>
46 #include <signal.h>
47 #include <stdio.h>
48 #include <string.h>
49 #include <errno.h>
50 #include <limits.h>
51 #include <unistd.h>
52 #include <sys/fcntl.h>
53 #include <sys/times.h>
54 #include <sys/param.h>
55 #include <sys/types.h>
56 #include <sys/wait.h>
57 #include <sys/sysctl.h>
58 
59 /*
60  * Evaluate a command.
61  */
62 
63 #include "shell.h"
64 #include "nodes.h"
65 #include "syntax.h"
66 #include "expand.h"
67 #include "parser.h"
68 #include "jobs.h"
69 #include "eval.h"
70 #include "builtins.h"
71 #include "options.h"
72 #include "exec.h"
73 #include "redir.h"
74 #include "input.h"
75 #include "output.h"
76 #include "trap.h"
77 #include "var.h"
78 #include "memalloc.h"
79 #include "error.h"
80 #include "show.h"
81 #include "mystring.h"
82 #include "main.h"
83 #ifndef SMALL
84 #include "nodenames.h"
85 #include "myhistedit.h"
86 #endif
87 
88 
89 STATIC enum skipstate evalskip;	/* != SKIPNONE if we are skipping commands */
90 STATIC int skipcount;		/* number of levels to skip */
91 STATIC int loopnest;		/* current loop nesting level */
92 STATIC int funcnest;		/* depth of function calls */
93 STATIC int builtin_flags;	/* evalcommand flags for builtins */
94 /*
95  * Base function nesting level inside a dot command.  Set to 0 initially
96  * and to (funcnest + 1) before every dot command to enable
97  *   1) detection of being in a file sourced by a dot command and
98  *   2) counting of function nesting in that file for the implementation
99  *      of the return command.
100  * The value is reset to its previous value after the dot command.
101  */
102 STATIC int dot_funcnest;
103 
104 
105 const char *commandname;
106 struct strlist *cmdenviron;
107 int exitstatus;			/* exit status of last command */
108 int back_exitstatus;		/* exit status of backquoted command */
109 
110 
111 STATIC void evalloop(union node *, int);
112 STATIC void evalfor(union node *, int);
113 STATIC void evalcase(union node *, int);
114 STATIC void evalsubshell(union node *, int);
115 STATIC void expredir(union node *);
116 STATIC void evalpipe(union node *);
117 STATIC void evalcommand(union node *, int, struct backcmd *);
118 STATIC void prehash(union node *);
119 
120 STATIC char *find_dot_file(char *);
121 
122 /*
123  * Called to reset things after an exception.
124  */
125 
126 #ifdef mkinit
127 INCLUDE "eval.h"
128 
129 RESET {
130 	reset_eval();
131 }
132 
133 SHELLPROC {
134 	exitstatus = 0;
135 }
136 #endif
137 
138 void
139 reset_eval(void)
140 {
141 	evalskip = SKIPNONE;
142 	dot_funcnest = 0;
143 	loopnest = 0;
144 	funcnest = 0;
145 }
146 
147 static int
148 sh_pipe(int fds[2])
149 {
150 	int nfd;
151 
152 	if (pipe(fds))
153 		return -1;
154 
155 	if (fds[0] < 3) {
156 		nfd = fcntl(fds[0], F_DUPFD, 3);
157 		if (nfd != -1) {
158 			close(fds[0]);
159 			fds[0] = nfd;
160 		}
161 	}
162 
163 	if (fds[1] < 3) {
164 		nfd = fcntl(fds[1], F_DUPFD, 3);
165 		if (nfd != -1) {
166 			close(fds[1]);
167 			fds[1] = nfd;
168 		}
169 	}
170 	return 0;
171 }
172 
173 
174 /*
175  * The eval commmand.
176  */
177 
178 int
179 evalcmd(int argc, char **argv)
180 {
181         char *p;
182         char *concat;
183         char **ap;
184 
185         if (argc > 1) {
186                 p = argv[1];
187                 if (argc > 2) {
188                         STARTSTACKSTR(concat);
189                         ap = argv + 2;
190                         for (;;) {
191                                 while (*p)
192                                         STPUTC(*p++, concat);
193                                 if ((p = *ap++) == NULL)
194                                         break;
195                                 STPUTC(' ', concat);
196                         }
197                         STPUTC('\0', concat);
198                         p = grabstackstr(concat);
199                 }
200                 evalstring(p, builtin_flags & EV_TESTED);
201         }
202         return exitstatus;
203 }
204 
205 
206 /*
207  * Execute a command or commands contained in a string.
208  */
209 
210 void
211 evalstring(char *s, int flag)
212 {
213 	union node *n;
214 	struct stackmark smark;
215 
216 	setstackmark(&smark);
217 	setinputstring(s, 1);
218 
219 	while ((n = parsecmd(0)) != NEOF) {
220 		TRACE(("evalstring: "); showtree(n));
221 		if (nflag == 0)
222 			evaltree(n, flag | EV_MORE);
223 		popstackmark(&smark);
224 	}
225 	popfile();
226 	popstackmark(&smark);
227 }
228 
229 
230 
231 /*
232  * Evaluate a parse tree.  The value is left in the global variable
233  * exitstatus.
234  */
235 
236 void
237 evaltree(union node *n, int flags)
238 {
239 	bool do_etest;
240 
241 	do_etest = false;
242 	if (n == NULL || nflag) {
243 		TRACE(("evaltree(%s) called\n", n == NULL ? "NULL" : "-n"));
244 		if (nflag == 0)
245 			exitstatus = 0;
246 		goto out;
247 	}
248 #ifndef SMALL
249 	displayhist = 1;	/* show history substitutions done with fc */
250 #endif
251 #ifdef NODETYPENAME
252 	TRACE(("pid %d, evaltree(%p: %s(%d), %#x) called\n",
253 	    getpid(), n, NODETYPENAME(n->type), n->type, flags));
254 #else
255 	TRACE(("pid %d, evaltree(%p: %d, %#x) called\n",
256 	    getpid(), n, n->type, flags));
257 #endif
258 	switch (n->type) {
259 	case NSEMI:
260 		evaltree(n->nbinary.ch1, (flags & EV_TESTED) |
261 		    (n->nbinary.ch2 ? EV_MORE : 0));
262 		if (nflag || evalskip)
263 			goto out;
264 		evaltree(n->nbinary.ch2, flags);
265 		break;
266 	case NAND:
267 		evaltree(n->nbinary.ch1, EV_TESTED | EV_MORE);
268 		if (nflag || evalskip || exitstatus != 0)
269 			goto out;
270 		evaltree(n->nbinary.ch2, flags);
271 		break;
272 	case NOR:
273 		evaltree(n->nbinary.ch1, EV_TESTED | EV_MORE);
274 		if (nflag || evalskip || exitstatus == 0)
275 			goto out;
276 		evaltree(n->nbinary.ch2, flags);
277 		break;
278 	case NREDIR:
279 		expredir(n->nredir.redirect);
280 		redirect(n->nredir.redirect, REDIR_PUSH | REDIR_KEEP);
281 		evaltree(n->nredir.n, flags);
282 		popredir();
283 		break;
284 	case NSUBSHELL:
285 		evalsubshell(n, flags & ~EV_MORE);
286 		do_etest = !(flags & EV_TESTED);
287 		break;
288 	case NBACKGND:
289 		evalsubshell(n, flags & ~EV_MORE);
290 		break;
291 	case NIF: {
292 		evaltree(n->nif.test, EV_TESTED | EV_MORE);
293 		if (nflag || evalskip)
294 			goto out;
295 		if (exitstatus == 0)
296 			evaltree(n->nif.ifpart, flags);
297 		else if (n->nif.elsepart)
298 			evaltree(n->nif.elsepart, flags);
299 		else
300 			exitstatus = 0;
301 		break;
302 	}
303 	case NWHILE:
304 	case NUNTIL:
305 		evalloop(n, flags);
306 		break;
307 	case NFOR:
308 		evalfor(n, flags);
309 		break;
310 	case NCASE:
311 		evalcase(n, flags);
312 		break;
313 	case NDEFUN:
314 		defun(n->narg.text, n->narg.next);
315 		exitstatus = 0;
316 		break;
317 	case NNOT:
318 		evaltree(n->nnot.com, (flags & EV_MORE) | EV_TESTED);
319 		exitstatus = !exitstatus;
320 		break;
321 	case NPIPE:
322 		evalpipe(n);
323 		do_etest = !(flags & EV_TESTED);
324 		break;
325 	case NCMD:
326 		evalcommand(n, flags, NULL);
327 		do_etest = !(flags & EV_TESTED);
328 		break;
329 	default:
330 #ifdef NODETYPENAME
331 		out1fmt("Node type = %d(%s)\n", n->type, NODETYPENAME(n->type));
332 #else
333 		out1fmt("Node type = %d\n", n->type);
334 #endif
335 		flushout(&output);
336 		break;
337 	}
338 out:
339 	if (pendingsigs)
340 		dotrap();
341 	if ((flags & EV_EXIT) != 0 || (eflag && exitstatus != 0 && do_etest))
342 		exitshell(exitstatus);
343 }
344 
345 
346 STATIC void
347 evalloop(union node *n, int flags)
348 {
349 	int status;
350 
351 	loopnest++;
352 	status = 0;
353 
354 #ifdef NODETYPENAME
355 	TRACE(("evalloop %s: ", NODETYPENAME(n->type)));
356 #else
357 	TRACE(("evalloop %s: ", n->type == NWHILE ? "while" : "until"));
358 #endif
359 	TRACE((""); showtree(n->nbinary.ch1));
360 	TRACE(("evalloop    do: "); showtree(n->nbinary.ch2));
361 	TRACE(("evalloop  done\n"));
362 
363 	for (;;) {
364 		evaltree(n->nbinary.ch1, EV_TESTED | EV_MORE);
365 		if (nflag)
366 			break;
367 		if (evalskip) {
368 skipping:	  if (evalskip == SKIPCONT && --skipcount <= 0) {
369 				evalskip = SKIPNONE;
370 				continue;
371 			}
372 			if (evalskip == SKIPBREAK && --skipcount <= 0)
373 				evalskip = SKIPNONE;
374 			break;
375 		}
376 		if (n->type == NWHILE) {
377 			if (exitstatus != 0)
378 				break;
379 		} else {
380 			if (exitstatus == 0)
381 				break;
382 		}
383 		evaltree(n->nbinary.ch2, (flags & EV_TESTED) | EV_MORE);
384 		status = exitstatus;
385 		if (evalskip)
386 			goto skipping;
387 	}
388 	loopnest--;
389 	exitstatus = status;
390 }
391 
392 
393 
394 STATIC void
395 evalfor(union node *n, int flags)
396 {
397 	struct arglist arglist;
398 	union node *argp;
399 	struct strlist *sp;
400 	struct stackmark smark;
401 	int status;
402 
403 	status = nflag ? exitstatus : 0;
404 
405 	setstackmark(&smark);
406 	arglist.lastp = &arglist.list;
407 	for (argp = n->nfor.args ; argp ; argp = argp->narg.next) {
408 		expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
409 		if (evalskip)
410 			goto out;
411 	}
412 	*arglist.lastp = NULL;
413 
414 	loopnest++;
415 	for (sp = arglist.list ; sp ; sp = sp->next) {
416 		int f = flags & (EV_TESTED | EV_MORE);
417 
418 		if (sp->next)
419 			f |= EV_MORE;
420 
421 		setvar(n->nfor.var, sp->text, 0);
422 		evaltree(n->nfor.body, f);
423 		status = exitstatus;
424 		if (nflag)
425 			break;
426 		if (evalskip) {
427 			if (evalskip == SKIPCONT && --skipcount <= 0) {
428 				evalskip = SKIPNONE;
429 				continue;
430 			}
431 			if (evalskip == SKIPBREAK && --skipcount <= 0)
432 				evalskip = SKIPNONE;
433 			break;
434 		}
435 	}
436 	loopnest--;
437 	exitstatus = status;
438 out:
439 	popstackmark(&smark);
440 }
441 
442 
443 
444 STATIC void
445 evalcase(union node *n, int flags)
446 {
447 	union node *cp;
448 	union node *patp;
449 	struct arglist arglist;
450 	struct stackmark smark;
451 	int status = 0;
452 
453 	setstackmark(&smark);
454 	arglist.lastp = &arglist.list;
455 	expandarg(n->ncase.expr, &arglist, EXP_TILDE);
456 	for (cp = n->ncase.cases ; cp && evalskip == 0 ; cp = cp->nclist.next) {
457 		for (patp = cp->nclist.pattern ; patp ; patp = patp->narg.next) {
458 			if (casematch(patp, arglist.list->text)) {
459 				if (evalskip == 0) {
460 					evaltree(cp->nclist.body, flags);
461 					status = exitstatus;
462 				}
463 				goto out;
464 			}
465 		}
466 	}
467 out:
468 	exitstatus = status;
469 	popstackmark(&smark);
470 }
471 
472 
473 
474 /*
475  * Kick off a subshell to evaluate a tree.
476  */
477 
478 STATIC void
479 evalsubshell(union node *n, int flags)
480 {
481 	struct job *jp;
482 	int backgnd = (n->type == NBACKGND);
483 
484 	expredir(n->nredir.redirect);
485 	INTOFF;
486 	jp = makejob(n, 1);
487 	if (forkshell(jp, n, backgnd ? FORK_BG : FORK_FG) == 0) {
488 		INTON;
489 		if (backgnd)
490 			flags &=~ EV_TESTED;
491 		redirect(n->nredir.redirect, REDIR_KEEP);
492 		/* never returns */
493 		evaltree(n->nredir.n, flags | EV_EXIT);
494 	}
495 	exitstatus = backgnd ? 0 : waitforjob(jp);
496 	INTON;
497 }
498 
499 
500 
501 /*
502  * Compute the names of the files in a redirection list.
503  */
504 
505 STATIC void
506 expredir(union node *n)
507 {
508 	union node *redir;
509 
510 	for (redir = n ; redir ; redir = redir->nfile.next) {
511 		struct arglist fn;
512 
513 		fn.lastp = &fn.list;
514 		switch (redir->type) {
515 		case NFROMTO:
516 		case NFROM:
517 		case NTO:
518 		case NCLOBBER:
519 		case NAPPEND:
520 			expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR);
521 			redir->nfile.expfname = fn.list->text;
522 			break;
523 		case NFROMFD:
524 		case NTOFD:
525 			if (redir->ndup.vname) {
526 				expandarg(redir->ndup.vname, &fn, EXP_FULL | EXP_TILDE);
527 				fixredir(redir, fn.list->text, 1);
528 			}
529 			break;
530 		}
531 	}
532 }
533 
534 
535 
536 /*
537  * Evaluate a pipeline.  All the processes in the pipeline are children
538  * of the process creating the pipeline.  (This differs from some versions
539  * of the shell, which make the last process in a pipeline the parent
540  * of all the rest.)
541  */
542 
543 STATIC void
544 evalpipe(union node *n)
545 {
546 	struct job *jp;
547 	struct nodelist *lp;
548 	int pipelen;
549 	int prevfd;
550 	int pip[2];
551 
552 	TRACE(("evalpipe(0x%lx) called\n", (long)n));
553 	pipelen = 0;
554 	for (lp = n->npipe.cmdlist ; lp ; lp = lp->next)
555 		pipelen++;
556 	INTOFF;
557 	jp = makejob(n, pipelen);
558 	prevfd = -1;
559 	for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
560 		prehash(lp->n);
561 		pip[1] = -1;
562 		if (lp->next) {
563 			if (sh_pipe(pip) < 0) {
564 				if (prevfd >= 0)
565 					close(prevfd);
566 				error("Pipe call failed");
567 			}
568 		}
569 		if (forkshell(jp, lp->n, n->npipe.backgnd ? FORK_BG : FORK_FG) == 0) {
570 			INTON;
571 			if (prevfd > 0)
572 				movefd(prevfd, 0);
573 			if (pip[1] >= 0) {
574 				close(pip[0]);
575 				movefd(pip[1], 1);
576 			}
577 			evaltree(lp->n, EV_EXIT);
578 		}
579 		if (prevfd >= 0)
580 			close(prevfd);
581 		prevfd = pip[0];
582 		close(pip[1]);
583 	}
584 	if (n->npipe.backgnd == 0) {
585 		exitstatus = waitforjob(jp);
586 		TRACE(("evalpipe:  job done exit status %d\n", exitstatus));
587 	} else
588 		exitstatus = 0;
589 	INTON;
590 }
591 
592 
593 
594 /*
595  * Execute a command inside back quotes.  If it's a builtin command, we
596  * want to save its output in a block obtained from malloc.  Otherwise
597  * we fork off a subprocess and get the output of the command via a pipe.
598  * Should be called with interrupts off.
599  */
600 
601 void
602 evalbackcmd(union node *n, struct backcmd *result)
603 {
604 	int pip[2];
605 	struct job *jp;
606 	struct stackmark smark;		/* unnecessary */
607 
608 	setstackmark(&smark);
609 	result->fd = -1;
610 	result->buf = NULL;
611 	result->nleft = 0;
612 	result->jp = NULL;
613 	if (nflag || n == NULL) {
614 		goto out;
615 	}
616 #ifdef notyet
617 	/*
618 	 * For now we disable executing builtins in the same
619 	 * context as the shell, because we are not keeping
620 	 * enough state to recover from changes that are
621 	 * supposed only to affect subshells. eg. echo "`cd /`"
622 	 */
623 	if (n->type == NCMD) {
624 		exitstatus = oexitstatus;
625 		evalcommand(n, EV_BACKCMD, result);
626 	} else
627 #endif
628 	{
629 		INTOFF;
630 		if (sh_pipe(pip) < 0)
631 			error("Pipe call failed");
632 		jp = makejob(n, 1);
633 		if (forkshell(jp, n, FORK_NOJOB) == 0) {
634 			FORCEINTON;
635 			close(pip[0]);
636 			movefd(pip[1], 1);
637 			eflag = 0;
638 			evaltree(n, EV_EXIT);
639 			/* NOTREACHED */
640 		}
641 		close(pip[1]);
642 		result->fd = pip[0];
643 		result->jp = jp;
644 		INTON;
645 	}
646 out:
647 	popstackmark(&smark);
648 	TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n",
649 		result->fd, result->buf, result->nleft, result->jp));
650 }
651 
652 static const char *
653 syspath(void)
654 {
655 	static char *sys_path = NULL;
656 	static int mib[] = {CTL_USER, USER_CS_PATH};
657 	static char def_path[] = "PATH=/usr/bin:/bin:/usr/sbin:/sbin";
658 	size_t len;
659 
660 	if (sys_path == NULL) {
661 		if (sysctl(mib, 2, 0, &len, 0, 0) != -1 &&
662 		    (sys_path = ckmalloc(len + 5)) != NULL &&
663 		    sysctl(mib, 2, sys_path + 5, &len, 0, 0) != -1) {
664 			memcpy(sys_path, "PATH=", 5);
665 		} else {
666 			ckfree(sys_path);
667 			/* something to keep things happy */
668 			sys_path = def_path;
669 		}
670 	}
671 	return sys_path;
672 }
673 
674 static int
675 parse_command_args(int argc, char **argv, int *use_syspath)
676 {
677 	int sv_argc = argc;
678 	char *cp, c;
679 
680 	*use_syspath = 0;
681 
682 	for (;;) {
683 		argv++;
684 		if (--argc == 0)
685 			break;
686 		cp = *argv;
687 		if (*cp++ != '-')
688 			break;
689 		if (*cp == '-' && cp[1] == 0) {
690 			argv++;
691 			argc--;
692 			break;
693 		}
694 		while ((c = *cp++)) {
695 			switch (c) {
696 			case 'p':
697 				*use_syspath = 1;
698 				break;
699 			default:
700 				/* run 'typecmd' for other options */
701 				return 0;
702 			}
703 		}
704 	}
705 	return sv_argc - argc;
706 }
707 
708 int vforked = 0;
709 extern char *trap[];
710 
711 /*
712  * Execute a simple command.
713  */
714 
715 STATIC void
716 evalcommand(union node *cmd, int flgs, struct backcmd *backcmd)
717 {
718 	struct stackmark smark;
719 	union node *argp;
720 	struct arglist arglist;
721 	struct arglist varlist;
722 	volatile int flags = flgs;
723 	char ** volatile argv;
724 	volatile int argc;
725 	char **envp;
726 	int varflag;
727 	struct strlist *sp;
728 	volatile int mode;
729 	int pip[2];
730 	struct cmdentry cmdentry;
731 	struct job * volatile jp;
732 	struct jmploc jmploc;
733 	struct jmploc *volatile savehandler = NULL;
734 	const char *volatile savecmdname;
735 	volatile struct shparam saveparam;
736 	struct localvar *volatile savelocalvars;
737 	volatile int e;
738 	char * volatile lastarg;
739 	const char * volatile path = pathval();
740 	volatile int temp_path;
741 
742 	vforked = 0;
743 	/* First expand the arguments. */
744 	TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
745 	setstackmark(&smark);
746 	back_exitstatus = 0;
747 
748 	arglist.lastp = &arglist.list;
749 	varflag = 1;
750 	/* Expand arguments, ignoring the initial 'name=value' ones */
751 	for (argp = cmd->ncmd.args ; argp ; argp = argp->narg.next) {
752 		char *p = argp->narg.text;
753 		if (varflag && is_name(*p)) {
754 			do {
755 				p++;
756 			} while (is_in_name(*p));
757 			if (*p == '=')
758 				continue;
759 		}
760 		expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
761 		varflag = 0;
762 	}
763 	*arglist.lastp = NULL;
764 
765 	expredir(cmd->ncmd.redirect);
766 
767 	/* Now do the initial 'name=value' ones we skipped above */
768 	varlist.lastp = &varlist.list;
769 	for (argp = cmd->ncmd.args ; argp ; argp = argp->narg.next) {
770 		char *p = argp->narg.text;
771 		if (!is_name(*p))
772 			break;
773 		do
774 			p++;
775 		while (is_in_name(*p));
776 		if (*p != '=')
777 			break;
778 		expandarg(argp, &varlist, EXP_VARTILDE);
779 	}
780 	*varlist.lastp = NULL;
781 
782 	argc = 0;
783 	for (sp = arglist.list ; sp ; sp = sp->next)
784 		argc++;
785 	argv = stalloc(sizeof (char *) * (argc + 1));
786 
787 	for (sp = arglist.list ; sp ; sp = sp->next) {
788 		TRACE(("evalcommand arg: %s\n", sp->text));
789 		*argv++ = sp->text;
790 	}
791 	*argv = NULL;
792 	lastarg = NULL;
793 	if (iflag && funcnest == 0 && argc > 0)
794 		lastarg = argv[-1];
795 	argv -= argc;
796 
797 	/* Print the command if xflag is set. */
798 	if (xflag) {
799 		char sep = 0;
800 		out2str(ps4val());
801 		for (sp = varlist.list ; sp ; sp = sp->next) {
802 			char *p;
803 
804 			if (sep != 0)
805 				outc(sep, &errout);
806 
807 			/*
808 			 * The "var=" part should not be quoted, regardless
809 			 * of the value, or it would not represent an
810 			 * assignment, but rather a command
811 			 */
812 			p = strchr(sp->text, '=');
813 			if (p != NULL) {
814 				*p = '\0';	/*XXX*/
815 				out2shstr(sp->text);
816 				out2c('=');
817 				*p++ = '=';	/*XXX*/
818 			} else
819 				p = sp->text;
820 			out2shstr(p);
821 			sep = ' ';
822 		}
823 		for (sp = arglist.list ; sp ; sp = sp->next) {
824 			if (sep != 0)
825 				outc(sep, &errout);
826 			out2shstr(sp->text);
827 			sep = ' ';
828 		}
829 		outc('\n', &errout);
830 		flushout(&errout);
831 	}
832 
833 	/* Now locate the command. */
834 	if (argc == 0) {
835 		cmdentry.cmdtype = CMDSPLBLTIN;
836 		cmdentry.u.bltin = bltincmd;
837 	} else {
838 		static const char PATH[] = "PATH=";
839 		int cmd_flags = DO_ERR;
840 
841 		/*
842 		 * Modify the command lookup path, if a PATH= assignment
843 		 * is present
844 		 */
845 		for (sp = varlist.list; sp; sp = sp->next)
846 			if (strncmp(sp->text, PATH, sizeof(PATH) - 1) == 0)
847 				path = sp->text + sizeof(PATH) - 1;
848 
849 		do {
850 			int argsused, use_syspath;
851 			find_command(argv[0], &cmdentry, cmd_flags, path);
852 			if (cmdentry.cmdtype == CMDUNKNOWN) {
853 				exitstatus = 127;
854 				flushout(&errout);
855 				goto out;
856 			}
857 
858 			/* implement the 'command' builtin here */
859 			if (cmdentry.cmdtype != CMDBUILTIN ||
860 			    cmdentry.u.bltin != bltincmd)
861 				break;
862 			cmd_flags |= DO_NOFUNC;
863 			argsused = parse_command_args(argc, argv, &use_syspath);
864 			if (argsused == 0) {
865 				/* use 'type' builting to display info */
866 				cmdentry.u.bltin = typecmd;
867 				break;
868 			}
869 			argc -= argsused;
870 			argv += argsused;
871 			if (use_syspath)
872 				path = syspath() + 5;
873 		} while (argc != 0);
874 		if (cmdentry.cmdtype == CMDSPLBLTIN && cmd_flags & DO_NOFUNC)
875 			/* posix mandates that 'command <splbltin>' act as if
876 			   <splbltin> was a normal builtin */
877 			cmdentry.cmdtype = CMDBUILTIN;
878 	}
879 
880 	/* Fork off a child process if necessary. */
881 	if (cmd->ncmd.backgnd || (trap[0] && (flags & EV_EXIT) != 0)
882 	 || (cmdentry.cmdtype == CMDNORMAL && (flags & EV_EXIT) == 0)
883 	 || ((flags & EV_BACKCMD) != 0
884 	    && ((cmdentry.cmdtype != CMDBUILTIN && cmdentry.cmdtype != CMDSPLBLTIN)
885 		 || cmdentry.u.bltin == dotcmd
886 		 || cmdentry.u.bltin == evalcmd))) {
887 		INTOFF;
888 		jp = makejob(cmd, 1);
889 		mode = cmd->ncmd.backgnd;
890 		if (mode)
891 			flags &= ~EV_MORE;
892 		if (flags & EV_BACKCMD) {
893 			mode = FORK_NOJOB;
894 			if (sh_pipe(pip) < 0)
895 				error("Pipe call failed");
896 		}
897 #ifdef DO_SHAREDVFORK
898 		/* It is essential that if DO_SHAREDVFORK is defined that the
899 		 * child's address space is actually shared with the parent as
900 		 * we rely on this.
901 		 */
902 		if (usefork == 0 && cmdentry.cmdtype == CMDNORMAL) {
903 			pid_t	pid;
904 			int serrno;
905 
906 			savelocalvars = localvars;
907 			localvars = NULL;
908 			vforked = 1;
909 			switch (pid = vfork()) {
910 			case -1:
911 				serrno = errno;
912 				TRACE(("Vfork failed, errno=%d\n", serrno));
913 				INTON;
914 				error("Cannot vfork (%s)", strerror(serrno));
915 				break;
916 			case 0:
917 				/* Make sure that exceptions only unwind to
918 				 * after the vfork(2)
919 				 */
920 				if (setjmp(jmploc.loc)) {
921 					if (exception == EXSHELLPROC) {
922 						/* We can't progress with the vfork,
923 						 * so, set vforked = 2 so the parent
924 						 * knows, and _exit();
925 						 */
926 						vforked = 2;
927 						_exit(0);
928 					} else {
929 						_exit(exerrno);
930 					}
931 				}
932 				savehandler = handler;
933 				handler = &jmploc;
934 				listmklocal(varlist.list, VEXPORT | VNOFUNC);
935 				forkchild(jp, cmd, mode, vforked);
936 				break;
937 			default:
938 				handler = savehandler;	/* restore from vfork(2) */
939 				poplocalvars();
940 				localvars = savelocalvars;
941 				if (vforked == 2) {
942 					vforked = 0;
943 
944 					(void)waitpid(pid, NULL, 0);
945 					/* We need to progress in a normal fork fashion */
946 					goto normal_fork;
947 				}
948 				vforked = 0;
949 				forkparent(jp, cmd, mode, pid);
950 				goto parent;
951 			}
952 		} else {
953 normal_fork:
954 #endif
955 			if (forkshell(jp, cmd, mode) != 0)
956 				goto parent;	/* at end of routine */
957 			FORCEINTON;
958 #ifdef DO_SHAREDVFORK
959 		}
960 #endif
961 		if (flags & EV_BACKCMD) {
962 			if (!vforked) {
963 				FORCEINTON;
964 			}
965 			close(pip[0]);
966 			movefd(pip[1], 1);
967 		}
968 		flags |= EV_EXIT;
969 	}
970 
971 	/* This is the child process if a fork occurred. */
972 	/* Execute the command. */
973 	switch (cmdentry.cmdtype) {
974 	case CMDFUNCTION:
975 #ifdef DEBUG
976 		trputs("Shell function:  ");  trargs(argv);
977 #endif
978 		redirect(cmd->ncmd.redirect, flags & EV_MORE ? REDIR_PUSH : 0);
979 		saveparam = shellparam;
980 		shellparam.malloc = 0;
981 		shellparam.reset = 1;
982 		shellparam.nparam = argc - 1;
983 		shellparam.p = argv + 1;
984 		shellparam.optnext = NULL;
985 		INTOFF;
986 		savelocalvars = localvars;
987 		localvars = NULL;
988 		INTON;
989 		if (setjmp(jmploc.loc)) {
990 			if (exception == EXSHELLPROC) {
991 				freeparam((volatile struct shparam *)
992 				    &saveparam);
993 			} else {
994 				freeparam(&shellparam);
995 				shellparam = saveparam;
996 			}
997 			poplocalvars();
998 			localvars = savelocalvars;
999 			handler = savehandler;
1000 			longjmp(handler->loc, 1);
1001 		}
1002 		savehandler = handler;
1003 		handler = &jmploc;
1004 		listmklocal(varlist.list, VEXPORT);
1005 		/* stop shell blowing its stack */
1006 		if (++funcnest > 1000)
1007 			error("too many nested function calls");
1008 		evaltree(cmdentry.u.func, flags & EV_TESTED);
1009 		funcnest--;
1010 		INTOFF;
1011 		poplocalvars();
1012 		localvars = savelocalvars;
1013 		freeparam(&shellparam);
1014 		shellparam = saveparam;
1015 		handler = savehandler;
1016 		if (flags & EV_MORE)
1017 			popredir();
1018 		INTON;
1019 		if (evalskip == SKIPFUNC) {
1020 			evalskip = SKIPNONE;
1021 			skipcount = 0;
1022 		}
1023 		if (flags & EV_EXIT)
1024 			exitshell(exitstatus);
1025 		break;
1026 
1027 	case CMDBUILTIN:
1028 	case CMDSPLBLTIN:
1029 #ifdef DEBUG
1030 		trputs("builtin command:  ");  trargs(argv);
1031 #endif
1032 		mode = (cmdentry.u.bltin == execcmd) ? 0 : REDIR_PUSH;
1033 		if (flags == EV_BACKCMD) {
1034 			memout.nleft = 0;
1035 			memout.nextc = memout.buf;
1036 			memout.bufsize = 64;
1037 			mode |= REDIR_BACKQ;
1038 		}
1039 		e = -1;
1040 		savehandler = handler;
1041 		savecmdname = commandname;
1042 		handler = &jmploc;
1043 		temp_path = 0;
1044 		if (!setjmp(jmploc.loc)) {
1045 			/* We need to ensure the command hash table isn't
1046 			 * corruped by temporary PATH assignments.
1047 			 * However we must ensure the 'local' command works!
1048 			 */
1049 			if (path != pathval() && (cmdentry.u.bltin == hashcmd ||
1050 			    cmdentry.u.bltin == typecmd)) {
1051 				savelocalvars = localvars;
1052 				localvars = 0;
1053 				temp_path = 1;
1054 				mklocal(path - 5 /* PATH= */, 0);
1055 			}
1056 			redirect(cmd->ncmd.redirect, mode);
1057 
1058 			/* exec is a special builtin, but needs this list... */
1059 			cmdenviron = varlist.list;
1060 			/* we must check 'readonly' flag for all builtins */
1061 			listsetvar(varlist.list,
1062 				cmdentry.cmdtype == CMDSPLBLTIN ? 0 : VNOSET);
1063 			commandname = argv[0];
1064 			/* initialize nextopt */
1065 			argptr = argv + 1;
1066 			optptr = NULL;
1067 			/* and getopt */
1068 			optreset = 1;
1069 			optind = 1;
1070 			builtin_flags = flags;
1071 			exitstatus = cmdentry.u.bltin(argc, argv);
1072 		} else {
1073 			e = exception;
1074 			exitstatus = e == EXINT ? SIGINT + 128 :
1075 					e == EXEXEC ? exerrno : 2;
1076 		}
1077 		handler = savehandler;
1078 		flushall();
1079 		out1 = &output;
1080 		out2 = &errout;
1081 		freestdout();
1082 		if (temp_path) {
1083 			poplocalvars();
1084 			localvars = savelocalvars;
1085 		}
1086 		cmdenviron = NULL;
1087 		if (e != EXSHELLPROC) {
1088 			commandname = savecmdname;
1089 			if (flags & EV_EXIT)
1090 				exitshell(exitstatus);
1091 		}
1092 		if (e != -1) {
1093 			if ((e != EXERROR && e != EXEXEC)
1094 			    || cmdentry.cmdtype == CMDSPLBLTIN)
1095 				exraise(e);
1096 			FORCEINTON;
1097 		}
1098 		if (cmdentry.u.bltin != execcmd)
1099 			popredir();
1100 		if (flags == EV_BACKCMD) {
1101 			backcmd->buf = memout.buf;
1102 			backcmd->nleft = memout.nextc - memout.buf;
1103 			memout.buf = NULL;
1104 		}
1105 		break;
1106 
1107 	default:
1108 #ifdef DEBUG
1109 		trputs("normal command:  ");  trargs(argv);
1110 #endif
1111 		redirect(cmd->ncmd.redirect,
1112 		    (vforked ? REDIR_VFORK : 0) | REDIR_KEEP);
1113 		if (!vforked)
1114 			for (sp = varlist.list ; sp ; sp = sp->next)
1115 				setvareq(sp->text, VEXPORT|VSTACK);
1116 		envp = environment();
1117 		shellexec(argv, envp, path, cmdentry.u.index, vforked);
1118 		break;
1119 	}
1120 	goto out;
1121 
1122 parent:	/* parent process gets here (if we forked) */
1123 	exitstatus = 0;		/* if not altered just below */
1124 	if (mode == FORK_FG) {	/* argument to fork */
1125 		exitstatus = waitforjob(jp);
1126 	} else if (mode == FORK_NOJOB) {
1127 		backcmd->fd = pip[0];
1128 		close(pip[1]);
1129 		backcmd->jp = jp;
1130 	}
1131 	FORCEINTON;
1132 
1133 out:
1134 	if (lastarg)
1135 		/* dsl: I think this is intended to be used to support
1136 		 * '_' in 'vi' command mode during line editing...
1137 		 * However I implemented that within libedit itself.
1138 		 */
1139 		setvar("_", lastarg, 0);
1140 	popstackmark(&smark);
1141 }
1142 
1143 
1144 /*
1145  * Search for a command.  This is called before we fork so that the
1146  * location of the command will be available in the parent as well as
1147  * the child.  The check for "goodname" is an overly conservative
1148  * check that the name will not be subject to expansion.
1149  */
1150 
1151 STATIC void
1152 prehash(union node *n)
1153 {
1154 	struct cmdentry entry;
1155 
1156 	if (n && n->type == NCMD && n->ncmd.args)
1157 		if (goodname(n->ncmd.args->narg.text))
1158 			find_command(n->ncmd.args->narg.text, &entry, 0,
1159 				     pathval());
1160 }
1161 
1162 int
1163 in_function(void)
1164 {
1165 	return funcnest;
1166 }
1167 
1168 enum skipstate
1169 current_skipstate(void)
1170 {
1171 	return evalskip;
1172 }
1173 
1174 void
1175 stop_skipping(void)
1176 {
1177 	evalskip = SKIPNONE;
1178 	skipcount = 0;
1179 }
1180 
1181 /*
1182  * Builtin commands.  Builtin commands whose functions are closely
1183  * tied to evaluation are implemented here.
1184  */
1185 
1186 /*
1187  * No command given.
1188  */
1189 
1190 int
1191 bltincmd(int argc, char **argv)
1192 {
1193 	/*
1194 	 * Preserve exitstatus of a previous possible redirection
1195 	 * as POSIX mandates
1196 	 */
1197 	return back_exitstatus;
1198 }
1199 
1200 
1201 /*
1202  * Handle break and continue commands.  Break, continue, and return are
1203  * all handled by setting the evalskip flag.  The evaluation routines
1204  * above all check this flag, and if it is set they start skipping
1205  * commands rather than executing them.  The variable skipcount is
1206  * the number of loops to break/continue, or the number of function
1207  * levels to return.  (The latter is always 1.)  It should probably
1208  * be an error to break out of more loops than exist, but it isn't
1209  * in the standard shell so we don't make it one here.
1210  */
1211 
1212 int
1213 breakcmd(int argc, char **argv)
1214 {
1215 	int n = argc > 1 ? number(argv[1]) : 1;
1216 
1217 	if (n > loopnest)
1218 		n = loopnest;
1219 	if (n > 0) {
1220 		evalskip = (**argv == 'c')? SKIPCONT : SKIPBREAK;
1221 		skipcount = n;
1222 	}
1223 	return 0;
1224 }
1225 
1226 int
1227 dotcmd(int argc, char **argv)
1228 {
1229 	exitstatus = 0;
1230 
1231 	if (argc >= 2) {		/* That's what SVR2 does */
1232 		char *fullname;
1233 		/*
1234 		 * dot_funcnest needs to be 0 when not in a dotcmd, so it
1235 		 * cannot be restored with (funcnest + 1).
1236 		 */
1237 		int dot_funcnest_old;
1238 		struct stackmark smark;
1239 
1240 		setstackmark(&smark);
1241 		fullname = find_dot_file(argv[1]);
1242 		setinputfile(fullname, 1);
1243 		commandname = fullname;
1244 		dot_funcnest_old = dot_funcnest;
1245 		dot_funcnest = funcnest + 1;
1246 		cmdloop(0);
1247 		dot_funcnest = dot_funcnest_old;
1248 		popfile();
1249 		popstackmark(&smark);
1250 	}
1251 	return exitstatus;
1252 }
1253 
1254 /*
1255  * Take commands from a file.  To be compatible we should do a path
1256  * search for the file, which is necessary to find sub-commands.
1257  */
1258 
1259 STATIC char *
1260 find_dot_file(char *basename)
1261 {
1262 	char *fullname;
1263 	const char *path = pathval();
1264 	struct stat statb;
1265 
1266 	/* don't try this for absolute or relative paths */
1267 	if (strchr(basename, '/')) {
1268 		if (stat(basename, &statb) == 0) {
1269 			if (S_ISDIR(statb.st_mode))
1270 				error("%s: is a directory", basename);
1271 			if (S_ISBLK(statb.st_mode))
1272 				error("%s: is a block device", basename);
1273 			return basename;
1274 		}
1275 	} else while ((fullname = padvance(&path, basename)) != NULL) {
1276 		if ((stat(fullname, &statb) == 0)) {
1277 			/* weird format is to ease future code... */
1278 			if (S_ISDIR(statb.st_mode) || S_ISBLK(statb.st_mode))
1279 				;
1280 #if notyet
1281 			else if (unreadable()) {
1282 				/*
1283 				 * testing this via st_mode is ugly to get
1284 				 * correct (and would ignore ACLs).
1285 				 * better way is just to open the file.
1286 				 * But doing that here would (currently)
1287 				 * mean opening the file twice, which
1288 				 * might not be safe.  So, defer this
1289 				 * test until code is restructures so
1290 				 * we can return a fd.   Then we also
1291 				 * get to fix the mem leak just below...
1292 				 */
1293 			}
1294 #endif
1295 			else {
1296 				/*
1297 				 * Don't bother freeing here, since
1298 				 * it will be freed by the caller.
1299 				 * XXX no it won't - a bug for later.
1300 				 */
1301 				return fullname;
1302 			}
1303 		}
1304 		stunalloc(fullname);
1305 	}
1306 
1307 	/* not found in the PATH */
1308 	error("%s: not found", basename);
1309 	/* NOTREACHED */
1310 }
1311 
1312 
1313 
1314 /*
1315  * The return command.
1316  *
1317  * Quoth the POSIX standard:
1318  *   The return utility shall cause the shell to stop executing the current
1319  *   function or dot script. If the shell is not currently executing
1320  *   a function or dot script, the results are unspecified.
1321  *
1322  * As for the unspecified part, there seems to be no de-facto standard: bash
1323  * ignores the return with a warning, zsh ignores the return in interactive
1324  * mode but seems to liken it to exit in a script.  (checked May 2014)
1325  *
1326  * We choose to silently ignore the return.  Older versions of this shell
1327  * set evalskip to SKIPFILE causing the shell to (indirectly) exit.  This
1328  * had at least the problem of circumventing the check for stopped jobs,
1329  * which would occur for exit or ^D.
1330  */
1331 
1332 int
1333 returncmd(int argc, char **argv)
1334 {
1335 	int ret = argc > 1 ? number(argv[1]) : exitstatus;
1336 
1337 	if ((dot_funcnest == 0 && funcnest)
1338 	    || (dot_funcnest > 0 && funcnest - (dot_funcnest - 1) > 0)) {
1339 		evalskip = SKIPFUNC;
1340 		skipcount = 1;
1341 	} else if (dot_funcnest > 0) {
1342 		evalskip = SKIPFILE;
1343 		skipcount = 1;
1344 	} else {
1345 		/* XXX: should a warning be issued? */
1346 		ret = 0;
1347 	}
1348 
1349 	return ret;
1350 }
1351 
1352 
1353 int
1354 falsecmd(int argc, char **argv)
1355 {
1356 	return 1;
1357 }
1358 
1359 
1360 int
1361 truecmd(int argc, char **argv)
1362 {
1363 	return 0;
1364 }
1365 
1366 
1367 int
1368 execcmd(int argc, char **argv)
1369 {
1370 	if (argc > 1) {
1371 		struct strlist *sp;
1372 
1373 		iflag = 0;		/* exit on error */
1374 		mflag = 0;
1375 		optschanged();
1376 		for (sp = cmdenviron; sp; sp = sp->next)
1377 			setvareq(sp->text, VEXPORT|VSTACK);
1378 		shellexec(argv + 1, environment(), pathval(), 0, 0);
1379 	}
1380 	return 0;
1381 }
1382 
1383 static int
1384 conv_time(clock_t ticks, char *seconds, size_t l)
1385 {
1386 	static clock_t tpm = 0;
1387 	clock_t mins;
1388 	int i;
1389 
1390 	if (!tpm)
1391 		tpm = sysconf(_SC_CLK_TCK) * 60;
1392 
1393 	mins = ticks / tpm;
1394 	snprintf(seconds, l, "%.4f", (ticks - mins * tpm) * 60.0 / tpm );
1395 
1396 	if (seconds[0] == '6' && seconds[1] == '0') {
1397 		/* 59.99995 got rounded up... */
1398 		mins++;
1399 		strlcpy(seconds, "0.0", l);
1400 		return mins;
1401 	}
1402 
1403 	/* suppress trailing zeros */
1404 	i = strlen(seconds) - 1;
1405 	for (; seconds[i] == '0' && seconds[i - 1] != '.'; i--)
1406 		seconds[i] = 0;
1407 	return mins;
1408 }
1409 
1410 int
1411 timescmd(int argc, char **argv)
1412 {
1413 	struct tms tms;
1414 	int u, s, cu, cs;
1415 	char us[8], ss[8], cus[8], css[8];
1416 
1417 	nextopt("");
1418 
1419 	times(&tms);
1420 
1421 	u = conv_time(tms.tms_utime, us, sizeof(us));
1422 	s = conv_time(tms.tms_stime, ss, sizeof(ss));
1423 	cu = conv_time(tms.tms_cutime, cus, sizeof(cus));
1424 	cs = conv_time(tms.tms_cstime, css, sizeof(css));
1425 
1426 	outfmt(out1, "%dm%ss %dm%ss\n%dm%ss %dm%ss\n",
1427 		u, us, s, ss, cu, cus, cs, css);
1428 
1429 	return 0;
1430 }
1431