summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarren Tucker <dtucker@dtucker.net>2018-02-25 10:20:31 +1100
committerDarren Tucker <dtucker@dtucker.net>2018-02-26 00:09:04 +1100
commite9dede06e5bc582a4aeb5b1cd5a7a640d7de3609 (patch)
treef149ff2fb7ff3d427cfd1e7fcee416e7922ada84
parent2eb4041493fd2635ffdc64a852d02b38c4955e0b (diff)
Handle calloc(0,x) where different from malloc.
Configure assumes that if malloc(0) returns null then calloc(0,n) also does. On some old platforms (SunOS4) malloc behaves as expected (as determined by AC_FUNC_MALLOC) but calloc doesn't. Test for this at configure time and activate the replacement function if found, plus handle this case in rpl_calloc.
-rw-r--r--configure.ac19
-rw-r--r--openbsd-compat/bsd-malloc.c2
2 files changed, 19 insertions, 2 deletions
diff --git a/configure.ac b/configure.ac
index 03cc3f86..605844ba 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1337,8 +1337,23 @@ AC_FUNC_STRFTIME
AC_FUNC_MALLOC
AC_FUNC_REALLOC
# autoconf doesn't have AC_FUNC_CALLOC so fake it if malloc returns NULL;
-if test "x$ac_cv_func_malloc_0_nonnull" != "xyes"; then
- AC_DEFINE(HAVE_CALLOC, 0, [calloc(x, 0) returns NULL])
+AC_MSG_CHECKING([if calloc(0, N) returns non-null])
+AC_RUN_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[ #include <stdlib.h> ]],
+ [[ void *p = calloc(0, 1); exit(p == NULL); ]]
+ )],
+ [ func_calloc_0_nonnull=yes ],
+ [ func_calloc_0_nonnull=no ],
+ [ AC_MSG_WARN([cross compiling: assuming same as malloc])
+ func_calloc_0_nonnull="$ac_cv_func_malloc_0_nonnull"]
+)
+AC_MSG_RESULT([$func_calloc_0_nonnull])
+
+if test "x$func_calloc_0_nonnull" == "xyes"; then
+ AC_DEFINE(HAVE_CALLOC, 1, [calloc(0, x) returns non-null])
+else
+ AC_DEFINE(HAVE_CALLOC, 0, [calloc(0, x) returns NULL])
AC_DEFINE(calloc, rpl_calloc,
[Define to rpl_calloc if the replacement function should be used.])
fi
diff --git a/openbsd-compat/bsd-malloc.c b/openbsd-compat/bsd-malloc.c
index 6402ab58..482facdc 100644
--- a/openbsd-compat/bsd-malloc.c
+++ b/openbsd-compat/bsd-malloc.c
@@ -50,6 +50,8 @@ rpl_realloc(void *ptr, size_t size)
{
if (size == 0)
size = 1;
+ if (ptr == 0)
+ return malloc(size);
return realloc(ptr, size);
}
#endif