vasprintf.c (6a18a77221ca134826742f1aa91fe4966f772b22) | vasprintf.c (15aa00d597010009c3fb718ded37438aa3f601ab) |
---|---|
1/* $OpenBSD: vasprintf.c,v 1.4 1998/06/21 22:13:47 millert Exp $ */ 2 3/* 4 * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com> 5 * All rights reserved. | 1/*- 2 * Copyright (c) 1996 Peter Wemm <peter@freebsd.org> |
6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. | 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. |
15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. | |
17 * | 12 * |
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 19 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 24 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 27 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. |
28 */ 29 | 24 */ 25 |
30#include <sys/cdefs.h> 31__FBSDID("$FreeBSD$"); | 26#if defined(LIBC_RCS) && !defined(lint) 27static char rcsid[] = "$Id$"; 28#endif /* LIBC_RCS and not lint */ |
32 33#include <stdio.h> 34#include <stdlib.h> | 29 30#include <stdio.h> 31#include <stdlib.h> |
35#include <errno.h> 36#include "local.h" | |
37 | 32 |
33#if __STDC__ 34#include <stdarg.h> 35#else 36#include <varargs.h> 37#endif 38 39#define CHUNK_SPARE 128 /* how much spare to allocate to avoid realloc calls */ 40 41struct bufcookie { 42 char *base; /* start of buffer */ 43 int size; 44 int left; 45}; 46 47static int 48writehook(cookie, buf, len) 49 void *cookie; 50 char *buf; 51 int len; 52{ 53 struct bufcookie *h = (struct bufcookie *)cookie; 54 55 if (len == 0) 56 return 0; 57 58 if (len > h->left) { 59 /* grow malloc region */ 60 h->left = h->left + len + CHUNK_SPARE; 61 h->size = h->size + len + CHUNK_SPARE; 62 h->base = realloc(h->base, h->size); 63 if (h->base == NULL) 64 return (-1); 65 } 66 /* "write" it */ 67 (void)memcpy(h->base + h->size - h->left, buf, len); 68 h->left -= len; 69 return (0); 70} 71 72 |
|
38int | 73int |
39vasprintf(char **str, const char *fmt, __va_list ap) | 74vasprintf(str, fmt, ap) 75 char **str; 76 const char *fmt; 77 va_list ap; |
40{ | 78{ |
41 FILE f = FAKE_FILE; | |
42 int ret; | 79 int ret; |
80 FILE *f; 81 struct bufcookie h; |
|
43 | 82 |
44 f._flags = __SWR | __SSTR | __SALC; 45 f._bf._base = f._p = malloc(128); 46 if (f._bf._base == NULL) { 47 *str = NULL; 48 errno = ENOMEM; | 83 h.base = malloc(CHUNK_SPARE); 84 if (h.base == NULL) |
49 return (-1); | 85 return (-1); |
86 h.size = CHUNK_SPARE; 87 h.left = CHUNK_SPARE; 88 89 f = funopen(&h, NULL, writehook, NULL, NULL); 90 if (f == NULL) { 91 free(h.base); 92 return (-1); |
|
50 } | 93 } |
51 f._bf._size = f._w = 127; /* Leave room for the NUL */ 52 ret = __vfprintf(&f, fmt, ap); | 94 ret = vfprintf(f, fmt, ap); 95 fclose(f); |
53 if (ret < 0) { | 96 if (ret < 0) { |
54 free(f._bf._base); 55 *str = NULL; 56 errno = ENOMEM; | 97 free(h.base); |
57 return (-1); 58 } | 98 return (-1); 99 } |
59 *f._p = '\0'; 60 *str = (char *)f._bf._base; | 100 if (h.base == NULL) /* failed to realloc in writehook */ 101 return (-1); 102 103 h.base[h.size - h.left] = '\0'; 104 *str = realloc(h.base, h.size - h.left + 1); 105 if (*str == NULL) /* failed to realloc it to actual size */ 106 return -1; |
61 return (ret); 62} | 107 return (ret); 108} |