Replace gettimeofday() by clock_gettime().
[paraslash.git] / daemon.c
index ffdec4e..18ad156 100644 (file)
--- a/daemon.c
+++ b/daemon.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1997-2011 Andre Noll <maan@systemlinux.org>
+ * Copyright (C) 1997-2013 Andre Noll <maan@systemlinux.org>
  *
  * Licensed under the GPL v2. For licencing details see COPYING.
  */
@@ -10,8 +10,7 @@
 #include <pwd.h>
 #include <sys/types.h> /* getgrnam() */
 #include <grp.h>
-#include <sys/time.h>
-#include <stdbool.h>
+#include <signal.h>
 
 #include "para.h"
 #include "daemon.h"
@@ -65,8 +64,6 @@ void daemon_set_default_log_colors(void)
  * \param arg The loglevel/color specifier.
  *
  * \a arg must be of the form "ll:[fg [bg]] [attr]".
- *
- * \return 1 On success, -1 on errors.
  */
 void daemon_set_log_color_or_die(char const *arg)
 {
@@ -142,14 +139,25 @@ static bool daemon_test_flag(unsigned flag)
        return me->flags & flag;
 }
 
+static void dummy_sighandler(__a_unused int s)
+{
+}
+
 /**
  * Do the usual stuff to become a daemon.
  *
- * Fork, become session leader, dup fd 0, 1, 2 to /dev/null.
+ * \param parent_waits Whether the parent process should pause before exit.
  *
- * \sa fork(2), setsid(2), dup(2).
+ * Fork, become session leader, cd to /, and dup fd 0, 1, 2 to /dev/null. If \a
+ * parent_waits is false, the parent process terminates immediately.
+ * Otherwise, it calls pause() to sleep until it receives \p SIGTERM or \p
+ * SIGCHLD and exits successfully thereafter. This behaviour is useful if the
+ * daemon process should not detach from the console until the child process
+ * has completed its setup.
+ *
+ * \sa fork(2), setsid(2), dup(2), pause(2).
  */
-void daemonize(void)
+void daemonize(bool parent_waits)
 {
        pid_t pid;
        int null;
@@ -158,8 +166,14 @@ void daemonize(void)
        pid = fork();
        if (pid < 0)
                goto err;
-       if (pid)
+       if (pid) {
+               if (parent_waits) {
+                       signal(SIGTERM, dummy_sighandler);
+                       signal(SIGCHLD, dummy_sighandler);
+                       pause();
+               }
                exit(EXIT_SUCCESS); /* parent exits */
+       }
        /* become session leader */
        if (setsid() < 0)
                goto err;
@@ -339,7 +353,7 @@ __malloc char *get_server_uptime_str(const struct timeval *current_time)
  * \param ll The log level.
  * \param fmt The format string describing the log message.
  */
-__printf_2_3 void para_log(int ll, const char* fmt,...)
+__printf_2_3 void daemon_log(int ll, const char* fmt,...)
 {
        va_list argp;
        FILE *fp;
@@ -359,7 +373,7 @@ __printf_2_3 void para_log(int ll, const char* fmt,...)
                fprintf(fp, "%s", color);
        if (log_time || log_timing) {
                struct timeval tv;
-               gettimeofday(&tv, NULL);
+               clock_get_realtime(&tv);
                if (daemon_test_flag(DF_LOG_TIME)) { /* print date and time */
                        time_t t1 = tv.tv_sec;
                        char str[100];