OLD | NEW |
1 #include <stdarg.h> | 1 #include <stdarg.h> |
2 #include <sys/socket.h> | 2 #include <sys/socket.h> |
3 #include <stdio.h> | 3 #include <stdio.h> |
4 #include <unistd.h> | 4 #include <unistd.h> |
5 #include <syslog.h> | 5 #include <syslog.h> |
6 #include <time.h> | 6 #include <time.h> |
7 #include <signal.h> | 7 #include <signal.h> |
8 #include <string.h> | 8 #include <string.h> |
9 #include <pthread.h> | 9 #include <pthread.h> |
10 #include <errno.h> | 10 #include <errno.h> |
11 #include <fcntl.h> | 11 #include <fcntl.h> |
12 #include "libc.h" | 12 #include "libc.h" |
13 | 13 |
14 static volatile int lock[2]; | 14 static volatile int lock[2]; |
15 static char log_ident[32]; | 15 static char log_ident[32]; |
16 static int log_opt; | 16 static int log_opt; |
17 static int log_facility = LOG_USER; | 17 static int log_facility = LOG_USER; |
18 static int log_mask = 0xff; | 18 static int log_mask = 0xff; |
19 static int log_fd = -1; | 19 static int log_fd = -1; |
20 | 20 |
21 int setlogmask(int maskpri) | 21 int setlogmask(int maskpri) { |
22 { | 22 LOCK(lock); |
23 » LOCK(lock); | 23 int ret = log_mask; |
24 » int ret = log_mask; | 24 if (maskpri) |
25 » if (maskpri) log_mask = maskpri; | 25 log_mask = maskpri; |
26 » UNLOCK(lock); | 26 UNLOCK(lock); |
27 » return ret; | 27 return ret; |
28 } | 28 } |
29 | 29 |
30 static const struct { | 30 static const struct { |
31 » short sun_family; | 31 short sun_family; |
32 » char sun_path[9]; | 32 char sun_path[9]; |
33 } log_addr = { | 33 } log_addr = {AF_UNIX, "/dev/log"}; |
34 » AF_UNIX, | |
35 » "/dev/log" | |
36 }; | |
37 | 34 |
38 void closelog(void) | 35 void closelog(void) { |
39 { | 36 int cs; |
40 » int cs; | 37 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); |
41 » pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); | 38 LOCK(lock); |
42 » LOCK(lock); | 39 close(log_fd); |
43 » close(log_fd); | 40 log_fd = -1; |
44 » log_fd = -1; | 41 UNLOCK(lock); |
45 » UNLOCK(lock); | 42 pthread_setcancelstate(cs, 0); |
46 » pthread_setcancelstate(cs, 0); | |
47 } | 43 } |
48 | 44 |
49 static void __openlog() | 45 static void __openlog() { |
50 { | 46 log_fd = socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0); |
51 » log_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0); | 47 if (log_fd >= 0) |
52 » if (log_fd >= 0) connect(log_fd, (void *)&log_addr, sizeof log_addr); | 48 connect(log_fd, (void*)&log_addr, sizeof log_addr); |
53 } | 49 } |
54 | 50 |
55 void openlog(const char *ident, int opt, int facility) | 51 void openlog(const char* ident, int opt, int facility) { |
56 { | 52 int cs; |
57 » int cs; | 53 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); |
58 » pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); | 54 LOCK(lock); |
59 » LOCK(lock); | |
60 | 55 |
61 » if (ident) { | 56 if (ident) { |
62 » » size_t n = strnlen(ident, sizeof log_ident - 1); | 57 size_t n = strnlen(ident, sizeof log_ident - 1); |
63 » » memcpy(log_ident, ident, n); | 58 memcpy(log_ident, ident, n); |
64 » » log_ident[n] = 0; | 59 log_ident[n] = 0; |
65 » } else { | 60 } else { |
66 » » log_ident[0] = 0; | 61 log_ident[0] = 0; |
67 » } | 62 } |
68 » log_opt = opt; | 63 log_opt = opt; |
69 » log_facility = facility; | 64 log_facility = facility; |
70 | 65 |
71 » if ((opt & LOG_NDELAY) && log_fd<0) __openlog(); | 66 if ((opt & LOG_NDELAY) && log_fd < 0) |
| 67 __openlog(); |
72 | 68 |
73 » UNLOCK(lock); | 69 UNLOCK(lock); |
74 » pthread_setcancelstate(cs, 0); | 70 pthread_setcancelstate(cs, 0); |
75 } | 71 } |
76 | 72 |
77 static int is_lost_conn(int e) | 73 static int is_lost_conn(int e) { |
78 { | 74 return e == ECONNREFUSED || e == ECONNRESET || e == ENOTCONN || e == EPIPE; |
79 » return e==ECONNREFUSED || e==ECONNRESET || e==ENOTCONN || e==EPIPE; | |
80 } | 75 } |
81 | 76 |
82 static void _vsyslog(int priority, const char *message, va_list ap) | 77 static void _vsyslog(int priority, const char* message, va_list ap) { |
83 { | 78 char timebuf[16]; |
84 » char timebuf[16]; | 79 time_t now; |
85 » time_t now; | 80 struct tm tm; |
86 » struct tm tm; | 81 char buf[1024]; |
87 » char buf[1024]; | 82 int errno_save = errno; |
88 » int errno_save = errno; | 83 int pid; |
89 » int pid; | 84 int l, l2; |
90 » int l, l2; | 85 int hlen; |
91 » int hlen; | 86 int fd; |
92 » int fd; | |
93 | 87 |
94 » if (log_fd < 0) __openlog(); | 88 if (log_fd < 0) |
| 89 __openlog(); |
95 | 90 |
96 » if (!(priority & LOG_FACMASK)) priority |= log_facility; | 91 if (!(priority & LOG_FACMASK)) |
| 92 priority |= log_facility; |
97 | 93 |
98 » now = time(NULL); | 94 now = time(NULL); |
99 » gmtime_r(&now, &tm); | 95 gmtime_r(&now, &tm); |
100 » strftime(timebuf, sizeof timebuf, "%b %e %T", &tm); | 96 strftime(timebuf, sizeof timebuf, "%b %e %T", &tm); |
101 | 97 |
102 » pid = (log_opt & LOG_PID) ? getpid() : 0; | 98 pid = (log_opt & LOG_PID) ? getpid() : 0; |
103 » l = snprintf(buf, sizeof buf, "<%d>%s %n%s%s%.0d%s: ", | 99 l = snprintf(buf, sizeof buf, "<%d>%s %n%s%s%.0d%s: ", priority, timebuf, |
104 » » priority, timebuf, &hlen, log_ident, | 100 &hlen, log_ident, pid ? "[" : "", pid, pid ? "]" : ""); |
105 » » pid ? "[" : "", pid, pid ? "]" : ""); | 101 errno = errno_save; |
106 » errno = errno_save; | 102 l2 = vsnprintf(buf + l, sizeof buf - l, message, ap); |
107 » l2 = vsnprintf(buf+l, sizeof buf - l, message, ap); | 103 if (l2 >= 0) { |
108 » if (l2 >= 0) { | 104 if (l2 >= sizeof buf - l) |
109 » » if (l2 >= sizeof buf - l) l = sizeof buf - 1; | 105 l = sizeof buf - 1; |
110 » » else l += l2; | 106 else |
111 » » if (buf[l-1] != '\n') buf[l++] = '\n'; | 107 l += l2; |
112 » » if (send(log_fd, buf, l, 0) < 0 && (!is_lost_conn(errno) | 108 if (buf[l - 1] != '\n') |
113 » » || connect(log_fd, (void *)&log_addr, sizeof log_addr) < 0 | 109 buf[l++] = '\n'; |
114 » » || send(log_fd, buf, l, 0) < 0) | 110 if (send(log_fd, buf, l, 0) < 0 && |
115 » » && (log_opt & LOG_CONS)) { | 111 (!is_lost_conn(errno) || |
116 » » » fd = open("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC); | 112 connect(log_fd, (void*)&log_addr, sizeof log_addr) < 0 || |
117 » » » if (fd >= 0) { | 113 send(log_fd, buf, l, 0) < 0) && |
118 » » » » dprintf(fd, "%.*s", l-hlen, buf+hlen); | 114 (log_opt & LOG_CONS)) { |
119 » » » » close(fd); | 115 fd = open("/dev/console", O_WRONLY | O_NOCTTY | O_CLOEXEC); |
120 » » » } | 116 if (fd >= 0) { |
121 » » } | 117 dprintf(fd, "%.*s", l - hlen, buf + hlen); |
122 » » if (log_opt & LOG_PERROR) dprintf(2, "%.*s", l-hlen, buf+hlen); | 118 close(fd); |
123 » } | 119 } |
| 120 } |
| 121 if (log_opt & LOG_PERROR) |
| 122 dprintf(2, "%.*s", l - hlen, buf + hlen); |
| 123 } |
124 } | 124 } |
125 | 125 |
126 void __vsyslog(int priority, const char *message, va_list ap) | 126 void __vsyslog(int priority, const char* message, va_list ap) { |
127 { | 127 int cs; |
128 » int cs; | 128 if (!(log_mask & LOG_MASK(priority & 7)) || (priority & ~0x3ff)) |
129 » if (!(log_mask & LOG_MASK(priority&7)) || (priority&~0x3ff)) return; | 129 return; |
130 » pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); | 130 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); |
131 » LOCK(lock); | 131 LOCK(lock); |
132 » _vsyslog(priority, message, ap); | 132 _vsyslog(priority, message, ap); |
133 » UNLOCK(lock); | 133 UNLOCK(lock); |
134 » pthread_setcancelstate(cs, 0); | 134 pthread_setcancelstate(cs, 0); |
135 } | 135 } |
136 | 136 |
137 void syslog(int priority, const char *message, ...) | 137 void syslog(int priority, const char* message, ...) { |
138 { | 138 va_list ap; |
139 » va_list ap; | 139 va_start(ap, message); |
140 » va_start(ap, message); | 140 __vsyslog(priority, message, ap); |
141 » __vsyslog(priority, message, ap); | 141 va_end(ap); |
142 » va_end(ap); | |
143 } | 142 } |
144 | 143 |
145 weak_alias(__vsyslog, vsyslog); | 144 weak_alias(__vsyslog, vsyslog); |
OLD | NEW |