1 /* **************************** */
2 /* Memory management functions. */
3 /* **************************** */
4
5 /* Created by Kevin Locke (from numerous canonical examples). */
6 /* */
7 /* Adapted for use by smenu. */
8 /* */
9 /* I hereby place this file in the public domain. It may be freely */
10 /* reproduced, distributed, used, modified, built upon, or otherwise */
11 /* employed by anyone for any purpose without restriction. */
12 /* """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" */
13
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <errno.h>
18
19 #include "config.h"
20 #include "xmalloc.h"
21
22 /* The following rpl_* function are necessary for AIX which doesn't */
23 /* provide 'GNU compatible' allocation functions. */
24 /* Every call to malloc()/realloc() is then replaced by a call to */
25 /* rpl_malloc()/rpl_realloc() as defined in the GNU generated config.h. */
26 /* """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" */
27
28 #ifdef malloc
29
30 #undef malloc
31 extern void * malloc(size_t);
32
33 void *
rpl_malloc(size_t size)34 rpl_malloc(size_t size)
35 {
36 if (!size)
37 size++;
38 return malloc(size);
39 }
40
41 #undef realloc
42 extern void *
43 realloc(void *, size_t);
44
45 void *
rpl_realloc(void * ptr,size_t size)46 rpl_realloc(void * ptr, size_t size)
47 {
48 if (!size)
49 size++;
50 return (ptr ? realloc(ptr, size) : malloc(size));
51 }
52
53 #endif
54
55 /* ================== */
56 /* Customized malloc. */
57 /* ================== */
58 void *
xmalloc(size_t size)59 xmalloc(size_t size)
60 {
61 void * allocated;
62 size_t real_size;
63
64 real_size = (size > 0) ? size : 1;
65 allocated = malloc(real_size);
66 if (allocated == NULL)
67 {
68 fprintf(stderr,
69 "Error: Insufficient memory (attempt to malloc %lu bytes)\n",
70 (unsigned long int)size);
71
72 exit(EXIT_FAILURE);
73 }
74
75 return allocated;
76 }
77
78 /* ================== */
79 /* Customized calloc. */
80 /* ================== */
81 void *
xcalloc(size_t n,size_t size)82 xcalloc(size_t n, size_t size)
83 {
84 void * allocated;
85
86 n = (n > 0) ? n : 1;
87 size = (size > 0) ? size : 1;
88 allocated = calloc(n, size);
89 if (allocated == NULL)
90 {
91 fprintf(stderr,
92 "Error: Insufficient memory (attempt to calloc %lu bytes)\n",
93 (unsigned long int)size);
94
95 exit(EXIT_FAILURE);
96 }
97
98 return allocated;
99 }
100
101 /* =================== */
102 /* Customized realloc. */
103 /* =================== */
104 void *
xrealloc(void * p,size_t size)105 xrealloc(void * p, size_t size)
106 {
107 void * allocated;
108
109 allocated = realloc(p, size);
110 if (allocated == NULL && size > 0)
111 {
112 fprintf(stderr,
113 "Error: Insufficient memory (attempt to xrealloc %lu bytes)\n",
114 (unsigned long int)size);
115
116 exit(EXIT_FAILURE);
117 }
118
119 return allocated;
120 }
121
122 /* ==================================== */
123 /* strdup implementation using xmalloc. */
124 /* ==================================== */
125 char *
xstrdup(const char * p)126 xstrdup(const char * p)
127 {
128 char * allocated;
129
130 #ifdef HAVE_STRDUP
131 allocated = strdup(p);
132
133 if (allocated == NULL)
134 {
135 fprintf(stderr, "Error: Insufficient memory for strdup.\n");
136
137 exit(EXIT_FAILURE);
138 }
139 #else
140 allocated = xmalloc(strlen(p) + 1);
141 strcpy(allocated, p);
142 #endif
143
144 return allocated;
145 }
146
147 /* =================================================== */
148 /* strndup implementation using xmalloc. */
149 /* This version guarantees that there is a final '\0'. */
150 /* =================================================== */
151 char *
xstrndup(const char * str,size_t len)152 xstrndup(const char * str, size_t len)
153 {
154 char * p;
155
156 #ifdef HAVE_STRNDUP
157 p = strndup(str, len);
158
159 if (p == NULL)
160 {
161 fprintf(stderr, "Error: Insufficient memory for strndup.\n");
162
163 exit(EXIT_FAILURE);
164 }
165 #else
166 p = memchr(str, '\0', len);
167
168 if (p)
169 len = p - str;
170
171 p = xmalloc(len + 1);
172 memcpy(p, str, len);
173 p[len] = '\0';
174 #endif
175
176 return p;
177 }
178