syslogd: Refactor backgrounding/daemonization w/ code from FreeBSD
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
parent
a3f3ed1833
commit
f46850b000
112
src/syslogd.c
112
src/syslogd.c
@ -167,7 +167,6 @@ void domark(void *arg);
|
|||||||
void doflush(void *arg);
|
void doflush(void *arg);
|
||||||
void debug_switch();
|
void debug_switch();
|
||||||
void die(int sig);
|
void die(int sig);
|
||||||
void doexit(int sig);
|
|
||||||
void init();
|
void init();
|
||||||
static int strtobytes(char *arg);
|
static int strtobytes(char *arg);
|
||||||
static int cfparse(FILE *fp, struct files *newf);
|
static int cfparse(FILE *fp, struct files *newf);
|
||||||
@ -175,6 +174,9 @@ int decode(char *name, struct _code *codetab);
|
|||||||
static void logit(char *, ...);
|
static void logit(char *, ...);
|
||||||
void sighup_handler(int);
|
void sighup_handler(int);
|
||||||
static int validate(struct sockaddr *sa, const char *hname);
|
static int validate(struct sockaddr *sa, const char *hname);
|
||||||
|
static int waitdaemon(int);
|
||||||
|
static void timedout(int);
|
||||||
|
|
||||||
|
|
||||||
static int addpeer(struct peer *pe0)
|
static int addpeer(struct peer *pe0)
|
||||||
{
|
{
|
||||||
@ -248,7 +250,7 @@ int usage(int code)
|
|||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
pid_t ppid = getpid();
|
pid_t ppid = 1;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
int pflag = 0, bflag = 0;
|
int pflag = 0, bflag = 0;
|
||||||
int ch;
|
int ch;
|
||||||
@ -376,30 +378,10 @@ int main(int argc, char *argv[])
|
|||||||
else
|
else
|
||||||
kern_console_off();
|
kern_console_off();
|
||||||
|
|
||||||
if (!Foreground) {
|
if (!Foreground && !Debug) {
|
||||||
chdir("/");
|
ppid = waitdaemon(30);
|
||||||
|
if (ppid < 0)
|
||||||
signal(SIGTERM, doexit);
|
err(1, "Failed daemonizing");
|
||||||
if (fork()) {
|
|
||||||
/*
|
|
||||||
* Parent process
|
|
||||||
*/
|
|
||||||
sleep(300);
|
|
||||||
/*
|
|
||||||
* Not reached unless something major went wrong. 5
|
|
||||||
* minutes should be a fair amount of time to wait.
|
|
||||||
* Please note that this procedure is important since
|
|
||||||
* the father must not exit before syslogd isn't
|
|
||||||
* initialized or the klogd won't be able to flush its
|
|
||||||
* logs. -Joey
|
|
||||||
*/
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
signal(SIGTERM, SIG_DFL);
|
|
||||||
for (int i = 0; i < getdtablesize(); i++)
|
|
||||||
(void)close(i);
|
|
||||||
untty();
|
|
||||||
} else if (Debug) {
|
} else if (Debug) {
|
||||||
debugging_on = 1;
|
debugging_on = 1;
|
||||||
setlinebuf(stdout);
|
setlinebuf(stdout);
|
||||||
@ -434,18 +416,16 @@ int main(int argc, char *argv[])
|
|||||||
debugging_on = 0;
|
debugging_on = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Send a signal to the parent to it can terminate.
|
|
||||||
*/
|
|
||||||
if (getpid() != ppid)
|
|
||||||
kill(ppid, SIGTERM);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tell system we're up and running by creating /run/syslogd.pid
|
* Tell system we're up and running by creating /run/syslogd.pid
|
||||||
*/
|
*/
|
||||||
if (pidfile(PidFile))
|
if (pidfile(PidFile))
|
||||||
logit("Failed creating %s: %s", PidFile, strerror(errno));
|
logit("Failed creating %s: %s", PidFile, strerror(errno));
|
||||||
|
|
||||||
|
/* Tell parent we're up and running */
|
||||||
|
if (ppid != 1)
|
||||||
|
kill(ppid, SIGALRM);
|
||||||
|
|
||||||
/* Main loop begins here. */
|
/* Main loop begins here. */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int rc;
|
int rc;
|
||||||
@ -2009,11 +1989,73 @@ void die(int signo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Signal handler to terminate the parent process.
|
* fork off and become a daemon, but wait for the child to come online
|
||||||
|
* before returning to the parent, or we get disk thrashing at boot etc.
|
||||||
|
* Set a timer so we don't hang forever if it wedges.
|
||||||
*/
|
*/
|
||||||
void doexit(int signo)
|
static int waitdaemon(int maxwait)
|
||||||
{
|
{
|
||||||
exit(0);
|
int fd;
|
||||||
|
int status;
|
||||||
|
pid_t pid, childpid;
|
||||||
|
|
||||||
|
childpid = fork();
|
||||||
|
switch (childpid) {
|
||||||
|
case -1:
|
||||||
|
return -1;
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
signal(SIGALRM, timedout);
|
||||||
|
alarm(maxwait);
|
||||||
|
while ((pid = wait3(&status, 0, NULL)) != -1) {
|
||||||
|
if (WIFEXITED(status))
|
||||||
|
errx(1, "child pid %d exited with return code %d",
|
||||||
|
pid, WEXITSTATUS(status));
|
||||||
|
if (WIFSIGNALED(status))
|
||||||
|
errx(1, "child pid %d exited on signal %d%s",
|
||||||
|
pid, WTERMSIG(status),
|
||||||
|
WCOREDUMP(status) ? " (core dumped)" :
|
||||||
|
"");
|
||||||
|
if (pid == childpid) /* it's gone... */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setsid() == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
(void)chdir("/");
|
||||||
|
fd = open(_PATH_DEVNULL, O_RDWR, 0);
|
||||||
|
if (fd != -1) {
|
||||||
|
(void)dup2(fd, STDIN_FILENO);
|
||||||
|
(void)dup2(fd, STDOUT_FILENO);
|
||||||
|
(void)dup2(fd, STDERR_FILENO);
|
||||||
|
if (fd > STDERR_FILENO)
|
||||||
|
(void)close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return getppid();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We get a SIGALRM from the child when it's running and finished doing it's
|
||||||
|
* fsync()'s or O_SYNC writes for all the boot messages.
|
||||||
|
*
|
||||||
|
* We also get a signal from the kernel if the timer expires, so check to
|
||||||
|
* see what happened.
|
||||||
|
*/
|
||||||
|
static void timedout(int signo)
|
||||||
|
{
|
||||||
|
int left;
|
||||||
|
|
||||||
|
left = alarm(0);
|
||||||
|
signal(SIGALRM, SIG_DFL);
|
||||||
|
if (left == 0)
|
||||||
|
errx(1, "timed out waiting for child");
|
||||||
|
|
||||||
|
_exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create fallback .conf with err+panic sent to console */
|
/* Create fallback .conf with err+panic sent to console */
|
||||||
|
Loading…
Reference in New Issue
Block a user