GIT 1.5.2.5
[gitweb.git] / send-pack.c
index 6756264b293e18467a59dc0222ee82e586cda76f..d5b51628dfbcc44b22b5069df19eeac67dda1e57 100644 (file)
@@ -3,12 +3,12 @@
 #include "tag.h"
 #include "refs.h"
 #include "pkt-line.h"
-#include "exec_cmd.h"
+#include "run-command.h"
 
 static const char send_pack_usage[] =
-"git-send-pack [--all] [--exec=git-receive-pack] <remote> [<head>...]\n"
-"  --all and explicit <head> specification are mutually exclusive.";
-static const char *exec = "git-receive-pack";
+"git-send-pack [--all] [--force] [--receive-pack=<git-receive-pack>] [--verbose] [--thin] [<host>:]<directory> [<ref>...]\n"
+"  --all and explicit <ref> specification are mutually exclusive.";
+static const char *receivepack = "git-receive-pack";
 static int verbose;
 static int send_all;
 static int force_update;
@@ -19,44 +19,35 @@ static int use_thin_pack;
  */
 static int pack_objects(int fd, struct ref *refs)
 {
-       int pipe_fd[2];
-       pid_t pid;
-
-       if (pipe(pipe_fd) < 0)
-               return error("send-pack: pipe failed");
-       pid = fork();
-       if (!pid) {
-               /*
-                * The child becomes pack-objects --revs; we feed
-                * the revision parameters to it via its stdin and
-                * let its stdout go back to the other end.
-                */
-               static const char *args[] = {
-                       "pack-objects",
-                       "--all-progress",
-                       "--revs",
-                       "--stdout",
-                       NULL,
-                       NULL,
-               };
-               if (use_thin_pack)
-                       args[4] = "--thin";
-               dup2(pipe_fd[0], 0);
-               dup2(fd, 1);
-               close(pipe_fd[0]);
-               close(pipe_fd[1]);
-               close(fd);
-               execv_git_cmd(args);
-               die("git-pack-objects exec failed (%s)", strerror(errno));
-       }
+       /*
+        * The child becomes pack-objects --revs; we feed
+        * the revision parameters to it via its stdin and
+        * let its stdout go back to the other end.
+        */
+       const char *args[] = {
+               "pack-objects",
+               "--all-progress",
+               "--revs",
+               "--stdout",
+               NULL,
+               NULL,
+       };
+       struct child_process po;
+
+       if (use_thin_pack)
+               args[4] = "--thin";
+       memset(&po, 0, sizeof(po));
+       po.argv = args;
+       po.in = -1;
+       po.out = fd;
+       po.git_cmd = 1;
+       if (start_command(&po))
+               die("git-pack-objects failed (%s)", strerror(errno));
 
        /*
         * We feed the pack-objects we just spawned with revision
         * parameters by writing to the pipe.
         */
-       close(pipe_fd[0]);
-       close(fd);
-
        while (refs) {
                char buf[42];
 
@@ -65,38 +56,23 @@ static int pack_objects(int fd, struct ref *refs)
                        memcpy(buf + 1, sha1_to_hex(refs->old_sha1), 40);
                        buf[0] = '^';
                        buf[41] = '\n';
-                       if (!write_or_whine(pipe_fd[1], buf, 42,
+                       if (!write_or_whine(po.in, buf, 42,
                                                "send-pack: send refs"))
                                break;
                }
                if (!is_null_sha1(refs->new_sha1)) {
                        memcpy(buf, sha1_to_hex(refs->new_sha1), 40);
                        buf[40] = '\n';
-                       if (!write_or_whine(pipe_fd[1], buf, 41,
+                       if (!write_or_whine(po.in, buf, 41,
                                                "send-pack: send refs"))
                                break;
                }
                refs = refs->next;
        }
-       close(pipe_fd[1]);
-
-       for (;;) {
-               int status, code;
-               pid_t waiting = waitpid(pid, &status, 0);
 
-               if (waiting < 0) {
-                       if (errno == EINTR)
-                               continue;
-                       return error("waitpid failed (%s)", strerror(errno));
-               }
-               if ((waiting != pid) || WIFSIGNALED(status) ||
-                   !WIFEXITED(status))
-                       return error("pack-objects died with strange error");
-               code = WEXITSTATUS(status);
-               if (code)
-                       return -code;
-               return 0;
-       }
+       if (finish_command(&po))
+               return error("pack-objects died with strange error");
+       return 0;
 }
 
 static void unmark_and_free(struct commit_list *list, unsigned int mark)
@@ -377,8 +353,12 @@ int main(int argc, char **argv)
                char *arg = *argv;
 
                if (*arg == '-') {
-                       if (!strncmp(arg, "--exec=", 7)) {
-                               exec = arg + 7;
+                       if (!prefixcmp(arg, "--receive-pack=")) {
+                               receivepack = arg + 15;
+                               continue;
+                       }
+                       if (!prefixcmp(arg, "--exec=")) {
+                               receivepack = arg + 7;
                                continue;
                        }
                        if (!strcmp(arg, "--all")) {
@@ -413,7 +393,7 @@ int main(int argc, char **argv)
                usage(send_pack_usage);
        verify_remote_names(nr_heads, heads);
 
-       pid = git_connect(fd, dest, exec);
+       pid = git_connect(fd, dest, receivepack);
        if (pid < 0)
                return 1;
        ret = send_pack(fd[0], fd[1], nr_heads, heads);