/*------------------------------------------------------------------------- * * fe_memutils.c * memory management support for frontend code * * Portions Copyright (c) 1996-2022, 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) { 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); }