static int system_log = 0;
+static int parent_fd = 0;
+
static time_t last_limited = 0;
#ifdef WINNT
} else {
fprintf(stderr, "Fatal error : %s\n", buf);
}
+ if (parent_fd) {
+ write(parent_fd, buf, strlen(buf) + 1);
+ }
#endif
MAI_CleanupAndExit();
/* ================================================== */
+void
+LOG_SetParentFd(int fd)
+{
+ parent_fd = fd;
+}
+
+/* ================================================== */
+
+void
+LOG_CloseParentFd()
+{
+ if (parent_fd > 0)
+ close(parent_fd);
+}
+
+/* ================================================== */
+
int
LOG_RateLimited(void)
{
/* Log messages to syslog instead of stderr */
extern void LOG_OpenSystemLog(void);
+/* Send fatal message also to the foreground process */
+extern void LOG_SetParentFd(int fd);
+
+/* Close the pipe to the foreground process so it can exit */
+extern void LOG_CloseParentFd(void);
+
/* Return zero once per 10 seconds */
extern int LOG_RateLimited(void);
static void
post_acquire_hook(void *anything)
{
+ /* Close the pipe to the foreground process so it can exit */
+ LOG_CloseParentFd();
CNF_AddSources();
CNF_AddBroadcasts();
#else
- int pid, fd;
+ int pid, fd, pipefd[2];
+
+ /* Create pipe which will the daemon use to notify the grandparent
+ when it's initialised or send an error message */
+ if (pipe(pipefd)) {
+ LOG(LOGS_ERR, LOGF_Logging, "Could not detach, pipe failed : %s", strerror(errno));
+ }
/* Does this preserve existing signal handlers? */
pid = fork();
if (pid < 0) {
LOG(LOGS_ERR, LOGF_Logging, "Could not detach, fork failed : %s", strerror(errno));
} else if (pid > 0) {
- exit(0); /* In the 'grandparent' */
+ /* In the 'grandparent' */
+ char message[1024];
+ int r;
+
+ close(pipefd[1]);
+ r = read(pipefd[0], message, sizeof (message));
+ if (r) {
+ if (r > 0) {
+ /* Print the error message from the child */
+ fprintf(stderr, "%.1024s\n", message);
+ }
+ exit(1);
+ } else
+ exit(0);
} else {
+ close(pipefd[0]);
setsid();
} else {
/* In the child we want to leave running as the daemon */
- /* Don't keep stdin/out/err from before. */
+ /* Don't keep stdin/out/err from before. But don't close
+ the parent pipe yet. */
for (fd=0; fd<1024; fd++) {
- close(fd);
+ if (fd != pipefd[1])
+ close(fd);
}
/* Change current directory to / */
chdir("/");
+
+ LOG_SetParentFd(pipefd[1]);
}
}
if (maybe_another_chronyd_running(&other_pid)) {
LOG_FATAL(LOGF_Main, "Another chronyd may already be running (pid=%d), check lockfile (%s)",
other_pid, CNF_GetPidFile());
- exit(1);
}
/* Write our lockfile to prevent other chronyds running. This has *GOT* to