diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake index 3c6e544dc9..decc1e03e3 100644 --- a/ConfigureChecks.cmake +++ b/ConfigureChecks.cmake @@ -99,6 +99,7 @@ if(UNIX) list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE) check_function_exists("memmem" HAVE_MEMMEM) check_function_exists("strcasestr" HAVE_STRCASESTR) + check_function_exists("vasprintf" HAVE_VASPRINTF) cmake_pop_check_state() endif() diff --git a/cmakeconfig.h.in b/cmakeconfig.h.in index c88d6453b8..8ed1662cf3 100644 --- a/cmakeconfig.h.in +++ b/cmakeconfig.h.in @@ -259,6 +259,9 @@ /* Define if you have the 'strcasestr' function. */ #cmakedefine HAVE_STRCASESTR 1 +/* Define if you have the 'vasprintf' function. */ +#cmakedefine HAVE_VASPRINTF 1 + /* Define to 1 if `st_birthtime' is a member of `struct stat'. */ #cmakedefine HAVE_STRUCT_STAT_ST_BIRTHTIME 1 diff --git a/wsutil/wmem/wmem_strutl.c b/wsutil/wmem/wmem_strutl.c index 48b0e88561..dfc7271ef7 100644 --- a/wsutil/wmem/wmem_strutl.c +++ b/wsutil/wmem/wmem_strutl.c @@ -8,22 +8,13 @@ * * SPDX-License-Identifier: GPL-2.0-or-later */ - +#define _GNU_SOURCE #include "config.h" +#include "wmem_strutl.h" #include -#include - -#ifdef _WIN32 #include -#endif - -#include -#include - -#include "wmem_core.h" -#include "wmem_allocator.h" -#include "wmem_strutl.h" +#include gchar * wmem_strdup(wmem_allocator_t *allocator, const gchar *src) @@ -71,6 +62,22 @@ wmem_strdup_printf(wmem_allocator_t *allocator, const gchar *fmt, ...) return dst; } +#ifdef HAVE_VASPRINTF +static char * +_strdup_vasprintf(const char *fmt, va_list ap) +{ + char *str = NULL; + int ret; + + ret = vasprintf(&str, fmt, ap); + if (ret == -1 && errno == ENOMEM) { + /* Out of memory. We have to mimic GLib here and abort. */ + g_error("%s: failed to allocate memory", G_STRLOC); + } + return str; +} +#endif /* HAVE_VASPRINTF */ + #define WMEM_STRDUP_VPRINTF_DEFAULT_BUFFER 256 char * wmem_strdup_vprintf(wmem_allocator_t *allocator, const char *fmt, va_list ap) @@ -81,6 +88,12 @@ wmem_strdup_vprintf(wmem_allocator_t *allocator, const char *fmt, va_list ap) char *new_buf; size_t new_buf_size; +#ifdef HAVE_VASPRINTF + if (allocator == NULL) { + return _strdup_vasprintf(fmt, ap); + } +#endif + va_copy(ap2, ap); needed_len = vsnprintf(buf, sizeof(buf), fmt, ap2); va_end(ap2); diff --git a/wsutil/wmem/wmem_strutl.h b/wsutil/wmem/wmem_strutl.h index 531867ac86..dceeb32bdc 100644 --- a/wsutil/wmem/wmem_strutl.h +++ b/wsutil/wmem/wmem_strutl.h @@ -12,9 +12,10 @@ #ifndef __WMEM_STRUTL_H__ #define __WMEM_STRUTL_H__ -#include +#include +#include -#include +#include "wmem_core.h" #ifdef __cplusplus extern "C" {