* 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.
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>
#include <stdarg.h>
#include "un-namespace.h"
+#include "libc_private.h"
-extern char **environ;
+#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);
}
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);
}
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);
}
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
}
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;
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
* 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);
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:
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;
}
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));
+}