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