Commit ea5f35e2 authored by Tycho Andersen's avatar Tycho Andersen Committed by Pavel Emelyanov

pie: add printf-like functionality to simple_buf

We'll use this in the next patch for printing paths to LSM files in /proc.
Signed-off-by: 's avatarTycho Andersen <tycho.andersen@canonical.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent a5019ff3
...@@ -16,7 +16,11 @@ extern int log_get_fd(void); ...@@ -16,7 +16,11 @@ extern int log_get_fd(void);
extern void log_set_loglevel(unsigned int loglevel); extern void log_set_loglevel(unsigned int loglevel);
extern unsigned int log_get_loglevel(void); 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 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); extern int write_pidfile(int pid);
......
...@@ -5,17 +5,18 @@ ...@@ -5,17 +5,18 @@
#include "syscall.h" #include "syscall.h"
#include "log.h" #include "log.h"
#define LOG_SIMPLE_CHUNK 72
struct simple_buf { struct simple_buf {
char buf[LOG_SIMPLE_CHUNK]; char buf[LOG_SIMPLE_CHUNK];
char *bp; char *bp;
void (*flush)(struct simple_buf *b);
}; };
static int logfd = -1; static int logfd = -1;
static int cur_loglevel = DEFAULT_LOGLEVEL; 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[0] = 'p';
b->buf[1] = 'i'; b->buf[1] = 'i';
...@@ -23,26 +24,32 @@ static void sbuf_init(struct simple_buf *b) ...@@ -23,26 +24,32 @@ static void sbuf_init(struct simple_buf *b)
b->buf[3] = ':'; b->buf[3] = ':';
b->buf[4] = ' '; b->buf[4] = ' ';
b->bp = b->buf + 5; 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) if (b->bp == b->buf + 5)
return; return;
sys_write(logfd, b->buf, b->bp - b->buf); 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) 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 = c;
b->bp++; b->bp++;
if (b->bp - b->buf >= LOG_SIMPLE_CHUNK - 2) { if (b->bp - b->buf >= LOG_SIMPLE_CHUNK - 2) {
b->bp[0] = '>'; b->bp[0] = '>';
b->bp[1] = '\n'; b->bp[1] = '\n';
b->bp += 2; 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) ...@@ -197,18 +204,9 @@ static void print_hex_l(unsigned long num, struct simple_buf *b)
print_string(z, 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; const char *s = format;
struct simple_buf b;
if (loglevel > cur_loglevel)
return;
sbuf_init(&b);
va_start(args, format);
while (1) { while (1) {
int along = 0; int along = 0;
...@@ -216,7 +214,7 @@ void print_on_level(unsigned int loglevel, const char *format, ...) ...@@ -216,7 +214,7 @@ void print_on_level(unsigned int loglevel, const char *format, ...)
break; break;
if (*s != '%') { if (*s != '%') {
sbuf_putc(&b, *s); sbuf_putc(b, *s);
s++; s++;
continue; continue;
} }
...@@ -231,24 +229,56 @@ void print_on_level(unsigned int loglevel, const char *format, ...) ...@@ -231,24 +229,56 @@ void print_on_level(unsigned int loglevel, const char *format, ...)
switch (*s) { switch (*s) {
case 's': case 's':
print_string(va_arg(args, char *), &b); print_string(va_arg(args, char *), b);
break; break;
case 'd': case 'd':
if (along) if (along)
print_num_l(va_arg(args, long), &b); print_num_l(va_arg(args, long), b);
else else
print_num(va_arg(args, int), &b); print_num(va_arg(args, int), b);
break; break;
case 'x': case 'x':
if (along) if (along)
print_hex_l(va_arg(args, long), &b); print_hex_l(va_arg(args, long), b);
else else
print_hex(va_arg(args, unsigned int), &b); print_hex(va_arg(args, unsigned int), b);
break; break;
} }
s++; 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); va_end(args);
*b.bp = 0;
sbuf_flush(&b); for (p = b.buf; p <= b.bp; p++)
output[p - b.buf] = *p;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment