LogoopenSUSE Build Service > Projects
Sign Up | Log In

View File sysklogd-1.4.1-signal.dif of Package syslogd.363 (Project openSUSE:12.1:Update)

--- syslogd.c
+++ syslogd.c	2008-03-26 16:45:54.247851855 +0000
@@ -770,6 +770,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);
@@ -783,7 +786,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
@@ -932,12 +937,32 @@ int main(argc, argv)
 		dprintf("Checking pidfile.\n");
 		if (!check_pid(PidFile))
 		{
-			if (fork()) {
+			pid_t pid;
+			int n = 0, status;
+
+			signal (SIGTERM, doexit);
+
+			switch ((pid = fork())) {
+			default:
+			retry:
 				/*
 				 * Parent process
 				 */
-				signal (SIGTERM, doexit);
-				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.
@@ -947,11 +972,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();
 			}
-			num_fds = getdtablesize();
-			for (i= 0; i < num_fds; i++)
-				(void) close(i);
-			untty();
 		}
 		else
 		{
@@ -1028,6 +1056,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);
@@ -1044,7 +1074,7 @@ int main(argc, argv)
 	    (char **) 0 )
 	{
 		logerror("Cannot allocate memory for message parts table.");
-		die(0);
+		dienow();
 	}
 	for(i= 0; i < num_fds; ++i)
 	    parts[i] = (char *) 0;
@@ -1067,9 +1097,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
 		/*
@@ -1256,7 +1291,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;
 	}
@@ -1406,8 +1441,8 @@ crunch_list(list)
 void untty()
 #ifdef SYSV
 {
-	if ( !Debug ) {
-		setsid();
+	if ( !Debug && !sid ) {
+		sid = setsid();
 	}
 	return;
 }
@@ -1597,8 +1632,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;
@@ -2128,9 +2162,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
@@ -2289,13 +2321,21 @@ void logerror(type)
 	return;
 }
 
-void die(sig)
+void die(int sig)
+{
+	char buf[100];
+	leave++;
 
-	int 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);
+	signal(sig, SIG_IGN);
+}
+
+void dienow(void)
 {
 	register struct filed *f;
-	char buf[100];
 	int lognum;
 	int i;
 	int was_initialized = Initialized;
@@ -2311,24 +2351,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
@@ -2342,7 +2389,7 @@ void die(sig)
 void doexit(sig)
 	int sig;
 {
-	exit (0);
+	leave++;
 }
 #endif
 
@@ -2403,7 +2450,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;
 			}
 		}