tprint: use own locking.h instead of pthread directly
[netsniff-ng.git] / src / tprintf.c
blob2778c4412f7066a2024d0ebb08c3f330a6662488
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 <assert.h>
13 #include "xsys.h"
14 #include "tprintf.h"
15 #include "die.h"
16 #include "locking.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;
26 spinlock_lock(&buffer_lock);
27 ret = get_tty_size() - 5 - lcount;
28 spinlock_unlock(&buffer_lock);
29 return ret;
33 * We want to print our stuff terminal aligned. Since we're printing packets
34 * we're in slowpath anyways. If stdin/stdout are connected to a terminal
35 * then default size = 1024; else size = 4096.
37 void tprintf_flush(void)
39 char *ptr = buffer;
40 size_t flush_len = get_tty_size() - 5;
41 while (buffer_use-- > 0) {
42 if (lcount == flush_len) {
43 fputs("\n ", stdout);
44 lcount = 3;
45 while (buffer_use > 0 && (*ptr == ' ' ||
46 *ptr == ',' || *ptr == '\n')) {
47 buffer_use--;
48 ptr++;
51 if (*ptr == '\n') {
52 flush_len = get_tty_size() - 5;
53 lcount = -1;
55 /* Collect in stream buffer. */
56 fputc(*ptr, stdout);
57 ptr++;
58 lcount++;
60 fflush(stdout);
61 buffer_use++;
62 assert(buffer_use == 0);
65 void tprintf_init(void)
67 spinlock_init(&buffer_lock/*,PTHREAD_PROCESS_SHARED*/);
68 memset(buffer, 0, sizeof(buffer));
71 void tprintf_cleanup(void)
73 spinlock_lock(&buffer_lock);
74 tprintf_flush();
75 spinlock_unlock(&buffer_lock);
76 spinlock_destroy(&buffer_lock);
79 void tprintf(char *msg, ...)
81 int ret;
82 va_list vl;
84 va_start(vl, msg);
85 spinlock_lock(&buffer_lock);
86 ret = vsnprintf(buffer + buffer_use,
87 sizeof(buffer) - buffer_use,
88 msg, vl);
89 if (ret < 0)
90 /* Something screwed up! Unexpected. */
91 goto out;
92 if (ret >= sizeof(buffer) - buffer_use) {
93 tprintf_flush();
94 /* Rewrite the buffer */
95 ret = vsnprintf(buffer + buffer_use,
96 sizeof(buffer) - buffer_use,
97 msg, vl);
98 /* Again, we've failed! This shouldn't happen! So
99 * switch to vfprintf temporarily :-( */
100 if (ret >= sizeof(buffer) - buffer_use) {
101 fprintf(stderr, "BUG (buffer too large) -->\n");
102 vfprintf(stdout, msg, vl);
103 fprintf(stderr, " <--\n");
104 goto out;
107 if (ret < sizeof(buffer) - buffer_use)
108 buffer_use += ret;
109 out:
110 spinlock_unlock(&buffer_lock);
111 va_end(vl);