summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Crispin <blogic@openwrt.org>2013-09-28 21:01:20 +0200
committerJohn Crispin <blogic@openwrt.org>2013-09-28 21:47:43 +0200
commitb5e17105b163442a030559b7b2c2454b82b3fd4c (patch)
treecd7eb3d97307f17703a62360f65938172e360576
parentf51f9cc5738d340423e44e678829402b367cf866 (diff)
downloadunitd-b5e17105b163442a030559b7b2c2454b82b3fd4c.tar
unitd-b5e17105b163442a030559b7b2c2454b82b3fd4c.zip
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>
-rw-r--r--procd.h8
-rw-r--r--rcS.c2
-rw-r--r--syslog.c34
-rw-r--r--syslog.h2
4 files changed, 39 insertions, 7 deletions
diff --git a/procd.h b/procd.h
index f7a333e..34cc9a1 100644
--- a/procd.h
+++ b/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)
diff --git a/rcS.c b/rcS.c
index 774c77e..f041f09 100644
--- a/rcS.c
+++ b/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);
}
diff --git a/syslog.c b/syslog.c
index 01b6e7e..dbb7a5a 100644
--- a/syslog.c
+++ b/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;
diff --git a/syslog.h b/syslog.h
index b2471eb..fd78363 100644
--- a/syslog.h
+++ b/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