mhd_compat.c 2.8 KB

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