xmalloc: put __hidden behind signature
[netsniff-ng.git] / tprintf.c
blobbbdfb552a1f72d125af84c5f9d54a702f18042ad
1 /*
2 * netsniff-ng - the packet sniffing beast
3 * By Daniel Borkmann <daniel@netsniff-ng.org>
4 * Copyright 2009, 2010 Daniel Borkmann.
5 * Subject to the GPL, version 2.
6 */
8 #define _BSD_SOURCE
9 #include <stdio.h>
10 #include <stdarg.h>
12 #include "xutils.h"
13 #include "tprintf.h"
14 #include "die.h"
15 #include "locking.h"
16 #include "built_in.h"
18 #define term_trailing_size 5
19 #define term_starting_size 3
21 #define term_curr_size (get_tty_size() - term_trailing_size)
23 static char buffer[1024];
25 static volatile size_t buffer_use = 0;
27 static struct spinlock buffer_lock;
29 static inline void __tprintf_flush_newline(void)
31 int i;
33 fputc('\n', stdout);
34 for (i = 0; i < term_starting_size; ++i)
35 fputc(' ', stdout);
38 static inline int __tprintf_flush_skip(char *buffer, int i, size_t max)
40 int val = buffer[i];
42 if (val == ' ' || val == ',')
43 return 1;
45 return 0;
48 static void __tprintf_flush(void)
50 int i;
51 static ssize_t line_count = 0;
52 size_t term_len = term_curr_size;
54 for (i = 0; i < buffer_use; ++i) {
55 if (buffer[i] == '\n') {
56 term_len = term_curr_size;
57 line_count = -1;
60 if (line_count == term_len) {
61 __tprintf_flush_newline();
62 line_count = term_starting_size;
64 while (i < buffer_use &&
65 __tprintf_flush_skip(buffer, i, buffer_use))
66 i++;
69 fputc(buffer[i], stdout);
70 line_count++;
73 fflush(stdout);
74 buffer_use = 0;
77 void tprintf_flush(void)
79 spinlock_lock(&buffer_lock);
80 __tprintf_flush();
81 spinlock_unlock(&buffer_lock);
84 void tprintf_init(void)
86 spinlock_init(&buffer_lock);
88 setvbuf(stdout, NULL, _IONBF, 0);
89 setvbuf(stderr, NULL, _IONBF, 0);
92 void tprintf_cleanup(void)
94 tprintf_flush();
95 spinlock_destroy(&buffer_lock);
98 void tprintf(char *msg, ...)
100 ssize_t ret;
101 ssize_t avail;
102 va_list vl;
104 spinlock_lock(&buffer_lock);
106 avail = sizeof(buffer) - buffer_use;
107 bug_on(avail < 0);
109 va_start(vl, msg);
110 ret = vsnprintf(buffer + buffer_use, avail, msg, vl);
111 va_end(vl);
113 if (ret < 0)
114 panic("vsnprintf screwed up in tprintf!\n");
115 if (ret > sizeof(buffer))
116 panic("No mem in tprintf left!\n");
117 if (ret >= avail) {
118 __tprintf_flush();
120 avail = sizeof(buffer) - buffer_use;
121 bug_on(avail < 0);
123 va_start(vl, msg);
124 ret = vsnprintf(buffer + buffer_use, avail, msg, vl);
125 va_end(vl);
127 if (ret < 0)
128 panic("vsnprintf screwed up in tprintf!\n");
131 buffer_use += ret;
133 spinlock_unlock(&buffer_lock);