Now that the run_command family supports all of the redirection modes needed by builtin-bundle, we can use those functions rather than the underlying POSIX primitives. This should help to make the bundle command slightly more portable to other systems, like Windows. Signed-off-by: Shawn O. Pearce <spearce@xxxxxxxxxxx> --- Yes, this replaces my earlier version of the same patch. I failed to test it before sending it out; the earlier version returned a bad status code in create_bundle. builtin-bundle.c | 129 +++++++++++++----------------------------------------- 1 files changed, 30 insertions(+), 99 deletions(-) diff --git a/builtin-bundle.c b/builtin-bundle.c index 7868080..0a9b738 100644 --- a/builtin-bundle.c +++ b/builtin-bundle.c @@ -4,7 +4,7 @@ #include "diff.h" #include "revision.h" #include "list-objects.h" -#include "exec_cmd.h" +#include "run-command.h" /* * Basic handler for bundle files to connect repositories via sneakernet. @@ -99,67 +99,6 @@ static int read_header(const char *path, struct bundle_header *header) { return fd; } -/* if in && *in >= 0, take that as input file descriptor instead */ -static int fork_with_pipe(const char **argv, int *in, int *out) -{ - int needs_in, needs_out; - int fdin[2], fdout[2], pid; - - needs_in = in && *in < 0; - if (needs_in) { - if (pipe(fdin) < 0) - return error("could not setup pipe"); - *in = fdin[1]; - } - - needs_out = out && *out < 0; - if (needs_out) { - if (pipe(fdout) < 0) - return error("could not setup pipe"); - *out = fdout[0]; - } - - if ((pid = fork()) < 0) { - if (needs_in) { - close(fdin[0]); - close(fdin[1]); - } - if (needs_out) { - close(fdout[0]); - close(fdout[1]); - } - return error("could not fork"); - } - if (!pid) { - if (needs_in) { - dup2(fdin[0], 0); - close(fdin[0]); - close(fdin[1]); - } else if (in) { - dup2(*in, 0); - close(*in); - } - if (needs_out) { - dup2(fdout[1], 1); - close(fdout[0]); - close(fdout[1]); - } else if (out) { - dup2(*out, 1); - close(*out); - } - exit(execv_git_cmd(argv)); - } - if (needs_in) - close(fdin[0]); - else if (in) - close(*in); - if (needs_out) - close(fdout[1]); - else if (out) - close(*out); - return pid; -} - static int list_refs(struct ref_list *r, int argc, const char **argv) { int i; @@ -263,9 +202,10 @@ static int create_bundle(struct bundle_header *header, const char *path, int bundle_fd = -1; const char **argv_boundary = xmalloc((argc + 4) * sizeof(const char *)); const char **argv_pack = xmalloc(5 * sizeof(const char *)); - int pid, in, out, i, status, ref_count = 0; + int i, ref_count = 0; char buffer[1024]; struct rev_info revs; + struct child_process rls; bundle_fd = (!strcmp(path, "-") ? 1 : open(path, O_CREAT | O_EXCL | O_WRONLY, 0666)); @@ -285,11 +225,13 @@ static int create_bundle(struct bundle_header *header, const char *path, argv_boundary[1] = "--boundary"; argv_boundary[2] = "--pretty=oneline"; argv_boundary[argc + 2] = NULL; - out = -1; - pid = fork_with_pipe(argv_boundary, NULL, &out); - if (pid < 0) + memset(&rls, 0, sizeof(rls)); + rls.argv = argv_boundary; + rls.out = -1; + rls.git_cmd = 1; + if (start_command(&rls)) return -1; - while ((i = read_string(out, buffer, sizeof(buffer))) > 0) { + while ((i = read_string(rls.out, buffer, sizeof(buffer))) > 0) { unsigned char sha1[20]; if (buffer[0] == '-') { write_or_die(bundle_fd, buffer, i); @@ -303,11 +245,8 @@ static int create_bundle(struct bundle_header *header, const char *path, object->flags |= SHOWN; } } - while ((i = waitpid(pid, &status, 0)) < 0) - if (errno != EINTR) - return error("rev-list died"); - if (!WIFEXITED(status) || WEXITSTATUS(status)) - return error("rev-list died %d", WEXITSTATUS(status)); + if (finish_command(&rls)) + return error("rev-list died"); /* write references */ argc = setup_revisions(argc, argv, &revs, NULL); @@ -352,26 +291,23 @@ static int create_bundle(struct bundle_header *header, const char *path, argv_pack[2] = "--stdout"; argv_pack[3] = "--thin"; argv_pack[4] = NULL; - in = -1; - out = bundle_fd; - pid = fork_with_pipe(argv_pack, &in, &out); - if (pid < 0) + memset(&rls, 0, sizeof(rls)); + rls.argv = argv_pack; + rls.in = -1; + rls.out = bundle_fd; + rls.git_cmd = 1; + if (start_command(&rls)) return error("Could not spawn pack-objects"); for (i = 0; i < revs.pending.nr; i++) { struct object *object = revs.pending.objects[i].item; if (object->flags & UNINTERESTING) - write(in, "^", 1); - write(in, sha1_to_hex(object->sha1), 40); - write(in, "\n", 1); + write(rls.in, "^", 1); + write(rls.in, sha1_to_hex(object->sha1), 40); + write(rls.in, "\n", 1); } - close(in); - while (waitpid(pid, &status, 0) < 0) - if (errno != EINTR) - return -1; - if (!WIFEXITED(status) || WEXITSTATUS(status)) + if (finish_command(&rls)) return error ("pack-objects died"); - - return status; + return 0; } static int unbundle(struct bundle_header *header, int bundle_fd, @@ -379,22 +315,17 @@ static int unbundle(struct bundle_header *header, int bundle_fd, { const char *argv_index_pack[] = {"index-pack", "--fix-thin", "--stdin", NULL}; - int pid, status, dev_null; + struct child_process ip; if (verify_bundle(header, 0)) return -1; - dev_null = open("/dev/null", O_WRONLY); - if (dev_null < 0) - return error("Could not open /dev/null"); - pid = fork_with_pipe(argv_index_pack, &bundle_fd, &dev_null); - if (pid < 0) - return error("Could not spawn index-pack"); - while (waitpid(pid, &status, 0) < 0) - if (errno != EINTR) - return error("index-pack died"); - if (!WIFEXITED(status) || WEXITSTATUS(status)) - return error("index-pack exited with status %d", - WEXITSTATUS(status)); + memset(&ip, 0, sizeof(ip)); + ip.argv = argv_index_pack; + ip.in = bundle_fd; + ip.no_stdout = 1; + ip.git_cmd = 1; + if (run_command(&ip)) + return error("index-pack died"); return list_heads(header, argc, argv); } -- 1.5.0.3.985.gcf0b4 - To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html