summaryrefslogtreecommitdiffstats
path: root/src/common/fe_memutils.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/fe_memutils.c')
-rw-r--r--src/common/fe_memutils.c176
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);
+}