blob: 0f7576407e4945f9ab86dc33691661ea2e3d757a [file] [log] [blame]
Rich Felker0b44a032011-02-12 00:22:29 -05001#include <stdarg.h>
2#include <sys/socket.h>
3#include <stdio.h>
4#include <fcntl.h>
5#include <unistd.h>
6#include <syslog.h>
7#include <time.h>
8#include <signal.h>
9#include <string.h>
10#include "libc.h"
11
12static int lock;
13static const char *log_ident;
14static int log_opt;
15static int log_facility = LOG_USER;
16static int log_mask = 0xff;
Rich Felker19c18302011-04-13 18:32:33 -040017static int log_fd = -1;
Rich Felker0b44a032011-02-12 00:22:29 -050018
19int setlogmask(int maskpri)
20{
21 int old = log_mask;
22 if (maskpri) log_mask = maskpri;
23 return old;
24}
25
26static const struct {
27 short sun_family;
28 char sun_path[9];
29} log_addr = {
30 AF_UNIX,
31 "/dev/log"
32};
33
34void closelog(void)
35{
36 LOCK(&lock);
Rich Felker19c18302011-04-13 18:32:33 -040037 close(log_fd);
38 log_fd = -1;
Rich Felker0b44a032011-02-12 00:22:29 -050039 UNLOCK(&lock);
40}
41
42static void __openlog(const char *ident, int opt, int facility)
43{
Rich Felker0b44a032011-02-12 00:22:29 -050044 log_ident = ident;
45 log_opt = opt;
46 log_facility = facility;
47
Rich Felker19c18302011-04-13 18:32:33 -040048 if (!(opt & LOG_NDELAY) || log_fd>=0) return;
Rich Felker0b44a032011-02-12 00:22:29 -050049
Rich Felker19c18302011-04-13 18:32:33 -040050 log_fd = socket(AF_UNIX, SOCK_DGRAM, 0);
51 fcntl(log_fd, F_SETFD, FD_CLOEXEC);
Rich Felker0b44a032011-02-12 00:22:29 -050052}
53
54void openlog(const char *ident, int opt, int facility)
55{
56 LOCK(&lock);
57 __openlog(ident, opt, facility);
58 UNLOCK(&lock);
59}
60
Rich Felker19c18302011-04-13 18:32:33 -040061void __vsyslog(int priority, const char *message, va_list ap)
Rich Felker0b44a032011-02-12 00:22:29 -050062{
Rich Felker0b44a032011-02-12 00:22:29 -050063 char timebuf[16];
64 time_t now;
65 struct tm tm;
Rich Felker19c18302011-04-13 18:32:33 -040066 char buf[256];
67 int pid;
68 int l, l2;
Rich Felker0b44a032011-02-12 00:22:29 -050069
70 if (!(log_mask & LOG_MASK(priority&7)) || (priority&~0x3ff)) return;
71
72 LOCK(&lock);
73
Rich Felker19c18302011-04-13 18:32:33 -040074 if (log_fd < 0) {
75 __openlog(log_ident, log_opt | LOG_NDELAY, log_facility);
76 if (log_fd < 0) {
77 UNLOCK(&lock);
78 return;
79 }
Rich Felker0b44a032011-02-12 00:22:29 -050080 }
81
Rich Felker0b44a032011-02-12 00:22:29 -050082 now = time(NULL);
83 gmtime_r(&now, &tm);
84 strftime(timebuf, sizeof timebuf, "%b %e %T", &tm);
85
Rich Felker19c18302011-04-13 18:32:33 -040086 pid = (log_opt & LOG_PID) ? getpid() : 0;
87 l = snprintf(buf, sizeof buf, "<%d>%s %s%s%.0d%s: ",
88 priority, timebuf,
89 log_ident ? log_ident : "",
90 "["+!pid, pid, "]"+!pid);
91 l2 = vsnprintf(buf+l, sizeof buf - l, message, ap);
92 if (l2 >= 0) {
93 l += l2;
94 if (buf[l-1] != '\n') buf[l++] = '\n';
95 sendto(log_fd, buf, l, 0, (void *)&log_addr, 11);
96 }
Rich Felker0b44a032011-02-12 00:22:29 -050097
Rich Felker0b44a032011-02-12 00:22:29 -050098 UNLOCK(&lock);
99}
Rich Felker19c18302011-04-13 18:32:33 -0400100
101void syslog(int priority, const char *message, ...)
102{
103 va_list ap;
104 va_start(ap, message);
105 __vsyslog(priority, message, ap);
106 va_end(ap);
107}
108
109weak_alias(__vsyslog, vsyslog);