X-Git-Url: https://git.saurik.com/apple/libc.git/blobdiff_plain/9385eb3d10ebe5eb398c52040ec3dbfba9b0cdcf..aa54d2fad3d9038b43475aa93c76795c5141a993:/gen/FreeBSD/exec.c diff --git a/gen/FreeBSD/exec.c b/gen/FreeBSD/exec.c index a22d31b..86cf335 100644 --- a/gen/FreeBSD/exec.c +++ b/gen/FreeBSD/exec.c @@ -10,10 +10,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,7 +31,7 @@ static char sccsid[] = "@(#)exec.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/exec.c,v 1.20 2003/01/03 23:16:55 tjr Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/gen/exec.c,v 1.27 2009/12/05 18:55:16 ed Exp $"); #include "namespace.h" #include @@ -50,14 +46,19 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/exec.c,v 1.20 2003/01/03 23:16:55 tjr Exp $ #include #include "un-namespace.h" +#include "libc_private.h" -extern char **environ; +#include +#define environ (*_NSGetEnviron()) + +int +_execvpe(const char *name, char * const argv[], char * const envp[]); int execl(const char *name, const char *arg, ...) { va_list ap; - char **argv; + const char **argv; int n; va_start(ap, arg); @@ -72,18 +73,19 @@ execl(const char *name, const char *arg, ...) } va_start(ap, arg); n = 1; - argv[0] = (char *)arg; + argv[0] = arg; while ((argv[n] = va_arg(ap, char *)) != NULL) n++; va_end(ap); - return (_execve(name, argv, environ)); + return (_execve(name, __DECONST(char **, argv), environ)); } int execle(const char *name, const char *arg, ...) { va_list ap; - char **argv, **envp; + const char **argv; + char **envp; int n; va_start(ap, arg); @@ -98,19 +100,19 @@ execle(const char *name, const char *arg, ...) } va_start(ap, arg); n = 1; - argv[0] = (char *)arg; + argv[0] = arg; while ((argv[n] = va_arg(ap, char *)) != NULL) n++; envp = va_arg(ap, char **); va_end(ap); - return (_execve(name, argv, envp)); + return (_execve(name, __DECONST(char **, argv), envp)); } int execlp(const char *name, const char *arg, ...) { va_list ap; - char **argv; + const char **argv; int n; va_start(ap, arg); @@ -125,11 +127,11 @@ execlp(const char *name, const char *arg, ...) } va_start(ap, arg); n = 1; - argv[0] = (char *)arg; + argv[0] = arg; while ((argv[n] = va_arg(ap, char *)) != NULL) n++; va_end(ap); - return (execvp(name, argv)); + return (execvp(name, __DECONST(char **, argv))); } int @@ -142,23 +144,28 @@ execv(name, argv) } int -execvp(name, argv) - const char *name; - char * const *argv; +execvp(const char *name, char * const *argv) +{ + return (_execvpe(name, argv, environ)); +} + +static int +execvPe(const char *name, const char *path, char * const *argv, + char * const *envp) { - char **memp; - int cnt, lp, ln; - char *p; + const char **memp; + size_t cnt, lp, ln; int eacces, save_errno; - char *bp, *cur, *path, buf[MAXPATHLEN]; + char *cur, buf[MAXPATHLEN]; + const char *p, *bp; struct stat sb; eacces = 0; /* If it's an absolute or relative path name, it's easy. */ if (index(name, '/')) { - bp = (char *)name; - cur = path = NULL; + bp = name; + cur = NULL; goto retry; } bp = buf; @@ -169,22 +176,18 @@ execvp(name, argv) return (-1); } - /* Get the path we're searching. */ - if (!(path = getenv("PATH"))) - path = _PATH_DEFPATH; cur = alloca(strlen(path) + 1); if (cur == NULL) { errno = ENOMEM; return (-1); } strcpy(cur, path); - path = cur; - while ( (p = strsep(&cur, ":")) ) { + while ((p = strsep(&cur, ":")) != NULL) { /* * It's a SHELL path -- double, leading and trailing colons * mean the current directory. */ - if (!*p) { + if (*p == '\0') { p = "."; lp = 1; } else @@ -197,7 +200,7 @@ execvp(name, argv) * the user may execute the wrong program. */ if (lp + ln + 2 > sizeof(buf)) { - (void)_write(STDERR_FILENO, "execvp: ", 8); + (void)_write(STDERR_FILENO, "execvP: ", 8); (void)_write(STDERR_FILENO, p, lp); (void)_write(STDERR_FILENO, ": path too long\n", 16); @@ -208,8 +211,8 @@ execvp(name, argv) bcopy(name, buf + lp + 1, ln); buf[lp + ln + 1] = '\0'; -retry: (void)_execve(bp, argv, environ); - switch(errno) { +retry: (void)_execve(bp, argv, envp); + switch (errno) { case E2BIG: goto done; case ELOOP: @@ -227,7 +230,8 @@ retry: (void)_execve(bp, argv, environ); memp[0] = "sh"; memp[1] = bp; bcopy(argv + 1, memp + 2, cnt * sizeof(char *)); - (void)_execve(_PATH_BSHELL, memp, environ); + (void)_execve(_PATH_BSHELL, + __DECONST(char **, memp), envp); goto done; case ENOMEM: goto done; @@ -259,8 +263,27 @@ retry: (void)_execve(bp, argv, environ); } if (eacces) errno = EACCES; - else + else if (cur) errno = ENOENT; + /* else use existing errno from _execve */ done: return (-1); } + +int +execvP(const char *name, const char *path, char * const argv[]) +{ + return execvPe(name, path, argv, environ); +} + +__private_extern__ int +_execvpe(const char *name, char * const argv[], char * const envp[]) +{ + const char *path; + + /* Get the path we're searching. */ + if ((path = getenv("PATH")) == NULL) + path = _PATH_DEFPATH; + + return (execvPe(name, path, argv, envp)); +}