/* * Copyright (c) 2005 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. */ #include "sm/generic.h" SM_RCSID("@(#)$Id: asprintf.c,v 1.2 2007/01/09 06:06:23 ca Exp $") #if !HAVE_ASPRINTF #include "sm/varargs.h" #include "sm/io.h" #include "sm/assert.h" #include "sm/heap.h" /* ** ASPRINTF -- printf to a dynamically allocated string ** ** Parameters: ** str -- *str receives a pointer to the allocated string ** fmt -- format directives for printing ** ... -- argument list ** ** Results: ** On failure, set *str to NULL, set errno, and return -1. ** ** On success, set *str to a pointer to a nul-terminated ** string buffer containing printf output, and return the ** length of the string (not counting the nul). */ #define SM_VA_BUFSIZE 128 #if !HAVE_VSNPRINTF # define vsnprintf sm_vsnprintf #else # include #endif int asprintf(char **str, const char *fmt, ...) { int ret; va_list ap; size_t len; char *buf; SM_REQUIRE(str != NULL); SM_REQUIRE(fmt != NULL); len = SM_VA_BUFSIZE; buf = NULL; do { buf = malloc(len); if (buf == NULL) goto err2; va_start(ap, fmt); ret = vsnprintf(buf, len, fmt, ap); va_end(ap); if (ret == -1) goto err; if (ret >= len) { len = ret + 1; free(buf); buf = NULL; } } while (buf == NULL); *str = buf; return ret; err: if (buf != NULL) free(buf); err2: *str = NULL; errno = ENOMEM; return -1; } #endif /* !HAVE_ASPRINTF */