Code

modify/delete conflict resolution overwrites untracked file
[git.git] / daemon.c
index ce3a6f58f3c5c6bb88617510422c4053e0d545a2..8dcde73200d1ddbc0dec0dbfdc2f4ff15047abd9 100644 (file)
--- a/daemon.c
+++ b/daemon.c
 static int log_syslog;
 static int verbose;
 static int reuseaddr;
+static int child_handler_pipe[2];
 
 static const char daemon_usage[] =
-"git-daemon [--verbose] [--syslog] [--export-all]\n"
+"git daemon [--verbose] [--syslog] [--export-all]\n"
 "           [--timeout=n] [--init-timeout=n] [--strict-paths]\n"
 "           [--base-path=path] [--base-path-relaxed]\n"
 "           [--user-path | --user-path=path]\n"
@@ -788,10 +789,12 @@ static void child_handler(int signo)
                                pid = -pid;
                        dead_child[reaped % MAX_CHILDREN] = pid;
                        children_reaped = reaped + 1;
+                       write(child_handler_pipe[1], &status, 1);
                        continue;
                }
                break;
        }
+       signal(SIGCHLD, child_handler);
 }
 
 static int set_reuse_addr(int sockfd)
@@ -933,29 +936,24 @@ static int service_loop(int socknum, int *socklist)
        struct pollfd *pfd;
        int i;
 
-       pfd = xcalloc(socknum, sizeof(struct pollfd));
+       if (pipe(child_handler_pipe) < 0)
+               die ("Could not set up pipe for child handler");
+
+       pfd = xcalloc(socknum + 1, sizeof(struct pollfd));
 
        for (i = 0; i < socknum; i++) {
                pfd[i].fd = socklist[i];
                pfd[i].events = POLLIN;
        }
+       pfd[socknum].fd = child_handler_pipe[0];
+       pfd[socknum].events = POLLIN;
 
        signal(SIGCHLD, child_handler);
 
        for (;;) {
                int i;
-               int timeout;
 
-               /*
-                * This 1-sec timeout could lead to idly looping but it is
-                * here so that children culled in child_handler() are reported
-                * without too much delay.  We could probably set up a pipe
-                * to ourselves that we poll, and write to the fd from child_handler()
-                * to wake us up (and consume it when the poll() returns...
-                */
-               timeout = (children_spawned != children_deleted) ? 1000 : -1;
-               i = poll(pfd, socknum, timeout);
-               if (i < 0) {
+               if (poll(pfd, socknum + 1, -1) < 0) {
                        if (errno != EINTR) {
                                error("poll failed, resuming: %s",
                                      strerror(errno));
@@ -963,9 +961,9 @@ static int service_loop(int socknum, int *socklist)
                        }
                        continue;
                }
-               if (i == 0) {
+               if (pfd[socknum].revents & POLLIN) {
+                       read(child_handler_pipe[0], &i, 1);
                        check_dead_children();
-                       continue;
                }
 
                for (i = 0; i < socknum; i++) {