+bool daemon_init_colors_or_die(int color_arg, int color_arg_auto,
+ int color_arg_no, bool logfile_given)
+{
+ if (color_arg == color_arg_no)
+ return false;
+ if (color_arg == color_arg_auto) {
+ if (logfile_given)
+ return false;
+ if (!isatty(STDERR_FILENO))
+ return false;
+ }
+ daemon_set_flag(DF_COLOR_LOG);
+ daemon_set_default_log_colors();
+ return true;
+}
+
+/**
+ * Init or change the name of the log file.
+ *
+ * \param logfile_name The full path of the logfile.
+ */
+void daemon_set_logfile(const char *logfile_name)
+{
+ free(me->logfile_name);
+ me->logfile_name = NULL;
+ if (!logfile_name)
+ return;
+ if (me->old_cwd && logfile_name[0] != '/')
+ me->logfile_name = make_message("%s/%s", me->old_cwd,
+ logfile_name);
+ else
+ 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(const 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;
+}
+
+/**
+ * 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, a pipe is created prior to the fork() and the parent tries to
+ * read a single byte from the reading end of the pipe. The child is supposed
+ * to write to the writing end of the pipe after it completed its setup
+ * procedure successfully. This behaviour is useful to let the parent process
+ * die with an error if the child process aborts early, since in this case the
+ * read() will return non-positive.
+ *
+ * \return This function either succeeds or calls exit(3). If parent_waits is
+ * true, the return value is the file descriptor of the writing end of the
+ * pipe. Otherwise the function returns zero.
+ *
+ * \sa fork(2), setsid(2), dup(2), pause(2).
+ */
+int daemonize(bool parent_waits)