Use the new EXISTS protocol command to determine whether a file is new
[libpwmd.git] / mem.c
blob6cb9d36f8f7a86c81bbcef54dcab1a87f902521b
1 /* vim:tw=78:ts=8:sw=4:set ft=c: */
2 /*
3 Copyright (C) 2006-2007 Ben Kibbey <bjk@luxsci.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <unistd.h>
22 #include <string.h>
23 #include <assert.h>
24 #include <err.h>
26 #ifdef HAVE_CONFIG_H
27 #include <config.h>
28 #endif
30 #include "gettext.h"
31 #define N_(msgid) gettext(msgid)
33 #include "mem.h"
35 static struct memlist_s *memlist;
37 static struct memlist_s *memlist_remove(struct memlist_s *list, struct memlist_s *r)
39 struct memlist_s *m, *last = NULL, *p;
41 for (m = list; m; m = m->next) {
42 if (m->ptr == r->ptr) {
43 memset(m->ptr, 0, m->size);
44 free(m->ptr);
46 if (RUNNING_ON_VALGRIND)
47 VALGRIND_FREELIKE_BLOCK(m->ptr, 0);
49 p = m->next;
50 free(m);
52 if (RUNNING_ON_VALGRIND)
53 VALGRIND_FREELIKE_BLOCK(m, 0);
55 if (last) {
56 if (p)
57 last->next = p;
58 else
59 last->next = NULL;
61 else if (p)
62 list = p;
63 else
64 list = NULL;
66 break;
69 last = m;
72 return list;
75 static struct memlist_s *memlist_append(struct memlist_s *list, struct memlist_s *p)
77 struct memlist_s *m;
79 if (!list) {
80 list = p;
81 list->next = NULL;
82 return list;
85 for (m = list; m; m = m->next) {
86 if (!m->next) {
87 m->next = p;
88 m = m->next;
89 m->next = NULL;
90 break;
94 return list;
97 void xfree(void *ptr)
99 struct memlist_s *m;
101 if (!ptr)
102 return;
104 for (m = memlist; m; m = m->next) {
105 if (m->ptr == ptr) {
106 #ifdef DEBUG
107 fprintf(stderr, "xfree(): %p %i\n", ptr, m->size);
108 #endif
109 memlist = memlist_remove(memlist, m);
110 return;
114 warnx("xfree(): %p %s:", ptr, N_("not found"));
115 assert(0);
118 void *xmalloc(size_t size)
120 void *p;
121 struct memlist_s *m;
123 if (size <= 0)
124 return NULL;
126 if ((m = (struct memlist_s *)malloc(sizeof(struct memlist_s))) == NULL)
127 return NULL;
129 if (RUNNING_ON_VALGRIND)
130 VALGRIND_MALLOCLIKE_BLOCK(m, sizeof(struct memlist_s), 0, 0);
132 if ((p = malloc(size)) == NULL) {
133 free(m);
135 if (RUNNING_ON_VALGRIND)
136 VALGRIND_FREELIKE_BLOCK(m, 0);
138 return NULL;
141 if (RUNNING_ON_VALGRIND)
142 VALGRIND_MALLOCLIKE_BLOCK(p, size, 0, 0);
144 m->ptr = p;
145 m->size = size;
146 memlist = memlist_append(memlist, m);
147 #ifdef DEBUG
148 fprintf(stderr, "xmalloc(): %p %i\n", p, size);
149 #endif
150 return m->ptr;
153 void *xcalloc(size_t nmemb, size_t size)
155 void *p;
156 struct memlist_s *m;
158 if (size <= 0)
159 return NULL;
161 if ((m = (struct memlist_s *)malloc(sizeof(struct memlist_s))) == NULL)
162 return NULL;
164 if (RUNNING_ON_VALGRIND)
165 VALGRIND_MALLOCLIKE_BLOCK(m, sizeof(struct memlist_s), 0, 0);
167 if ((p = calloc(nmemb, size)) == NULL) {
168 free(m);
170 if (RUNNING_ON_VALGRIND)
171 VALGRIND_FREELIKE_BLOCK(m, 0);
173 return NULL;
176 if (RUNNING_ON_VALGRIND)
177 VALGRIND_MALLOCLIKE_BLOCK(p, nmemb * size, 0, 1);
179 m->ptr = p;
180 m->size = nmemb * size;
181 memlist = memlist_append(memlist, m);
182 #ifdef DEBUG
183 fprintf(stderr, "xcalloc(): %p %i\n", p, nmemb * size);
184 #endif
185 return m->ptr;
188 void *xrealloc(void *ptr, size_t size)
190 void *p;
191 struct memlist_s *m;
193 if (!ptr)
194 return xmalloc(size);
196 if (size <= 0)
197 return ptr;
199 for (m = memlist; m; m = m->next) {
200 if (m->ptr == ptr) {
201 if ((p = malloc(size)) == NULL)
202 return NULL;
204 if (RUNNING_ON_VALGRIND)
205 VALGRIND_MALLOCLIKE_BLOCK(p, size, 0, 0);
207 memcpy(p, m->ptr, size < m->size ? size : m->size);
208 memset(m->ptr, 0, m->size);
209 free(m->ptr);
211 if (RUNNING_ON_VALGRIND)
212 VALGRIND_FREELIKE_BLOCK(m->ptr, 0);
214 m->ptr = p;
215 m->size = size;
216 #ifdef DEBUG
217 fprintf(stderr, "xrealloc(): %p %i\n", p, size);
218 #endif
219 return m->ptr;
223 warnx("xrealloc(): %p %s", ptr, N_("not found"));
224 assert(0);
225 return NULL;
228 char *xstrdup(const char *str)
230 char *t, *tp;
231 size_t len;
232 const char *p;
234 if (!str)
235 return NULL;
237 len = strlen(str) + 1;
239 if ((t = (char *)xmalloc(len * sizeof(char))) == NULL)
240 return NULL;
242 for (p = str, tp = t; *p; p++)
243 *tp++ = *p;
245 *tp = 0;
246 #ifdef DEBUG
247 fprintf(stderr, "xstrdup(): %p\n", t);
248 #endif
249 return t;
252 void xpanic(void)
254 struct memlist_s *m;
256 for (m = memlist; m; m = memlist)
257 xfree(m->ptr);