Code

gitweb: Allow for pre-parsed difftree info in git_patchset_body
[git.git] / daemon.c
index cdc42668633ec5a7b93544cca3fc92298d8556f4..012936f3bd76d9f9648ba9498b4126c7d6861e5c 100644 (file)
--- a/daemon.c
+++ b/daemon.c
@@ -19,27 +19,27 @@ static const char daemon_usage[] =
 "git-daemon [--verbose] [--syslog] [--inetd | --port=n] [--export-all]\n"
 "           [--timeout=n] [--init-timeout=n] [--strict-paths]\n"
 "           [--base-path=path] [--user-path | --user-path=path]\n"
-"           [--reuseaddr] [directory...]";
+"           [--reuseaddr] [--detach] [--pid-file=file] [directory...]";
 
 /* List of acceptable pathname prefixes */
-static char **ok_paths = NULL;
-static int strict_paths = 0;
+static char **ok_paths;
+static int strict_paths;
 
 /* If this is set, git-daemon-export-ok is not required */
-static int export_all_trees = 0;
+static int export_all_trees;
 
 /* Take all paths relative to this one if non-NULL */
-static char *base_path = NULL;
+static char *base_path;
 
 /* If defined, ~user notation is allowed and the string is inserted
  * after ~user/.  E.g. a request to git://host/~alice/frotz would
  * go to /home/alice/pub_git/frotz with --user-path=pub_git.
  */
-static const char *user_path = NULL;
+static const char *user_path;
 
 /* Timeout, and initial timeout */
-static unsigned int timeout = 0;
-static unsigned int init_timeout = 0;
+static unsigned int timeout;
+static unsigned int init_timeout;
 
 static void logreport(int priority, const char *err, va_list params)
 {
@@ -333,12 +333,12 @@ static int execute(struct sockaddr *addr)
 static int max_connections = 25;
 
 /* These are updated by the signal handler */
-static volatile unsigned int children_reaped = 0;
+static volatile unsigned int children_reaped;
 static pid_t dead_child[MAX_CHILDREN];
 
 /* These are updated by the main loop */
-static unsigned int children_spawned = 0;
-static unsigned int children_deleted = 0;
+static unsigned int children_spawned;
+static unsigned int children_deleted;
 
 static struct child {
        pid_t pid;
@@ -674,6 +674,24 @@ static void sanitize_stdfds(void)
                close(fd);
 }
 
+static void daemonize(void)
+{
+       switch (fork()) {
+               case 0:
+                       break;
+               case -1:
+                       die("fork failed: %s", strerror(errno));
+               default:
+                       exit(0);
+       }
+       if (setsid() == -1)
+               die("setsid failed: %s", strerror(errno));
+       close(0);
+       close(1);
+       close(2);
+       sanitize_stdfds();
+}
+
 static void store_pid(const char *path)
 {
        FILE *f = fopen(path, "w");
@@ -699,6 +717,7 @@ int main(int argc, char **argv)
        int port = DEFAULT_GIT_PORT;
        int inetd_mode = 0;
        const char *pid_file = NULL;
+       int detach = 0;
        int i;
 
        /* Without this we cannot rely on waitpid() to tell
@@ -767,6 +786,11 @@ int main(int argc, char **argv)
                        pid_file = arg + 11;
                        continue;
                }
+               if (!strcmp(arg, "--detach")) {
+                       detach = 1;
+                       log_syslog = 1;
+                       continue;
+               }
                if (!strcmp(arg, "--")) {
                        ok_paths = &argv[i+1];
                        break;
@@ -799,7 +823,10 @@ int main(int argc, char **argv)
                return execute(peer);
        }
 
-       sanitize_stdfds();
+       if (detach)
+               daemonize();
+       else
+               sanitize_stdfds();
 
        if (pid_file)
                store_pid(pid_file);