summaryrefslogtreecommitdiffstats
path: root/lib/libc/gen/syslog.c
diff options
context:
space:
mode:
authorjjbg <jjbg@openbsd.org>2001-10-24 08:16:42 +0000
committerjjbg <jjbg@openbsd.org>2001-10-24 08:16:42 +0000
commitf2f906231a04467a15d704e9431ae973c1b94763 (patch)
tree1d43313c32fe68d76d9c731ab42f109047f660fb /lib/libc/gen/syslog.c
parentAlpha supports wscons. -moj (diff)
downloadwireguard-openbsd-f2f906231a04467a15d704e9431ae973c1b94763.tar.xz
wireguard-openbsd-f2f906231a04467a15d704e9431ae973c1b94763.zip
syslog_r() implementation. deraadt@ ok.
Diffstat (limited to 'lib/libc/gen/syslog.c')
-rw-r--r--lib/libc/gen/syslog.c263
1 files changed, 168 insertions, 95 deletions
diff --git a/lib/libc/gen/syslog.c b/lib/libc/gen/syslog.c
index fa6b9511921..beabbcce9ba 100644
--- a/lib/libc/gen/syslog.c
+++ b/lib/libc/gen/syslog.c
@@ -32,7 +32,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char rcsid[] = "$OpenBSD: syslog.c,v 1.11 2001/08/18 22:56:22 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: syslog.c,v 1.12 2001/10/24 08:16:42 jjbg Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
@@ -56,17 +56,15 @@ static char rcsid[] = "$OpenBSD: syslog.c,v 1.11 2001/08/18 22:56:22 deraadt Exp
#include <varargs.h>
#endif
-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 */
+static struct syslog_data sdata = SYSLOG_DATA_INIT;
+
extern char *__progname; /* Program name, from crt0. */
static void disconnectlog __P((void)); /* disconnect from syslogd */
static void connectlog __P((void)); /* (re)connect to syslogd */
+static void disconnectlog_r __P((struct syslog_data *));
+static void connectlog_r __P((struct syslog_data *));
+
/*
* syslog, vsyslog --
* print message on log file; output is intended for syslogd(8).
@@ -98,8 +96,76 @@ vsyslog(pri, fmt, ap)
register const char *fmt;
va_list ap;
{
- register int cnt;
- register char ch, *p, *t;
+ vsyslog_r(pri, &sdata, fmt, ap);
+}
+
+static void
+disconnectlog()
+{
+ disconnectlog_r(&sdata);
+}
+
+static void
+connectlog()
+{
+ connectlog_r(&sdata);
+}
+
+void
+openlog(ident, logstat, logfac)
+ const char *ident;
+ int logstat, logfac;
+{
+ openlog_r(ident, logstat, logfac, &sdata);
+}
+
+void
+closelog()
+{
+ closelog_r(&sdata);
+}
+
+/* setlogmask -- set the log mask level */
+int
+setlogmask(pmask)
+ int pmask;
+{
+ return setlogmask_r(pmask, &sdata);
+}
+
+/* Reentrant version of syslog, i.e. syslog_r() */
+
+void
+#ifdef __STDC__
+syslog_r(int pri, struct syslog_data *data, const char *fmt, ...)
+#else
+syslog_r(pri, data, fmt, va_alist)
+ int pri;
+ struct syslog_data *data;
+ char *fmt;
+ va_dcl
+#endif
+{
+ va_list ap;
+
+#ifdef __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ vsyslog_r(pri, data, fmt, ap);
+ va_end(ap);
+}
+
+void
+vsyslog_r(pri, data, fmt, ap)
+ int pri;
+ struct syslog_data *data;
+ const char *fmt;
+ va_list ap;
+{
+ int cnt;
+ char ch, *p, *t;
time_t now;
int fd, saved_errno;
#define TBUF_LEN 2048
@@ -110,65 +176,64 @@ vsyslog(pri, fmt, ap)
#define INTERNALLOG LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID
/* Check for invalid bits. */
if (pri & ~(LOG_PRIMASK|LOG_FACMASK)) {
- syslog(INTERNALLOG,
- "syslog: unknown facility/priority: %x", pri);
+ if (data == &sdata) {
+ syslog(INTERNALLOG,
+ "syslog: unknown facility/priority: %x", pri);
+ } else {
+ syslog_r(INTERNALLOG, data,
+ "syslog_r: unknown facility/priority: %x", pri);
+ }
pri &= LOG_PRIMASK|LOG_FACMASK;
}
/* Check priority against setlogmask values. */
- if (!(LOG_MASK(LOG_PRI(pri)) & LogMask))
+ if (!(LOG_MASK(LOG_PRI(pri)) & data->log_mask))
return;
saved_errno = errno;
- /* Set default facility if none specified. */
- if ((pri & LOG_FACMASK) == 0)
- pri |= LogFacility;
+ /* If we have been called through syslog(), no need for reentrancy. */
+ if (data == &sdata)
+ (void)time(&now);
+
+ p = tbuf;
+ tbuf_left = TBUF_LEN;
+
+#define DEC() \
+ do { \
+ if (prlen < 0) \
+ prlen = 0; \
+ if (prlen >= tbuf_left) \
+ prlen = tbuf_left - 1; \
+ p += prlen; \
+ tbuf_left -= prlen; \
+ } while (0)
+
+ prlen = snprintf(p, tbuf_left, "<%d>", pri);
+ DEC();
- /* Build the message. */
-
- /*
- * Although it's tempting, we can't ignore the possibility of
- * overflowing the buffer when assembling the "fixed" portion
- * of the message. Strftime's "%h" directive expands to the
- * locale's abbreviated month name, but if the user has the
- * ability to construct to his own locale files, it may be
- * arbitrarily long.
+ /*
+ * syslogd will expand time automagically for reentrant case, and
+ * for normal case, just do like before
*/
- (void)time(&now);
-
- p = tbuf;
- tbuf_left = TBUF_LEN;
-
-#define DEC() \
- do { \
- if (prlen < 0) \
- prlen = 0; \
- else if (prlen >= tbuf_left) \
- prlen = tbuf_left - 1; \
- p += prlen; \
- tbuf_left -= prlen; \
- } while (0)
-
- prlen = snprintf(p, tbuf_left, "<%d>", pri);
- DEC();
-
- prlen = strftime(p, tbuf_left, "%h %e %T ", localtime(&now));
- DEC();
+ if (data == &sdata) {
+ prlen = strftime(p, tbuf_left, "%h %e %T ", localtime(&now));
+ DEC();
+ }
- if (LogStat & LOG_PERROR)
+ if (data->log_stat & LOG_PERROR)
stdp = p;
- if (LogTag == NULL)
- LogTag = __progname;
- if (LogTag != NULL) {
- prlen = snprintf(p, tbuf_left, "%s", LogTag);
+ if (data->log_tag == NULL)
+ data->log_tag = __progname;
+ if (data->log_tag != NULL) {
+ prlen = snprintf(p, tbuf_left, "%s", data->log_tag);
DEC();
}
- if (LogStat & LOG_PID) {
+ if (data->log_stat & LOG_PID) {
prlen = snprintf(p, tbuf_left, "[%d]", getpid());
DEC();
}
- if (LogTag != NULL) {
+ if (data->log_tag != NULL) {
if (tbuf_left > 1) {
*p++ = ':';
tbuf_left--;
@@ -179,15 +244,18 @@ vsyslog(pri, fmt, ap)
}
}
- /*
- * We wouldn't need this mess if printf handled %m, or if
- * strerror() had been invented before syslog().
- */
+ /* strerror() is not reentrant */
+
for (t = fmt_cpy, fmt_left = FMT_LEN; (ch = *fmt); ++fmt) {
if (ch == '%' && fmt[1] == 'm') {
++fmt;
- prlen = snprintf(t, fmt_left, "%s",
- strerror(saved_errno));
+ if (data == &sdata) {
+ prlen = snprintf(t, fmt_left, "%s",
+ strerror(saved_errno));
+ } else {
+ prlen = snprintf(t, fmt_left, "Error %d",
+ saved_errno);
+ }
if (prlen >= fmt_left)
prlen = fmt_left - 1;
t += prlen;
@@ -206,7 +274,7 @@ vsyslog(pri, fmt, ap)
cnt = p - tbuf;
/* Output to stderr if requested. */
- if (LogStat & LOG_PERROR) {
+ if (data->log_stat & LOG_PERROR) {
struct iovec iov[2];
iov[0].iov_base = stdp;
@@ -217,19 +285,19 @@ vsyslog(pri, fmt, ap)
}
/* Get connected, output the message to the local logger. */
- if (!opened)
- openlog(LogTag, LogStat, 0);
- connectlog();
- if (send(LogFile, tbuf, cnt, 0) >= 0)
+ if (!data->opened)
+ openlog_r(data->log_tag, data->log_stat, 0, data);
+ connectlog_r(data);
+ if (send(data->log_file, 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)
+ disconnectlog_r(data);
+ connectlog_r(data);
+ if (send(data->log_file, tbuf, cnt, 0) >= 0)
return;
/*
@@ -237,7 +305,7 @@ vsyslog(pri, fmt, ap)
* if console blocks everything will. Make sure the error reported
* is the one from the syslogd failure.
*/
- if (LogStat & LOG_CONS &&
+ if (data->log_stat & LOG_CONS &&
(fd = open(_PATH_CONSOLE, O_WRONLY, 0)) >= 0) {
struct iovec iov[2];
@@ -252,79 +320,84 @@ vsyslog(pri, fmt, ap)
}
static void
-disconnectlog()
+disconnectlog_r(data)
+ struct syslog_data *data;
{
/*
* 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;
+ if (data->log_file != -1) {
+ close(data->log_file);
+ data->log_file = -1;
}
- connected = 0; /* retry connect */
+ data->connected = 0; /* retry connect */
}
static void
-connectlog()
+connectlog_r(data)
+ struct syslog_data *data;
{
struct sockaddr_un SyslogAddr; /* AF_UNIX address of local logger */
- if (LogFile == -1) {
- if ((LogFile = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1)
+ if (data->log_file == -1) {
+ if ((data->log_file = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1)
return;
- (void)fcntl(LogFile, F_SETFD, 1);
+ (void)fcntl(data->log_file, F_SETFD, 1);
}
- if (LogFile != -1 && !connected) {
+ if (data->log_file != -1 && !data->connected) {
memset(&SyslogAddr, '\0', sizeof(SyslogAddr));
SyslogAddr.sun_len = sizeof(SyslogAddr);
SyslogAddr.sun_family = AF_UNIX;
strlcpy(SyslogAddr.sun_path, _PATH_LOG,
sizeof(SyslogAddr.sun_path));
- if (connect(LogFile, (struct sockaddr *)&SyslogAddr,
+ if (connect(data->log_file, (struct sockaddr *)&SyslogAddr,
sizeof(SyslogAddr)) == -1) {
- (void)close(LogFile);
- LogFile = -1;
+ (void)close(data->log_file);
+ data->log_file = -1;
} else
- connected = 1;
+ data->connected = 1;
}
}
void
-openlog(ident, logstat, logfac)
+openlog_r(ident, logstat, logfac, data)
const char *ident;
int logstat, logfac;
+ struct syslog_data *data;
{
if (ident != NULL)
- LogTag = ident;
- LogStat = logstat;
+ data->log_tag = ident;
+ data->log_stat = logstat;
if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0)
- LogFacility = logfac;
+ data->log_fac = logfac;
- if (LogStat & LOG_NDELAY) /* open immediately */
- connectlog();
+ if (data->log_stat & LOG_NDELAY) /* open immediately */
+ connectlog_r(data);
- opened = 1; /* ident and facility has been set */
+ data->opened = 1; /* ident and facility has been set */
}
void
-closelog()
+closelog_r(data)
+ struct syslog_data *data;
{
- (void)close(LogFile);
- LogFile = -1;
- connected = 0;
+ (void)close(data->log_file);
+ data->log_file = -1;
+ data->connected = 0;
}
/* setlogmask -- set the log mask level */
int
-setlogmask(pmask)
+setlogmask_r(pmask, data)
int pmask;
+ struct syslog_data *data;
{
int omask;
- omask = LogMask;
+ omask = data->log_mask;
if (pmask != 0)
- LogMask = pmask;
+ data->log_mask = pmask;
return (omask);
}