diff options
Diffstat (limited to 'usr/klibc/syslog.c')
-rw-r--r-- | usr/klibc/syslog.c | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/usr/klibc/syslog.c b/usr/klibc/syslog.c new file mode 100644 index 0000000..4052eaa --- /dev/null +++ b/usr/klibc/syslog.c @@ -0,0 +1,89 @@ +/* + * 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); +} |