From 98158e9cfd2808613f305bf587ce697762c884bb Mon Sep 17 00:00:00 2001 From: Johannes Sixt Date: Fri, 19 Oct 2007 21:47:53 +0200 Subject: Change git_connect() to return a struct child_process instead of a pid_t. This prepares the API of git_connect() and finish_connect() to operate on a struct child_process. Currently, we just use that object as a placeholder for the pid that we used to return. A follow-up patch will change the implementation of git_connect() and finish_connect() to make full use of the object. Old code had early-return-on-error checks at the calling sites of git_connect(), but since git_connect() dies on errors anyway, these checks were removed. [sp: Corrected style nit of "conn == NULL" to "!conn"] Signed-off-by: Johannes Sixt Signed-off-by: Shawn O. Pearce --- builtin-fetch-pack.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'builtin-fetch-pack.c') diff --git a/builtin-fetch-pack.c b/builtin-fetch-pack.c index 8f25d509a0..f56592fea7 100644 --- a/builtin-fetch-pack.c +++ b/builtin-fetch-pack.c @@ -762,7 +762,7 @@ struct ref *fetch_pack(struct fetch_pack_args *my_args, { int i, ret; int fd[2]; - pid_t pid; + struct child_process *conn; struct ref *ref; struct stat st; @@ -773,16 +773,14 @@ struct ref *fetch_pack(struct fetch_pack_args *my_args, st.st_mtime = 0; } - pid = git_connect(fd, (char *)dest, uploadpack, + conn = git_connect(fd, (char *)dest, uploadpack, args.verbose ? CONNECT_VERBOSE : 0); - if (pid < 0) - return NULL; if (heads && nr_heads) nr_heads = remove_duplicates(nr_heads, heads); ref = do_fetch_pack(fd, nr_heads, heads, pack_lockfile); close(fd[0]); close(fd[1]); - ret = finish_connect(pid); + ret = finish_connect(conn); if (!ret && nr_heads) { /* If the heads to pull were given, we should have -- cgit v1.2.1 From 477822c35dbf3d5f16fce1425638e761e60ede3d Mon Sep 17 00:00:00 2001 From: Johannes Sixt Date: Fri, 19 Oct 2007 21:47:57 +0200 Subject: Use start_comand() in builtin-fetch-pack.c instead of explicit fork/exec. Signed-off-by: Johannes Sixt Signed-off-by: Shawn O. Pearce --- builtin-fetch-pack.c | 56 +++++++++++++++------------------------------------- 1 file changed, 16 insertions(+), 40 deletions(-) (limited to 'builtin-fetch-pack.c') diff --git a/builtin-fetch-pack.c b/builtin-fetch-pack.c index f56592fea7..871b7042e7 100644 --- a/builtin-fetch-pack.c +++ b/builtin-fetch-pack.c @@ -7,6 +7,7 @@ #include "pack.h" #include "sideband.h" #include "fetch-pack.h" +#include "run-command.h" static int transfer_unpack_limit = -1; static int fetch_unpack_limit = -1; @@ -491,18 +492,19 @@ static pid_t setup_sideband(int fd[2], int xd[2]) static int get_pack(int xd[2], char **pack_lockfile) { - int status; - pid_t pid, side_pid; + pid_t side_pid; int fd[2]; const char *argv[20]; char keep_arg[256]; char hdr_arg[256]; const char **av; int do_keep = args.keep_pack; - int keep_pipe[2]; + struct child_process cmd; side_pid = setup_sideband(fd, xd); + memset(&cmd, 0, sizeof(cmd)); + cmd.argv = argv; av = argv; *hdr_arg = 0; if (!args.keep_pack && unpack_limit) { @@ -519,8 +521,8 @@ static int get_pack(int xd[2], char **pack_lockfile) } if (do_keep) { - if (pack_lockfile && pipe(keep_pipe)) - die("fetch-pack: pipe setup failure: %s", strerror(errno)); + if (pack_lockfile) + cmd.out = -1; *av++ = "index-pack"; *av++ = "--stdin"; if (!args.quiet && !args.no_progress) @@ -544,43 +546,17 @@ static int get_pack(int xd[2], char **pack_lockfile) *av++ = hdr_arg; *av++ = NULL; - pid = fork(); - if (pid < 0) + cmd.in = fd[0]; + cmd.git_cmd = 1; + if (start_command(&cmd)) die("fetch-pack: unable to fork off %s", argv[0]); - if (!pid) { - dup2(fd[0], 0); - if (do_keep && pack_lockfile) { - dup2(keep_pipe[1], 1); - close(keep_pipe[0]); - close(keep_pipe[1]); - } - close(fd[0]); - close(fd[1]); - execv_git_cmd(argv); - die("%s exec failed", argv[0]); - } - close(fd[0]); close(fd[1]); - if (do_keep && pack_lockfile) { - close(keep_pipe[1]); - *pack_lockfile = index_pack_lockfile(keep_pipe[0]); - close(keep_pipe[0]); - } - while (waitpid(pid, &status, 0) < 0) { - if (errno != EINTR) - die("waiting for %s: %s", argv[0], strerror(errno)); - } - if (WIFEXITED(status)) { - int code = WEXITSTATUS(status); - if (code) - die("%s died with error code %d", argv[0], code); - return 0; - } - if (WIFSIGNALED(status)) { - int sig = WTERMSIG(status); - die("%s died of signal %d", argv[0], sig); - } - die("%s died of unnatural causes %d", argv[0], status); + if (do_keep && pack_lockfile) + *pack_lockfile = index_pack_lockfile(cmd.out); + + if (finish_command(&cmd)) + die("%s failed", argv[0]); + return 0; } static struct ref *do_fetch_pack(int fd[2], -- cgit v1.2.1 From 088fab5fc48ebb8b476c3b32dd25df3aa4236f94 Mon Sep 17 00:00:00 2001 From: Johannes Sixt Date: Fri, 19 Oct 2007 21:48:01 +0200 Subject: Use the asyncronous function infrastructure in builtin-fetch-pack.c. We run the sideband demultiplexer in an asynchronous function. Note that earlier there was a check in the child process that closed xd[1] only if it was different from xd[0]; this test is no longer needed because git_connect() always returns two different file descriptors (see ec587fde0a76780931c7ac32474c8c000aa45134). Signed-off-by: Johannes Sixt Signed-off-by: Shawn O. Pearce --- builtin-fetch-pack.c | 39 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 deletions(-) (limited to 'builtin-fetch-pack.c') diff --git a/builtin-fetch-pack.c b/builtin-fetch-pack.c index 871b7042e7..51d8a32791 100644 --- a/builtin-fetch-pack.c +++ b/builtin-fetch-pack.c @@ -457,42 +457,37 @@ static int everything_local(struct ref **refs, int nr_match, char **match) return retval; } -static pid_t setup_sideband(int fd[2], int xd[2]) +static int sideband_demux(int fd, void *data) { - pid_t side_pid; + int *xd = data; + close(xd[1]); + return recv_sideband("fetch-pack", xd[0], fd, 2); +} + +static void setup_sideband(int fd[2], int xd[2], struct async *demux) +{ if (!use_sideband) { fd[0] = xd[0]; fd[1] = xd[1]; - return 0; + return; } /* xd[] is talking with upload-pack; subprocess reads from * xd[0], spits out band#2 to stderr, and feeds us band#1 - * through our fd[0]. + * through demux->out. */ - if (pipe(fd) < 0) - die("fetch-pack: unable to set up pipe"); - side_pid = fork(); - if (side_pid < 0) + demux->proc = sideband_demux; + demux->data = xd; + if (start_async(demux)) die("fetch-pack: unable to fork off sideband demultiplexer"); - if (!side_pid) { - /* subprocess */ - close(fd[0]); - if (xd[0] != xd[1]) - close(xd[1]); - if (recv_sideband("fetch-pack", xd[0], fd[1], 2)) - exit(1); - exit(0); - } close(xd[0]); - close(fd[1]); + fd[0] = demux->out; fd[1] = xd[1]; - return side_pid; } static int get_pack(int xd[2], char **pack_lockfile) { - pid_t side_pid; + struct async demux; int fd[2]; const char *argv[20]; char keep_arg[256]; @@ -501,7 +496,7 @@ static int get_pack(int xd[2], char **pack_lockfile) int do_keep = args.keep_pack; struct child_process cmd; - side_pid = setup_sideband(fd, xd); + setup_sideband(fd, xd, &demux); memset(&cmd, 0, sizeof(cmd)); cmd.argv = argv; @@ -556,6 +551,8 @@ static int get_pack(int xd[2], char **pack_lockfile) if (finish_command(&cmd)) die("%s failed", argv[0]); + if (use_sideband && finish_async(&demux)) + die("error in sideband demultiplexer"); return 0; } -- cgit v1.2.1