upload-pack: prepare for sideband message support.
authorJunio C Hamano <junkio@cox.net>
Wed, 21 Jun 2006 05:48:23 +0000 (22:48 -0700)
committerJunio C Hamano <junkio@cox.net>
Wed, 21 Jun 2006 09:34:14 +0000 (02:34 -0700)
This does not implement sideband for propagating the status to
the downloader yet, but add code to capture the standard error
output from the pack-objects process in preparation for sending
it off to the client when the protocol extension allows us to do
so.

Signed-off-by: Junio C Hamano <junkio@cox.net>
pack-objects.c
upload-pack.c

index 179560f..7a8c16c 100644 (file)
@@ -1221,6 +1221,10 @@ int main(int argc, char **argv)
                                local = 1;
                                continue;
                        }
                                local = 1;
                                continue;
                        }
+                       if (!strcmp("--progress", arg)) {
+                               progress = 1;
+                               continue;
+                       }
                        if (!strcmp("--incremental", arg)) {
                                incremental = 1;
                                continue;
                        if (!strcmp("--incremental", arg)) {
                                incremental = 1;
                                continue;
index a9a8f2e..13eaa22 100644 (file)
@@ -36,11 +36,13 @@ static int strip(char *line, int len)
 
 static void create_pack_file(void)
 {
 
 static void create_pack_file(void)
 {
-       /* Pipes between rev-list to pack-objects and pack-objects to us. */
-       int lp_pipe[2], pu_pipe[2];
+       /* Pipes between rev-list to pack-objects, pack-objects to us
+        * and pack-objects error stream for progress bar.
+        */
+       int lp_pipe[2], pu_pipe[2], pe_pipe[2];
        pid_t pid_rev_list, pid_pack_objects;
        int create_full_pack = (nr_our_refs == nr_needs && !nr_has);
        pid_t pid_rev_list, pid_pack_objects;
        int create_full_pack = (nr_our_refs == nr_needs && !nr_has);
-       char data[8193];
+       char data[8193], progress[128];
        int buffered = -1;
 
        if (pipe(lp_pipe) < 0)
        int buffered = -1;
 
        if (pipe(lp_pipe) < 0)
@@ -95,6 +97,8 @@ static void create_pack_file(void)
 
        if (pipe(pu_pipe) < 0)
                die("git-upload-pack: unable to create pipe");
 
        if (pipe(pu_pipe) < 0)
                die("git-upload-pack: unable to create pipe");
+       if (pipe(pe_pipe) < 0)
+               die("git-upload-pack: unable to create pipe");
        pid_pack_objects = fork();
        if (pid_pack_objects < 0) {
                /* daemon sets things up to ignore TERM */
        pid_pack_objects = fork();
        if (pid_pack_objects < 0) {
                /* daemon sets things up to ignore TERM */
@@ -104,12 +108,15 @@ static void create_pack_file(void)
        if (!pid_pack_objects) {
                dup2(lp_pipe[0], 0);
                dup2(pu_pipe[1], 1);
        if (!pid_pack_objects) {
                dup2(lp_pipe[0], 0);
                dup2(pu_pipe[1], 1);
+               dup2(pe_pipe[1], 2);
 
                close(lp_pipe[0]);
                close(lp_pipe[1]);
                close(pu_pipe[0]);
                close(pu_pipe[1]);
 
                close(lp_pipe[0]);
                close(lp_pipe[1]);
                close(pu_pipe[0]);
                close(pu_pipe[1]);
-               execl_git_cmd("pack-objects", "--stdout", NULL);
+               close(pe_pipe[0]);
+               close(pe_pipe[1]);
+               execl_git_cmd("pack-objects", "--stdout", "--progress", NULL);
                kill(pid_rev_list, SIGKILL);
                die("git-upload-pack: unable to exec git-pack-objects");
        }
                kill(pid_rev_list, SIGKILL);
                die("git-upload-pack: unable to exec git-pack-objects");
        }
@@ -117,20 +124,23 @@ static void create_pack_file(void)
        close(lp_pipe[0]);
        close(lp_pipe[1]);
 
        close(lp_pipe[0]);
        close(lp_pipe[1]);
 
-       /* We read from pu_pipe[0] to capture the pack data.
+       /* We read from pe_pipe[0] to capture stderr output for
+        * progress bar, and pu_pipe[0] to capture the pack data.
         */
         */
+       close(pe_pipe[1]);
        close(pu_pipe[1]);
 
        while (1) {
                const char *who;
        close(pu_pipe[1]);
 
        while (1) {
                const char *who;
+               char *cp;
                struct pollfd pfd[2];
                pid_t pid;
                int status;
                ssize_t sz;
                struct pollfd pfd[2];
                pid_t pid;
                int status;
                ssize_t sz;
-               int pu, pollsize;
+               int pe, pu, pollsize;
 
                pollsize = 0;
 
                pollsize = 0;
-               pu = -1;
+               pe = pu = -1;
 
                if (0 <= pu_pipe[0]) {
                        pfd[pollsize].fd = pu_pipe[0];
 
                if (0 <= pu_pipe[0]) {
                        pfd[pollsize].fd = pu_pipe[0];
@@ -138,6 +148,12 @@ static void create_pack_file(void)
                        pu = pollsize;
                        pollsize++;
                }
                        pu = pollsize;
                        pollsize++;
                }
+               if (0 <= pe_pipe[0]) {
+                       pfd[pollsize].fd = pe_pipe[0];
+                       pfd[pollsize].events = POLLIN;
+                       pe = pollsize;
+                       pollsize++;
+               }
 
                if (pollsize) {
                        if (poll(pfd, pollsize, -1) < 0) {
 
                if (pollsize) {
                        if (poll(pfd, pollsize, -1) < 0) {
@@ -187,6 +203,22 @@ static void create_pack_file(void)
                                if (sz < 0)
                                        goto fail;
                        }
                                if (sz < 0)
                                        goto fail;
                        }
+                       if (0 <= pe && (pfd[pe].revents & (POLLIN|POLLHUP))) {
+                               /* Status ready; we do not use it for now,
+                                * but later we will add side-band to send it
+                                * to the other side.
+                                */
+                               sz = read(pe_pipe[0], progress,
+                                         sizeof(progress));
+                               if (0 < sz)
+                                       write(2, progress, sz);
+                               else if (sz == 0) {
+                                       close(pe_pipe[0]);
+                                       pe_pipe[0] = -1;
+                               }
+                               else
+                                       goto fail;
+                       }
                }
 
                /* See if the children are still there */
                }
 
                /* See if the children are still there */