diff options
| author | Peter Wemm <peter@FreeBSD.org> | 1998-07-08 00:44:56 +0000 | 
|---|---|---|
| committer | Peter Wemm <peter@FreeBSD.org> | 1998-07-08 00:44:56 +0000 | 
| commit | 64a965e7078acf9079cbe7f2c001852d4f6f2832 (patch) | |
| tree | d6005da7a2cb386634264fa94eb6f2e530f58edc | |
| parent | 0cc5719c0ab3056a57719c13edb1d65234911c64 (diff) | |
Notes
| -rw-r--r-- | lib/libc/stdio/asprintf.c | 58 | ||||
| -rw-r--r-- | lib/libc/stdio/fvwrite.c | 19 | ||||
| -rw-r--r-- | lib/libc/stdio/printf.3 | 16 | ||||
| -rw-r--r-- | lib/libc/stdio/vasprintf.c | 148 | 
4 files changed, 99 insertions, 142 deletions
| diff --git a/lib/libc/stdio/asprintf.c b/lib/libc/stdio/asprintf.c index 9b4d05b4397b..7a3e39aeace2 100644 --- a/lib/libc/stdio/asprintf.c +++ b/lib/libc/stdio/asprintf.c @@ -1,5 +1,8 @@ -/*- - * Copyright (c) 1996  Peter Wemm <peter@freebsd.org> +/*	$OpenBSD: asprintf.c,v 1.4 1998/06/21 22:13:46 millert Exp $	*/ + +/* + * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved.   *   * Redistribution and use in source and binary forms, with or without   * modification, are permitted provided that the following conditions @@ -9,51 +12,70 @@   * 2. Redistributions in binary form must reproduce the above copyright   *    notice, this list of conditions and the following disclaimer in the   *    documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + *    derived from this software without specific prior written permission.   * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.   */  #if defined(LIBC_RCS) && !defined(lint) -static char rcsid[] = "$Id$"; +static char rcsid[] = "$Id: asprintf.c,v 1.3 1997/02/22 15:01:45 peter Exp $";  #endif /* LIBC_RCS and not lint */  #include <stdio.h> +#include <stdlib.h> +#include <errno.h>  #if __STDC__  #include <stdarg.h>  #else  #include <varargs.h>  #endif -#if __STDC__  int +#if __STDC__  asprintf(char **str, char const *fmt, ...)  #else -int  asprintf(str, fmt, va_alist)  	char **str; -	char *fmt; +	const char *fmt;  	va_dcl  #endif  {  	int ret;  	va_list ap; +	FILE f;  #if __STDC__  	va_start(ap, fmt);  #else  	va_start(ap);  #endif -	ret = vasprintf(str, fmt, ap); +	f._file = -1; +	f._flags = __SWR | __SSTR | __SALC; +	f._bf._base = f._p = (unsigned char *)malloc(128); +	if (f._bf._base == NULL) { +		*str = NULL; +		errno = ENOMEM; +		return (-1); +	} +	f._bf._size = f._w = 127;		/* Leave room for the NULL */ +	ret = vfprintf(&f, fmt, ap); +	*f._p = '\0';  	va_end(ap); +	f._bf._base = realloc(f._bf._base, f._bf._size + 1); +	if (f._bf._base == NULL) { +		errno = ENOMEM; +		ret = -1; +	} +	*str = (char *)f._bf._base;  	return (ret);  } diff --git a/lib/libc/stdio/fvwrite.c b/lib/libc/stdio/fvwrite.c index 5061773fe851..75dfca92430f 100644 --- a/lib/libc/stdio/fvwrite.c +++ b/lib/libc/stdio/fvwrite.c @@ -39,10 +39,11 @@  static char sccsid[] = "@(#)fvwrite.c	8.1 (Berkeley) 6/4/93";  #endif  static const char rcsid[] = -		"$Id: fvwrite.c,v 1.6 1997/12/24 13:17:13 ache Exp $"; +		"$Id: fvwrite.c,v 1.7 1997/12/24 23:23:18 ache Exp $";  #endif /* LIBC_SCCS and not lint */  #include <stdio.h> +#include <stdlib.h>  #include <string.h>  #include "local.h"  #include "fvwrite.h" @@ -111,6 +112,22 @@ __sfvwrite(fp, uio)  		 */  		do {  			GETIOV(;); +			if ((fp->_flags & (__SALC | __SSTR)) == +			    (__SALC | __SSTR) && fp->_w < len) { +				size_t blen = fp->_p - fp->_bf._base; + +				/* +				 * Alloc an extra 128 bytes (+ 1 for NULL) +				 * so we don't call realloc(3) so often. +				 */ +				fp->_w = len + 128; +				fp->_bf._size = blen + len + 128; +				fp->_bf._base = +				    realloc(fp->_bf._base, fp->_bf._size + 1); +				if (fp->_bf._base == NULL) +					goto err; +				fp->_p = fp->_bf._base + blen; +			}  			w = fp->_w;  			if (fp->_flags & __SSTR) {  				if (len < w) diff --git a/lib/libc/stdio/printf.3 b/lib/libc/stdio/printf.3 index 6d2affb25025..082be148639f 100644 --- a/lib/libc/stdio/printf.3 +++ b/lib/libc/stdio/printf.3 @@ -615,19 +615,15 @@ conform to  .St -ansiC .  .Sh HISTORY  The functions -.Fn snprintf -and -.Fn vsnprintf -are new to this release. -.Pp -The functions  .Fn asprintf  and  .Fn vasprintf -first appeared in the GNU C library.  This implementation is thought -to be compatible but is not derived from the GNU code.  This implementation -was written by Peter Wemm <peter@FreeBSD.org> and first appeared in -.Fx 2.2 . +first appeared in the GNU C library. +These were implemented by Peter Wemm <peter@FreeBSD.org> in +.Fx 2.2 , +but were later replaced with a different implementation +from Todd C. Miller <Todd.Miller@courtesan.com> for +.Ox 2.3 .  .Sh BUGS  The conversion formats  .Cm \&%D , diff --git a/lib/libc/stdio/vasprintf.c b/lib/libc/stdio/vasprintf.c index a8403d7764d6..87db4cd5dbcd 100644 --- a/lib/libc/stdio/vasprintf.c +++ b/lib/libc/stdio/vasprintf.c @@ -1,5 +1,8 @@ -/*- - * Copyright (c) 1996  Peter Wemm <peter@freebsd.org> +/*	$OpenBSD: vasprintf.c,v 1.4 1998/06/21 22:13:47 millert Exp $	*/ + +/* + * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved.   *   * Redistribution and use in source and binary forms, with or without   * modification, are permitted provided that the following conditions @@ -9,135 +12,54 @@   * 2. Redistributions in binary form must reproduce the above copyright   *    notice, this list of conditions and the following disclaimer in the   *    documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + *    derived from this software without specific prior written permission.   * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.   */  #if defined(LIBC_RCS) && !defined(lint) -static char rcsid[] = "$Id: vasprintf.c,v 1.7 1997/07/06 08:42:37 peter Exp $"; +static char rcsid[] = "$Id: vasprintf.c,v 1.8 1998/03/09 06:51:23 jb Exp $";  #endif /* LIBC_RCS and not lint */  #include <stdio.h>  #include <stdlib.h> -#include <string.h> - -#if __STDC__ -#include <stdarg.h> -#else -#include <varargs.h> -#endif - -#define CHUNK_SPARE 128 /* how much spare to allocate to avoid realloc calls */ - -struct bufcookie { -	char	*base;	/* start of buffer */ -	size_t	size; -	size_t	left; -}; - -static int 	writehook __P((void *cookie, const char *, int)); - -static int -writehook(cookie, buf, len) -	void *cookie; -	const char *buf; -	int   len; -{ -	struct bufcookie *h = (struct bufcookie *)cookie; -	char *newbuf; - -	if (len == 0) -		return 0; - -	if (len > h->left) { -		/* grow malloc region */ - 		/* -		 * XXX this is linearly expanded, which is slow for obscenely -		 * large strings. -		 */ -		h->left = h->left + len + CHUNK_SPARE; -		h->size = h->size + len + CHUNK_SPARE; -		newbuf = realloc(h->base, h->size); -		if (newbuf == NULL) { -			free(h->base); -			h->base = NULL; -			return (-1); -		} else -			h->base = newbuf; -	} -	/* "write" it */ -	(void)memcpy(h->base + h->size - h->left, buf, (size_t)len); -	h->left -= len; -	return (len); -} - +#include <errno.h>  int  vasprintf(str, fmt, ap)  	char **str;  	const char *fmt; -	va_list ap; +	_BSD_VA_LIST_ ap;  {  	int ret; -	FILE *f; -	struct bufcookie h; +	FILE f; -	h.base = malloc(CHUNK_SPARE); -	if (h.base == NULL) -		return (-1); -	h.size = CHUNK_SPARE; -	h.left = CHUNK_SPARE; - -	f = funopen(&h, NULL, writehook, NULL, NULL); -	if (f == NULL) { -		free(h.base); +	f._file = -1; +	f._flags = __SWR | __SSTR | __SALC; +	f._bf._base = f._p = (unsigned char *)malloc(128); +	if (f._bf._base == NULL) { +		*str = NULL; +		errno = ENOMEM;  		return (-1);  	} -	ret = vfprintf(f, fmt, ap); -	fclose(f); - -	/* -	 * clean up the wreckage. Did writehook fail or did something else -	 * in stdio explode perhaps? -	 */ -	if (h.base == NULL)	/* realloc failed in writehook */ -		return (-1); -	if (ret < 0) {		/* something else? */ -		free(h.base); -		return (-1); -	} - -	/* -	 * At this point, we have a non-null terminated string in a -	 * buffer.  There may not be enough room to null-terminate it -	 * (h.left == 0) - if realloc failes to expand it, it's fatal. -	 * If we were merely trying to shrink the buffer, a realloc failure -	 * is not [yet] fatal. Note that when realloc returns NULL, -	 * the original buffer is left allocated and valid. -	 */ -	if (h.left == 1)	/* exact fit, do not realloc */ -		*str = h.base; -	else { -		*str = realloc(h.base, (size_t)(h.size - h.left + 1)); -		if (*str == NULL) { -			/* failed to expand? - fatal */ -			if (h.left == 0) { -				free(h.base); -				return (-1); -			} -			*str = h.base;	/* use oversize original buffer */ -		} +	f._bf._size = f._w = 127;		/* Leave room for the NULL */ +	ret = vfprintf(&f, fmt, ap); +	*f._p = '\0'; +	f._bf._base = realloc(f._bf._base, f._bf._size + 1); +	if (f._bf._base == NULL) { +		errno = ENOMEM; +		ret = -1;  	} -	(*str)[h.size - h.left] = '\0'; +	*str = (char *)f._bf._base;  	return (ret);  } | 
