diff options
Diffstat (limited to 'allocn.c')
-rw-r--r-- | allocn.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/allocn.c b/allocn.c new file mode 100644 index 0000000..168e54c --- /dev/null +++ b/allocn.c @@ -0,0 +1,38 @@ +/* See LICENSE file for copyright and license details. */ +#include "libsimple.h" + + +static inline size_t +alloc_size_product(size_t n, va_list ap) +{ + size_t prod = n; + if (!n) { + errno = EINVAL; + return 0; + } + for (;;) { + n = va_arg(ap, size_t); + if (!n) + break; + if (n >= SIZE_MAX / prod) { + errno = ENOMEM; + return 0; + } + prod *= n; + } + return prod; +} + +void * +libsimple_vmalloczn(int clear, size_t n, va_list ap) +{ + n = alloc_size_product(n, ap); + return !n ? NULL : clear ? calloc(1, n) : malloc(n); +} + +void * +libsimple_vreallocn(void *ptr, size_t n, va_list ap) +{ + n = alloc_size_product(n, ap); + return !n ? NULL : realloc(ptr, n); +} |