docs: Added note to curvetun doc
[netsniff-ng.git] / src / tprintf.c
blob553438071b036e50f71fc68f7de730d078e83b77
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>
11 #include <pthread.h>
12 #include <assert.h>
14 #include "xsys.h"
15 #include "tprintf.h"
16 #include "die.h"
18 static char buffer[1024];
19 static size_t buffer_use = 0;
20 static pthread_spinlock_t buffer_lock;
22 static size_t lcount = 0;
24 size_t tprintf_get_free_count(void)
26 size_t ret;
27 pthread_spin_lock(&buffer_lock);
28 ret = get_tty_size() - 5 - lcount;
29 pthread_spin_unlock(&buffer_lock);
30 return ret;
34 * We want to print our stuff terminal aligned. Since we're printing packets
35 * we're in slowpath anyways. If stdin/stdout are connected to a terminal
36 * then default size = 1024; else size = 4096.
38 void tprintf_flush(void)
40 char *ptr = buffer;
41 size_t flush_len = get_tty_size() - 5;
43 while (buffer_use-- > 0) {
44 if (lcount == flush_len) {
45 fputs("\n ", stdout);
46 lcount = 3;
47 while (buffer_use > 0 && (*ptr == ' ' ||
48 *ptr == ',' || *ptr == '\n')) {
49 buffer_use--;
50 ptr++;
54 if (*ptr == '\n') {
55 flush_len = get_tty_size() - 5;
56 lcount = -1;
59 /* Collect in stream buffer. */
60 fputc(*ptr, stdout);
61 ptr++;
63 lcount++;
66 fflush(stdout);
67 buffer_use++;
68 assert(buffer_use == 0);
71 void tprintf_init(void)
73 pthread_spin_init(&buffer_lock, PTHREAD_PROCESS_SHARED);
74 memset(buffer, 0, sizeof(buffer));
77 void tprintf_cleanup(void)
79 pthread_spin_lock(&buffer_lock);
80 tprintf_flush();
81 pthread_spin_unlock(&buffer_lock);
82 pthread_spin_destroy(&buffer_lock);
85 void tprintf(char *msg, ...)
87 int ret;
88 va_list vl;
90 va_start(vl, msg);
91 pthread_spin_lock(&buffer_lock);
93 ret = vsnprintf(buffer + buffer_use,
94 sizeof(buffer) - buffer_use,
95 msg, vl);
96 if (ret < 0)
97 /* Something screwed up! Unexpected. */
98 goto out;
100 if (ret >= sizeof(buffer) - buffer_use) {
101 tprintf_flush();
103 /* Rewrite the buffer */
104 ret = vsnprintf(buffer + buffer_use,
105 sizeof(buffer) - buffer_use,
106 msg, vl);
107 /* Again, we've failed! This shouldn't happen! So
108 * switch to vfprintf temporarily :-( */
109 if (ret >= sizeof(buffer) - buffer_use) {
110 fprintf(stderr, "BUG (buffer too large) -->\n");
111 vfprintf(stdout, msg, vl);
112 fprintf(stderr, " <--\n");
113 goto out;
117 if (ret < sizeof(buffer) - buffer_use)
118 buffer_use += ret;
120 out:
121 pthread_spin_unlock(&buffer_lock);
122 va_end(vl);