diff options
Diffstat (limited to 'src/common/fe_memutils.c')
-rw-r--r-- | src/common/fe_memutils.c | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/src/common/fe_memutils.c b/src/common/fe_memutils.c new file mode 100644 index 0000000..b027a02 --- /dev/null +++ b/src/common/fe_memutils.c @@ -0,0 +1,176 @@ +/*------------------------------------------------------------------------- + * + * fe_memutils.c + * memory management support for frontend code + * + * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/common/fe_memutils.c + * + *------------------------------------------------------------------------- + */ + +#ifndef FRONTEND +#error "This file is not expected to be compiled for backend code" +#endif + +#include "postgres_fe.h" + +static inline void * +pg_malloc_internal(size_t size, int flags) +{ + void *tmp; + + /* Avoid unportable behavior of malloc(0) */ + if (size == 0) + size = 1; + tmp = malloc(size); + if (tmp == NULL) + { + if ((flags & MCXT_ALLOC_NO_OOM) == 0) + { + fprintf(stderr, _("out of memory\n")); + exit(EXIT_FAILURE); + } + return NULL; + } + + if ((flags & MCXT_ALLOC_ZERO) != 0) + MemSet(tmp, 0, size); + return tmp; +} + +void * +pg_malloc(size_t size) +{ + return pg_malloc_internal(size, 0); +} + +void * +pg_malloc0(size_t size) +{ + return pg_malloc_internal(size, MCXT_ALLOC_ZERO); +} + +void * +pg_malloc_extended(size_t size, int flags) +{ + return pg_malloc_internal(size, flags); +} + +void * +pg_realloc(void *ptr, size_t size) +{ + void *tmp; + + /* Avoid unportable behavior of realloc(NULL, 0) */ + if (ptr == NULL && size == 0) + size = 1; + tmp = realloc(ptr, size); + if (!tmp) + { + fprintf(stderr, _("out of memory\n")); + exit(EXIT_FAILURE); + } + return tmp; +} + +/* + * "Safe" wrapper around strdup(). + */ +char * +pg_strdup(const char *in) +{ + char *tmp; + + if (!in) + { + fprintf(stderr, + _("cannot duplicate null pointer (internal error)\n")); + exit(EXIT_FAILURE); + } + tmp = strdup(in); + if (!tmp) + { + fprintf(stderr, _("out of memory\n")); + exit(EXIT_FAILURE); + } + return tmp; +} + +void +pg_free(void *ptr) +{ + if (ptr != NULL) + free(ptr); +} + +/* + * Frontend emulation of backend memory management functions. Useful for + * programs that compile backend files. + */ +void * +palloc(Size size) +{ + return pg_malloc_internal(size, 0); +} + +void * +palloc0(Size size) +{ + return pg_malloc_internal(size, MCXT_ALLOC_ZERO); +} + +void * +palloc_extended(Size size, int flags) +{ + return pg_malloc_internal(size, flags); +} + +void +pfree(void *pointer) +{ + pg_free(pointer); +} + +char * +pstrdup(const char *in) +{ + return pg_strdup(in); +} + +char * +pnstrdup(const char *in, Size size) +{ + char *tmp; + int len; + + if (!in) + { + fprintf(stderr, + _("cannot duplicate null pointer (internal error)\n")); + exit(EXIT_FAILURE); + } + + len = strnlen(in, size); + tmp = malloc(len + 1); + if (tmp == NULL) + { + fprintf(stderr, _("out of memory\n")); + exit(EXIT_FAILURE); + } + + memcpy(tmp, in, len); + tmp[len] = '\0'; + + return tmp; +} + +void * +repalloc(void *pointer, Size size) +{ + return pg_realloc(pointer, size); +} |