redir.c revision dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0
1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* $NetBSD: redir.c,v 1.29 2004/07/08 03:57:33 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[] = "@(#)redir.c 8.2 (Berkeley) 5/4/95"; 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project__RCSID("$NetBSD: redir.c,v 1.29 2004/07/08 03:57:33 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 <sys/types.h> 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/param.h> /* PIPE_BUF */ 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <signal.h> 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h> 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <fcntl.h> 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h> 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h> 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h> 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Code for dealing with input/output redirection. 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "main.h" 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "shell.h" 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "nodes.h" 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "jobs.h" 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "options.h" 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "expand.h" 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "redir.h" 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "output.h" 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "memalloc.h" 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "error.h" 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define EMPTY -2 /* marks an unused slot in redirtab */ 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef PIPE_BUF 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project# define PIPESIZE 4096 /* amount of buffering in a pipe */ 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project# define PIPESIZE PIPE_BUF 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define signal bsd_signal 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectMKINIT 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct redirtab { 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct redirtab *next; 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project short renamed[10]; 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectMKINIT struct redirtab *redirlist; 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * We keep track of whether or not fd0 has been redirected. This is for 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * background commands, where we want to redirect fd0 to /dev/null only 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * if it hasn't already been redirected. 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/ 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint fd0_redirected = 0; 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC void openredirect(union node *, char[10], int); 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC int openhere(union node *); 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Process a list of redirection commands. If the REDIR_PUSH flag is set, 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * old file descriptors are stashed away so that the redirection can be 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * undone by calling popredir. If the REDIR_BACKQ flag is set, then the 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * standard output, and the standard error if it becomes a duplicate of 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * stdout, is saved in memory. 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectredirect(union node *redir, int flags) 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project union node *n; 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct redirtab *sv = NULL; 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int i; 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd; 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int try; 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char memory[10]; /* file descriptors to write to memory */ 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (i = 10 ; --i >= 0 ; ) 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memory[i] = 0; 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memory[1] = flags & REDIR_BACKQ; 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (flags & REDIR_PUSH) { 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* We don't have to worry about REDIR_VFORK here, as 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * flags & REDIR_PUSH is never true if REDIR_VFORK is set. 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sv = ckmalloc(sizeof (struct redirtab)); 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (i = 0 ; i < 10 ; i++) 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sv->renamed[i] = EMPTY; 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sv->next = redirlist; 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project redirlist = sv; 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (n = redir ; n ; n = n->nfile.next) { 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = n->nfile.fd; 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project try = 0; 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((n->nfile.type == NTOFD || n->nfile.type == NFROMFD) && 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project n->ndup.dupfd == fd) 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; /* redirect from/to same file descriptor */ 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((flags & REDIR_PUSH) && sv->renamed[fd] == EMPTY) { 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTOFF; 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectagain: 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((i = fcntl(fd, F_DUPFD, 10)) == -1) { 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch (errno) { 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case EBADF: 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!try) { 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project openredirect(n, memory, flags); 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project try++; 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto again; 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* FALLTHROUGH*/ 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project default: 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTON; 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("%d: %s", fd, strerror(errno)); 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* NOTREACHED */ 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!try) { 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sv->renamed[fd] = i; 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTON; 159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fd == 0) 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd0_redirected++; 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!try) 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project openredirect(n, memory, flags); 166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (memory[1]) 168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1 = &memout; 169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (memory[2]) 170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out2 = &memout; 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC void 175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectopenredirect(union node *redir, char memory[10], int flags) 176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd = redir->nfile.fd; 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *fname; 179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int f; 180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int oflags = O_WRONLY|O_CREAT|O_TRUNC, eflags; 181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* 183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * We suppress interrupts so that we won't leave open file 184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * descriptors around. This may not be such a good idea because 185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * an open of a device or a fifo can block indefinitely. 186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTOFF; 188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memory[fd] = 0; 189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch (redir->nfile.type) { 190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case NFROM: 191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fname = redir->nfile.expfname; 192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (flags & REDIR_VFORK) 193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project eflags = O_NONBLOCK; 194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project eflags = 0; 196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((f = open(fname, O_RDONLY|eflags)) < 0) 197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto eopen; 198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (eflags) 199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (void)fcntl(f, F_SETFL, fcntl(f, F_GETFL, 0) & ~eflags); 200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case NFROMTO: 202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fname = redir->nfile.expfname; 203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((f = open(fname, O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0) 204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto ecreate; 205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case NTO: 207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (Cflag) 208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project oflags |= O_EXCL; 209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* FALLTHROUGH */ 210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case NCLOBBER: 211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fname = redir->nfile.expfname; 212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((f = open(fname, oflags, 0666)) < 0) 213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto ecreate; 214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case NAPPEND: 216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fname = redir->nfile.expfname; 217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666)) < 0) 218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto ecreate; 219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case NTOFD: 221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case NFROMFD: 222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (redir->ndup.dupfd >= 0) { /* if not ">&-" */ 223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (memory[redir->ndup.dupfd]) 224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memory[fd] = 1; 225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project copyfd(redir->ndup.dupfd, fd); 227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTON; 229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case NHERE: 231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case NXHERE: 232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project f = openhere(redir); 233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project default: 235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project abort(); 236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (f != fd) { 239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project copyfd(f, fd); 240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(f); 241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTON; 243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectecreate: 245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("cannot create %s: %s", fname, errmsg(errno, E_CREAT)); 246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecteopen: 247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("cannot open %s: %s", fname, errmsg(errno, E_OPEN)); 248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Handle here documents. Normally we fork off a process to write the 253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * data to a pipe. If the document is short, we can stuff the data in 254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * the pipe without forking. 255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC int 258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectopenhere(union node *redir) 259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int pip[2]; 261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len = 0; 262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (pipe(pip) < 0) 264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("Pipe call failed"); 265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (redir->type == NHERE) { 266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = strlen(redir->nhere.doc->narg.text); 267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (len <= PIPESIZE) { 268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project xwrite(pip[1], redir->nhere.doc->narg.text, len); 269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto out; 270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) { 273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(pip[0]); 274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project signal(SIGINT, SIG_IGN); 275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project signal(SIGQUIT, SIG_IGN); 276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project signal(SIGHUP, SIG_IGN); 277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef SIGTSTP 278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project signal(SIGTSTP, SIG_IGN); 279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project signal(SIGPIPE, SIG_DFL); 281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (redir->type == NHERE) 282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project xwrite(pip[1], redir->nhere.doc->narg.text, len); 283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project expandhere(redir->nhere.doc, pip[1]); 285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project _exit(0); 286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectout: 288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(pip[1]); 289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return pip[0]; 290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Undo the effects of the last redirection. 296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid 299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectpopredir(void) 300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct redirtab *rp = redirlist; 302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int i; 303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (i = 0 ; i < 10 ; i++) { 305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (rp->renamed[i] != EMPTY) { 306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (i == 0) 307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd0_redirected--; 308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(i); 309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (rp->renamed[i] >= 0) { 310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project copyfd(rp->renamed[i], i); 311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(rp->renamed[i]); 312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTOFF; 316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project redirlist = rp->next; 317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ckfree(rp); 318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTON; 319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Undo all redirections. Called on error or interrupt. 323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef mkinit 326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectINCLUDE "redir.h" 328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectRESET { 330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (redirlist) 331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project popredir(); 332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSHELLPROC { 335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project clearredir(0); 336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* Return true if fd 0 has already been redirected at least once. */ 341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint 342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectfd0_redirected_p () { 343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return fd0_redirected != 0; 344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Discard all saved file descriptors. 348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid 351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectclearredir(vforked) 352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int vforked; 353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct redirtab *rp; 355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int i; 356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (rp = redirlist ; rp ; rp = rp->next) { 358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (i = 0 ; i < 10 ; i++) { 359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (rp->renamed[i] >= 0) { 360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(rp->renamed[i]); 361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!vforked) 363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project rp->renamed[i] = EMPTY; 364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copy a file descriptor to be >= to. Returns -1 372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * if the source file descriptor is closed, EMPTY if there are no unused 373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * file descriptors left. 374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint 377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectcopyfd(int from, int to) 378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int newfd; 380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project newfd = fcntl(from, F_DUPFD, to); 382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (newfd < 0) { 383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (errno == EMFILE) 384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return EMPTY; 385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("%d: %s", from, strerror(errno)); 387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return newfd; 389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 390