diff options
Diffstat (limited to 'lib/libc/gen/exec.c')
-rw-r--r-- | lib/libc/gen/exec.c | 47 |
1 files changed, 26 insertions, 21 deletions
diff --git a/lib/libc/gen/exec.c b/lib/libc/gen/exec.c index 2f7eadd..72b6db4 100644 --- a/lib/libc/gen/exec.c +++ b/lib/libc/gen/exec.c @@ -58,19 +58,20 @@ buildargv(ap, arg, envpp) const char *arg; char ***envpp; { - static int memsize; - static char **argv; - register int off; + register char **argv, **nargv; + register int memsize, off; argv = NULL; - for (off = 0;; ++off) { + for (off = memsize = 0;; ++off) { if (off >= memsize) { memsize += 50; /* Starts out at 0. */ memsize *= 2; /* Ramp up fast. */ - if (!(argv = realloc(argv, memsize * sizeof(char *)))) { - memsize = 0; + nargv = realloc(argv, memsize * sizeof(char *)); + if (nargv == NULL) { + free(argv); return (NULL); } + argv = nargv; if (off == 0) { argv[0] = (char *)arg; off = 1; @@ -104,7 +105,7 @@ execl(name, arg, va_alist) #else va_start(ap); #endif - if (argv = buildargv(ap, arg, NULL)) + if ( (argv = buildargv(ap, arg, NULL)) ) (void)execve(name, argv, environ); va_end(ap); sverrno = errno; @@ -132,7 +133,7 @@ execle(name, arg, va_alist) #else va_start(ap); #endif - if (argv = buildargv(ap, arg, &envp)) + if ( (argv = buildargv(ap, arg, &envp)) ) (void)execve(name, argv, envp); va_end(ap); sverrno = errno; @@ -160,7 +161,7 @@ execlp(name, arg, va_alist) #else va_start(ap); #endif - if (argv = buildargv(ap, arg, NULL)) + if ( (argv = buildargv(ap, arg, NULL)) ) (void)execvp(name, argv); va_end(ap); sverrno = errno; @@ -183,13 +184,14 @@ execvp(name, argv) const char *name; char * const *argv; { - static int memsize; - static char **memp; + char **memp; register int cnt, lp, ln; register char *p; int eacces, etxtbsy; char *bp, *cur, *path, buf[MAXPATHLEN]; + eacces = etxtbsy = 0; + /* If it's an absolute or relative path name, it's easy. */ if (index(name, '/')) { bp = (char *)name; @@ -198,13 +200,18 @@ execvp(name, argv) } bp = buf; + /* If it's an empty path name, fail in the usual POSIX way. */ + if (*name == '\0') { + errno = ENOENT; + return (-1); + } + /* Get the path we're searching. */ if (!(path = getenv("PATH"))) path = _PATH_DEFPATH; cur = path = strdup(path); - eacces = etxtbsy = 0; - while (p = strsep(&cur, ":")) { + while ( (p = strsep(&cur, ":")) ) { /* * It's a SHELL path -- double, leading and trailing colons * mean the current directory. @@ -240,18 +247,16 @@ retry: (void)execve(bp, argv, environ); case ENOENT: break; case ENOEXEC: - for (cnt = 0; argv[cnt]; ++cnt); - if ((cnt + 2) * sizeof(char *) > memsize) { - memsize = (cnt + 2) * sizeof(char *); - if ((memp = realloc(memp, memsize)) == NULL) { - memsize = 0; - goto done; - } - } + for (cnt = 0; argv[cnt]; ++cnt) + ; + memp = malloc((cnt + 2) * sizeof(char *)); + if (memp == NULL) + goto done; memp[0] = "sh"; memp[1] = bp; bcopy(argv + 1, memp + 2, cnt * sizeof(char *)); (void)execve(_PATH_BSHELL, memp, environ); + free(memp); goto done; case ETXTBSY: if (etxtbsy < 3) |