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