| /* |
| * syslog.c |
| * |
| * Issue syslog messages via the kernel printk queue. |
| */ |
| |
| #include <stdio.h> |
| #include <string.h> |
| #include <stdarg.h> |
| #include <syslog.h> |
| #include <unistd.h> |
| #include <fcntl.h> |
| |
| /* Maximum size for a kernel message */ |
| #define BUFLEN 1024 |
| |
| /* Logging node */ |
| #define LOGDEV "/dev/kmsg" |
| |
| /* Max length of ID string */ |
| #define MAXID 31 /* MAXID+5 must be < BUFLEN */ |
| |
| int __syslog_fd = -1; |
| static char id[MAXID + 1]; |
| static int syslog_flags = 0; |
| |
| void openlog(const char *ident, int option, int facility) |
| { |
| int fd; |
| |
| (void)option; |
| (void)facility; /* Unused */ |
| |
| if (__syslog_fd == -1) { |
| __syslog_fd = fd = open(LOGDEV, O_WRONLY); |
| if (fd == -1) |
| return; |
| fcntl(fd, F_SETFD, (long)FD_CLOEXEC); |
| } |
| |
| syslog_flags = option; |
| |
| strncpy(id, ident ? ident : "", MAXID); |
| } |
| |
| void vsyslog(int prio, const char *format, va_list ap) |
| { |
| char buf[BUFLEN]; |
| int len; |
| int fd; |
| |
| if (__syslog_fd == -1) |
| openlog(NULL, 0, 0); |
| |
| buf[0] = '<'; |
| buf[1] = LOG_PRI(prio) + '0'; |
| buf[2] = '>'; |
| len = 3; |
| |
| if (syslog_flags & LOG_PID) |
| len += sprintf(buf + 3, "%s[%u]: ", id, getpid()); |
| else if (*id) |
| len += sprintf(buf + 3, "%s: ", id); |
| |
| len += vsnprintf(buf + len, BUFLEN - len, format, ap); |
| |
| if (len > BUFLEN - 1) |
| len = BUFLEN - 1; |
| if (buf[len - 1] != '\n') |
| buf[len++] = '\n'; |
| |
| fd = __syslog_fd; |
| if (fd == -1) |
| fd = 2; /* Failed to open log, write to stderr */ |
| |
| write(fd, buf, len); |
| |
| if (syslog_flags & LOG_PERROR) |
| _fwrite(buf + 3, len - 3, stderr); |
| } |
| |
| void syslog(int prio, const char *format, ...) |
| { |
| va_list ap; |
| |
| va_start(ap, format); |
| vsyslog(prio, format, ap); |
| va_end(ap); |
| } |