1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* $NetBSD: jobs.c,v 1.62 2003/12/18 00:56:05 christos Exp $ */ 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*- 4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (c) 1991, 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[] = "@(#)jobs.c 8.5 (Berkeley) 5/4/95"; 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project__RCSID("$NetBSD: jobs.c,v 1.62 2003/12/18 00:56:05 christos 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 <fcntl.h> 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <signal.h> 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h> 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h> 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h> 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define _PATH_DEVNULL "/dev/null" 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/types.h> 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/param.h> 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef BSD 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/wait.h> 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/time.h> 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/resource.h> 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/wait.h> 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define killpg(s,i) kill(-(s),i) 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/ioctl.h> 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "shell.h" 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if JOBS 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if OLD_TTY_DRIVER 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "sgtty.h" 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <termios.h> 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#undef CEOF /* syntax.h redefines this */ 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "redir.h" 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "show.h" 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "main.h" 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "parser.h" 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "nodes.h" 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "jobs.h" 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "options.h" 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "trap.h" 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "syntax.h" 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "input.h" 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "output.h" 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "memalloc.h" 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "error.h" 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "mystring.h" 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// Use of process groups is disabled to allow adb shell children to terminate when the shell dies 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define USE_PROCESS_GROUPS 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic struct job *jobtab; /* array of jobs */ 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int njobs; /* size of array */ 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int jobs_invalid; /* set in child */ 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectMKINIT pid_t backgndpid = -1; /* pid of last background process */ 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if JOBS 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint initialpgrp; /* pgrp of shell on invocation */ 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int curjob = -1; /* current job */ 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int ttyfd = -1; 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC void restartjob(struct job *); 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC void freejob(struct job *); 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC struct job *getjob(const char *, int); 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC int dowait(int, struct job *); 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC int onsigchild(void); 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC int waitproc(int, struct job *, int *); 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC void cmdtxt(union node *); 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC void cmdlist(union node *, int); 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC void cmdputs(const char *); 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef OLD_TTY_DRIVER 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic pid_t tcgetpgrp(int fd); 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int tcsetpgrp(int fd, pid_t pgrp); 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic pid_t 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttcgetpgrp(int fd) 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pid_t pgrp; 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ioctl(fd, TIOCGPGRP, (char *)&pgrp) == -1) 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return pgrp; 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttcsetpgrp(int fd, pid_tpgrp) 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return ioctl(fd, TIOCSPGRP, (char *)&pgrp); 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Turn job control on and off. 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Note: This code assumes that the third arg to ioctl is a character 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * pointer, which is true on Berkeley systems but not System V. Since 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * System V doesn't have job control yet, this isn't a problem now. 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectMKINIT int jobctl; 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectsetjobctl(int on) 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef OLD_TTY_DRIVER 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ldisc; 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (on == jobctl || rootshell == 0) 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (on) { 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if defined(FIOCLEX) || defined(FD_CLOEXEC) 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int err; 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int i; 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ttyfd != -1) 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(ttyfd); 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((ttyfd = open("/dev/tty", O_RDWR)) == -1) { 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (i = 0; i < 3; i++) { 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (isatty(i) && (ttyfd = dup(i)) != -1) 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (i == 3) 161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto out; 162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* Move to a high fd */ 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (i = 10; i > 2; i--) { 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((err = fcntl(ttyfd, F_DUPFD, (1 << i) - 1)) != -1) 166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (err != -1) { 169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(ttyfd); 170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ttyfd = err; 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef FIOCLEX 173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = ioctl(ttyfd, FIOCLEX, 0); 174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#elif FD_CLOEXEC 175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = fcntl(ttyfd, F_SETFD, 176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fcntl(ttyfd, F_GETFD, 0) | FD_CLOEXEC); 177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (err == -1) { 179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(ttyfd); 180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ttyfd = -1; 181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto out; 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out2str("sh: Need FIOCLEX or FD_CLOEXEC to support job control"); 185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto out; 186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project do { /* while we are in the background */ 188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((initialpgrp = tcgetpgrp(ttyfd)) < 0) { 189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectout: 190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out2str("sh: can't access tty; job control turned off\n"); 191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mflag = 0; 192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (initialpgrp == -1) 195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project initialpgrp = getpgrp(); 196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else if (initialpgrp != getpgrp()) { 197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project killpg(0, SIGTTIN); 198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } while (0); 201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef OLD_TTY_DRIVER 203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ioctl(ttyfd, TIOCGETD, (char *)&ldisc) < 0 204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project || ldisc != NTTYDISC) { 205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out2str("sh: need new tty driver to run job control; job control turned off\n"); 206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mflag = 0; 207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project setsignal(SIGTSTP, 0); 211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project setsignal(SIGTTOU, 0); 212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project setsignal(SIGTTIN, 0); 213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef USE_PROCESS_GROUPS 214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (getpgid(0) != rootpid && setpgid(0, rootpid) == -1) 215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("Cannot set process group (%s) at %d", 216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strerror(errno), __LINE__); 217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (tcsetpgrp(ttyfd, rootpid) == -1) 218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("Cannot set tty process group (%s) at %d", 219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strerror(errno), __LINE__); 220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { /* turning job control off */ 222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef USE_PROCESS_GROUPS 223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (getpgid(0) != initialpgrp && setpgid(0, initialpgrp) == -1) 224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("Cannot set process group (%s) at %d", 225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strerror(errno), __LINE__); 226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (tcsetpgrp(ttyfd, initialpgrp) == -1) 227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("Cannot set tty process group (%s) at %d", 228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strerror(errno), __LINE__); 229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(ttyfd); 231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ttyfd = -1; 232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project setsignal(SIGTSTP, 0); 233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project setsignal(SIGTTOU, 0); 234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project setsignal(SIGTTIN, 0); 235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jobctl = on; 237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef mkinit 241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectINCLUDE <stdlib.h> 242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSHELLPROC { 244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project backgndpid = -1; 245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if JOBS 246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jobctl = 0; 247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if JOBS 255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint 256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectfgcmd(int argc, char **argv) 257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct job *jp; 259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int i; 260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int status; 261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project nextopt(""); 263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jp = getjob(*argptr, 0); 264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (jp->jobctl == 0) 265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("job not created under job control"); 266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1fmt("%s", jp->ps[0].cmd); 267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (i = 1; i < jp->nprocs; i++) 268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1fmt(" | %s", jp->ps[i].cmd ); 269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1c('\n'); 270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project flushall(); 271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (i = 0; i < jp->nprocs; i++) 273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (tcsetpgrp(ttyfd, jp->ps[i].pid) != -1) 274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (i >= jp->nprocs) { 277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("Cannot set tty process group (%s) at %d", 278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strerror(errno), __LINE__); 279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project restartjob(jp); 281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTOFF; 282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project status = waitforjob(jp); 283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTON; 284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return status; 285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void 288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectset_curjob(struct job *jp, int mode) 289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct job *jp1, *jp2; 291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int i, ji; 292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ji = jp - jobtab; 294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* first remove from list */ 296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ji == curjob) 297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project curjob = jp->prev_job; 298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else { 299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (i = 0; i < njobs; i++) { 300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (jobtab[i].prev_job != ji) 301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jobtab[i].prev_job = jp->prev_job; 303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* Then re-insert in correct position */ 308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch (mode) { 309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 0: /* job being deleted */ 310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jp->prev_job = -1; 311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 1: /* newly created job or backgrounded job, 313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put after all stopped jobs. */ 314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (curjob != -1 && jobtab[curjob].state == JOBSTOPPED) { 315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (jp1 = jobtab + curjob; ; jp1 = jp2) { 316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (jp1->prev_job == -1) 317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jp2 = jobtab + jp1->prev_job; 319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (jp2->state != JOBSTOPPED) 320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jp->prev_job = jp1->prev_job; 323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jp1->prev_job = ji; 324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* FALLTHROUGH */ 327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 2: /* newly stopped job - becomes curjob */ 328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jp->prev_job = curjob; 329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project curjob = ji; 330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint 335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectbgcmd(int argc, char **argv) 336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct job *jp; 338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int i; 339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project nextopt(""); 341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project do { 342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jp = getjob(*argptr, 0); 343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (jp->jobctl == 0) 344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("job not created under job control"); 345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project set_curjob(jp, 1); 346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1fmt("[%ld] %s", (long)(jp - jobtab + 1), jp->ps[0].cmd); 347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (i = 1; i < jp->nprocs; i++) 348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1fmt(" | %s", jp->ps[i].cmd ); 349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1c('\n'); 350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project flushall(); 351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project restartjob(jp); 352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } while (*argptr && *++argptr); 353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC void 358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectrestartjob(struct job *jp) 359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct procstat *ps; 361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int i; 362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (jp->state == JOBDONE) 364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTOFF; 366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (i = 0; i < jp->nprocs; i++) 367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (killpg(jp->ps[i].pid, SIGCONT) != -1) 368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (i >= jp->nprocs) 370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("Cannot continue job (%s)", strerror(errno)); 371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (ps = jp->ps, i = jp->nprocs ; --i >= 0 ; ps++) { 372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (WIFSTOPPED(ps->status)) { 373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ps->status = -1; 374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jp->state = JOBRUNNING; 375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTON; 378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void 382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectshowjob(struct output *out, struct job *jp, int mode) 383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int procno; 385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int st; 386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct procstat *ps; 387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int col; 388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char s[64]; 389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if JOBS 391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (mode & SHOW_PGID) { 392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* just output process (group) id of pipeline */ 393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project outfmt(out, "%ld\n", (long)jp->ps->pid); 394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project procno = jp->nprocs; 399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!procno) 400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (mode & SHOW_PID) 403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mode |= SHOW_MULTILINE; 404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((procno > 1 && !(mode & SHOW_MULTILINE)) 406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project || (mode & SHOW_SIGNALLED)) { 407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* See if we have more than one status to report */ 408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ps = jp->ps; 409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project st = ps->status; 410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project do { 411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int st1 = ps->status; 412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (st1 != st) 413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* yes - need multi-line output */ 414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mode |= SHOW_MULTILINE; 415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (st1 == -1 || !(mode & SHOW_SIGNALLED) || WIFEXITED(st1)) 416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (WIFSTOPPED(st1) || ((st1 = WTERMSIG(st1) & 0x7f) 418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project && st1 != SIGINT && st1 != SIGPIPE)) 419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mode |= SHOW_ISSIG; 420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } while (ps++, --procno); 422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project procno = jp->nprocs; 423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (mode & SHOW_SIGNALLED && !(mode & SHOW_ISSIG)) { 426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (jp->state == JOBDONE && !(mode & SHOW_NO_FREE)) { 427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project TRACE(("showjob: freeing job %d\n", jp - jobtab + 1)); 428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project freejob(jp); 429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (ps = jp->ps; --procno >= 0; ps++) { /* for each process */ 434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ps == jp->ps) 435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fmtstr(s, 16, "[%ld] %c ", 436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (long)(jp - jobtab + 1), 437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if JOBS 438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jp == jobtab + curjob ? '+' : 439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project curjob != -1 && jp == jobtab + 440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jobtab[curjob].prev_job ? '-' : 441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ' '); 443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fmtstr(s, 16, " " ); 445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project col = strlen(s); 446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (mode & SHOW_PID) { 447dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fmtstr(s + col, 16, "%ld ", (long)ps->pid); 448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project col += strlen(s + col); 449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 450dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ps->status == -1) { 451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project scopy("Running", s + col); 452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (WIFEXITED(ps->status)) { 453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project st = WEXITSTATUS(ps->status); 454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (st) 455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fmtstr(s + col, 16, "Done(%d)", st); 456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fmtstr(s + col, 16, "Done"); 458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if JOBS 460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (WIFSTOPPED(ps->status)) 461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project st = WSTOPSIG(ps->status); 462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else /* WIFSIGNALED(ps->status) */ 463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project st = WTERMSIG(ps->status); 465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project st &= 0x7f; 466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (st < NSIG && sys_siglist[st]) 467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project scopyn(sys_siglist[st], s + col, 32); 468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fmtstr(s + col, 16, "Signal %d", st); 470dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (WCOREDUMP(ps->status)) { 471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project col += strlen(s + col); 472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project scopyn(" (core dumped)", s + col, 64 - col); 473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project col += strlen(s + col); 476dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project outstr(s, out); 477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project do { 478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project outc(' ', out); 479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project col++; 480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } while (col < 30); 481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project outstr(ps->cmd, out); 482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (mode & SHOW_MULTILINE) { 483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (procno > 0) { 484dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project outc(' ', out); 485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project outc('|', out); 486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (--procno >= 0) 489dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project outfmt(out, " | %s", (++ps)->cmd ); 490dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 491dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project outc('\n', out); 492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 493dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project flushout(out); 494dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jp->changed = 0; 495dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (jp->state == JOBDONE && !(mode & SHOW_NO_FREE)) 496dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project freejob(jp); 497dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 498dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 499dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 500dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint 501dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectjobscmd(int argc, char **argv) 502dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 503dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int mode, m; 504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int sv = jobs_invalid; 505dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 506dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jobs_invalid = 0; 507dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mode = 0; 508dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while ((m = nextopt("lp"))) 509dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (m == 'l') 510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mode = SHOW_PID; 511dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 512dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mode = SHOW_PGID; 513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (*argptr) 514dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project do 515dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project showjob(out1, getjob(*argptr,0), mode); 516dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (*++argptr); 517dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 518dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project showjobs(out1, mode); 519dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jobs_invalid = sv; 520dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 521dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 522dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 523dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 524dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 525dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Print a list of jobs. If "change" is nonzero, only print jobs whose 526dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * statuses have changed since the last call to showjobs. 527dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 528dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * If the shell is interrupted in the process of creating a job, the 529dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * result may be a job structure containing zero processes. Such structures 530dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * will be freed here. 531dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 532dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 533dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid 534dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectshowjobs(struct output *out, int mode) 535dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 536dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int jobno; 537dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct job *jp; 538dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int silent = 0, gotpid; 539dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 540dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project TRACE(("showjobs(%x) called\n", mode)); 541dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 542dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* If not even one one job changed, there is nothing to do */ 543dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project gotpid = dowait(0, NULL); 544dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (dowait(0, NULL) > 0) 545dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 546dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef JOBS 547dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* 548dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Check if we are not in our foreground group, and if not 549dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * put us in it. 550dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 551dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (mflag && gotpid != -1 && tcgetpgrp(ttyfd) != getpid()) { 552dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (tcsetpgrp(ttyfd, getpid()) == -1) 553dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("Cannot set tty process group (%s) at %d", 554dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strerror(errno), __LINE__); 555dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project TRACE(("repaired tty process group\n")); 556dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project silent = 1; 557dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 558dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 559dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (jobs_invalid) 560dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 561dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 562dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (jobno = 1, jp = jobtab ; jobno <= njobs ; jobno++, jp++) { 563dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!jp->used) 564dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 565dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (jp->nprocs == 0) { 566dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project freejob(jp); 567dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 568dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 569dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((mode & SHOW_CHANGED) && !jp->changed) 570dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 571dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (silent && jp->changed) { 572dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jp->changed = 0; 573dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 574dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 575dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project showjob(out, jp, mode); 576dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 577dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 578dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 579dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 580dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Mark a job structure as unused. 581dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 582dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 583dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC void 584dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectfreejob(struct job *jp) 585dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 586dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTOFF; 587dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (jp->ps != &jp->ps0) { 588dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ckfree(jp->ps); 589dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jp->ps = &jp->ps0; 590dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 591dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jp->nprocs = 0; 592dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jp->used = 0; 593dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if JOBS 594dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project set_curjob(jp, 0); 595dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 596dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTON; 597dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 598dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 599dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 600dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 601dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint 602dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectwaitcmd(int argc, char **argv) 603dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 604dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct job *job; 605dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int status, retval = 127; 606dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct job *jp; 607dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 608dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project nextopt(""); 609dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 610dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!*argptr) { 611dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* wait for all jobs */ 612dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jp = jobtab; 613dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (jobs_invalid) 614dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 615dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (;;) { 616dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (jp >= jobtab + njobs) { 617dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* no running procs */ 618dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 619dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 620dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!jp->used || jp->state != JOBRUNNING) { 621dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jp++; 622dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 623dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 624dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (dowait(1, (struct job *)NULL) == -1) 625dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 128 + SIGINT; 626dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jp = jobtab; 627dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 628dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 629dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 630dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (; *argptr; argptr++) { 631dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project job = getjob(*argptr, 1); 632dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!job) { 633dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project retval = 127; 634dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 635dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 636dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* loop until process terminated or stopped */ 637dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (job->state == JOBRUNNING) { 638dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (dowait(1, (struct job *)NULL) == -1) 639dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 128 + SIGINT; 640dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 641dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project status = job->ps[job->nprocs].status; 642dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (WIFEXITED(status)) 643dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project retval = WEXITSTATUS(status); 644dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if JOBS 645dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else if (WIFSTOPPED(status)) 646dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project retval = WSTOPSIG(status) + 128; 647dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 648dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else { 649dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* XXX: limits number of signals */ 650dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project retval = WTERMSIG(status) + 128; 651dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 652dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!iflag) 653dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project freejob(job); 654dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 655dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return retval; 656dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 657dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 658dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 659dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 660dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint 661dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectjobidcmd(int argc, char **argv) 662dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 663dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct job *jp; 664dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int i; 665dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 666dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project nextopt(""); 667dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jp = getjob(*argptr, 0); 668dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (i = 0 ; i < jp->nprocs ; ) { 669dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1fmt("%ld", (long)jp->ps[i].pid); 670dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1c(++i < jp->nprocs ? ' ' : '\n'); 671dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 672dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 673dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 674dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 675dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint 676dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectgetjobpgrp(const char *name) 677dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 678dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct job *jp; 679dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 680dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jp = getjob(name, 1); 681dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (jp == 0) 682dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 683dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -jp->ps[0].pid; 684dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 685dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 686dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 687dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Convert a job name to a job structure. 688dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 689dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 690dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC struct job * 691dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectgetjob(const char *name, int noerror) 692dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 693dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int jobno = -1; 694dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct job *jp; 695dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int pid; 696dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int i; 697dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char *err_msg = "No such job: %s"; 698dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 699dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (name == NULL) { 700dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if JOBS 701dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jobno = curjob; 702dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 703dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err_msg = "No current job"; 704dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (name[0] == '%') { 705dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (is_number(name + 1)) { 706dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jobno = number(name + 1) - 1; 707dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (!name[2]) { 708dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch (name[1]) { 709dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if JOBS 710dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 0: 711dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case '+': 712dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case '%': 713dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jobno = curjob; 714dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err_msg = "No current job"; 715dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 716dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case '-': 717dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jobno = curjob; 718dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (jobno != -1) 719dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jobno = jobtab[jobno].prev_job; 720dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err_msg = "No previous job"; 721dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 722dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 723dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project default: 724dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto check_pattern; 725dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 726dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 727dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct job *found; 728dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project check_pattern: 729dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project found = NULL; 730dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) { 731dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!jp->used || jp->nprocs <= 0) 732dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 733dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((name[1] == '?' 734dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project && strstr(jp->ps[0].cmd, name + 2)) 735dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project || prefix(name + 1, jp->ps[0].cmd)) { 736dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (found) { 737dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err_msg = "%s: ambiguous"; 738dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project found = 0; 739dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 740dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 741dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project found = jp; 742dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 743dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 744dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (found) 745dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return found; 746dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 747dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 748dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (is_number(name)) { 749dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pid = number(name); 750dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) { 751dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (jp->used && jp->nprocs > 0 752dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project && jp->ps[jp->nprocs - 1].pid == pid) 753dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return jp; 754dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 755dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 756dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 757dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!jobs_invalid && jobno >= 0 && jobno < njobs) { 758dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jp = jobtab + jobno; 759dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (jp->used) 760dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return jp; 761dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 762dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!noerror) 763dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error(err_msg, name); 764dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 765dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 766dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 767dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 768dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 769dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 770dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Return a new job structure, 771dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 772dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 773dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct job * 774dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectmakejob(union node *node, int nprocs) 775dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 776dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int i; 777dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct job *jp; 778dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 779dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (jobs_invalid) { 780dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (i = njobs, jp = jobtab ; --i >= 0 ; jp++) { 781dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (jp->used) 782dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project freejob(jp); 783dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 784dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jobs_invalid = 0; 785dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 786dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 787dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (i = njobs, jp = jobtab ; ; jp++) { 788dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (--i < 0) { 789dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTOFF; 790dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (njobs == 0) { 791dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jobtab = ckmalloc(4 * sizeof jobtab[0]); 792dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 793dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jp = ckmalloc((njobs + 4) * sizeof jobtab[0]); 794dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memcpy(jp, jobtab, njobs * sizeof jp[0]); 795dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* Relocate `ps' pointers */ 796dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (i = 0; i < njobs; i++) 797dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (jp[i].ps == &jobtab[i].ps0) 798dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jp[i].ps = &jp[i].ps0; 799dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ckfree(jobtab); 800dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jobtab = jp; 801dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 802dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jp = jobtab + njobs; 803dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (i = 4 ; --i >= 0 ; jobtab[njobs++].used = 0); 804dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTON; 805dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 806dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 807dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (jp->used == 0) 808dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 809dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 810dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTOFF; 811dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jp->state = JOBRUNNING; 812dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jp->used = 1; 813dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jp->changed = 0; 814dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jp->nprocs = 0; 815dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if JOBS 816dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jp->jobctl = jobctl; 817dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project set_curjob(jp, 1); 818dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 819dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (nprocs > 1) { 820dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jp->ps = ckmalloc(nprocs * sizeof (struct procstat)); 821dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 822dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jp->ps = &jp->ps0; 823dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 824dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTON; 825dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project TRACE(("makejob(0x%lx, %d) returns %%%d\n", (long)node, nprocs, 826dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jp - jobtab + 1)); 827dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return jp; 828dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 829dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 830dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 831dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 832dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Fork off a subshell. If we are doing job control, give the subshell its 833dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * own process group. Jp is a job structure that the job is to be added to. 834dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * N is the command that will be evaluated by the child. Both jp and n may 835dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * be NULL. The mode parameter can be one of the following: 836dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * FORK_FG - Fork off a foreground process. 837dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * FORK_BG - Fork off a background process. 838dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * FORK_NOJOB - Like FORK_FG, but don't give the process its own 839dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * process group even if job control is on. 840dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 841dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * When job control is turned off, background processes have their standard 842dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * input redirected to /dev/null (except for the second and later processes 843dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * in a pipeline). 844dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 845dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 846dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint 847dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectforkshell(struct job *jp, union node *n, int mode) 848dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 849dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int pid; 850dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 851dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project TRACE(("forkshell(%%%d, %p, %d) called\n", jp - jobtab, n, mode)); 852dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch ((pid = fork())) { 853dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case -1: 854dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project TRACE(("Fork failed, errno=%d\n", errno)); 855dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTON; 856dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("Cannot fork"); 857dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 858dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 0: 859dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project forkchild(jp, n, mode, 0); 860dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 861dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project default: 862dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return forkparent(jp, n, mode, pid); 863dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 864dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 865dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 866dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint 867dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectforkparent(struct job *jp, union node *n, int mode, pid_t pid) 868dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 869dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int pgrp; 870dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 871dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (rootshell && mode != FORK_NOJOB && mflag) { 872dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (jp == NULL || jp->nprocs == 0) 873dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pgrp = pid; 874dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 875dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pgrp = jp->ps[0].pid; 876dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef USE_PROCESS_GROUPS 877dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* This can fail because we are doing it in the child also */ 878dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (void)setpgid(pid, pgrp); 879dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 880dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 881dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (mode == FORK_BG) 882dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project backgndpid = pid; /* set $! */ 883dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (jp) { 884dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct procstat *ps = &jp->ps[jp->nprocs++]; 885dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ps->pid = pid; 886dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ps->status = -1; 887dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ps->cmd[0] = 0; 888dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (/* iflag && rootshell && */ n) 889dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project commandtext(ps, n); 890dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 891dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project TRACE(("In parent shell: child = %d\n", pid)); 892dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return pid; 893dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 894dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 895dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid 896dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectforkchild(struct job *jp, union node *n, int mode, int vforked) 897dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 898dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int wasroot; 899dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int pgrp; 900dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char *devnull = _PATH_DEVNULL; 901dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char *nullerr = "Can't open %s"; 902dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 903dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project wasroot = rootshell; 904dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project TRACE(("Child shell %d\n", getpid())); 905dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!vforked) 906dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project rootshell = 0; 907dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 908dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project closescript(vforked); 909dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project clear_traps(vforked); 910dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if JOBS 911dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!vforked) 912dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jobctl = 0; /* do job control only in root shell */ 913dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (wasroot && mode != FORK_NOJOB && mflag) { 914dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (jp == NULL || jp->nprocs == 0) 915dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pgrp = getpid(); 916dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 917dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pgrp = jp->ps[0].pid; 918dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef USE_PROCESS_GROUPS 919dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* This can fail because we are doing it in the parent also */ 920dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (void)setpgid(0, pgrp); 921dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (mode == FORK_FG) { 922dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (tcsetpgrp(ttyfd, pgrp) == -1) 923dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("Cannot set tty process group (%s) at %d", 924dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strerror(errno), __LINE__); 925dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 926dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 927dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project setsignal(SIGTSTP, vforked); 928dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project setsignal(SIGTTOU, vforked); 929dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (mode == FORK_BG) { 930dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ignoresig(SIGINT, vforked); 931dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ignoresig(SIGQUIT, vforked); 932dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((jp == NULL || jp->nprocs == 0) && 933dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ! fd0_redirected_p ()) { 934dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(0); 935dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (open(devnull, O_RDONLY) != 0) 936dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error(nullerr, devnull); 937dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 938dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 939dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 940dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (mode == FORK_BG) { 941dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ignoresig(SIGINT, vforked); 942dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ignoresig(SIGQUIT, vforked); 943dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((jp == NULL || jp->nprocs == 0) && 944dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ! fd0_redirected_p ()) { 945dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(0); 946dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (open(devnull, O_RDONLY) != 0) 947dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error(nullerr, devnull); 948dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 949dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 950dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 951dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (wasroot && iflag) { 952dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project setsignal(SIGINT, vforked); 953dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project setsignal(SIGQUIT, vforked); 954dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project setsignal(SIGTERM, vforked); 955dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 956dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 957dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!vforked) 958dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jobs_invalid = 1; 959dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 960dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 961dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 962dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Wait for job to finish. 963dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 964dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Under job control we have the problem that while a child process is 965dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * running interrupts generated by the user are sent to the child but not 966dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * to the shell. This means that an infinite loop started by an inter- 967dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * active user may be hard to kill. With job control turned off, an 968dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * interactive user may place an interactive program inside a loop. If 969dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * the interactive program catches interrupts, the user doesn't want 970dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * these interrupts to also abort the loop. The approach we take here 971dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * is to have the shell ignore interrupt signals while waiting for a 972dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * forground process to terminate, and then send itself an interrupt 973dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * signal if the child process was terminated by an interrupt signal. 974dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Unfortunately, some programs want to do a bit of cleanup and then 975dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * exit on interrupt; unless these processes terminate themselves by 976dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * sending a signal to themselves (instead of calling exit) they will 977dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * confuse this approach. 978dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 979dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 980dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint 981dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectwaitforjob(struct job *jp) 982dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 983dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if JOBS 984dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int mypgrp = getpgrp(); 985dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 986dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int status; 987dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int st; 988dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 989dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTOFF; 990dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project TRACE(("waitforjob(%%%d) called\n", jp - jobtab + 1)); 991dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (jp->state == JOBRUNNING) { 992dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dowait(1, jp); 993dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 994dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if JOBS 995dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (jp->jobctl) { 996dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (tcsetpgrp(ttyfd, mypgrp) == -1) 997dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("Cannot set tty process group (%s) at %d", 998dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strerror(errno), __LINE__); 999dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1000dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (jp->state == JOBSTOPPED && curjob != jp - jobtab) 1001dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project set_curjob(jp, 2); 1002dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 1003dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project status = jp->ps[jp->nprocs - 1].status; 1004dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* convert to 8 bits */ 1005dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (WIFEXITED(status)) 1006dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project st = WEXITSTATUS(status); 1007dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if JOBS 1008dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else if (WIFSTOPPED(status)) 1009dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project st = WSTOPSIG(status) + 128; 1010dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 1011dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 1012dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project st = WTERMSIG(status) + 128; 1013dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project TRACE(("waitforjob: job %d, nproc %d, status %x, st %x\n", 1014dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jp - jobtab + 1, jp->nprocs, status, st )); 1015dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if JOBS 1016dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (jp->jobctl) { 1017dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* 1018dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * This is truly gross. 1019dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * If we're doing job control, then we did a TIOCSPGRP which 1020dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * caused us (the shell) to no longer be in the controlling 1021dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * session -- so we wouldn't have seen any ^C/SIGINT. So, we 1022dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * intuit from the subprocess exit status whether a SIGINT 1023dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * occurred, and if so interrupt ourselves. Yuck. - mycroft 1024dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 1025dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (WIFSIGNALED(status) && WTERMSIG(status) == SIGINT) 1026dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project raise(SIGINT); 1027dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1028dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 1029dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (! JOBS || jp->state == JOBDONE) 1030dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project freejob(jp); 1031dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTON; 1032dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return st; 1033dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 1034dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1035dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1036dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1037dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 1038dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Wait for a process to terminate. 1039dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 1040dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1041dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC int 1042dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdowait(int block, struct job *job) 1043dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 1044dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int pid; 1045dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int status; 1046dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct procstat *sp; 1047dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct job *jp; 1048dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct job *thisjob; 1049dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int done; 1050dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int stopped; 1051dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project extern volatile char gotsig[]; 1052dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1053dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project TRACE(("dowait(%d) called\n", block)); 1054dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project do { 1055dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pid = waitproc(block, job, &status); 1056dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project TRACE(("wait returns pid %d, status %d\n", pid, status)); 1057dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } while (pid == -1 && errno == EINTR && gotsig[SIGINT - 1] == 0); 1058dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (pid <= 0) 1059dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return pid; 1060dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTOFF; 1061dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project thisjob = NULL; 1062dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (jp = jobtab ; jp < jobtab + njobs ; jp++) { 1063dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (jp->used) { 1064dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project done = 1; 1065dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project stopped = 1; 1066dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (sp = jp->ps ; sp < jp->ps + jp->nprocs ; sp++) { 1067dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (sp->pid == -1) 1068dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 1069dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (sp->pid == pid) { 1070dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project TRACE(("Job %d: changing status of proc %d from 0x%x to 0x%x\n", jp - jobtab + 1, pid, sp->status, status)); 1071dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sp->status = status; 1072dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project thisjob = jp; 1073dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1074dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (sp->status == -1) 1075dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project stopped = 0; 1076dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else if (WIFSTOPPED(sp->status)) 1077dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project done = 0; 1078dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1079dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (stopped) { /* stopped or done */ 1080dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int state = done ? JOBDONE : JOBSTOPPED; 1081dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (jp->state != state) { 1082dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project TRACE(("Job %d: changing state from %d to %d\n", jp - jobtab + 1, jp->state, state)); 1083dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jp->state = state; 1084dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if JOBS 1085dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (done) 1086dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project set_curjob(jp, 0); 1087dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 1088dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1089dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1090dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1091dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1092dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1093dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (thisjob && thisjob->state != JOBRUNNING) { 1094dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int mode = 0; 1095dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!rootshell || !iflag) 1096dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mode = SHOW_SIGNALLED; 1097dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (job == thisjob) 1098dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mode = SHOW_SIGNALLED | SHOW_NO_FREE; 1099dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (mode) 1100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project showjob(out2, thisjob, mode); 1101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else { 1102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project TRACE(("Not printing status, rootshell=%d, job=%p\n", 1103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project rootshell, job)); 1104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project thisjob->changed = 1; 1105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTON; 1109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return pid; 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 * Do a wait system call. If job control is compiled in, we accept 1116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * stopped processes. If block is zero, we return a value of zero 1117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * rather than blocking. 1118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 1119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * System V doesn't have a non-blocking wait system call. It does 1120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * have a SIGCLD signal that is sent to a process when one of it's 1121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * children dies. The obvious way to use SIGCLD would be to install 1122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * a handler for SIGCLD which simply bumped a counter when a SIGCLD 1123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * was received, and have waitproc bump another counter when it got 1124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * the status of a process. Waitproc would then know that a wait 1125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * system call would not block if the two counters were different. 1126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * This approach doesn't work because if a process has children that 1127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * have not been waited for, System V will send it a SIGCLD when it 1128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * installs a signal handler for SIGCLD. What this means is that when 1129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * a child exits, the shell will be sent SIGCLD signals continuously 1130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * until is runs out of stack space, unless it does a wait call before 1131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * restoring the signal handler. The code below takes advantage of 1132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * this (mis)feature by installing a signal handler for SIGCLD and 1133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * then checking to see whether it was called. If there are any 1134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * children to be waited for, it will be. 1135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 1136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * If neither SYSV nor BSD is defined, we don't implement nonblocking 1137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * waits at all. In this case, the user will not be informed when 1138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * a background process until the next time she runs a real program 1139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * (as opposed to running a builtin command or just typing return), 1140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * and the jobs command may give out of date information. 1141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 1142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef SYSV 1144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC int gotsigchild; 1145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC int onsigchild() { 1147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project gotsigchild = 1; 1148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 1149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 1150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC int 1153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectwaitproc(int block, struct job *jp, int *status) 1154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 1155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef BSD 1156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int flags = 0; 1157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if JOBS 1159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (jp != NULL && jp->jobctl) 1160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project flags |= WUNTRACED; 1161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 1162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (block == 0) 1163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project flags |= WNOHANG; 1164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return wait3(status, flags, (struct rusage *)NULL); 1165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 1166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef SYSV 1167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int (*save)(); 1168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (block == 0) { 1170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project gotsigchild = 0; 1171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project save = signal(SIGCLD, onsigchild); 1172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project signal(SIGCLD, save); 1173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (gotsigchild == 0) 1174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 1175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return wait(status); 1177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 1178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (block == 0) 1179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 1180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return wait(status); 1181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 1182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 1183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 1184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 1186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * return 1 if there are stopped jobs, otherwise 0 1187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 1188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint job_warning = 0; 1189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint 1190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstoppedjobs(void) 1191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 1192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int jobno; 1193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct job *jp; 1194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (job_warning || jobs_invalid) 1196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return (0); 1197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (jobno = 1, jp = jobtab; jobno <= njobs; jobno++, jp++) { 1198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (jp->used == 0) 1199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 1200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (jp->state == JOBSTOPPED) { 1201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out2str("You have stopped jobs.\n"); 1202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project job_warning = 2; 1203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return (1); 1204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return (0); 1208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 1209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 1211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Return a string identifying a command (to be printed by the 1212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * jobs command). 1213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 1214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC char *cmdnextc; 1216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC int cmdnleft; 1217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid 1219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectcommandtext(struct procstat *ps, union node *n) 1220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 1221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len; 1222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdnextc = ps->cmd; 1224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (iflag || mflag || sizeof ps->cmd < 100) 1225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = sizeof(ps->cmd); 1226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 1227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = sizeof(ps->cmd) / 10; 1228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdnleft = len; 1229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdtxt(n); 1230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (cmdnleft <= 0) { 1231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *p = ps->cmd + len - 4; 1232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p[0] = '.'; 1233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p[1] = '.'; 1234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p[2] = '.'; 1235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p[3] = 0; 1236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else 1237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *cmdnextc = '\0'; 1238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project TRACE(("commandtext: ps->cmd %x, end %x, left %d\n\t\"%s\"\n", 1239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ps->cmd, cmdnextc, cmdnleft, ps->cmd)); 1240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 1241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC void 1244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectcmdtxt(union node *n) 1245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 1246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project union node *np; 1247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct nodelist *lp; 1248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char *p; 1249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int i; 1250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char s[2]; 1251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (n == NULL || cmdnleft <= 0) 1253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 1254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch (n->type) { 1255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case NSEMI: 1256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdtxt(n->nbinary.ch1); 1257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdputs("; "); 1258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdtxt(n->nbinary.ch2); 1259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 1260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case NAND: 1261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdtxt(n->nbinary.ch1); 1262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdputs(" && "); 1263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdtxt(n->nbinary.ch2); 1264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 1265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case NOR: 1266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdtxt(n->nbinary.ch1); 1267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdputs(" || "); 1268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdtxt(n->nbinary.ch2); 1269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 1270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case NPIPE: 1271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) { 1272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdtxt(lp->n); 1273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (lp->next) 1274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdputs(" | "); 1275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 1277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case NSUBSHELL: 1278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdputs("("); 1279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdtxt(n->nredir.n); 1280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdputs(")"); 1281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 1282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case NREDIR: 1283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case NBACKGND: 1284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdtxt(n->nredir.n); 1285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 1286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case NIF: 1287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdputs("if "); 1288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdtxt(n->nif.test); 1289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdputs("; then "); 1290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdtxt(n->nif.ifpart); 1291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (n->nif.elsepart) { 1292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdputs("; else "); 1293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdtxt(n->nif.elsepart); 1294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdputs("; fi"); 1296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 1297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case NWHILE: 1298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdputs("while "); 1299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto until; 1300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case NUNTIL: 1301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdputs("until "); 1302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectuntil: 1303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdtxt(n->nbinary.ch1); 1304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdputs("; do "); 1305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdtxt(n->nbinary.ch2); 1306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdputs("; done"); 1307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 1308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case NFOR: 1309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdputs("for "); 1310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdputs(n->nfor.var); 1311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdputs(" in "); 1312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdlist(n->nfor.args, 1); 1313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdputs("; do "); 1314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdtxt(n->nfor.body); 1315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdputs("; done"); 1316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 1317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case NCASE: 1318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdputs("case "); 1319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdputs(n->ncase.expr->narg.text); 1320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdputs(" in "); 1321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (np = n->ncase.cases; np; np = np->nclist.next) { 1322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdtxt(np->nclist.pattern); 1323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdputs(") "); 1324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdtxt(np->nclist.body); 1325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdputs(";; "); 1326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdputs("esac"); 1328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 1329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case NDEFUN: 1330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdputs(n->narg.text); 1331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdputs("() { ... }"); 1332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 1333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case NCMD: 1334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdlist(n->ncmd.args, 1); 1335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdlist(n->ncmd.redirect, 0); 1336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 1337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case NARG: 1338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdputs(n->narg.text); 1339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 1340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case NTO: 1341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p = ">"; i = 1; goto redir; 1342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case NCLOBBER: 1343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p = ">|"; i = 1; goto redir; 1344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case NAPPEND: 1345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p = ">>"; i = 1; goto redir; 1346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case NTOFD: 1347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p = ">&"; i = 1; goto redir; 1348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case NFROM: 1349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p = "<"; i = 0; goto redir; 1350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case NFROMFD: 1351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p = "<&"; i = 0; goto redir; 1352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case NFROMTO: 1353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p = "<>"; i = 0; goto redir; 1354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectredir: 1355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (n->nfile.fd != i) { 1356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s[0] = n->nfile.fd + '0'; 1357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s[1] = '\0'; 1358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdputs(s); 1359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdputs(p); 1361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (n->type == NTOFD || n->type == NFROMFD) { 1362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s[0] = n->ndup.dupfd + '0'; 1363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s[1] = '\0'; 1364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdputs(s); 1365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 1366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdtxt(n->nfile.fname); 1367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 1369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case NHERE: 1370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case NXHERE: 1371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdputs("<<..."); 1372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 1373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project default: 1374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdputs("???"); 1375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 1376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 1378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC void 1380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectcmdlist(union node *np, int sep) 1381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 1382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (; np; np = np->narg.next) { 1383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!sep) 1384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdputs(" "); 1385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdtxt(np); 1386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (sep && np->narg.next) 1387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdputs(" "); 1388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 1390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC void 1393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectcmdputs(const char *s) 1394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 1395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char *p, *str = 0; 1396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char c, cc[2] = " "; 1397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *nextc; 1398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int nleft; 1399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int subtype = 0; 1400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int quoted = 0; 1401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project static char vstype[16][4] = { "", "}", "-", "+", "?", "=", 1402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "#", "##", "%", "%%" }; 1403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p = s; 1405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project nextc = cmdnextc; 1406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project nleft = cmdnleft; 1407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (nleft > 0 && (c = *p++) != 0) { 1408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch (c) { 1409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CTLESC: 1410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project c = *p++; 1411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 1412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CTLVAR: 1413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project subtype = *p++; 1414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((subtype & VSTYPE) == VSLENGTH) 1415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project str = "${#"; 1416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 1417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project str = "${"; 1418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!(subtype & VSQUOTE) != !(quoted & 1)) { 1419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project quoted ^= 1; 1420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project c = '"'; 1421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else 1422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project c = *str++; 1423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 1424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CTLENDVAR: 1425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (quoted & 1) { 1426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project c = '"'; 1427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project str = "}"; 1428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else 1429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project c = '}'; 1430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project quoted >>= 1; 1431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project subtype = 0; 1432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 1433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CTLBACKQ: 1434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project c = '$'; 1435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project str = "(...)"; 1436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 1437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CTLBACKQ+CTLQUOTE: 1438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project c = '"'; 1439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project str = "$(...)\""; 1440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 1441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CTLARI: 1442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project c = '$'; 1443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project str = "(("; 1444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 1445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CTLENDARI: 1446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project c = ')'; 1447dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project str = ")"; 1448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 1449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case CTLQUOTEMARK: 1450dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project quoted ^= 1; 1451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project c = '"'; 1452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 1453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case '=': 1454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (subtype == 0) 1455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 1456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project str = vstype[subtype & VSTYPE]; 1457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (subtype & VSNUL) 1458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project c = ':'; 1459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 1460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project c = *str++; 1461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (c != '}') 1462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project quoted <<= 1; 1463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 1464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case '\'': 1465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case '\\': 1466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case '"': 1467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case '$': 1468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* These can only happen inside quotes */ 1469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cc[0] = c; 1470dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project str = cc; 1471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project c = '\\'; 1472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 1473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project default: 1474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 1475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1476dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project do { 1477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *nextc++ = c; 1478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } while (--nleft > 0 && str && (c = *str++)); 1479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project str = 0; 1480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((quoted & 1) && nleft) { 1482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *nextc++ = '"'; 1483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project nleft--; 1484dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdnleft = nleft; 1486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdnextc = nextc; 1487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 1488