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; 690dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct jmploc *volatile savehandler; 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(); 697dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project volatile int temp_path; 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