proto_ipv6_mobility_hdr.h: Headerfixing
[netsniff-ng.git] / src / tprintf.c
blob093165538076cd517678cba139659e2badb28899
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 "xsys.h"
13 #include "tprintf.h"
14 #include "die.h"
15 #include "locking.h"
16 #include "built_in.h"
18 static char buffer[1024];
19 static size_t buffer_use = 0;
20 static struct spinlock buffer_lock;
21 static size_t lcount = 0;
23 size_t tprintf_get_free_count(void)
25 size_t ret;
27 spinlock_lock(&buffer_lock);
28 ret = get_tty_size() - 5 - lcount;
29 spinlock_unlock(&buffer_lock);
31 return ret;
35 * We want to print our stuff terminal aligned. Since we're printing packets
36 * we're in slowpath anyways. If stdin/stdout are connected to a terminal
37 * then default size = 1024; else size = 4096.
39 void tprintf_flush(void)
41 char *ptr = buffer;
42 size_t flush_len = get_tty_size() - 5;
44 while (buffer_use-- > 0) {
45 if (lcount == flush_len) {
46 fputs("\n ", stdout);
47 lcount = 3;
48 while (buffer_use > 0 && (*ptr == ' ' ||
49 *ptr == ',' || *ptr == '\n')) {
50 buffer_use--;
51 ptr++;
55 if (*ptr == '\n') {
56 flush_len = get_tty_size() - 5;
57 lcount = -1;
60 /* Collect in stream buffer. */
61 fputc(*ptr, stdout);
62 ptr++;
63 lcount++;
66 fflush(stdout);
67 buffer_use++;
69 bug_on(buffer_use > 0);
72 void tprintf_init(void)
74 spinlock_init(&buffer_lock);
75 memset(buffer, 0, sizeof(buffer));
78 void tprintf_cleanup(void)
80 spinlock_lock(&buffer_lock);
81 tprintf_flush();
82 spinlock_unlock(&buffer_lock);
84 spinlock_destroy(&buffer_lock);
87 void tprintf(char *msg, ...)
89 int ret;
90 va_list vl;
92 va_start(vl, msg);
94 spinlock_lock(&buffer_lock);
95 ret = vsnprintf(buffer + buffer_use,
96 sizeof(buffer) - buffer_use,
97 msg, vl);
98 if (ret < 0)
99 /* Something screwed up! Unexpected. */
100 goto out;
101 if (ret >= sizeof(buffer) - buffer_use) {
102 tprintf_flush();
103 /* Rewrite the buffer */
104 ret = vsnprintf(buffer + buffer_use,
105 sizeof(buffer) - buffer_use,
106 msg, vl);
108 /* Again, we've failed! This shouldn't happen! So
109 * switch to vfprintf temporarily :-( */
110 if (ret >= sizeof(buffer) - buffer_use) {
111 fprintf(stderr, "BUG (buffer too large) -->\n");
112 vfprintf(stdout, msg, vl);
113 fprintf(stderr, " <--\n");
114 goto out;
118 if (ret < sizeof(buffer) - buffer_use)
119 buffer_use += ret;
120 out:
121 spinlock_unlock(&buffer_lock);
123 va_end(vl);