1506c6deff726c8c052ff5abb0cef57e63707bd1cElliott Hughes/*	$OpenBSD: vasprintf.c,v 1.19 2015/12/28 22:08:18 mmcc Exp $	*/
21dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
51dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
61dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Permission to use, copy, modify, and distribute this software for any
71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * purpose with or without fee is hereby granted, provided that the above
81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * copyright notice and this permission notice appear in all copies.
91dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdio.h>
201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdlib.h>
211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <string.h>
221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <errno.h>
231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "local.h"
241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint
261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectvasprintf(char **str, const char *fmt, __va_list ap)
271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int ret;
291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	FILE f;
301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	struct __sfileext fext;
311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	unsigned char *_base;
321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	_FILEEXT_SETUP(&f, &fext);
341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	f._file = -1;
351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	f._flags = __SWR | __SSTR | __SALC;
36506c6deff726c8c052ff5abb0cef57e63707bd1cElliott Hughes	f._bf._base = f._p = malloc(128);
371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (f._bf._base == NULL)
381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		goto err;
391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	f._bf._size = f._w = 127;		/* Leave room for the NUL */
40f582340a6a48588aa50da17e1620e8f91b146941Kenny Root	ret = __vfprintf(&f, fmt, ap);
411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (ret == -1)
421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		goto err;
431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	*f._p = '\0';
441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	_base = realloc(f._bf._base, ret + 1);
451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (_base == NULL)
461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		goto err;
471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	*str = (char *)_base;
481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (ret);
491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projecterr:
51506c6deff726c8c052ff5abb0cef57e63707bd1cElliott Hughes	free(f._bf._base);
52506c6deff726c8c052ff5abb0cef57e63707bd1cElliott Hughes	f._bf._base = NULL;
531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	*str = NULL;
541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	errno = ENOMEM;
551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (-1);
561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
57506c6deff726c8c052ff5abb0cef57e63707bd1cElliott HughesDEF_WEAK(vasprintf);
58