aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--coreutils/printf.c42
1 files changed, 23 insertions, 19 deletions
diff --git a/coreutils/printf.c b/coreutils/printf.c
index b5b1c6576..cc26ecd03 100644
--- a/coreutils/printf.c
+++ b/coreutils/printf.c
@@ -166,15 +166,29 @@ static void my_flush(void)
166 buflen = bufmax = 0; 166 buflen = bufmax = 0;
167} 167}
168 168
169static int my_putchar(int ch) 169static void copy_to_buffer(const char *str, int len)
170{ 170{
171 if (buflen + 1 >= bufmax) { 171 char *newbuf;
172 bufmax += 256; 172
173 buffer = xrealloc(buffer, bufmax); 173 if (buflen + len >= bufmax) {
174 bufmax += 256 + len;
175 if ((newbuf = realloc(buffer, bufmax)) == NULL) {
176 my_flush();
177 return;
178 }
179 buffer = newbuf;
174 } 180 }
175 buffer[buflen++] = ch; 181 memcpy(buffer + buflen, str, len);
176 if (buflen > 40 && ch == '\n') 182 buflen += len;
183
184 if (buflen > 40 && buffer[buflen-1] == '\n')
177 my_flush(); 185 my_flush();
186}
187
188static int my_putchar(int ch)
189{
190 char str[1] = { (char)ch };
191 copy_to_buffer(str, 1);
178 return ch; 192 return ch;
179} 193}
180 194
@@ -188,20 +202,10 @@ static int my_printf(const char *format, ...)
188 len = vasprintf(&str, format, list); 202 len = vasprintf(&str, format, list);
189 va_end(list); 203 va_end(list);
190 204
191 if (len < 0) 205 if (len >= 0) {
192 bb_die_memory_exhausted(); 206 copy_to_buffer(str, len);
193 207 free(str);
194 if (buflen + len >= bufmax) {
195 bufmax += 256 + len;
196 buffer = xrealloc(buffer, bufmax);
197 } 208 }
198 memcpy(buffer + buflen, str, len);
199 buflen += len;
200 free(str);
201
202 if (buflen > 40 && buffer[buflen-1] == '\n')
203 my_flush();
204
205 return len; 209 return len;
206} 210}
207 211