From: Felix Fietkau <nbd@nbd.name>
Date: Mon, 6 Nov 2017 09:46:38 +0000 (+0100)
Subject: logd: use uloop instead of ustream_fd for syslog
X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=7a49632ec93647187d5f87d9fdb6b3e81341d505;p=oweals%2Fubox.git

logd: use uloop instead of ustream_fd for syslog

Using a stream buffer for a datagram socket makes no sense. This change
fixes dealing with line buffer truncation on large incoming messages

Signed-off-by: Felix Fietkau <nbd@nbd.name>
---

diff --git a/log/syslog.c b/log/syslog.c
index 754baa9..f1c7606 100644
--- a/log/syslog.c
+++ b/log/syslog.c
@@ -25,6 +25,7 @@
 #include <string.h>
 #include <stdio.h>
 #include <syslog.h>
+#include <errno.h>
 
 #include <libubox/uloop.h>
 #include <libubox/usock.h>
@@ -34,9 +35,10 @@
 
 #define LOG_DEFAULT_SIZE	(16 * 1024)
 #define LOG_DEFAULT_SOCKET	"/dev/log"
-#define LOG_LINE_LEN		256
 #define SYSLOG_PADDING		16
 
+#define MAXLINE			1024
+
 #define KLOG_DEFAULT_PROC	"/proc/kmsg"
 
 #define PAD(x) (x % 4) ? (((x) - (x % 4)) + 4) : (x)
@@ -129,26 +131,32 @@ 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[MAXLINE];
 	int len;
 
-	do {
-		str = ustream_get_read_buf(s, NULL);
-		if (!str)
+	while (1) {
+		char *c;
+
+		len = recv(fd->fd, buf, MAXLINE - 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;
+		for (c = buf; *c; c++) {
+		    if (*c == '\n')
+			*c = ' ';
+		}
+
+		log_add(buf, c - buf + 1, SOURCE_SYSLOG);
+	}
 }
 
 static void
@@ -172,9 +180,8 @@ klog_cb(struct ustream *s, int bytes)
 	} while (1);
 }
 
-static struct ustream_fd slog = {
-	.stream.string_data = true,
-	.stream.notify_read = slog_cb,
+static struct uloop_fd syslog_fd = {
+	.cb = syslog_handle_fd
 };
 
 static struct ustream_fd klog = {
@@ -200,16 +207,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 +301,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);