--- syslogd.c | 107 +++++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 78 insertions(+), 29 deletions(-) --- syslogd.c +++ syslogd.c 2022-10-18 06:25:00.236304111 +0000 @@ -826,6 +826,9 @@ extern int errno; int main(int argc, char **argv); char **crunch_list(char *list); int usage(void); +#ifdef SYSV +static pid_t sid; +#endif void untty(void); void printchopped(const char *hname, char *msg, int len, int fd); void printline(const char *hname, char *msg); @@ -839,7 +842,9 @@ const char *cvthname(struct sockaddr *f) void domark(); void debug_switch(); void logerror(const char *type); +static volatile sig_atomic_t leave; void die(int sig); +void dienow(void); #ifndef TESTING void doexit(int sig); #endif @@ -991,12 +996,32 @@ int main(argc, argv) dprintf("Checking pidfile.\n"); if (!check_pid(PidFile)) { + pid_t pid; + int n = 0, status; + signal (SIGTERM, doexit); - if (fork()) { + + switch ((pid = fork())) { + default: + retry: /* * Parent process */ - sleep(300); + switch (waitpid(pid, &status, WNOHANG|WUNTRACED)) { + case -1: + if (errno == EINTR) + goto retry; + break; + case 0: + if (leave) + exit(0); + usleep(10*1000); + if (++n < 30000) + goto retry; + default: + break; + } + case -1: /* * Not reached unless something major went wrong. 5 * minutes should be a fair amount of time to wait. @@ -1006,12 +1031,14 @@ int main(argc, argv) * logs. -Joey */ exit(1); + case 0: + signal (SIGTERM, SIG_DFL); + + num_fds = getdtablesize(); + for (i = 0; i < num_fds; i++) + (void) close(i); + untty(); } - signal (SIGTERM, SIG_DFL); - num_fds = getdtablesize(); - for (i= 0; i < num_fds; i++) - (void) close(i); - untty(); } else { @@ -1091,6 +1118,8 @@ int main(argc, argv) if (isupper(*p)) *p = tolower(*p); + leave = 0; + (void) signal(SIGTERM, die); (void) signal(SIGINT, Debug ? die : SIG_IGN); (void) signal(SIGQUIT, Debug ? die : SIG_IGN); @@ -1111,7 +1140,7 @@ int main(argc, argv) if (getpid() != ppid) kill (ppid, SIGTERM); #endif - die(0); + dienow(); } for(i= 0; i < num_fds; ++i) parts[i] = (char *) 0; @@ -1134,9 +1163,14 @@ int main(argc, argv) /* Main loop begins here. */ for (;;) { int nfds; + + if (leave) + dienow(); + errno = 0; FD_ZERO(&readfds); maxfds = 0; + #ifdef SYSLOG_UNIXAF #ifndef TESTING /* @@ -1322,7 +1356,7 @@ static int create_unix_socket(const char dprintf("cannot create %s (%d).\n", path, errno); close(fd); #ifndef SYSV - die(0); + dienow(); #endif return -1; } @@ -1480,8 +1514,8 @@ crunch_list(list) void untty() #ifdef SYSV { - if ( !Debug ) { - setsid(); + if ( !Debug && !sid ) { + sid = setsid(); } return; } @@ -1677,8 +1711,7 @@ void printsys(msg) /* * Decode a priority into textual information like auth.emerg. */ -char *textpri(pri) - int pri; +char *textpri(int pri) { static char res[20]; CODE *c_pri, *c_fac; @@ -2239,9 +2272,7 @@ void reapchild() (void) signal(SIGCHLD, reapchild); /* reset signal handler -ASP */ wait ((int *)0); #else - union wait status; - - while (wait3(&status, WNOHANG, (struct rusage *) NULL) > 0) + while (waitpid(-1, (int*)0, WNOHANG|WUNTRACED) > 0) ; #endif #ifdef linux @@ -2400,11 +2431,21 @@ void logerror(type) return; } -void die(sig) - int sig; +void die(int sig) { - register struct filed *f; char buf[100]; + leave++; + + dprintf("syslogd: exiting on signal %d\n", sig); + (void) snprintf(buf, sizeof(buf), "exiting on signal %d", sig); + errno = 0; + logmsg(LOG_SYSLOG|LOG_INFO, buf, LocalHostName, ADDDATE); + signal(sig, SIG_IGN); +} + +void dienow(void) +{ + register struct filed *f; int lognum; int i; int was_initialized = Initialized; @@ -2420,24 +2461,31 @@ void die(sig) } Initialized = was_initialized; - if (sig) { - dprintf("syslogd: exiting on signal %d\n", sig); - (void) snprintf(buf, sizeof(buf), "exiting on signal %d", sig); - errno = 0; - logmsg(LOG_SYSLOG|LOG_INFO, buf, LocalHostName, ADDDATE); - } /* Close the UNIX sockets. */ - for (i = 0; i < nfunix; i++) + for (i = 0; i < nfunix; i++) if (funix[i] != -1) close(funix[i]); + /* Close the inet socket. */ if (InetInuse) close(inetm); /* Clean-up files. */ - for (i = 0; i < nfunix; i++) + for (i = 0; i < nfunix; i++) if (funixn[i] && funix[i] != -1) (void)unlink(funixn[i]); + + for (lognum = 0; lognum <= nlogs; lognum++) { + f = &Files[lognum]; + if (f->f_file < 0) + continue; + if (f->f_type & F_FILE) { + (void) fdatasync(f->f_file); + (void) close(f->f_file); + f->f_file = -1; + } + } + #ifndef TESTING (void) remove_pid(PidFile); #endif @@ -2451,7 +2499,7 @@ void die(sig) void doexit(sig) int sig; { - exit (0); + leave++; } #endif @@ -2516,7 +2564,8 @@ void init() case F_TTY: case F_CONSOLE: case F_USOCK: - (void) close(f->f_file); + if (f->f_file >= 0) + (void) close(f->f_file); break; } }