[CRIU] [PATCH 2/4] pie: add printf-like functionality to simple_buf

Tycho Andersen tycho.andersen at canonical.com
Mon Jun 15 14:50:35 PDT 2015


We'll use this in the next patch for printing paths to LSM files in /proc.

Signed-off-by: Tycho Andersen <tycho.andersen at canonical.com>
---
 include/log.h    |  4 +++
 pie/log-simple.c | 76 +++++++++++++++++++++++++++++++++++++++-----------------
 2 files changed, 57 insertions(+), 23 deletions(-)

diff --git a/include/log.h b/include/log.h
index cc59870..fe53a7c 100644
--- a/include/log.h
+++ b/include/log.h
@@ -16,7 +16,11 @@ extern int log_get_fd(void);
 extern void log_set_loglevel(unsigned int loglevel);
 extern unsigned int log_get_loglevel(void);
 
+#define LOG_SIMPLE_CHUNK	72
+
 extern int vprint_num(char *buf, int blen, int num, char **ps);
+extern void simple_sprintf(char output[LOG_SIMPLE_CHUNK], const char *format, ...)
+	__attribute__ ((__format__ (__printf__, 2, 3)));
 
 extern int write_pidfile(int pid);
 
diff --git a/pie/log-simple.c b/pie/log-simple.c
index 6a9c6ae..a63e877 100644
--- a/pie/log-simple.c
+++ b/pie/log-simple.c
@@ -5,17 +5,18 @@
 #include "syscall.h"
 #include "log.h"
 
-#define LOG_SIMPLE_CHUNK	72
-
 struct simple_buf {
 	char buf[LOG_SIMPLE_CHUNK];
 	char *bp;
+	void (*flush)(struct simple_buf *b);
 };
 
 static int logfd = -1;
 static int cur_loglevel = DEFAULT_LOGLEVEL;
 
-static void sbuf_init(struct simple_buf *b)
+static void sbuf_log_flush(struct simple_buf *b);
+
+static void sbuf_log_init(struct simple_buf *b)
 {
 	b->buf[0] = 'p';
 	b->buf[1] = 'i';
@@ -23,26 +24,32 @@ static void sbuf_init(struct simple_buf *b)
 	b->buf[3] = ':';
 	b->buf[4] = ' ';
 	b->bp = b->buf + 5;
+	b->flush = sbuf_log_flush;
 }
 
-static void sbuf_flush(struct simple_buf *b)
+static void sbuf_log_flush(struct simple_buf *b)
 {
 	if (b->bp == b->buf + 5)
 		return;
 
 	sys_write(logfd, b->buf, b->bp - b->buf);
-	sbuf_init(b);
+	sbuf_log_init(b);
 }
 
 static void sbuf_putc(struct simple_buf *b, char c)
 {
+	/* TODO: maybe some warning or error here? */
+	if (b->bp - b->buf >= LOG_SIMPLE_CHUNK)
+		return;
+
 	*b->bp = c;
 	b->bp++;
 	if (b->bp - b->buf >= LOG_SIMPLE_CHUNK - 2) {
 		b->bp[0] = '>';
 		b->bp[1] = '\n';
 		b->bp += 2;
-		sbuf_flush(b);
+		if (b->flush)
+			b->flush(b);
 	}
 }
 
@@ -197,18 +204,9 @@ static void print_hex_l(unsigned long num, struct simple_buf *b)
 	print_string(z, b);
 }
 
-void print_on_level(unsigned int loglevel, const char *format, ...)
+void sbuf_printf(struct simple_buf *b, const char *format, va_list args)
 {
-	va_list args;
 	const char *s = format;
-	struct simple_buf b;
-
-	if (loglevel > cur_loglevel)
-		return;
-
-	sbuf_init(&b);
-
-	va_start(args, format);
 	while (1) {
 		int along = 0;
 
@@ -216,7 +214,7 @@ void print_on_level(unsigned int loglevel, const char *format, ...)
 			break;
 
 		if (*s != '%') {
-			sbuf_putc(&b, *s);
+			sbuf_putc(b, *s);
 			s++;
 			continue;
 		}
@@ -231,24 +229,56 @@ void print_on_level(unsigned int loglevel, const char *format, ...)
 
 		switch (*s) {
 		case 's':
-			print_string(va_arg(args, char *), &b);
+			print_string(va_arg(args, char *), b);
 			break;
 		case 'd':
 			if (along)
-				print_num_l(va_arg(args, long), &b);
+				print_num_l(va_arg(args, long), b);
 			else
-				print_num(va_arg(args, int), &b);
+				print_num(va_arg(args, int), b);
 			break;
 		case 'x':
 			if (along)
-				print_hex_l(va_arg(args, long), &b);
+				print_hex_l(va_arg(args, long), b);
 			else
-				print_hex(va_arg(args, unsigned int), &b);
+				print_hex(va_arg(args, unsigned int), b);
 			break;
 		}
 		s++;
 	}
+}
+
+void print_on_level(unsigned int loglevel, const char *format, ...)
+{
+	va_list args;
+	struct simple_buf b;
+
+	if (loglevel > cur_loglevel)
+		return;
+
+	sbuf_log_init(&b);
+
+	va_start(args, format);
+	sbuf_printf(&b, format, args);
+	va_end(args);
+
+	sbuf_log_flush(&b);
+}
+
+void simple_sprintf(char output[LOG_SIMPLE_CHUNK], const char *format, ...)
+{
+	va_list args;
+	struct simple_buf b;
+	char *p;
+
+	b.bp = b.buf;
+	b.flush = NULL;
+
+	va_start(args, format);
+	sbuf_printf(&b, format, args);
 	va_end(args);
+	*b.bp = 0;
 
-	sbuf_flush(&b);
+	for (p = b.buf; p <= b.bp; p++)
+		output[p - b.buf] = *p;
 }
-- 
2.1.4



More information about the CRIU mailing list