/* This file is part of libmicrohttpd Copyright (C) 2014-2016 Karlson2k (Evgeny Grin) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** * @file microhttpd/mhd_compat.c * @brief Implementation of platform missing functions. * @author Karlson2k (Evgeny Grin) */ #include "mhd_compat.h" #if defined(_WIN32) && !defined(__CYGWIN__) #include #include #ifndef HAVE_SNPRINTF #include #include #endif /* HAVE_SNPRINTF */ #endif /* _WIN32 && !__CYGWIN__ */ #ifndef HAVE_CALLOC #include /* for memset() */ #endif /* ! HAVE_CALLOC */ #if defined(_WIN32) && !defined(__CYGWIN__) #ifndef HAVE_SNPRINTF /* Emulate snprintf function on W32 */ int W32_snprintf (char *__restrict s, size_t n, const char *__restrict format, ...) { int ret; va_list args; if ( (0 != n) && (NULL != s) ) { va_start (args, format); ret = _vsnprintf (s, n, format, args); va_end (args); if ((int)n == ret) s[n - 1] = 0; if (ret >= 0) return ret; } va_start(args, format); ret = _vscprintf (format, args); va_end(args); if ( (0 <= ret) && (0 != n) && (NULL == s) ) return -1; return ret; } #endif /* HAVE_SNPRINTF */ #endif /* _WIN32 && !__CYGWIN__ */ #ifndef HAVE_CALLOC #ifdef __has_builtin # if __has_builtin(__builtin_mul_overflow) # define MHD_HAVE_NUL_OVERFLOW 1 # endif #elif __GNUC__+0 >= 5 # define MHD_HAVE_NUL_OVERFLOW 1 #endif /* __GNUC__ >= 5 */ void *MHD_calloc_(size_t nelem, size_t elsize) { size_t alloc_size; void *ptr; #ifdef MHD_HAVE_NUL_OVERFLOW if (__builtin_mul_overflow(nelem, elsize, &alloc_size) || 0 == alloc_size) return NULL; #else /* ! MHD_HAVE_NUL_OVERFLOW */ alloc_size = nelem * elsize; if (0 == alloc_size || elsize != alloc_size / nelem) return NULL; #endif /* ! MHD_HAVE_NUL_OVERFLOW */ ptr = malloc (alloc_size); if (NULL == ptr) return NULL; memset(ptr, 0, alloc_size); return ptr; } #endif /* ! HAVE_CALLOC */