11dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* $OpenBSD: exec.c,v 1.18 2005/08/08 08:05:34 espie Exp $ */ 21dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*- 31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (c) 1991, 1993 41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * The Regents of the University of California. All rights reserved. 51dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 61dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Redistribution and use in source and binary forms, with or without 71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * modification, are permitted provided that the following conditions 81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * are met: 91dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * notice, this list of conditions and the following disclaimer. 111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * documentation and/or other materials provided with the distribution. 141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 3. Neither the name of the University nor the names of its contributors 151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * may be used to endorse or promote products derived from this software 161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * without specific prior written permission. 171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * SUCH DAMAGE. 291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/param.h> 321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/types.h> 331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/uio.h> 341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <errno.h> 351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <unistd.h> 361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <limits.h> 371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdlib.h> 381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <string.h> 392cc2b2be692f1d559a09d2066e56e450249cc9c0Carl Shapiro#include <strings.h> 401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdio.h> 411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <paths.h> 421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdarg.h> 431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <alloca.h> 441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern char **environ; 461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint 481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectexecl(const char *name, const char *arg, ...) 491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project va_list ap; 511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char **argv; 521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int n; 531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project va_start(ap, arg); 551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = 1; 561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while (va_arg(ap, char *) != NULL) 571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n++; 581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project va_end(ap); 591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project argv = alloca((n + 1) * sizeof(*argv)); 601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (argv == NULL) { 611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = ENOMEM; 621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project va_start(ap, arg); 651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = 1; 661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project argv[0] = (char *)arg; 671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while ((argv[n] = va_arg(ap, char *)) != NULL) 681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n++; 691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project va_end(ap); 701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (execve(name, argv, environ)); 711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint 741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectexecle(const char *name, const char *arg, ...) 751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project va_list ap; 771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char **argv, **envp; 781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int n; 791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project va_start(ap, arg); 811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = 1; 821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while (va_arg(ap, char *) != NULL) 831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n++; 841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project va_end(ap); 851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project argv = alloca((n + 1) * sizeof(*argv)); 861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (argv == NULL) { 871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = ENOMEM; 881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project va_start(ap, arg); 911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = 1; 921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project argv[0] = (char *)arg; 931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while ((argv[n] = va_arg(ap, char *)) != NULL) 941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n++; 951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project envp = va_arg(ap, char **); 961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project va_end(ap); 971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (execve(name, argv, envp)); 981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint 1011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectexeclp(const char *name, const char *arg, ...) 1021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 1031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project va_list ap; 1041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char **argv; 1051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int n; 1061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project va_start(ap, arg); 1081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = 1; 1091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while (va_arg(ap, char *) != NULL) 1101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n++; 1111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project va_end(ap); 1121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project argv = alloca((n + 1) * sizeof(*argv)); 1131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (argv == NULL) { 1141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = ENOMEM; 1151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 1161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 1171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project va_start(ap, arg); 1181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = 1; 1191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project argv[0] = (char *)arg; 1201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while ((argv[n] = va_arg(ap, char *)) != NULL) 1211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n++; 1221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project va_end(ap); 1231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (execvp(name, argv)); 1241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 1251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint 1271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectexecv(const char *name, char * const *argv) 1281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 1291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void)execve(name, argv, environ); 1301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 1311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 1321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint 1341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectexecvp(const char *name, char * const *argv) 1351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 1361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char **memp; 1371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int cnt, lp, ln, len; 1381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char *p; 1391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int eacces = 0; 1401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char *bp, *cur, *path, buf[MAXPATHLEN]; 1411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 1431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Do not allow null name 1441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 1451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (name == NULL || *name == '\0') { 1461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = ENOENT; 1471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 1481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 1491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* If it's an absolute or relative path name, it's easy. */ 1511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (strchr(name, '/')) { 1521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project bp = (char *)name; 1531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cur = path = NULL; 1541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto retry; 1551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 1561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project bp = buf; 1571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* Get the path we're searching. */ 1591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (!(path = getenv("PATH"))) 1601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project path = _PATH_DEFPATH; 1611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project len = strlen(path) + 1; 1621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cur = alloca(len); 1631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (cur == NULL) { 1641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = ENOMEM; 1651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 1661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 1671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project strlcpy(cur, path, len); 1681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project path = cur; 1691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while ((p = strsep(&cur, ":"))) { 1701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 1711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * It's a SHELL path -- double, leading and trailing colons 1721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * mean the current directory. 1731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 1741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (!*p) { 1751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project p = "."; 1761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project lp = 1; 1771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else 1781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project lp = strlen(p); 1791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ln = strlen(name); 1801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 1821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * If the path is too long complain. This is a possible 1831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * security issue; given a way to make the path too long 1841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * the user may execute the wrong program. 1851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 1861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (lp + ln + 2 > (int)sizeof(buf)) { 1871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct iovec iov[3]; 1881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project iov[0].iov_base = "execvp: "; 1901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project iov[0].iov_len = 8; 1911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project iov[1].iov_base = p; 1921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project iov[1].iov_len = lp; 1931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project iov[2].iov_base = ": path too long\n"; 1941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project iov[2].iov_len = 16; 1951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void)writev(STDERR_FILENO, iov, 3); 1961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project continue; 1971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 19828a7c35feac8d73b94f99493534dad069afe5049Jim Huang memcpy(buf, p, lp); 1991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project buf[lp] = '/'; 20028a7c35feac8d73b94f99493534dad069afe5049Jim Huang memcpy(buf + lp + 1, name, ln); 2011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project buf[lp + ln + 1] = '\0'; 2021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectretry: (void)execve(bp, argv, environ); 2041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project switch(errno) { 2051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case E2BIG: 2061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto done; 2071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case EISDIR: 2081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case ELOOP: 2091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case ENAMETOOLONG: 2101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case ENOENT: 2111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 2121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case ENOEXEC: 2131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (cnt = 0; argv[cnt]; ++cnt) 2141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ; 2151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project memp = alloca((cnt + 2) * sizeof(char *)); 2161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (memp == NULL) 2171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto done; 2181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project memp[0] = "sh"; 2191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project memp[1] = bp; 22028a7c35feac8d73b94f99493534dad069afe5049Jim Huang memcpy(memp + 2, argv + 1, cnt * sizeof(char *)); 2211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void)execve(_PATH_BSHELL, memp, environ); 2221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto done; 2231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case ENOMEM: 2241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto done; 2251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case ENOTDIR: 2261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 2271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case ETXTBSY: 2281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 2291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * We used to retry here, but sh(1) doesn't. 2301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 2311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto done; 2321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case EACCES: 2331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project eacces = 1; 2341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 2351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project default: 2361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto done; 2371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 2381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 2391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (eacces) 2401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = EACCES; 2411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else if (!errno) 2421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = ENOENT; 2431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectdone: 2441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 2451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 246