diff options
author | Rainer Gerhards <rgerhards@adiscon.com> | 2005-10-19 13:45:09 +0000 |
---|---|---|
committer | Rainer Gerhards <rgerhards@adiscon.com> | 2005-10-19 13:45:09 +0000 |
commit | 42017aa38855678653baeb1cf88b87564abe0c27 (patch) | |
tree | 3a780ac4998bcb720239a0743790e2856a2a7dfe /syslogd.c | |
parent | bc6d3e81e83de83871b03856d55eb71c6a5a0a4c (diff) | |
download | rsyslog-42017aa38855678653baeb1cf88b87564abe0c27.tar.gz rsyslog-42017aa38855678653baeb1cf88b87564abe0c27.tar.xz rsyslog-42017aa38855678653baeb1cf88b87564abe0c27.zip |
rsyslogd still shares some code with the sysklogd project. Some patches for
this shared code have been brought over from the sysklogd CVS.
Diffstat (limited to 'syslogd.c')
-rw-r--r-- | syslogd.c | 58 |
1 files changed, 49 insertions, 9 deletions
@@ -2775,11 +2775,11 @@ int main(int argc, char **argv) dprintf("Checking pidfile.\n"); if (!check_pid(PidFile)) { + signal (SIGTERM, doexit); if (fork()) { /* * Parent process */ - signal (SIGTERM, doexit); sleep(300); /* * Not reached unless something major went wrong. 5 @@ -3139,7 +3139,10 @@ int main(int argc, char **argv) from); } } - } else if (i < 0 && errno != EINTR) { + } else if (i < 0 && errno != EINTR && errno != EAGAIN) { + /* see link below why we check EAGAIN: + * http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=188194 + */ dprintf("INET socket error: %d = %s.\n", \ errno, strerror(errno)); logerror("recvfrom inet"); @@ -3256,6 +3259,7 @@ static int create_udp_socket() { int fd, on = 1; struct sockaddr_in sin; + int sockflags; fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) { @@ -3285,6 +3289,27 @@ static int create_udp_socket() } } #endif + /* We must not block on the network socket, in case a packet + * gets lost between select and recv, otherwise the process + * will stall until the timeout, and other processes trying to + * log will also stall. + * Patch vom Colin Phipps <cph@cph.demon.co.uk> to the original + * sysklogd source. Applied to rsyslogd on 2005-10-19. + */ + if ((sockflags = fcntl(fd, F_GETFL)) != -1) { + sockflags |= O_NONBLOCK; + /* + * SETFL could fail too, so get it caught by the subsequent + * error check. + */ + sockflags = fcntl(fd, F_SETFL, sockflags); + } + if (sockflags == -1) { + logerror("fcntl(O_NONBLOCK), suspending inet"); + close(fd); + return -1; + } + if (bind(fd, (struct sockaddr *) &sin, sizeof(sin)) < 0) { logerror("bind, suspending inet"); close(fd); @@ -3294,9 +3319,7 @@ static int create_udp_socket() } #endif -char ** -crunch_list(list) - char *list; +static char **crunch_list(char *list) { int count, i; char *p, *q; @@ -3319,7 +3342,7 @@ crunch_list(list) for (count=i=0; p[i]; i++) if (p[i] == LIST_DELIMITER) count++; - if ((result = (char **)malloc(sizeof(char *) * count+2)) == NULL) { + if ((result = (char **)malloc(sizeof(char *) * (count+2))) == NULL) { printf ("Sorry, can't get enough memory, exiting.\n"); exit(0); } @@ -4708,11 +4731,17 @@ void endutent(void) * * Write the specified message to either the entire * world, or a list of approved users. + * + * rgerhards, 2005-10-19: applying the following sysklogd patch: + * Tue May 4 16:52:01 CEST 2004: Solar Designer <solar@openwall.com> + * Adjust the size of a variable to prevent a buffer overflow + * should _PATH_DEV ever contain something different than "/dev/". */ static void wallmsg(register struct filed *f) { - char p[6 + UNAMESZ]; + + char p[sizeof(_PATH_DEV) + UNAMESZ]; register int i; int ttyf; static int reenter = 0; @@ -4736,7 +4765,6 @@ static void wallmsg(register struct filed *f) if (fork() == 0) { (void) signal(SIGTERM, SIG_DFL); (void) alarm(0); - (void) signal(SIGALRM, endtty); #ifndef SYSV (void) signal(SIGTTOU, SIG_IGN); (void) sigsetmask(0); @@ -4752,7 +4780,7 @@ static void wallmsg(register struct filed *f) if (ut.ut_name[0] == '\0') continue; #ifndef BSD - if (ut.ut_type == LOGIN_PROCESS) + if (ut.ut_type != USER_PROCESS) continue; #endif if (!(strncmp (ut.ut_name,"LOGIN", 6))) /* paranoia */ @@ -4778,6 +4806,7 @@ static void wallmsg(register struct filed *f) strncat(p, ut.ut_line, UNAMESZ); if (setjmp(ttybuf) == 0) { + (void) signal(SIGALRM, endtty); (void) alarm(15); /* open the terminal */ ttyf = open(p, O_WRONLY|O_NOCTTY); @@ -4880,6 +4909,17 @@ static const char *cvthname(struct sockaddr_in *f) return (hp->h_name); } +/* This method is called by an alarm handler. As such, we can have potentially + * race-conditons. It might be a very good idea to change this to real threading, + * for now we "just" need to be very careful about potential side-effects. For an + * example (and explanation), see: + * http://lkml.org/lkml/2005/3/26/37 + * http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=301511 + * TODO: I assume there are actually some bugs here, we are just lucky that + * the interval is so seldom that they (usually) do not manifest. It would + * probably be a good idea to redisign this whole thing... + * rgerhards, 2005-10-19 + */ void domark() { register struct filed *f; |