daemon: signal_pidfile()
authorMarko Kreen <markokr@gmail.com>
Mon, 9 Aug 2010 22:17:58 +0000 (01:17 +0300)
committerMarko Kreen <markokr@gmail.com>
Tue, 31 Aug 2010 07:36:10 +0000 (10:36 +0300)
usual/daemon.c
usual/daemon.h

index fa94d228267835c1a1c26740db752b13f5137422..768a494cb2c285b04e72df121c83a24840f38fdf 100644 (file)
@@ -42,7 +42,15 @@ static void remove_pidfile(void)
        g_pidfile = NULL;
 }
 
-static void check_pidfile(const char *pidfile)
+/*
+ * Reads pid from pidfile and sends a signal to it.
+ *
+ * true - signaling was successful.
+ * false - ENOENT / ESRCH
+ *
+ * fatal() otherwise.
+ */
+bool signal_pidfile(const char *pidfile, int sig)
 {
        char buf[128 + 1];
        struct stat st;
@@ -50,43 +58,54 @@ static void check_pidfile(const char *pidfile)
        int fd, res;
 
        if (!pidfile || !pidfile[0])
-               return;
+               return false;
 
+intr_loop:
        /* check if pidfile exists */
-       if (stat(pidfile, &st) < 0) {
-               if (errno != ENOENT)
-                       fatal_perror("stat");
-               return;
-       }
+       if (stat(pidfile, &st) < 0)
+               goto fail;
 
        /* read old pid */
        fd = open(pidfile, O_RDONLY);
        if (fd < 0)
-               goto locked_pidfile;
+               goto fail;
        res = read(fd, buf, sizeof(buf) - 1);
        close(fd);
        if (res <= 0)
-               goto locked_pidfile;
+               goto fail;
 
        /* parse pid */
        buf[res] = 0;
-       pid = atol(buf);
-       if (pid <= 0)
-               goto locked_pidfile;
-
-       /* check if running */
-       if (kill(pid, 0) >= 0)
-               goto locked_pidfile;
-       if (errno != ESRCH)
-               goto locked_pidfile;
-
-       /* seems the pidfile is not in use */
-       log_info("Stale pidfile, removing");
-       unlink(pidfile);
-       return;
-
-locked_pidfile:
-       fatal("pidfile exists, another instance running?");
+       errno = 0;
+       pid = strtoul(buf, NULL, 10);
+       if (errno) {
+               /* should we panic, or say no such process exists? */
+               if (0)
+                       errno = ESRCH;
+               goto fail;
+       }
+
+       /* send the signal */
+       res = kill(pid, sig);
+       if (res == 0)
+               return true;
+fail:
+       /* decide error seriousness */
+       if (errno == EINTR)
+               goto intr_loop;
+       if (errno == ENOENT || errno == ESRCH)
+               return false;
+       fatal_perror("signal_pidfile: Unexpected error");
+}
+
+static void check_pidfile(const char *pidfile)
+{
+       if (signal_pidfile(pidfile, 0))
+               fatal("pidfile exists, another instance running?");
+       if (errno == ESRCH) {
+               log_info("Stale pidfile, removing");
+               unlink(pidfile);
+       }
 }
 
 static void write_pidfile(const char *pidfile)
index 3fbe175682abbf8ad368bf5142efd0a48c4ae68d..9a0ef3ee5b2e881179f350098d21f7d9a74e50d6 100644 (file)
@@ -21,6 +21,8 @@
 
 #include <usual/base.h>
 
+bool signal_pidfile(const char *pidfile, int sig);
+
 void daemonize(const char *pidfile, bool go_background);
 
 #endif