Tidy up daemonisation with regard to file descriptor mess

This moves daemonisation to the end of initialisation which
vastly simplifies the reporting logic and eliminates the need
for the child to communicate to the parent.

This is a backport from the release/4 branch.
This commit is contained in:
Aaron Jones 2016-08-21 00:34:38 +00:00
parent f70b6f55f9
commit 24ba10b6b1
No known key found for this signature in database
GPG key ID: EC6F86EE9CD840B5

View file

@ -149,39 +149,6 @@ ircd_shutdown(const char *reason)
exit(0); exit(0);
} }
/*
* print_startup - print startup information
*/
static void
print_startup(int pid)
{
int fd;
close(1);
fd = open("/dev/null", O_RDWR);
if (fd == -1) {
perror("open /dev/null");
exit(EXIT_FAILURE);
}
if (fd == 0)
fd = dup(fd);
if (fd != 1)
abort();
inotice("now running in %s mode from %s as pid %d ...",
!server_state_foreground ? "background" : "foreground",
ConfigFileEntry.dpath, pid);
/* let the parent process know the initialization was successful
* -- jilles */
if (!server_state_foreground)
write(0, ".", 1);
if (dup2(1, 0) == -1)
abort();
if (dup2(1, 2) == -1)
abort();
}
/* /*
* init_sys * init_sys
* *
@ -213,17 +180,18 @@ init_sys(void)
static int static int
make_daemon(void) make_daemon(void)
{ {
int pid; int pid, nullfd, fdx;
int pip[2];
char c;
if (pipe(pip) < 0) /* The below is approximately what daemon(1, 0) does, but
we need control over the parent after forking to print
the startup message -- Aaron */
if((nullfd = open("/dev/null", O_RDWR)) < 0)
{ {
perror("pipe"); perror("open /dev/null");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
dup2(pip[1], 0);
close(pip[1]);
if((pid = fork()) < 0) if((pid = fork()) < 0)
{ {
perror("fork"); perror("fork");
@ -231,22 +199,20 @@ make_daemon(void)
} }
else if(pid > 0) else if(pid > 0)
{ {
close(0); inotice("now running in background mode from %s as pid %d ...",
/* Wait for initialization to finish, successfully or ConfigFileEntry.dpath, pid);
* unsuccessfully. Until this point the child may still
* write to stdout/stderr.
* -- jilles */
if (read(pip[0], &c, 1) > 0)
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
else
exit(EXIT_FAILURE);
} }
close(pip[0]); for(fdx = 0; fdx <= 2; fdx++)
setsid(); if (fdx != nullfd)
/* fclose(stdin); (void) dup2(nullfd, fdx);
fclose(stdout);
fclose(stderr); */ if(nullfd > 2)
(void) close(nullfd);
(void) setsid();
return 0; return 0;
} }
@ -619,9 +585,6 @@ main(int argc, char *argv[])
if(!testing_conf) if(!testing_conf)
{ {
check_pidfile(pidFileName); check_pidfile(pidFileName);
if(!server_state_foreground)
make_daemon();
inotice("starting %s ...", ircd_version); inotice("starting %s ...", ircd_version);
inotice("%s", rb_lib_version()); inotice("%s", rb_lib_version());
} }
@ -739,7 +702,6 @@ main(int argc, char *argv[])
construct_umodebuf(); construct_umodebuf();
check_class(); check_class();
write_pidfile(pidFileName);
load_help(); load_help();
open_logfiles(); open_logfiles();
@ -758,7 +720,13 @@ main(int argc, char *argv[])
if(splitmode) if(splitmode)
check_splitmode_ev = rb_event_add("check_splitmode", check_splitmode, NULL, 5); check_splitmode_ev = rb_event_add("check_splitmode", check_splitmode, NULL, 5);
print_startup(getpid()); if(server_state_foreground)
inotice("now running in foreground mode from %s as pid %d ...",
ConfigFileEntry.dpath, getpid());
else
make_daemon();
write_pidfile(pidFileName);
rb_lib_loop(0); rb_lib_loop(0);