1 #include "config.h" 2 3 #if HAVE_VASPRINTF 4 5 int 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 36 int 37 vasprintf(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