diff --git a/lib/libc/gen/exec.c b/lib/libc/gen/exec.c index 6b19842b711e..467be8154790 100644 --- a/lib/libc/gen/exec.c +++ b/lib/libc/gen/exec.c @@ -36,7 +36,7 @@ static char sccsid[] = "@(#)exec.c 8.1 (Berkeley) 6/4/93"; #endif static const char rcsid[] = - "$Id: exec.c,v 1.9 1998/10/14 20:23:40 des Exp $"; + "$Id: exec.c,v 1.10 1998/10/15 17:14:15 des Exp $"; #endif /* LIBC_SCCS and not lint */ #include @@ -57,40 +57,6 @@ static const char rcsid[] = extern char **environ; -static char ** -buildargv(ap, arg, envpp) - va_list ap; - const char *arg; - char ***envpp; -{ - register char **argv, **nargv; - register int memsize, off; - - argv = NULL; - for (off = memsize = 0;; ++off) { - if (off >= memsize) { - memsize += 50; /* Starts out at 0. */ - memsize *= 2; /* Ramp up fast. */ - nargv = realloc(argv, memsize * sizeof(char *)); - if (nargv == NULL) { - free(argv); - return (NULL); - } - argv = nargv; - if (off == 0) { - argv[0] = (char *)arg; - off = 1; - } - } - if (!(argv[off] = va_arg(ap, char *))) - break; - } - /* Get environment pointer if user supposed to provide one. */ - if (envpp) - *envpp = va_arg(ap, char **); - return (argv); -} - int #if __STDC__ execl(const char *name, const char *arg, ...) @@ -115,8 +81,10 @@ execl(name, arg, va_alist) n++; va_end(ap); argv = alloca((n + 1) * sizeof(*argv)); - if (argv == NULL) + if (argv == NULL) { + errno = ENOMEM; return (-1); + } #if __STDC__ va_start(ap, arg); #else @@ -154,8 +122,10 @@ execle(name, arg, va_alist) n++; va_end(ap); argv = alloca((n + 1) * sizeof(*argv)); - if (argv == NULL) + if (argv == NULL) { + errno = ENOMEM; return (-1); + } #if __STDC__ va_start(ap, arg); #else @@ -183,19 +153,33 @@ execlp(name, arg, va_alist) va_list ap; int sverrno; char **argv; + int n; #if __STDC__ va_start(ap, arg); #else va_start(ap); #endif - if ( (argv = buildargv(ap, arg, NULL)) ) - (void)execvp(name, argv); + n = 1; + while (va_arg(ap, char *) != NULL) + n++; va_end(ap); - sverrno = errno; - free(argv); - errno = sverrno; - return (-1); + argv = alloca((n + 1) * sizeof(*argv)); + if (argv == NULL) { + errno = ENOMEM; + return (-1); + } +#if __STDC__ + va_start(ap, arg); +#else + va_start(ap); +#endif + n = 1; + argv[0] = (char *)arg; + while ((argv[n] = va_arg(ap, char *)) != NULL) + n++; + va_end(ap); + return (execvp(name, argv)); } int @@ -238,8 +222,13 @@ execvp(name, argv) /* Get the path we're searching. */ if (!(path = getenv("PATH"))) path = _PATH_DEFPATH; - cur = path = strdup(path); - + cur = alloca(strlen(path) + 1); + if (cur == NULL) { + errno = ENOMEM; + return (-1); + } + strcpy(cur, path); + path = cur; while ( (p = strsep(&cur, ":")) ) { /* * It's a SHELL path -- double, leading and trailing colons @@ -279,14 +268,16 @@ retry: (void)execve(bp, argv, environ); case ENOEXEC: for (cnt = 0; argv[cnt]; ++cnt) ; - memp = malloc((cnt + 2) * sizeof(char *)); - if (memp == NULL) + memp = alloca((cnt + 3) * sizeof(char *)); + if (memp == NULL) { + /* errno = ENOMEM; XXX override ENOEXEC? */ goto done; + } memp[0] = "sh"; memp[1] = bp; bcopy(argv + 1, memp + 2, cnt * sizeof(char *)); + memp[cnt + 2] = NULL; (void)execve(_PATH_BSHELL, memp, environ); - free(memp); goto done; case ENOMEM: goto done; @@ -320,7 +311,6 @@ retry: (void)execve(bp, argv, environ); errno = EACCES; else errno = ENOENT; -done: if (path) - free(path); +done: return (-1); }