daemon: use a custom die routine with syslog
[gitweb.git] / daemon.c
index bdfe80d2e4f4fc13ad45bd35aeeeb3ec71422a4f..a7636bc50c3d0148adaeaca5e624fcf1ab542d8d 100644 (file)
--- a/daemon.c
+++ b/daemon.c
@@ -35,7 +35,7 @@ static char *base_path = NULL;
  * 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 char *user_path = NULL;
+static const char *user_path = NULL;
 
 /* Timeout, and initial timeout */
 static unsigned int timeout = 0;
@@ -95,6 +95,12 @@ static void loginfo(const char *err, ...)
        va_end(params);
 }
 
+static void NORETURN daemon_die(const char *err, va_list params)
+{
+       logreport(LOG_ERR, err, params);
+       exit(1);
+}
+
 static int avoid_alias(char *p)
 {
        int sl, ndot;
@@ -472,7 +478,7 @@ static void child_handler(int signo)
                        children_reaped = reaped + 1;
                        /* XXX: Custom logging, since we don't wanna getpid() */
                        if (verbose) {
-                               char *dead = "";
+                               const char *dead = "";
                                if (!WIFEXITED(status) || WEXITSTATUS(status) > 0)
                                        dead = " (with error)";
                                if (log_syslog)
@@ -673,6 +679,11 @@ int main(int argc, char **argv)
        int inetd_mode = 0;
        int i;
 
+       /* Without this we cannot rely on waitpid() to tell
+        * what happened to our children.
+        */
+       signal(SIGCHLD, SIG_DFL);
+
        for (i = 1; i < argc; i++) {
                char *arg = argv[i];
 
@@ -741,23 +752,20 @@ int main(int argc, char **argv)
                usage(daemon_usage);
        }
 
-       if (log_syslog)
+       if (log_syslog) {
                openlog("git-daemon", 0, LOG_DAEMON);
-
-       if (strict_paths && (!ok_paths || !*ok_paths)) {
-               if (!inetd_mode)
-                       die("git-daemon: option --strict-paths requires a whitelist");
-
-               logerror("option --strict-paths requires a whitelist");
-               exit (1);
+               set_die_routine(daemon_die);
        }
 
+       if (strict_paths && (!ok_paths || !*ok_paths))
+               die("option --strict-paths requires a whitelist");
+
        if (inetd_mode) {
                struct sockaddr_storage ss;
                struct sockaddr *peer = (struct sockaddr *)&ss;
                socklen_t slen = sizeof(ss);
 
-               fclose(stderr); //FIXME: workaround
+               freopen("/dev/null", "w", stderr);
 
                if (getpeername(0, peer, &slen))
                        peer = NULL;