summaryrefslogtreecommitdiff
path: root/src/dmon.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dmon.c')
-rw-r--r--src/dmon.c171
1 files changed, 171 insertions, 0 deletions
diff --git a/src/dmon.c b/src/dmon.c
new file mode 100644
index 0000000..5845cda
--- /dev/null
+++ b/src/dmon.c
@@ -0,0 +1,171 @@
+/* $calcurse: dmon.c,v 1.1 2009/07/20 19:44:04 culot Exp $ */
+
+/*
+ * Calcurse - text-based organizer
+ *
+ * Copyright (c) 2009 Frederic Culot <frederic@culot.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Send your feedback or comments to : calcurse@culot.org
+ * Calcurse home page : http://culot.org/calcurse
+ *
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <paths.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+
+#include "utils.h"
+#include "i18n.h"
+#include "sigs.h"
+#include "mem.h"
+#include "io.h"
+#include "custom.h"
+#include "notify.h"
+#include "dmon.h"
+
+#define DMON_SLEEP_TIME 60
+
+static void
+dmon_sigs_hdlr (int sig)
+{
+ notify_free_app ();
+
+ exit (EXIT_SUCCESS);
+}
+
+static unsigned
+daemonize (int status)
+{
+ int fd;
+
+ /*
+ * Operate in the background: Daemonizing.
+ *
+ * First need to fork in order to become a child of the init process,
+ * once the father exits.
+ */
+ switch (fork ())
+ {
+ case -1: /* fork error */
+ ERROR_MSG (_("Could not fork: %s\n"), strerror (errno));
+ return 0;
+ break;
+ case 0: /* child */
+ break;
+ default: /* parent */
+ exit (status);
+ }
+
+ /*
+ * Process independency.
+ *
+ * Obtain a new process group and session in order to get detached from the
+ * controlling terminal.
+ */
+ if (setsid () == -1)
+ {
+ ERROR_MSG (_("Could not detach from the controlling terminal: %s\n"),
+ strerror (errno));
+ return 0;
+ }
+
+ /*
+ * Change working directory to root directory,
+ * to prevent filesystem unmounts.
+ */
+ if (chdir ("/") == -1)
+ {
+ ERROR_MSG (_("Could not change working directory: %s\n"),
+ strerror (errno));
+ return 0;
+ }
+
+ /* Redirect standard file descriptors to /dev/null. */
+ if ((fd = open (_PATH_DEVNULL, O_RDWR, 0)) != -1)
+ {
+ (void)dup2 (fd, STDIN_FILENO);
+ (void)dup2 (fd, STDOUT_FILENO);
+ (void)dup2 (fd, STDERR_FILENO);
+ if (fd > 2)
+ (void)close (fd);
+ }
+
+ /* Write access for the owner only. */
+ (void)umask (0022);
+
+ if (!sigs_set_hdlr (SIGINT, dmon_sigs_hdlr)
+ || !sigs_set_hdlr (SIGTERM, dmon_sigs_hdlr)
+ || !sigs_set_hdlr (SIGALRM, dmon_sigs_hdlr)
+ || !sigs_set_hdlr (SIGQUIT, dmon_sigs_hdlr)
+ || !sigs_set_hdlr (SIGCHLD, SIG_IGN))
+ return 0;
+
+ return 1;
+}
+
+void
+dmon_start (int parent_exit_status)
+{
+ conf_t conf;
+
+ if (!daemonize (parent_exit_status))
+ EXIT (_("Cannot daemonize, aborting\n"));
+
+ io_check_file (path_conf, (int *)0);
+ custom_load_conf (&conf, 0);
+
+ io_check_file (path_apts, (int *)0);
+ io_load_app ();
+
+ for (;;)
+ {
+ struct notify_app_s next;
+
+ (void)notify_get_next (&next);
+ if (next.got_app)
+ {
+ int left;
+
+ notify_update_app (next.time, next.state, next.txt);
+ left = notify_time_left ();
+
+ if (left < nbar.cntdwn)
+ notify_launch_cmd ();
+ }
+
+ if (next.txt)
+ mem_free (next.txt);
+
+ psleep (DMON_SLEEP_TIME);
+ }
+}