+void daemon_init_colors_or_die(int color_arg, int color_arg_auto,
+ int color_arg_no, bool logfile_given, char **log_color_argv,
+ int argc)
+{
+ int i;
+
+ if (color_arg == color_arg_no)
+ return;
+ if (color_arg == color_arg_auto) {
+ if (logfile_given)
+ return;
+ if (!isatty(STDERR_FILENO))
+ return;
+ }
+ daemon_set_flag(DF_COLOR_LOG);
+ daemon_set_default_log_colors();
+ for (i = 0; i < argc; i++)
+ daemon_set_log_color_or_die(log_color_argv[i]);
+}
+
+/**
+ * Init or change the name of the log file.
+ *
+ * \param logfile_name The full path of the logfile.
+ */
+void daemon_set_logfile(char *logfile_name)
+{
+ free(me->logfile_name);
+ me->logfile_name = NULL;
+ if (logfile_name)
+ me->logfile_name = para_strdup(logfile_name);
+}
+
+/**
+ * Suppress log messages with severity lower than the given loglevel.
+ *
+ * \param loglevel The smallest level that should be logged.
+ */
+void daemon_set_loglevel(char *loglevel)
+{
+ int ret = get_loglevel_by_name(loglevel);
+
+ assert(ret >= 0);
+ me->loglevel = ret;
+}
+
+/**
+ * Set one of the daemon config flags.
+ *
+ * \param flag The flag to set.
+ *
+ * \sa \ref daemon_flags.
+ */
+void daemon_set_flag(unsigned flag)
+{
+ me->flags |= flag;
+}
+
+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.
+ *
+ * \param parent_waits Whether the parent process should pause before exit.
+ *
+ * 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(bool parent_waits)