diff options
author | reinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f> | 2005-09-02 05:27:08 +0000 |
---|---|---|
committer | reinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f> | 2005-09-02 05:27:08 +0000 |
commit | 77693cbb08dad2ab6f65e6cd40b7646bb52b6f91 (patch) | |
tree | 123127bfc3ae4ba4bc7fca90d26a86154b913d6e | |
parent | 6696076f075b14f23e905f21395cb5ad638f9570 (diff) | |
download | lcd4linux-77693cbb08dad2ab6f65e6cd40b7646bb52b6f91.tar.gz |
[lcd4linux @ 2005-09-02 05:27:08 by reinelt]
double-fork daemonize patch from Petri Damsten
git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@586 3ae390bd-cb1e-0410-b409-cd5a39f66f1f
-rw-r--r-- | lcd4linux.c | 108 |
1 files changed, 71 insertions, 37 deletions
diff --git a/lcd4linux.c b/lcd4linux.c index a532b49..062ce51 100644 --- a/lcd4linux.c +++ b/lcd4linux.c @@ -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); |