Browse Source

syslog() is a blocking call on eglibc. as procd provides the actual syslog, weneed to make sure that we do not run into a deadlock.

Signed-off-by: John Crispin <blogic@openwrt.org>
Signed-off-by: Markus Stenberg <markus.stenberg@iki.fi>
John Crispin 10 years ago
parent
commit
b5e17105b1
4 changed files with 39 additions and 7 deletions
  1. 2 6
      procd.h
  2. 1 1
      rcS.c
  3. 34 0
      syslog.c
  4. 2 0
      syslog.h

+ 2 - 6
procd.h

@@ -31,17 +31,13 @@
 		fprintf(stderr, "procd: %s(%d): " fmt, __func__, __LINE__, ## __VA_ARGS__); \
 	} while (0)
 
-#define SYSLOG(p, fmt, ...) do { \
-	syslog(p, fmt, ## __VA_ARGS__); \
-	} while (0)
-
 #define LOG(fmt, ...) do { \
-	syslog(LOG_INFO, fmt, ## __VA_ARGS__); \
+	log_printf(fmt, ## __VA_ARGS__); \
 	fprintf(stderr, "procd: "fmt, ## __VA_ARGS__); \
 	} while (0)
 
 #define ERROR(fmt, ...) do { \
-	syslog(LOG_ERR, fmt, ## __VA_ARGS__); \
+	log_printf(fmt, ## __VA_ARGS__); \
 	fprintf(stderr, "procd: "fmt, ## __VA_ARGS__); \
 	} while (0)
 

+ 1 - 1
rcS.c

@@ -55,7 +55,7 @@ static void pipe_cb(struct ustream *s, int bytes)
 			break;
 		*newline = 0;
 		len = newline + 1 - str;
-		SYSLOG(6, buf->data);
+		log_printf(buf->data);
 		ustream_consume(s, len);
 	} while (1);
 }

+ 34 - 0
syslog.c

@@ -63,6 +63,12 @@ void log_add(char *buf, int size, int source)
 	int priority = 0;
 	int ret;
 
+	/* bounce out if we don't have init'ed yet (regmatch etc will blow) */
+	if (!log) {
+		fprintf(stderr, buf);
+		return;
+	}
+
 	/* strip trailing newline */
 	if (buf[size - 2] == '\n') {
 		buf[size - 2] = '\0';
@@ -121,6 +127,34 @@ void log_add(char *buf, int size, int source)
 	newest = next;
 }
 
+void log_printf(char *fmt, ...)
+{
+	static int buffer_len = 128;
+	static char *buffer;
+	va_list ap;
+	int n = 0;
+
+	do {
+		if (n)
+			buffer_len = n + 1;
+		if (!buffer)
+			buffer = malloc(buffer_len);
+		if (!buffer)
+			return;
+		va_start(ap, fmt);
+		n = vsnprintf(buffer, sizeof(buffer), fmt, ap);
+		va_end(ap);
+		if (n < 1)
+			return;
+		if (n >= buffer_len) {
+			free(buffer);
+			buffer = NULL;
+		}
+	} while (n >= buffer_len);
+
+	log_add(buffer, n, SOURCE_INTERNAL);
+}
+
 static void slog_cb(struct ustream *s, int bytes)
 {
 	struct ustream_buf *buf = s->r.head;

+ 2 - 0
syslog.h

@@ -18,6 +18,7 @@
 enum {
 	SOURCE_KLOG = 0,
 	SOURCE_SYSLOG = 1,
+	SOURCE_INTERNAL = 2,
 	SOURCE_ANY = 0xff,
 };
 
@@ -37,5 +38,6 @@ typedef void (*log_list_cb)(struct log_head *h);
 struct log_head* log_list(int count, struct log_head *h);
 int log_buffer_init(int size);
 void log_add(char *buf, int size, int source);
+void log_printf(char *fmt, ...);
 
 #endif