diff options
| author | reinelt <> | 2005-09-02 05:27:08 +0000 | 
|---|---|---|
| committer | reinelt <> | 2005-09-02 05:27:08 +0000 | 
| commit | cb38a04ae87b8c8bd75d91a24e68c94af0bf934a (patch) | |
| tree | 123127bfc3ae4ba4bc7fca90d26a86154b913d6e | |
| parent | c38464bf6e096534075716a2eb98b05bdc31ee22 (diff) | |
| download | lcd4linux-cb38a04ae87b8c8bd75d91a24e68c94af0bf934a.tar.gz | |
[lcd4linux @ 2005-09-02 05:27:08 by reinelt]
double-fork daemonize patch from Petri Damsten
| -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); | 
