diff options
author | Rich Felker <dalias@aerifal.cx> | 2011-04-13 18:32:33 -0400 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2011-04-13 18:32:33 -0400 |
commit | 19c1830eaaab05652d87b5ee9557d0d7a40c2f06 (patch) | |
tree | 5bdefc4579fd5385349497748e5f3477472d2c13 /src/misc/syslog.c | |
parent | a77411a50d22f6c9db305f19efda5ab2db3266de (diff) | |
download | musl-19c1830eaaab05652d87b5ee9557d0d7a40c2f06.tar.gz |
simplify syslog, add vsyslog interface (nonstandard)
with datagram sockets, depending on fprintf not to flush the output
early was very fragile; the new version simply uses a small fixed-size
buffer. it could be updated to dynamic-allocate large buffers if
needed, but i can't envision any admin being happy about finding
64kb-long lines in their syslog...
Diffstat (limited to 'src/misc/syslog.c')
-rw-r--r-- | src/misc/syslog.c | 67 |
1 files changed, 36 insertions, 31 deletions
diff --git a/src/misc/syslog.c b/src/misc/syslog.c index de42ce25..0f757640 100644 --- a/src/misc/syslog.c +++ b/src/misc/syslog.c @@ -14,7 +14,7 @@ static const char *log_ident; static int log_opt; static int log_facility = LOG_USER; static int log_mask = 0xff; -static FILE *log_f; +static int log_fd = -1; int setlogmask(int maskpri) { @@ -34,26 +34,21 @@ static const struct { void closelog(void) { LOCK(&lock); - if (log_f) fclose(log_f); - log_f = NULL; + close(log_fd); + log_fd = -1; UNLOCK(&lock); } static void __openlog(const char *ident, int opt, int facility) { - int fd; - log_ident = ident; log_opt = opt; log_facility = facility; - if (!(opt & LOG_NDELAY) || log_f) return; + if (!(opt & LOG_NDELAY) || log_fd>=0) return; - fd = socket(AF_UNIX, SOCK_DGRAM, 0); - fcntl(fd, F_SETFD, FD_CLOEXEC); - if (connect(fd, (void *)&log_addr, sizeof(short) + sizeof "/dev/log") < 0) - close(fd); - else log_f = fdopen(fd, "wb"); + log_fd = socket(AF_UNIX, SOCK_DGRAM, 0); + fcntl(log_fd, F_SETFD, FD_CLOEXEC); } void openlog(const char *ident, int opt, int facility) @@ -63,42 +58,52 @@ void openlog(const char *ident, int opt, int facility) UNLOCK(&lock); } -void syslog(int priority, const char *message, ...) +void __vsyslog(int priority, const char *message, va_list ap) { - va_list ap; char timebuf[16]; time_t now; struct tm tm; - //const char *fmt, *ident, *sep; - //int i; + char buf[256]; + int pid; + int l, l2; if (!(log_mask & LOG_MASK(priority&7)) || (priority&~0x3ff)) return; LOCK(&lock); - if (!log_f) __openlog(log_ident, log_opt | LOG_NDELAY, log_facility); - if (!log_f) { - UNLOCK(&lock); - return; + if (log_fd < 0) { + __openlog(log_ident, log_opt | LOG_NDELAY, log_facility); + if (log_fd < 0) { + UNLOCK(&lock); + return; + } } now = time(NULL); gmtime_r(&now, &tm); strftime(timebuf, sizeof timebuf, "%b %e %T", &tm); - fprintf(log_f, "<%d>%s ", priority, timebuf); - if (log_ident) fprintf(log_f, "%s", log_ident); - if (log_opt & LOG_PID) fprintf(log_f, "[%d]", getpid()); - if (log_ident) fprintf(log_f, ": "); + pid = (log_opt & LOG_PID) ? getpid() : 0; + l = snprintf(buf, sizeof buf, "<%d>%s %s%s%.0d%s: ", + priority, timebuf, + log_ident ? log_ident : "", + "["+!pid, pid, "]"+!pid); + l2 = vsnprintf(buf+l, sizeof buf - l, message, ap); + if (l2 >= 0) { + l += l2; + if (buf[l-1] != '\n') buf[l++] = '\n'; + sendto(log_fd, buf, l, 0, (void *)&log_addr, 11); + } + + UNLOCK(&lock); +} +void syslog(int priority, const char *message, ...) +{ + va_list ap; va_start(ap, message); - vfprintf(log_f, message, ap); + __vsyslog(priority, message, ap); va_end(ap); - fputc(0, log_f); - fflush(log_f); - - // Note: LOG_CONS is not supported because it is annoying!! - // syslogd will send messages to console if it deems them appropriate! - - UNLOCK(&lock); } + +weak_alias(__vsyslog, vsyslog); |