]> git.webhop.me Git - lcd4linux.git/commitdiff
[lcd4linux @ 2005-09-02 05:27:08 by reinelt]
authorreinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>
Fri, 2 Sep 2005 05:27:08 +0000 (05:27 +0000)
committerreinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>
Fri, 2 Sep 2005 05:27:08 +0000 (05:27 +0000)
double-fork daemonize patch from Petri Damsten

git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@586 3ae390bd-cb1e-0410-b409-cd5a39f66f1f

lcd4linux.c

index a532b492571c98e71f86b977a6e6b2ca14192c21..062ce5194f8a40974cdc0f34776d1d8ec4166f35 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: lcd4linux.c,v 1.78 2005/05/08 04:32:44 reinelt Exp $
+/* $Id: lcd4linux.c,v 1.79 2005/09/02 05:27:08 reinelt Exp $
  *
  * LCD4Linux
  *
@@ -23,6 +23,9 @@
  *
  *
  * $Log: lcd4linux.c,v $
+ * Revision 1.79  2005/09/02 05:27:08  reinelt
+ * double-fork daemonize patch from Petri Damsten
+ *
  * Revision 1.78  2005/05/08 04:32:44  reinelt
  * CodingStyle added and applied
  *
@@ -450,6 +453,70 @@ void handler(int signal)
 }
 
 
+static void daemonize(void)
+{
+
+    /* thanks to Petri Damsten, we now follow the guidelines from the UNIX Programming FAQ */
+    /* 1.7 How do I get my program to act like a daemon? */
+    /* http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16 */
+    /* especially the double-fork solved the 'lcd4linux dying when called from init' problem */
+
+    pid_t i;
+    int fd;
+
+
+    /* Step 1: fork() so that the parent can exit */
+    i = fork();
+    if (i < 0) {
+       error("fork(#1) failed: %s", strerror(errno));
+       exit(1);
+    }
+    if (i != 0)
+       exit(0);
+
+    /* Step 2: setsid() to become a process group and session group leader */
+    setsid();
+
+    /* Step 3: fork() again so the parent (the session group leader) can exit */
+    i = fork();
+    if (i < 0) {
+       error("fork(#2) failed: %s", strerror(errno));
+       exit(1);
+    }
+    if (i != 0)
+       exit(0);
+
+    /* Step 4: chdir("/") to ensure that our process doesn't keep any directory in use */
+    if (chdir("/") != 0) {
+       error("chdir(\"/\") failed: %s", strerror(errno));
+       exit(1);
+    }
+
+    /* Step 5: umask(0) so that we have complete control over the permissions of anything we write */
+    umask(0);
+
+    /* Step 6: Establish new open descriptors for stdin, stdout and stderr */
+    /* detach stdin */
+    if (freopen("/dev/null", "r", stdin) == NULL) {
+       error("freopen (/dev/null) failed: %s", strerror(errno));
+       exit(1);
+    }
+
+    /* detach stdout and stderr */
+    fd = open("/dev/null", O_WRONLY, 0666);
+    if (fd == -1) {
+       error("open (/dev/null) failed: %s", strerror(errno));
+       exit(1);
+    }
+    fflush(stdout);
+    dup2(fd, STDOUT_FILENO);
+    fflush(stderr);
+    dup2(fd, STDERR_FILENO);
+    close(fd);
+
+}
+
+
 int main(int argc, char *argv[])
 {
     char *cfg = "/etc/lcd4linux.conf";
@@ -546,48 +613,15 @@ int main(int argc, char *argv[])
     }
 
     if (!running_foreground) {
-       pid_t i;
-       int fd;
+
        debug("going background...");
-       i = fork();
-       if (i < 0) {
-           error("fork() failed: %s", strerror(errno));
-           exit(1);
-       }
-       if (i != 0)
-           exit(0);
+
+       daemonize();
 
        /* ignore nasty signals */
        signal(SIGINT, SIG_IGN);
        signal(SIGQUIT, SIG_IGN);
 
-       /* chdir("/") */
-       if (chdir("/") != 0) {
-           error("chdir(\"/\") failed: %s", strerror(errno));
-           exit(1);
-       }
-
-       /* we want full control over permissions */
-       umask(0);
-
-       /* detach stdin */
-       if (freopen("/dev/null", "r", stdin) == NULL) {
-           error("freopen (/dev/null) failed: %s", strerror(errno));
-           exit(1);
-       }
-
-       /* detach stdout and stderr */
-       fd = open("/dev/null", O_WRONLY, 0666);
-       if (fd == -1) {
-           error("open (/dev/null) failed: %s", strerror(errno));
-           exit(1);
-       }
-       fflush(stdout);
-       fflush(stderr);
-       dup2(fd, STDOUT_FILENO);
-       dup2(fd, STDERR_FILENO);
-       close(fd);
-
        /* create PID file */
        if ((pid = pid_init(PIDFILE)) != 0) {
            error("lcd4linux already running as process %d", pid);