mhd_compat.c (2861B)
1 /* 2 This file is part of libmicrohttpd 3 Copyright (C) 2014-2016 Karlson2k (Evgeny Grin) 4 5 This library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with this library; if not, write to the Free Software 17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 19 */ 20 21 /** 22 * @file microhttpd/mhd_compat.c 23 * @brief Implementation of platform missing functions. 24 * @author Karlson2k (Evgeny Grin) 25 */ 26 27 #include "mhd_compat.h" 28 #if defined(_WIN32) && ! defined(__CYGWIN__) 29 #include <stdint.h> 30 #include <time.h> 31 #ifndef HAVE_SNPRINTF 32 #include <stdio.h> 33 #include <stdarg.h> 34 #endif /* HAVE_SNPRINTF */ 35 #endif /* _WIN32 && !__CYGWIN__ */ 36 37 #ifndef HAVE_CALLOC 38 #include <string.h> /* for memset() */ 39 #endif /* ! HAVE_CALLOC */ 40 41 #if defined(_WIN32) && ! defined(__CYGWIN__) 42 43 #ifndef HAVE_SNPRINTF 44 /* Emulate snprintf function on W32 */ 45 int 46 W32_snprintf (char *__restrict s, 47 size_t n, 48 const char *__restrict format, 49 ...) 50 { 51 int ret; 52 va_list args; 53 54 if ( (0 != n) && 55 (NULL != s) ) 56 { 57 va_start (args, 58 format); 59 ret = _vsnprintf (s, 60 n, 61 format, 62 args); 63 va_end (args); 64 if ((int) n == ret) 65 s[n - 1] = 0; 66 if (ret >= 0) 67 return ret; 68 } 69 va_start (args, 70 format); 71 ret = _vscprintf (format, 72 args); 73 va_end (args); 74 if ( (0 <= ret) && 75 (0 != n) && 76 (NULL == s) ) 77 return -1; 78 79 return ret; 80 } 81 82 83 #endif /* HAVE_SNPRINTF */ 84 #endif /* _WIN32 && !__CYGWIN__ */ 85 86 #ifndef HAVE_CALLOC 87 88 #ifdef __has_builtin 89 # if __has_builtin (__builtin_mul_overflow) 90 # define MHD_HAVE_NUL_OVERFLOW 1 91 # endif 92 #elif __GNUC__ + 0 >= 5 93 # define MHD_HAVE_NUL_OVERFLOW 1 94 #endif /* __GNUC__ >= 5 */ 95 96 97 void * 98 MHD_calloc_ (size_t nelem, size_t elsize) 99 { 100 size_t alloc_size; 101 void *ptr; 102 #ifdef MHD_HAVE_NUL_OVERFLOW 103 if (__builtin_mul_overflow (nelem, elsize, &alloc_size) || (0 == alloc_size)) 104 return NULL; 105 #else /* ! MHD_HAVE_NUL_OVERFLOW */ 106 alloc_size = nelem * elsize; 107 if ((0 == alloc_size) || (elsize != alloc_size / nelem)) 108 return NULL; 109 #endif /* ! MHD_HAVE_NUL_OVERFLOW */ 110 ptr = malloc (alloc_size); 111 if (NULL == ptr) 112 return NULL; 113 memset (ptr, 0, alloc_size); 114 return ptr; 115 } 116 117 118 #endif /* ! HAVE_CALLOC */