Loading...
gen/FreeBSD/exec.c Libc-320 Libc-825.25
--- Libc/Libc-320/gen/FreeBSD/exec.c
+++ Libc/Libc-825.25/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 <sys/cdefs.h>
-__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 <sys/param.h>
@@ -50,14 +46,19 @@
 
 #include <stdarg.h>
 #include "un-namespace.h"
-
-extern char **environ;
+#include "libc_private.h"
+
+#include <crt_externs.h>
+#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 @@
 	}
 	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 @@
 	}
 	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 @@
 	}
 	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 @@
 }
 
 int
-execvp(name, argv)
-	const char *name;
-	char * const *argv;
-{
-	char **memp;
-	int cnt, lp, ln;
-	char *p;
+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)
+{
+	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 @@
 		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 @@
 		 * 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 @@
 		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 @@
 			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 @@
 	}
 	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));
+}