Files
git/spawn-pipe.c
Johannes Sixt f8fd915d0c Move environment functions from spawn-pipe.c to compat/mingw.c
We want to get rid of spawn-pipe.*, but these functions will be needed.

On the way, the function signature was changed to avoid warnings about
incompatible pointer types when the argument is the global variable
"environ".
2007-11-18 20:22:04 +01:00

132 lines
2.6 KiB
C

#include "git-compat-util.h"
#include "spawn-pipe.h"
extern char **environ;
/* cmd specifies the command to invoke.
* argv specifies its arguments; argv[0] will be replaced by the basename of cmd.
* env specifies the environment.
* pin and pout specify pipes; the read end of pin is made the standard input
* of the spawned process, and the write end of pout is mad the standard output.
* The respective unused ends of the pipes are closed both in the parent
* process as well as in the child process.
* Anyone of pin or pout can be NULL, or any one of the ends can be -1 to
* indicate that no processing shall occur.
*/
int spawnvpe_pipe(const char *cmd, const char **argv, const char **env,
int pin[], int pout[])
{
#ifdef __MINGW32__
char **path = mingw_get_path_split();
pid_t pid = spawnvppe_pipe(cmd, argv, env, path, pin, pout);
mingw_free_path_split(path);
#else
pid_t pid = spawnvppe_pipe(cmd, argv, env, NULL, pin, pout);
#endif
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, '/');
const char *argv0 = argv[0];
pid_t pid;
#ifdef __MINGW32__
int s0 = -1, s1 = -1, argc;
char *prog;
const char **qargv, *interpr;
if (!cmd_basename)
cmd_basename = strrchr(cmd, '\\');
#endif
if (!cmd_basename)
cmd_basename = cmd;
else
cmd_basename++;
argv[0] = cmd_basename;
#ifndef __MINGW32__
pid = fork();
if (pid < 0)
die("unable to fork");
if (!pid) {
if (pin) {
if (pin[0] >= 0) {
dup2(pin[0], 0);
close(pin[0]);
}
if (pin[1] >= 0)
close(pin[1]);
}
if (pout) {
if (pout[1] >= 0) {
dup2(pout[1], 1);
close(pout[1]);
}
if (pout[0] >= 0)
close(pout[0]);
}
environ = env;
execvp(cmd, argv);
die("exec failed");
}
if (pin && pin[0] >= 0)
close(pin[0]);
if (pout && pout[1] >= 1)
close(pout[1]);
#else
if (pin) {
if (pin[0] >= 0) {
s0 = dup(0);
dup2(pin[0], 0);
close(pin[0]);
}
}
if (pout) {
if (pout[1] >= 0) {
s1 = dup(1);
dup2(pout[1], 1);
close(pout[1]);
}
}
prog = mingw_path_lookup(cmd, path);
interpr = parse_interpreter(prog);
for (argc = 0; argv[argc];) argc++;
qargv = xmalloc((argc+2)*sizeof(char*));
if (!interpr) {
quote_argv(qargv, argv);
pid = spawnve(_P_NOWAIT, prog, qargv, env);
} else {
qargv[0] = interpr;
argv[0] = prog;
quote_argv(&qargv[1], argv);
pid = spawnvpe(_P_NOWAIT, interpr, qargv, env);
}
free(qargv); /* TODO: quoted args should be freed, too */
free(prog);
if (s0 >= 0) {
dup2(s0, 0);
close(s0);
}
if (s1 >= 0) {
dup2(s1, 1);
close(s1);
}
#endif
argv[0] = argv0;
return pid;
}