Index: lib/libc/gen/exec.c =================================================================== --- lib/libc/gen/exec.c +++ lib/libc/gen/exec.c @@ -149,8 +149,8 @@ const char **memp; size_t cnt, lp, ln; int eacces, save_errno; - char *cur, buf[MAXPATHLEN]; - const char *p, *bp; + char buf[MAXPATHLEN]; + const char *bp, *np, *op, *p; struct stat sb; eacces = 0; @@ -158,7 +158,6 @@ /* If it's an absolute or relative path name, it's easy. */ if (strchr(name, '/')) { bp = name; - cur = NULL; goto retry; } bp = buf; @@ -169,23 +168,34 @@ return (-1); } - cur = alloca(strlen(path) + 1); - if (cur == NULL) { - errno = ENOMEM; - return (-1); - } - strcpy(cur, path); - while ((p = strsep(&cur, ":")) != NULL) { + op = path; + ln = strlen(name); + while (op != NULL) { + np = strchrnul(op, ':'); + /* * It's a SHELL path -- double, leading and trailing colons * mean the current directory. */ - if (*p == '\0') { + if (*np == '\0') { + if (op == np) { + /* Trailing colon. */ + p = "."; + lp = 1; + } else { + /* Final non-empty component. */ + p = op; + lp = strlen(p); + } + } else if (np == op) { + /* Double colon in the middle, or a leading colon. */ p = "."; lp = 1; - } else - lp = strlen(p); - ln = strlen(name); + } else { + /* Standard non-empty component. */ + p = op; + lp = np - op; + } /* * If the path is too long complain. This is a possible @@ -204,6 +214,12 @@ bcopy(name, buf + lp + 1, ln); buf[lp + ln + 1] = '\0'; + /* Advance */ + if (*np == '\0') + op = NULL; + else + op = np + 1; + retry: (void)_execve(bp, argv, envp); switch (errno) { case E2BIG: