1#include "config.h" 2 3#if HAVE_VASPRINTF 4 5int dummy; 6 7#else 8 9/* $Id: compat_vasprintf.c,v 1.3 2015/10/06 18:32:19 schwarze Exp $ */ 10/* 11 * Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org> 12 * 13 * Permission to use, copy, modify, and distribute this software for any 14 * purpose with or without fee is hereby granted, provided that the above 15 * copyright notice and this permission notice appear in all copies. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 18 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 20 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 21 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 22 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 23 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 24 * 25 * This fallback implementation is not efficient: 26 * It does the formatting twice. 27 * Short of fiddling with the unknown internals of the system's 28 * printf(3) or completely reimplementing printf(3), i can't think 29 * of another portable solution. 30 */ 31 32#include <stdarg.h> 33#include <stdio.h> 34#include <stdlib.h> 35 36int 37vasprintf(char **ret, const char *format, va_list ap) 38{ 39 char buf[2]; 40 va_list ap2; 41 int sz; 42 43 va_copy(ap2, ap); 44 sz = vsnprintf(buf, sizeof(buf), format, ap2); 45 va_end(ap2); 46 47 if (sz != -1 && (*ret = malloc(sz + 1)) != NULL) { 48 if (vsnprintf(*ret, sz + 1, format, ap) == sz) 49 return sz; 50 free(*ret); 51 } 52 *ret = NULL; 53 return -1; 54} 55 56#endif 57