16b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes/* $NetBSD: popen.c,v 1.32 2012/06/25 22:32:43 abs Exp $ */ 26b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes 31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (c) 1988, 1993 51dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * The Regents of the University of California. All rights reserved. 61dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * This code is derived from software written by Ken Arnold and 81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * published in UNIX Review, Vol. 6, No. 8. 91dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Redistribution and use in source and binary forms, with or without 111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * modification, are permitted provided that the following conditions 121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * are met: 131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * notice, this list of conditions and the following disclaimer. 151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * documentation and/or other materials provided with the distribution. 181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 3. Neither the name of the University nor the names of its contributors 191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * may be used to endorse or promote products derived from this software 201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * without specific prior written permission. 211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * SUCH DAMAGE. 331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 356b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes#include <sys/cdefs.h> 366b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes#if defined(LIBC_SCCS) && !defined(lint) 376b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes#if 0 386b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughesstatic char sccsid[] = "@(#)popen.c 8.3 (Berkeley) 5/3/95"; 396b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes#else 406b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes__RCSID("$NetBSD: popen.c,v 1.32 2012/06/25 22:32:43 abs Exp $"); 416b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes#endif 426b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes#endif /* LIBC_SCCS and not lint */ 436b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes 446b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes#include "namespace.h" 451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/param.h> 461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/wait.h> 476b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes#include <sys/socket.h> 481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 496b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes#include <assert.h> 501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <errno.h> 516b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes#include <paths.h> 526b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes#include <signal.h> 531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdio.h> 541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdlib.h> 551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <string.h> 566b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes#include <unistd.h> 576b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes#include <fcntl.h> 586b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes 596b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes#include "env.h" 606b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes#include "reentrant.h" 616b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes 626b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes#ifdef __weak_alias 636b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes__weak_alias(popen,_popen) 646b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes__weak_alias(pclose,_pclose) 656b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes#endif 661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic struct pid { 681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct pid *next; 691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project FILE *fp; 706b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes#ifdef _REENTRANT 716b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes int fd; 726b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes#endif 731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project pid_t pid; 746b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes} *pidlist; 756b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes 766b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes#ifdef _REENTRANT 776b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughesstatic rwlock_t pidlist_lock = RWLOCK_INITIALIZER; 786b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes#endif 793884bfe9661955543ce203c60f9225bbdf33f6bbJP Abgrall 801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source ProjectFILE * 816b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughespopen(const char *command, const char *type) 821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 836b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes struct pid *cur, *old; 841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project FILE *iop; 856b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes const char * volatile xtype = type; 866b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes int pdes[2], pid, serrno; 876b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes volatile int twoway; 886b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes int flags; 896b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes 906b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes _DIAGASSERT(command != NULL); 916b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes _DIAGASSERT(xtype != NULL); 926b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes 936b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes flags = strchr(xtype, 'e') ? O_CLOEXEC : 0; 946b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes if (strchr(xtype, '+')) { 956b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes int stype = flags ? (SOCK_STREAM | SOCK_CLOEXEC) : SOCK_STREAM; 966b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes twoway = 1; 976b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes xtype = "r+"; 986b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes if (socketpair(AF_LOCAL, stype, 0, pdes) < 0) 996b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes return NULL; 1006b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes } else { 1016b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes twoway = 0; 1026b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes xtype = strrchr(xtype, 'r') ? "r" : "w"; 1036b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes if (pipe2(pdes, flags) == -1) 1046b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes return NULL; 1051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 1061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1076b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes if ((cur = malloc(sizeof(struct pid))) == NULL) { 1086b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes (void)close(pdes[0]); 1096b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes (void)close(pdes[1]); 1106b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes errno = ENOMEM; 1111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (NULL); 1121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 1131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1146b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes (void)rwlock_rdlock(&pidlist_lock); 1156b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes (void)__readlockenv(); 1166b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes switch (pid = vfork()) { 1171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case -1: /* Error. */ 1186b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes serrno = errno; 1196b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes (void)__unlockenv(); 1206b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes (void)rwlock_unlock(&pidlist_lock); 1216b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes free(cur); 1221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void)close(pdes[0]); 1231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void)close(pdes[1]); 1246b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes errno = serrno; 1251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (NULL); 1261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* NOTREACHED */ 1271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case 0: /* Child. */ 1286b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes /* POSIX.2 B.3.2.2 "popen() shall ensure that any streams 1296b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes from previous popen() calls that remain open in the 1306b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes parent process are closed in the new child process. */ 1316b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes for (old = pidlist; old; old = old->next) 1326b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes#ifdef _REENTRANT 1336b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes close(old->fd); /* don't allow a flush */ 1346b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes#else 1356b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes close(fileno(old->fp)); /* don't allow a flush */ 1366b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes#endif 1376b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes 1386b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes if (*xtype == 'r') { 1396b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes (void)close(pdes[0]); 1403884bfe9661955543ce203c60f9225bbdf33f6bbJP Abgrall if (pdes[1] != STDOUT_FILENO) { 1413884bfe9661955543ce203c60f9225bbdf33f6bbJP Abgrall (void)dup2(pdes[1], STDOUT_FILENO); 1423884bfe9661955543ce203c60f9225bbdf33f6bbJP Abgrall (void)close(pdes[1]); 1431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 1446b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes if (twoway) 1456b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes (void)dup2(STDOUT_FILENO, STDIN_FILENO); 1461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else { 1471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void)close(pdes[1]); 1481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (pdes[0] != STDIN_FILENO) { 1491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void)dup2(pdes[0], STDIN_FILENO); 1501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void)close(pdes[0]); 1511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 1521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 1536b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes 1546b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes execl(_PATH_BSHELL, "sh", "-c", command, NULL); 1551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project _exit(127); 1561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* NOTREACHED */ 1571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 1586b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes (void)__unlockenv(); 1591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* Parent; assume fdopen can't fail. */ 1616b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes if (*xtype == 'r') { 1626b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes iop = fdopen(pdes[0], xtype); 1636b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes#ifdef _REENTRANT 1646b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes cur->fd = pdes[0]; 1656b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes#endif 1661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void)close(pdes[1]); 1671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else { 1686b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes iop = fdopen(pdes[1], xtype); 1696b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes#ifdef _REENTRANT 1706b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes cur->fd = pdes[1]; 1716b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes#endif 1721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void)close(pdes[0]); 1731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 1741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* Link into list of file descriptors. */ 1761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cur->fp = iop; 1771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cur->pid = pid; 1781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cur->next = pidlist; 1791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project pidlist = cur; 1806b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes (void)rwlock_unlock(&pidlist_lock); 1811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (iop); 1831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 1841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 1861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * pclose -- 1871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Pclose returns -1 if stream is not associated with a `popened' command, 1881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * if already `pclosed', or waitpid returns an error. 1891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 1901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint 1911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectpclose(FILE *iop) 1921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 1931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct pid *cur, *last; 1941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int pstat; 1951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project pid_t pid; 1961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1976b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes _DIAGASSERT(iop != NULL); 1986b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes 1996b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes rwlock_wrlock(&pidlist_lock); 2006b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes 2011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* Find the appropriate file pointer. */ 2021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (last = NULL, cur = pidlist; cur; last = cur, cur = cur->next) 2031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (cur->fp == iop) 2041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 2056b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes if (cur == NULL) { 2066b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes (void)rwlock_unlock(&pidlist_lock); 2071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 2086b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes } 2091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void)fclose(iop); 2111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* Remove the entry from the linked list. */ 2131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (last == NULL) 2141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project pidlist = cur->next; 2151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else 2161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project last->next = cur->next; 2176b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes 2186b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes (void)rwlock_unlock(&pidlist_lock); 2196b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes 2206b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes do { 2216b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes pid = waitpid(cur->pid, &pstat, 0); 2226b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes } while (pid == -1 && errno == EINTR); 2236b3f49a5374305ce9690c3c5ca2aadc90f54c521Elliott Hughes 2241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project free(cur); 2251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (pid == -1 ? -1 : pstat); 2271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 228