X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=src%2Fmisc%2Fsyslog.c;h=ba9cc62b67626d4d621649660a2ab5f15830ac26;hb=3cd6f5229f079f892411e82fce3fe15c78eef4d8;hp=4809d2da68a9ab7f33c9a7c910e2b2eceebe0681;hpb=0b44a0315b47dd8eced9f3b7f31580cf14bbfc01;p=musl diff --git a/src/misc/syslog.c b/src/misc/syslog.c index 4809d2da..ba9cc62b 100644 --- a/src/misc/syslog.c +++ b/src/misc/syslog.c @@ -7,20 +7,21 @@ #include #include #include +#include #include "libc.h" +#include "atomic.h" -static int lock; -static const char *log_ident; +static int lock[2]; +static char log_ident[32]; 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) { - int old = log_mask; - if (maskpri) log_mask = maskpri; - return old; + if (maskpri) return a_swap(&log_mask, maskpri); + else return log_mask; } static const struct { @@ -33,83 +34,92 @@ static const struct { void closelog(void) { - LOCK(&lock); - if (log_f) fclose(log_f); - log_f = NULL; - UNLOCK(&lock); + int cs; + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); + LOCK(lock); + close(log_fd); + log_fd = -1; + UNLOCK(lock); + pthread_setcancelstate(cs, 0); } -static void __openlog(const char *ident, int opt, int facility) +static void __openlog() { - int fd; + log_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0); + if (log_fd >= 0) connect(log_fd, (void *)&log_addr, sizeof log_addr); +} - log_ident = ident; +void openlog(const char *ident, int opt, int facility) +{ + int cs; + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); + LOCK(lock); + + if (ident) { + size_t n = strnlen(ident, sizeof log_ident - 1); + memcpy(log_ident, ident, n); + log_ident[n] = 0; + } else { + log_ident[0] = 0; + } log_opt = opt; log_facility = facility; - if (!(opt & LOG_NDELAY) || log_f) return; + if ((opt & LOG_NDELAY) && log_fd<0) __openlog(); - fd = socket(AF_UNIX, SOCK_STREAM, 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"); -} - -void openlog(const char *ident, int opt, int facility) -{ - LOCK(&lock); - __openlog(ident, opt, facility); - UNLOCK(&lock); + UNLOCK(lock); + pthread_setcancelstate(cs, 0); } -void syslog(int priority, const char *message, ...) +static void _vsyslog(int priority, const char *message, va_list ap) { - struct sigaction sa; - 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(); + if (log_fd < 0) return; } - memset(&sa, 0, sizeof sa); - sa.sa_handler = SIG_IGN; - if (sigaction(SIGPIPE, &sa, &sa) < 0) { - // we must abandon logging or we might cause SIGPIPE - UNLOCK(&lock); - return; - } + if (!(priority & LOG_FACMASK)) priority |= log_facility; 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, "["+!pid, pid, "]"+!pid); + l2 = vsnprintf(buf+l, sizeof buf - l, message, ap); + if (l2 >= 0) { + if (l2 >= sizeof buf - l) l = sizeof buf - 1; + else l += l2; + if (buf[l-1] != '\n') buf[l++] = '\n'; + send(log_fd, buf, l, 0); + } +} +void __vsyslog(int priority, const char *message, va_list ap) +{ + int cs; + if (!(log_mask & LOG_MASK(priority&7)) || (priority&~0x3ff)) return; + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); + LOCK(lock); + _vsyslog(priority, message, ap); + UNLOCK(lock); + pthread_setcancelstate(cs, 0); +} + +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! - - sigaction(SIGPIPE, &sa, NULL); - - UNLOCK(&lock); } + +weak_alias(__vsyslog, vsyslog);