Split PATH into parts in advance, and pass the result to the new spawnvppe_pipe.

This commit is contained in:
Johannes Sixt
2007-01-16 14:58:49 +01:00
parent 23960ed3c3
commit 5f38ff014e
2 changed files with 73 additions and 16 deletions

View File

@@ -18,29 +18,72 @@ static char *lookup_prog(const char *dir, const char *cmd, int tryexe)
}
/*
* Determines the absolute path of cmd based on the PATH environment variable.
* Splits the PATH into parts.
*/
char **get_path_split()
{
char *p, **path, *envpath = getenv("PATH");
int i, n = 0;
if (!envpath || !*envpath)
return NULL;
envpath = xstrdup(envpath);
p = envpath;
while (p) {
char *dir = p;
p = strchr(p, ';');
if (p) *p++ = '\0';
if (*dir) { /* not earlier, catches series of ; */
++n;
}
}
if (!n)
return NULL;
path = xmalloc((n+1)*sizeof(char*));
p = envpath;
i = 0;
do {
if (*p)
path[i++] = xstrdup(p);
p = p+strlen(p)+1;
} while (i < n);
path[i] = NULL;
free(envpath);
return path;
}
void free_path_split(char **path)
{
if (!path)
return;
char **p = path;
while (*p)
free(*p++);
free(path);
}
/*
* Determines the absolute path of cmd using the the split path in path.
* If cmd contains a slash or backslash, no lookup is performed.
*/
static char *path_lookup(const char *cmd)
static char *path_lookup(const char *cmd, char **path)
{
char *p, *envpath = getenv("PATH");
char **p = path;
char *prog = NULL;
int len = strlen(cmd);
int tryexe = len < 4 || strcasecmp(cmd+len-4, ".exe");
if (strchr(cmd, '/') || strchr(cmd, '\\') ||
!envpath || !*envpath)
envpath = "";
envpath = xstrdup(envpath);
p = envpath;
while (p && !prog) {
const char *dir = p;
p = strchr(p, ';');
if (p) *p++ = '\0';
if (*dir)
prog = lookup_prog(dir, cmd, tryexe);
if (strchr(cmd, '/') || strchr(cmd, '\\'))
p = NULL;
while (*p && !prog) {
prog = lookup_prog(*p++, cmd, tryexe);
}
free(envpath);
if (!prog) {
prog = lookup_prog(".", cmd, tryexe);
if (!prog)
@@ -62,6 +105,19 @@ static char *path_lookup(const char *cmd)
*/
int spawnvpe_pipe(const char *cmd, const char **argv, const char **env,
int pin[], int pout[])
{
char **path = get_path_split();
pid_t pid = spawnvppe_pipe(cmd, argv, env, path, pin, pout);
free_path_split(path);
return pid;
}
int spawnvppe_pipe(const char *cmd, const char **argv, const char **env,
char **path,
int pin[], int pout[])
{
const char *cmd_basename = strrchr(cmd, '/');
pid_t pid;
@@ -127,7 +183,7 @@ int spawnvpe_pipe(const char *cmd, const char **argv, const char **env,
}
}
prog = path_lookup(cmd);
prog = path_lookup(cmd, path);
interpr = parse_interpreter(prog);
for (argc = 0; argv[argc];) argc++;