1
0
mirror of https://github.com/git/git.git synced 2024-11-19 00:44:22 +01:00

Use start_command() in git_connect() instead of explicit fork/exec.

The child process handling is delegated to start_command() and
finish_command().

Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
This commit is contained in:
Johannes Sixt 2007-10-19 21:47:54 +02:00 committed by Shawn O. Pearce
parent 98158e9cfd
commit f364cb8823

@ -482,11 +482,12 @@ struct child_process *git_connect(int fd[2], char *url,
char *host, *path = url;
char *end;
int c;
int pipefd[2][2];
struct child_process *conn;
enum protocol protocol = PROTO_LOCAL;
int free_path = 0;
char *port = NULL;
const char **arg;
struct strbuf cmd;
/* Without this we cannot rely on waitpid() to tell
* what happened to our children.
@ -572,14 +573,7 @@ struct child_process *git_connect(int fd[2], char *url,
return NULL;
}
if (pipe(pipefd[0]) < 0 || pipe(pipefd[1]) < 0)
die("unable to create pipe pair for communication");
conn = xcalloc(1, sizeof(*conn));
conn->pid = fork();
if (conn->pid < 0)
die("unable to fork");
if (!conn->pid) {
struct strbuf cmd;
strbuf_init(&cmd, MAX_CMD_LEN);
strbuf_addstr(&cmd, prog);
@ -588,43 +582,43 @@ struct child_process *git_connect(int fd[2], char *url,
if (cmd.len >= MAX_CMD_LEN)
die("command line too long");
dup2(pipefd[1][0], 0);
dup2(pipefd[0][1], 1);
close(pipefd[0][0]);
close(pipefd[0][1]);
close(pipefd[1][0]);
close(pipefd[1][1]);
conn->in = conn->out = -1;
conn->argv = arg = xcalloc(6, sizeof(*arg));
if (protocol == PROTO_SSH) {
const char *ssh, *ssh_basename;
ssh = getenv("GIT_SSH");
const char *ssh = getenv("GIT_SSH");
if (!ssh) ssh = "ssh";
ssh_basename = strrchr(ssh, '/');
if (!ssh_basename)
ssh_basename = ssh;
else
ssh_basename++;
if (!port)
execlp(ssh, ssh_basename, host, cmd.buf, NULL);
else
execlp(ssh, ssh_basename, "-p", port, host,
cmd.buf, NULL);
*arg++ = ssh;
if (port) {
*arg++ = "-p";
*arg++ = port;
}
*arg++ = host;
}
else {
unsetenv(ALTERNATE_DB_ENVIRONMENT);
unsetenv(DB_ENVIRONMENT);
unsetenv(GIT_DIR_ENVIRONMENT);
unsetenv(GIT_WORK_TREE_ENVIRONMENT);
unsetenv(GRAFT_ENVIRONMENT);
unsetenv(INDEX_ENVIRONMENT);
execlp("sh", "sh", "-c", cmd.buf, NULL);
/* remove these from the environment */
const char *env[] = {
ALTERNATE_DB_ENVIRONMENT,
DB_ENVIRONMENT,
GIT_DIR_ENVIRONMENT,
GIT_WORK_TREE_ENVIRONMENT,
GRAFT_ENVIRONMENT,
INDEX_ENVIRONMENT,
NULL
};
conn->env = env;
*arg++ = "sh";
*arg++ = "-c";
}
die("exec failed");
}
fd[0] = pipefd[0][0];
fd[1] = pipefd[1][1];
close(pipefd[0][1]);
close(pipefd[1][0]);
*arg++ = cmd.buf;
*arg = NULL;
if (start_command(conn))
die("unable to fork");
fd[0] = conn->out; /* read from child's stdout */
fd[1] = conn->in; /* write to child's stdin */
strbuf_release(&cmd);
if (free_path)
free(path);
return conn;
@ -632,13 +626,12 @@ struct child_process *git_connect(int fd[2], char *url,
int finish_connect(struct child_process *conn)
{
int code;
if (!conn)
return 0;
while (waitpid(conn->pid, NULL, 0) < 0) {
if (errno != EINTR)
return -1;
}
code = finish_command(conn);
free(conn->argv);
free(conn);
return 0;
return code;
}