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