flowtop: make function nested
[netsniff-ng.git] / src / tprintf.c
blob0356ee1b5c42997eb58f090a99c54bb4933e3810
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
20 #define term_curr_size (get_tty_size() - term_trailing_size)
22 static char buffer[1024];
23 static volatile size_t buffer_use = 0;
24 static struct spinlock buffer_lock;
26 static inline void __tprintf_flush_newline(void)
28 int i;
29 fputc('\n', stdout);
30 for (i = 0; i < term_starting_size; ++i)
31 fputc(' ', stdout);
34 static inline int __tprintf_flush_skip(char *buffer, int i, size_t max)
36 int val = buffer[i];
37 if (val == ' ' || val == ',')
38 return 1;
39 return 0;
42 static void __tprintf_flush(void)
44 int i;
45 static ssize_t line_count = 0;
46 size_t term_len = term_curr_size;
48 for (i = 0; i < buffer_use; ++i) {
49 if (buffer[i] == '\n') {
50 term_len = term_curr_size;
51 line_count = -1;
53 if (line_count == term_len) {
54 __tprintf_flush_newline();
55 line_count = term_starting_size;
56 while (i < buffer_use &&
57 __tprintf_flush_skip(buffer, i, buffer_use))
58 i++;
61 fputc(buffer[i], stdout);
62 line_count++;
65 fflush(stdout);
66 access_once(buffer_use) = 0;
69 void tprintf_flush(void)
71 spinlock_lock(&buffer_lock);
72 __tprintf_flush();
73 spinlock_unlock(&buffer_lock);
76 void tprintf_init(void)
78 spinlock_init(&buffer_lock);
81 void tprintf_cleanup(void)
83 tprintf_flush();
84 spinlock_destroy(&buffer_lock);
87 void tprintf(char *msg, ...)
89 ssize_t ret;
90 ssize_t avail;
91 va_list vl;
93 spinlock_lock(&buffer_lock);
95 avail = sizeof(buffer) - buffer_use;
96 bug_on(avail < 0);
98 va_start(vl, msg);
99 ret = vsnprintf(buffer + buffer_use, avail, msg, vl);
100 va_end(vl);
102 if (ret < 0)
103 panic("vsnprintf screwed up in tprintf!\n");
104 if (ret > sizeof(buffer))
105 panic("No mem in tprintf left!\n");
106 if (ret >= avail) {
107 __tprintf_flush();
109 avail = sizeof(buffer) - buffer_use;
110 bug_on(avail < 0);
112 va_start(vl, msg);
113 ret = vsnprintf(buffer + buffer_use, avail, msg, vl);
114 va_end(vl);
116 if (ret < 0)
117 panic("vsnprintf screwed up in tprintf!\n");
120 buffer_use += ret;
122 spinlock_unlock(&buffer_lock);