logd: move stripping of newlines to log_add()
[project/ubox.git] / log / syslog.c
index ac4f1ae..af6530c 100644 (file)
@@ -25,6 +25,8 @@
 #include <string.h>
 #include <stdio.h>
 #include <syslog.h>
+#include <errno.h>
+#include <ctype.h>
 
 #include <libubox/uloop.h>
 #include <libubox/usock.h>
@@ -34,7 +36,6 @@
 
 #define LOG_DEFAULT_SIZE       (16 * 1024)
 #define LOG_DEFAULT_SOCKET     "/dev/log"
-#define LOG_LINE_LEN           256
 #define SYSLOG_PADDING         16
 
 #define KLOG_DEFAULT_PROC      "/proc/kmsg"
@@ -51,7 +52,7 @@ static regex_t pat_tstamp;
 static struct log_head*
 log_next(struct log_head *h, int size)
 {
-       struct log_head *n = (struct log_head *) &h->data[PAD(sizeof(struct log_head) + size)];
+       struct log_head *n = (struct log_head *) &h->data[PAD(size)];
 
        return (n >= log_end) ? (log) : (n);
 }
@@ -63,6 +64,7 @@ log_add(char *buf, int size, int source)
        struct log_head *next;
        int priority = 0;
        int ret;
+       char *c;
 
        /* bounce out if we don't have init'ed yet (regmatch etc will blow) */
        if (!log) {
@@ -70,12 +72,19 @@ log_add(char *buf, int size, int source)
                return;
        }
 
-       /* strip trailing newline */
-       if (buf[size - 2] == '\n') {
-               buf[size - 2] = '\0';
-               size -= 1;
+       for (c = buf; *c; c++) {
+               if (*c == '\n')
+               *c = ' ';
        }
 
+       c = buf + size - 2;
+       while (isspace(*c)) {
+               size--;
+               c--;
+       }
+
+       buf[size - 1] = 0;
+
        /* strip the priority */
        ret = regexec(&pat_prio, buf, 3, matches, 0);
        if (!ret) {
@@ -129,26 +138,26 @@ log_add(char *buf, int size, int source)
 }
 
 static void
-slog_cb(struct ustream *s, int bytes)
+syslog_handle_fd(struct uloop_fd *fd, unsigned int events)
 {
-       struct ustream_buf *buf = s->r.head;
-       char *str;
+       static char buf[LOG_LINE_SIZE];
        int len;
 
-       do {
-               str = ustream_get_read_buf(s, NULL);
-               if (!str)
+       while (1) {
+               len = recv(fd->fd, buf, LOG_LINE_SIZE - 1, 0);
+               if (len < 0) {
+                       if (errno == EINTR)
+                               continue;
+
                        break;
-               len = strlen(buf->data);
-               if (!len) {
-                       bytes -= 1;
-                       ustream_consume(s, 1);
-                       continue;
                }
-               log_add(buf->data, len + 1, SOURCE_SYSLOG);
-               ustream_consume(s, len);
-               bytes -= len;
-       } while (bytes > 0);
+               if (!len)
+                       break;
+
+               buf[len] = 0;
+
+               log_add(buf, strlen(buf) + 1, SOURCE_SYSLOG);
+       }
 }
 
 static void
@@ -172,12 +181,11 @@ klog_cb(struct ustream *s, int bytes)
        } while (1);
 }
 
-struct ustream_fd slog = {
-       .stream.string_data = true,
-       .stream.notify_read = slog_cb,
+static struct uloop_fd syslog_fd = {
+       .cb = syslog_handle_fd
 };
 
-struct ustream_fd klog = {
+static struct ustream_fd klog = {
        .stream.string_data = true,
        .stream.notify_read = klog_cb,
 };
@@ -200,16 +208,15 @@ klog_open(void)
 static int
 syslog_open(void)
 {
-       int fd;
-
        unlink(log_dev);
-       fd = usock(USOCK_UNIX | USOCK_UDP | USOCK_SERVER | USOCK_NONBLOCK, log_dev, NULL);
-       if (fd < 0) {
+       syslog_fd.fd = usock(USOCK_UNIX | USOCK_UDP | USOCK_SERVER | USOCK_NONBLOCK, log_dev, NULL);
+       if (syslog_fd.fd < 0) {
                fprintf(stderr,"Failed to open %s\n", log_dev);
                return -1;
        }
        chmod(log_dev, 0666);
-       ustream_fd_init(&slog, fd);
+       uloop_fd_add(&syslog_fd, ULOOP_READ | ULOOP_EDGE_TRIGGER);
+
        return 0;
 }
 
@@ -295,9 +302,12 @@ log_init(int _log_size)
 void
 log_shutdown(void)
 {
-       ustream_free(&slog.stream);
+       if (syslog_fd.registered) {
+               uloop_fd_delete(&syslog_fd);
+               close(syslog_fd.fd);
+       }
+
        ustream_free(&klog.stream);
-       close(slog.fd.fd);
        close(klog.fd.fd);
        free(log);
        regfree(&pat_prio);