diff --git a/include/prototypes.h b/include/prototypes.h index a5862b86..79422469 100644 --- a/include/prototypes.h +++ b/include/prototypes.h @@ -371,7 +371,7 @@ extern void print_config(FILE * fp); extern int roll(int); extern int roundavg(double); extern int chance(double); -extern void disassoc(void); +extern int disassoc(void); extern int diffx(int, int); extern int diffy(int, int); extern int deltax(int, int); diff --git a/src/lib/gen/Makefile b/src/lib/gen/Makefile index befb7f9c..6c3847ae 100644 --- a/src/lib/gen/Makefile +++ b/src/lib/gen/Makefile @@ -40,7 +40,7 @@ OBJS = chance.o copy.o disassoc.o \ ioqueue.o mapdist.o minmax.o numstr.o onearg.o \ parse.o plur.o queue.o round.o scthash.o -NTOBJS = chance.obj copy.obj disassoc.obj \ +NTOBJS = chance.obj copy.obj \ emp_config.obj getstarg.obj getstring.obj \ io.obj ioqueue.obj mapdist.obj minmax.obj \ numstr.obj onearg.obj parse.obj plur.obj queue.obj round.obj \ diff --git a/src/lib/gen/disassoc.c b/src/lib/gen/disassoc.c index bd055c6d..11371b8a 100644 --- a/src/lib/gen/disassoc.c +++ b/src/lib/gen/disassoc.c @@ -25,48 +25,54 @@ * * --- * - * disassoc.c: Fork and close + * disassoc.c: Boilerplate daemonization code * * Known contributors to this file: * Doug Hay, 1998 + * Markus Armbruster, 2005 */ /* - * boilerplate daemon code; disassociate from - * the current tty by forking, closing all file - * descriptors, opening slash, and ioctl-ing - * TIOCNOTTY + * See W. Richard Stevens: UNIX Network Programming, Vol. 1 */ -#include -#if !defined(_WIN32) -#include -#include /* fork close dup2 */ -#endif #include -#include "gen.h" +#include +#include +#include "prototypes.h" -void +int disassoc(void) { -#if !defined(_WIN32) + pid_t pid; int i; - if (fork() != 0) - exit(0); - for (i = 0; i < 2; i++) - (void)close(i); - (void)open("/", O_RDONLY, 0); - (void)dup2(0, 1); - (void)dup2(0, 2); -#if defined hpux || defined Rel4 - setsid(); -#else - i = open("/dev/tty", O_RDWR, 0); - if (i > 0) { - (void)ioctl(i, TIOCNOTTY, 0); - (void)close(i); - } -#endif -#endif + if ((pid = fork()) < 0) + return -1; + else if (pid) + _exit(0); /* parent */ + + /* Become session leader of new session, lose controlling tty */ + if (setsid() < 0) + return -1; + + /* Lose session leader status, so we can't acquire a controlling tty */ + if ((pid = fork()) < 0) + return -1; + else if (pid) + _exit(0); /* parent */ + /* Note: no controlling tty, therefore no SIGHUP sent */ + + /* datadir is working directory, that's fine */ + + /* We opened a bunch of files already, so just close 0..2 */ + for (i = 0; i < 3; i++) + close(i); + + /* Library code may use 0..2; make sure that's safe */ + open("/dev/null", O_RDWR); + dup(0); + dup(0); + + return 0; } diff --git a/src/server/main.c b/src/server/main.c index d1968063..d8cefac0 100644 --- a/src/server/main.c +++ b/src/server/main.c @@ -235,8 +235,12 @@ main(int argc, char **argv) } daemonize = 0; #else /* !_WIN32 */ - if (daemonize) - disassoc(); + if (daemonize) { + if (disassoc() < 0) { + logerror("Can't become daemon (%s)", strerror(errno)); + _exit(1); + } + } #endif /* !_WIN32 */ start_server(flags);