1 /*-------------------------------------------------------------------------
2  *
3  * fe_memutils.c
4  *	  memory management support for frontend code
5  *
6  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *	  src/common/fe_memutils.c
12  *
13  *-------------------------------------------------------------------------
14  */
15 
16 #define FRONTEND
17 
18 #ifndef FRONTEND
19 #error "This file is not expected to be compiled for backend code"
20 #endif
21 
22 #include <sys/types.h>
23 #include <unistd.h>
24 #include <stdio.h>
25 #include <stdarg.h>
26 #include <stdlib.h>
27 #include <stdint.h>
28 #include <string.h>
29 
30 #include "pgproto/fe_memutils.h"
31 
32 static inline void *
pg_malloc_internal(size_t size,int flags)33 pg_malloc_internal(size_t size, int flags)
34 {
35 	void	   *tmp;
36 
37 	/* Avoid unportable behavior of malloc(0) */
38 	if (size == 0)
39 		size = 1;
40 	tmp = malloc(size);
41 	if (tmp == NULL)
42 	{
43 		if ((flags & MCXT_ALLOC_NO_OOM) == 0)
44 		{
45 			fprintf(stderr, _("out of memory\n"));
46 			exit(EXIT_FAILURE);
47 		}
48 		return NULL;
49 	}
50 
51 	if ((flags & MCXT_ALLOC_ZERO) != 0)
52 		MemSet(tmp, 0, size);
53 	return tmp;
54 }
55 
56 void *
pg_malloc(size_t size)57 pg_malloc(size_t size)
58 {
59 	return pg_malloc_internal(size, 0);
60 }
61 
62 void *
pg_malloc0(size_t size)63 pg_malloc0(size_t size)
64 {
65 	return pg_malloc_internal(size, MCXT_ALLOC_ZERO);
66 }
67 
68 void *
pg_malloc_extended(size_t size,int flags)69 pg_malloc_extended(size_t size, int flags)
70 {
71 	return pg_malloc_internal(size, flags);
72 }
73 
74 void *
pg_realloc(void * ptr,size_t size)75 pg_realloc(void *ptr, size_t size)
76 {
77 	void	   *tmp;
78 
79 	/* Avoid unportable behavior of realloc(NULL, 0) */
80 	if (ptr == NULL && size == 0)
81 		size = 1;
82 	tmp = realloc(ptr, size);
83 	if (!tmp)
84 	{
85 		fprintf(stderr, _("out of memory\n"));
86 		exit(EXIT_FAILURE);
87 	}
88 	return tmp;
89 }
90 
91 /*
92  * "Safe" wrapper around strdup().
93  */
94 char *
pg_strdup(const char * in)95 pg_strdup(const char *in)
96 {
97 	char	   *tmp;
98 
99 	if (!in)
100 	{
101 		fprintf(stderr,
102 				_("cannot duplicate null pointer (internal error)\n"));
103 		exit(EXIT_FAILURE);
104 	}
105 	tmp = strdup(in);
106 	if (!tmp)
107 	{
108 		fprintf(stderr, _("out of memory\n"));
109 		exit(EXIT_FAILURE);
110 	}
111 	return tmp;
112 }
113 
114 void
pg_free(void * ptr)115 pg_free(void *ptr)
116 {
117 	if (ptr != NULL)
118 		free(ptr);
119 }
120 
121 /*
122  * Frontend emulation of backend memory management functions.  Useful for
123  * programs that compile backend files.
124  */
125 void *
palloc(Size size)126 palloc(Size size)
127 {
128 	return pg_malloc_internal(size, 0);
129 }
130 
131 void *
palloc0(Size size)132 palloc0(Size size)
133 {
134 	return pg_malloc_internal(size, MCXT_ALLOC_ZERO);
135 }
136 
137 void *
palloc_extended(Size size,int flags)138 palloc_extended(Size size, int flags)
139 {
140 	return pg_malloc_internal(size, flags);
141 }
142 
143 void
pfree(void * pointer)144 pfree(void *pointer)
145 {
146 	pg_free(pointer);
147 }
148 
149 char *
pstrdup(const char * in)150 pstrdup(const char *in)
151 {
152 	return pg_strdup(in);
153 }
154 
155 void *
repalloc(void * pointer,Size size)156 repalloc(void *pointer, Size size)
157 {
158 	return pg_realloc(pointer, size);
159 }
160