diff --git a/harness.c b/harness.c index 4e02891f5..d92345794 100644 --- a/harness.c +++ b/harness.c @@ -63,6 +63,7 @@ static bool time_limited = false; typedef enum { TEST_MALLOC, TEST_CALLOC, + TEST_REALLOC, } alloc_t; /* Internal functions */ @@ -128,6 +129,7 @@ static void *alloc(alloc_t alloc_type, size_t size) char *msg_alloc_forbidden[] = { "Calls to malloc are disallowed", "Calls to calloc are disallowed", + "Calls to realloc are disallowed", }; report_event(MSG_FATAL, "%s", msg_alloc_forbidden[alloc_type]); return NULL; @@ -137,6 +139,7 @@ static void *alloc(alloc_t alloc_type, size_t size) char *msg_alloc_failure[] = { "Malloc returning NULL", "Calloc returning NULL", + "Realloc returning NULL", }; report_event(MSG_WARN, "%s", msg_alloc_failure[alloc_type]); return NULL; @@ -187,6 +190,28 @@ void *test_calloc(size_t nelem, size_t elsize) return alloc(TEST_CALLOC, nelem * elsize); } +/* + * Implementation of adjusting the size of the memory allocated + * by test_malloc or test_calloc. + */ +void *test_realloc(void *p, size_t new_size) +{ + if (!p) + return alloc(TEST_REALLOC, new_size); + + const block_element_t *b = find_header(p); + if (b->payload_size >= new_size) + return p; + + void *new_ptr = alloc(TEST_REALLOC, new_size); + if (!new_ptr) + return NULL; + memcpy(new_ptr, p, b->payload_size); + test_free(p); + + return new_ptr; +} + void test_free(void *p) { if (noallocate_mode) { diff --git a/harness.h b/harness.h index 3e2ccec40..69b67d445 100644 --- a/harness.h +++ b/harness.h @@ -12,9 +12,9 @@ void *test_malloc(size_t size); void *test_calloc(size_t nmemb, size_t size); +void *test_realloc(void *p, size_t new_size); void test_free(void *p); char *test_strdup(const char *s); -/* FIXME: provide test_realloc as well */ #ifdef INTERNAL @@ -56,6 +56,7 @@ void trigger_exception(char *msg); /* Tested program use our versions of malloc and free */ #define malloc test_malloc #define calloc test_calloc +#define realloc test_realloc #define free test_free /* Use undef to avoid strdup redefined error */