Move path handling functions from spawn-pipe.c to compat/mingw.c.

Since these functions are MinGW-specific, they better belong into this
compatibility file. They will be needed there in a follow-up change that
reimplements execvp().
This commit is contained in:
Johannes Sixt
2007-11-02 21:34:56 +01:00
parent fe77ba9245
commit 36e0147fe5
3 changed files with 94 additions and 93 deletions

View File

@@ -441,6 +441,94 @@ void mingw_execve(const char *cmd, const char **argv, const char **env)
}
}
static char *lookup_prog(const char *dir, const char *cmd, int tryexe)
{
char path[MAX_PATH];
snprintf(path, sizeof(path), "%s/%s.exe", dir, cmd);
if (tryexe && access(path, 0) == 0)
return xstrdup(path);
path[strlen(path)-4] = '\0';
if (access(path, 0) == 0)
return xstrdup(path);
return NULL;
}
/*
* Determines the absolute path of cmd using the the split path in path.
* If cmd contains a slash or backslash, no lookup is performed.
*/
char *mingw_path_lookup(const char *cmd, char **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, '\\'))
prog = xstrdup(cmd);
while (!prog && *p) {
prog = lookup_prog(*p++, cmd, tryexe);
}
if (!prog) {
prog = lookup_prog(".", cmd, tryexe);
if (!prog)
prog = xstrdup(cmd);
}
return prog;
}
/*
* Splits the PATH into parts.
*/
char **mingw_get_path_split(void)
{
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 mingw_free_path_split(char **path)
{
if (!path)
return;
char **p = path;
while (*p)
free(*p++);
free(path);
}
int mingw_socket(int domain, int type, int protocol)
{
SOCKET s = WSASocket(domain, type, protocol, NULL, 0, 0);

View File

@@ -499,6 +499,9 @@ int mingw_rename(const char*, const char*);
extern void quote_argv(const char **dst, const char **src);
extern const char *parse_interpreter(const char *cmd);
extern char *mingw_path_lookup(const char *cmd, char **path);
extern char **mingw_get_path_split(void);
extern void mingw_free_path_split(char **path);
/* Use git_lstat() instead of lstat()/stat() and
* git_fstat() instead of fstat() on Windows

View File

@@ -3,96 +3,6 @@
extern char **environ;
#ifdef __MINGW32__
static char *lookup_prog(const char *dir, const char *cmd, int tryexe)
{
char path[MAX_PATH];
snprintf(path, sizeof(path), "%s/%s.exe", dir, cmd);
if (tryexe && access(path, 0) == 0)
return xstrdup(path);
path[strlen(path)-4] = '\0';
if (access(path, 0) == 0)
return xstrdup(path);
return NULL;
}
/*
* 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, char **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, '\\'))
prog = xstrdup(cmd);
while (!prog && *p) {
prog = lookup_prog(*p++, cmd, tryexe);
}
if (!prog) {
prog = lookup_prog(".", cmd, tryexe);
if (!prog)
prog = xstrdup(cmd);
}
return prog;
}
#endif
/* cmd specifies the command to invoke.
* argv specifies its arguments; argv[0] will be replaced by the basename of cmd.
* env specifies the environment.
@@ -107,11 +17,11 @@ int spawnvpe_pipe(const char *cmd, const char **argv, const char **env,
int pin[], int pout[])
{
#ifdef __MINGW32__
char **path = get_path_split();
char **path = mingw_get_path_split();
pid_t pid = spawnvppe_pipe(cmd, argv, env, path, pin, pout);
free_path_split(path);
mingw_free_path_split(path);
#else
pid_t pid = spawnvppe_pipe(cmd, argv, env, NULL, pin, pout);
#endif
@@ -187,7 +97,7 @@ int spawnvppe_pipe(const char *cmd, const char **argv, const char **env,
}
}
prog = path_lookup(cmd, path);
prog = mingw_path_lookup(cmd, path);
interpr = parse_interpreter(prog);
for (argc = 0; argv[argc];) argc++;