summaryrefslogtreecommitdiffstats
path: root/lib/libc/gen/syslog.c
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1996-03-02 19:56:16 +0000
committerpeter <peter@FreeBSD.org>1996-03-02 19:56:16 +0000
commitd7f117dcfc9f17a4334a001b202d5c8488a15b48 (patch)
tree4e4ad70ee9ec150b50e5cf824a3660597a4614a9 /lib/libc/gen/syslog.c
parent8465726bdae0892d85c26b32cd01d2f6936303ef (diff)
downloadFreeBSD-src-d7f117dcfc9f17a4334a001b202d5c8488a15b48.zip
FreeBSD-src-d7f117dcfc9f17a4334a001b202d5c8488a15b48.tar.gz
If the send() to the AF_UNIX socket to the syslogd fails, attempt to
reconnect once using the saved openlog() parameters. This helps one of the system startup race conditions. If syslogd takes too long to get going, some daemons can fail the connection and forever log to the console even though the syslogd is running. That is ..unfortunate..
Diffstat (limited to 'lib/libc/gen/syslog.c')
-rw-r--r--lib/libc/gen/syslog.c74
1 files changed, 56 insertions, 18 deletions
diff --git a/lib/libc/gen/syslog.c b/lib/libc/gen/syslog.c
index 1ef9a66..1949332 100644
--- a/lib/libc/gen/syslog.c
+++ b/lib/libc/gen/syslog.c
@@ -36,7 +36,7 @@
static char sccsid[] = "From: @(#)syslog.c 8.4 (Berkeley) 3/18/94";
*/
static const char rcsid[] =
- "$Id: syslog.c,v 1.6 1995/10/21 07:05:01 peter Exp $";
+ "$Id: syslog.c,v 1.7 1995/10/22 14:37:08 phk Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
@@ -61,12 +61,16 @@ static const char rcsid[] =
static int LogFile = -1; /* fd for log */
static int connected; /* have done connect */
+static int opened; /* have done openlog() */
static int LogStat = 0; /* status bits, set by openlog() */
static const char *LogTag = NULL; /* string to tag the entry with */
static int LogFacility = LOG_USER; /* default facility code */
static int LogMask = 0xff; /* mask of priorities to be logged */
extern char *__progname; /* Program name, from crt0. */
+static void disconnectlog __P((void)); /* disconnect from syslogd */
+static void connectlog __P((void)); /* (re)connect to syslogd */
+
/*
* Format of the magic cookie passed through the stdio hook
*/
@@ -80,7 +84,8 @@ struct bufcookie {
* XXX: Maybe one day, dynamically allocate it so that the line length
* is `unlimited'.
*/
-static writehook(cookie, buf, len)
+static
+int writehook(cookie, buf, len)
void *cookie; /* really [struct bufcookie *] */
char *buf; /* characters to copy */
int len; /* length to copy */
@@ -233,8 +238,18 @@ vsyslog(pri, fmt, ap)
}
/* Get connected, output the message to the local logger. */
- if (!connected)
+ if (!opened)
openlog(LogTag, LogStat | LOG_NDELAY, 0);
+ connectlog();
+ if (send(LogFile, tbuf, cnt, 0) >= 0)
+ return;
+
+ /*
+ * If the send() failed, the odds are syslogd was restarted.
+ * Make one (only) attempt to reconnect to /dev/log.
+ */
+ disconnectlog();
+ connectlog();
if (send(LogFile, tbuf, cnt, 0) >= 0)
return;
@@ -261,33 +276,56 @@ vsyslog(pri, fmt, ap)
static struct sockaddr SyslogAddr; /* AF_UNIX address of local logger */
-void
-openlog(ident, logstat, logfac)
- const char *ident;
- int logstat, logfac;
+static void
+disconnectlog()
{
- if (ident != NULL)
- LogTag = ident;
- LogStat = logstat;
- if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0)
- LogFacility = logfac;
+ /*
+ * If the user closed the FD and opened another in the same slot,
+ * that's their problem. They should close it before calling on
+ * system services.
+ */
+ if (LogFile != -1) {
+ close(LogFile);
+ LogFile = -1;
+ }
+ connected = 0; /* retry connect */
+}
+static void
+connectlog()
+{
if (LogFile == -1) {
SyslogAddr.sa_family = AF_UNIX;
(void)strncpy(SyslogAddr.sa_data, _PATH_LOG,
sizeof(SyslogAddr.sa_data));
- if (LogStat & LOG_NDELAY) {
- if ((LogFile = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1)
- return;
- (void)fcntl(LogFile, F_SETFD, 1);
- }
+ if ((LogFile = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1)
+ return;
+ (void)fcntl(LogFile, F_SETFD, 1);
}
- if (LogFile != -1 && !connected)
+ if (LogFile != -1 && !connected) {
if (connect(LogFile, &SyslogAddr, sizeof(SyslogAddr)) == -1) {
(void)close(LogFile);
LogFile = -1;
} else
connected = 1;
+ }
+}
+
+void
+openlog(ident, logstat, logfac)
+ const char *ident;
+ int logstat, logfac;
+{
+ if (ident != NULL)
+ LogTag = ident;
+ LogStat = logstat;
+ if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0)
+ LogFacility = logfac;
+
+ if (LogStat & LOG_NDELAY) /* open immediately */
+ connectlog();
+
+ opened = 1; /* ident and facility has been set */
}
void
OpenPOWER on IntegriCloud