diff options
author | tjr <tjr@FreeBSD.org> | 2002-09-26 13:09:48 +0000 |
---|---|---|
committer | tjr <tjr@FreeBSD.org> | 2002-09-26 13:09:48 +0000 |
commit | 7733fef36f707ac0914a4c0b1cc2958accbeffb0 (patch) | |
tree | f105794d54fb6abf4d402d0071c4f01747390c74 /lib/libc/stdio/asprintf.c | |
parent | 9228738b8cc92ba9e9572b51f53ab8918f723077 (diff) | |
download | FreeBSD-src-7733fef36f707ac0914a4c0b1cc2958accbeffb0.zip FreeBSD-src-7733fef36f707ac0914a4c0b1cc2958accbeffb0.tar.gz |
Back out previous and solve the problems a different way: move va_start/
va_end closer to the __vfprintf() call, free the buffer when __vfprintf()
fails and don't bother trying to shrink the buffer with realloc() before
returning it.
Submitted by: bde
Diffstat (limited to 'lib/libc/stdio/asprintf.c')
-rw-r--r-- | lib/libc/stdio/asprintf.c | 33 |
1 files changed, 13 insertions, 20 deletions
diff --git a/lib/libc/stdio/asprintf.c b/lib/libc/stdio/asprintf.c index 214405e..f142651 100644 --- a/lib/libc/stdio/asprintf.c +++ b/lib/libc/stdio/asprintf.c @@ -44,35 +44,28 @@ asprintf(char **str, char const *fmt, ...) va_list ap; FILE f; struct __sFILEX ext; - unsigned char *_base; - va_start(ap, fmt); f._file = -1; f._flags = __SWR | __SSTR | __SALC; f._bf._base = f._p = (unsigned char *)malloc(128); - if (f._bf._base == NULL) - goto err; + if (f._bf._base == NULL) { + *str = NULL; + errno = ENOMEM; + return (-1); + } f._bf._size = f._w = 127; /* Leave room for the NUL */ f._extra = &ext; INITEXTRA(&f); + va_start(ap, fmt); ret = __vfprintf(&f, fmt, ap); /* Use unlocked __vfprintf */ - if (ret == -1) - goto err; - *f._p = '\0'; - _base = realloc(f._bf._base, ret + 1); - if (_base == NULL) - goto err; - *str = (char *)_base; va_end(ap); - return (ret); - -err: - va_end(ap); - if (f._bf._base != NULL) { + if (ret < 0) { free(f._bf._base); - f._bf._base = NULL; + *str = NULL; + errno = ENOMEM; + return (-1); } - *str = NULL; - errno = ENOMEM; - return (-1); + *f._p = '\0'; + *str = (char *)f._bf._base; + return (ret); } |