aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-11-25 10:10:14 -0500
committerJohannes Berg <johannes@sipsolutions.net>2009-11-25 10:10:14 -0500
commit93341c3407d8098efb955494ac6723d61ec2294e (patch)
treee6dee582dc9abdd01ada4a0e799009b01007b1cc
parentcaaf5c925977c2c29df8e624a46771bf715c2d7c (diff)
keep track of buffer full
The trace_seq buffer might fill up, and right now one needs to check the return value of each printf into the buffer to check for that. Instead, have the buffer keep track of whether it is full or not, and reject more input if it is full or would have overflowed with an input that wasn't added. Also simplify the buffer output function and have it print [truncated] when that is the case. Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
-rw-r--r--parse-events.h2
-rw-r--r--trace-seq.c46
2 files changed, 24 insertions, 24 deletions
diff --git a/parse-events.h b/parse-events.h
index c0dbc60..9c6d89f 100644
--- a/parse-events.h
+++ b/parse-events.h
@@ -23,6 +23,7 @@ struct trace_seq {
23 char buffer[TRACE_SEQ_SIZE]; 23 char buffer[TRACE_SEQ_SIZE];
24 unsigned int len; 24 unsigned int len;
25 unsigned int readpos; 25 unsigned int readpos;
26 int full;
26}; 27};
27 28
28static inline void 29static inline void
@@ -30,6 +31,7 @@ trace_seq_init(struct trace_seq *s)
30{ 31{
31 s->len = 0; 32 s->len = 0;
32 s->readpos = 0; 33 s->readpos = 0;
34 s->full = 0;
33} 35}
34 36
35extern int trace_seq_printf(struct trace_seq *s, const char *fmt, ...) 37extern int trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
diff --git a/trace-seq.c b/trace-seq.c
index 3e3e059..3143bbb 100644
--- a/trace-seq.c
+++ b/trace-seq.c
@@ -32,7 +32,7 @@ trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
32 va_list ap; 32 va_list ap;
33 int ret; 33 int ret;
34 34
35 if (!len) 35 if (s->full || !len)
36 return 0; 36 return 0;
37 37
38 va_start(ap, fmt); 38 va_start(ap, fmt);
@@ -40,8 +40,10 @@ trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
40 va_end(ap); 40 va_end(ap);
41 41
42 /* If we can't write it all, don't bother writing anything */ 42 /* If we can't write it all, don't bother writing anything */
43 if (ret >= len) 43 if (ret >= len) {
44 s->full = 1;
44 return 0; 45 return 0;
46 }
45 47
46 s->len += ret; 48 s->len += ret;
47 49
@@ -65,14 +67,16 @@ trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args)
65 int len = (TRACE_SEQ_SIZE - 1) - s->len; 67 int len = (TRACE_SEQ_SIZE - 1) - s->len;
66 int ret; 68 int ret;
67 69
68 if (!len) 70 if (s->full || !len)
69 return 0; 71 return 0;
70 72
71 ret = vsnprintf(s->buffer + s->len, len, fmt, args); 73 ret = vsnprintf(s->buffer + s->len, len, fmt, args);
72 74
73 /* If we can't write it all, don't bother writing anything */ 75 /* If we can't write it all, don't bother writing anything */
74 if (ret >= len) 76 if (ret >= len) {
77 s->full = 1;
75 return 0; 78 return 0;
79 }
76 80
77 s->len += ret; 81 s->len += ret;
78 82
@@ -93,8 +97,13 @@ int trace_seq_puts(struct trace_seq *s, const char *str)
93{ 97{
94 int len = strlen(str); 98 int len = strlen(str);
95 99
96 if (len > ((TRACE_SEQ_SIZE - 1) - s->len)) 100 if (s->full)
101 return 0;
102
103 if (len > ((TRACE_SEQ_SIZE - 1) - s->len)) {
104 s->full = 1;
97 return 0; 105 return 0;
106 }
98 107
99 memcpy(s->buffer + s->len, str, len); 108 memcpy(s->buffer + s->len, str, len);
100 s->len += len; 109 s->len += len;
@@ -104,8 +113,13 @@ int trace_seq_puts(struct trace_seq *s, const char *str)
104 113
105int trace_seq_putc(struct trace_seq *s, unsigned char c) 114int trace_seq_putc(struct trace_seq *s, unsigned char c)
106{ 115{
107 if (s->len >= (TRACE_SEQ_SIZE - 1)) 116 if (s->full)
117 return 0;
118
119 if (s->len >= (TRACE_SEQ_SIZE - 1)) {
120 s->full = 1;
108 return 0; 121 return 0;
122 }
109 123
110 s->buffer[s->len++] = c; 124 s->buffer[s->len++] = c;
111 125
@@ -114,22 +128,6 @@ int trace_seq_putc(struct trace_seq *s, unsigned char c)
114 128
115int trace_seq_do_printf(struct trace_seq *s) 129int trace_seq_do_printf(struct trace_seq *s)
116{ 130{
117 char *buf; 131 return printf("%.*s%s", s->len, s->buffer,
118 int ret; 132 s->full ? "[truncated]" : "");
119
120 if (!s->len)
121 return 0;
122
123 if (s->len < TRACE_SEQ_SIZE) {
124 s->buffer[s->len] = 0;
125 return printf("%s", s->buffer);
126 }
127
128 buf = malloc_or_die(s->len + 1);
129 memcpy(buf, s->buffer, s->len);
130 buf[s->len] = 0;
131 ret = printf("%s", buf);
132 free(buf);
133
134 return ret;
135} 133}