Browse Source

Reduce the initial buffer size for open_memstream

Reduce the initial buffer size for open_memstream (used by vasprintf),
as most strings are usually smaller than that.
Realloc the buffer after finishing the string to further reduce size.

Problem appears in case of UCLIBC_HAS_GLIBC_CUSTOM_STREAMS=y,
see http://dev.openwrt.org/ticket/13024

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: Leonid Lisovskiy <lly.dev@gmail.com>
Signed-off-by: Waldemar Brodkorb <wbx@uclibc-ng.org>
Waldemar Brodkorb 8 years ago
parent
commit
5a233790c3
3 changed files with 32 additions and 1 deletions
  1. 3 1
      libc/stdio/open_memstream.c
  2. 2 0
      libc/stdio/vasprintf.c
  3. 27 0
      test/malloc/tst-asprintf.c

+ 3 - 1
libc/stdio/open_memstream.c

@@ -17,6 +17,8 @@
 
 #define COOKIE ((__oms_cookie *) cookie)
 
+#define MEMSTREAM_BUFSIZ	256
+
 typedef struct {
 	char *buf;
 	size_t len;
@@ -134,7 +136,7 @@ FILE *open_memstream(char **bufloc, size_t *sizeloc)
 	register FILE *fp;
 
 	if ((cookie = malloc(sizeof(__oms_cookie))) != NULL) {
-		if ((cookie->buf = malloc(cookie->len = BUFSIZ)) == NULL) {
+		if ((cookie->buf = malloc(cookie->len = MEMSTREAM_BUFSIZ)) == NULL) {
 			goto EXIT_cookie;
 		}
 		*cookie->buf = 0;		/* Set nul terminator for buffer. */

+ 2 - 0
libc/stdio/vasprintf.c

@@ -39,6 +39,8 @@ int vasprintf(char **__restrict buf, const char * __restrict format,
 		if (rv < 0) {
 			free(*buf);
 			*buf = NULL;
+		} else {
+			*buf = realloc(*buf, rv + 1);
 		}
 	}
 

+ 27 - 0
test/malloc/tst-asprintf.c

@@ -0,0 +1,27 @@
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <malloc.h>
+
+static void my_stats(void)
+{
+	malloc_stats();
+	fprintf(stderr, "\n");
+}
+
+int main(int argc, char *argv[])
+{
+	char *a, *b;
+
+	my_stats();
+	asprintf(&b, "asdsadasd %ssdf\n", "AAAA");
+	my_stats();
+	asprintf(&a, "asdsadasd %ssdf\n", "AAAA");
+	my_stats();
+	free(a);
+	free(b);
+	my_stats();
+
+	return 0;
+}