Loading...
--- Libc/Libc-1725.40.4/sys/posix_spawn.c
+++ Libc/Libc-997.1.1/sys/posix_spawn.c
@@ -73,55 +73,48 @@
char *const argv[ __restrict], char *const envp[ __restrict])
{
const char *env_path;
- char path_buf[PATH_MAX];
- char *bp, *np, *op, *p;
+ char *bp;
+ char *cur;
+ char *p;
char **memp;
- size_t ln, lp;
+ int lp;
+ int ln;
int cnt;
int err = 0;
int eacces = 0;
struct stat sb;
-
- /* If it's an absolute or relative path name, it's easy. */
- if (strchr(file, '/')) {
- bp = (char *)file;
- env_path = op = NULL;
- goto retry;
- }
+ char path_buf[PATH_MAX];
if ((env_path = getenv("PATH")) == NULL)
env_path = _PATH_DEFPATH;
+ /* If it's an absolute or relative path name, it's easy. */
+ if (index(file, '/')) {
+ bp = (char *)file;
+ cur = NULL;
+ goto retry;
+ }
bp = path_buf;
/* If it's an empty path name, fail in the usual POSIX way. */
if (*file == '\0')
return (ENOENT);
- op = env_path;
- ln = strlen(file);
- while (op != NULL) {
- np = strchrnul(op, ':');
-
+ if ((cur = alloca(strlen(env_path) + 1)) == NULL)
+ return ENOMEM;
+ strcpy(cur, env_path);
+ while ((p = strsep(&cur, ":")) != NULL) {
/*
* It's a SHELL path -- double, leading and trailing colons
* mean the current directory.
*/
- if (np == op) {
- /* Empty component. */
+ if (*p == '\0') {
p = ".";
lp = 1;
} else {
- /* Non-empty component. */
- p = op;
- lp = np - op;
+ lp = strlen(p);
}
-
- /* Advance to the next component or terminate after this. */
- if (*np == '\0')
- op = NULL;
- else
- op = np + 1;
+ ln = strlen(file);
/*
* If the path is too long complain. This is a possible
@@ -151,28 +144,14 @@
case ENOEXEC:
for (cnt = 0; argv[cnt]; ++cnt)
;
-
- /*
- * cnt may be 0 above; always allocate at least
- * 3 entries so that we can at least fit "sh", bp, and
- * the NULL terminator. We can rely on cnt to take into
- * account the NULL terminator in all other scenarios,
- * as we drop argv[0].
- */
- memp = alloca(MAX(3, cnt + 2) * sizeof(char *));
+ memp = alloca((cnt + 2) * sizeof(char *));
if (memp == NULL) {
/* errno = ENOMEM; XXX override ENOEXEC? */
goto done;
}
- if (cnt > 0) {
- memp[0] = argv[0];
- memp[1] = bp;
- bcopy(argv + 1, memp + 2, cnt * sizeof(char *));
- } else {
- memp[0] = "sh";
- memp[1] = bp;
- memp[2] = NULL;
- }
+ memp[0] = "sh";
+ memp[1] = bp;
+ bcopy(argv + 1, memp + 2, cnt * sizeof(char *));
err = posix_spawn(pid, _PATH_BSHELL, file_actions, attrp, memp, envp);
goto done;
default:
@@ -194,13 +173,7 @@
}
if (eacces)
err = EACCES;
- /*
- * Preserve errno from posix_spawn(3) if it wasn't a PATH search, or
- * if it was a PATH search and we bailed out early. Note that every
- * branch in the loop jumps to the `done` label to preserve errno, so
- * this is more of a defensive check.
- */
- else if (env_path != NULL && op == NULL)
+ else
err = ENOENT;
done:
return (err);