contrib: Add helper to build Android dependencies.
[libpwmd.git] / src / mem.c
blob0bb2fadb92aae3f880f4daf53e5849222b862668
1 /*
2 Copyright (C) 2017-2023 Ben Kibbey <bjk@luxsci.net>
4 This file is part of libpwmd.
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License version 2.1 as published by the Free Software Foundation.
10 This library 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 GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
18 USA
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <stddef.h>
28 #ifdef HAVE_UNISTD_H
29 #include <unistd.h>
30 #endif
32 #include "mem.h"
34 void *
35 _xrealloc_gpgrt (void *p, size_t n)
37 if (n)
38 return p ? _xrealloc (p, n) : _xmalloc (n);
40 _xfree (p);
41 return NULL;
44 /* Borrowed from g10code:
45 * https://lists.gnupg.org/pipermail/gnupg-devel/2018-November/034060.html
47 void
48 wipememory (void *ptr, int c, size_t len)
50 #if defined(HAVE_W32_SYSTEM) && defined(SecureZeroMemory)
51 (void)c;
52 SecureZeroMemory (ptr, len);
53 #elif defined(HAVE_EXPLICIT_BZERO)
54 (void)c;
55 explicit_bzero (ptr, len);
56 #elif defined(HAVE_MEMSET_S)
57 memset_s (ptr, len, c, len);
58 #else
59 /* Prevent compiler from optimizing away the call to memset by accessing
60 memset through volatile pointer. */
61 static void *(*volatile memset_ptr)(void *, int, size_t) = (void *)memset;
62 memset_ptr (ptr, c, len);
63 #endif
66 #ifndef MEM_DEBUG
67 struct memchunk_s
69 size_t size;
70 char data[1];
73 void
74 _xfree (void *ptr)
76 struct memchunk_s *m;
77 void *p;
79 if (!ptr)
80 return;
82 m = (struct memchunk_s *)((char *)ptr-(offsetof (struct memchunk_s, data)));
83 p = (void *)((char *)m+(offsetof (struct memchunk_s, data)));
84 wipememory (p, 0, m->size);
85 free (m);
88 void *
89 _xmalloc (size_t size)
91 struct memchunk_s *m;
93 if (!size)
94 return NULL;
96 m = malloc (sizeof (struct memchunk_s)+size);
97 if (!m)
98 return NULL;
100 m->size = size;
101 return (void *)((char *)m+(offsetof (struct memchunk_s, data)));
104 void *
105 _xcalloc (size_t nmemb, size_t size)
107 void *p;
108 struct memchunk_s *m;
110 m = malloc (sizeof (struct memchunk_s)+(nmemb*size));
111 if (!m)
112 return NULL;
114 m->size = nmemb*size;
115 p = (void *)((char *)m+(offsetof (struct memchunk_s, data)));
116 memset (p, 0, m->size);
117 return p;
120 void *
121 _xrealloc (void *ptr, size_t size)
123 void *p, *np;
124 struct memchunk_s *m, *mp;
125 size_t n;
127 if (!size && ptr)
129 m = (struct memchunk_s *)((char *)ptr-(offsetof (struct memchunk_s, data)));
130 p = (void *)((char *)m+(offsetof (struct memchunk_s, data)));
131 wipememory (p, 0, m->size);
132 free (m);
133 return NULL;
135 else if (!ptr)
136 return _xmalloc (size);
138 m = malloc (sizeof (struct memchunk_s)+size);
139 if (!m)
140 return NULL;
142 m->size = size;
143 np = (void *)((char *)m+(offsetof (struct memchunk_s, data)));
145 mp = (struct memchunk_s *)((char *)ptr-(offsetof (struct memchunk_s, data)));
146 p = (void *)((char *)mp+(offsetof (struct memchunk_s, data)));
148 n = size > mp->size ? mp->size : size;
149 memcpy (np, p, n);
150 wipememory (p, 0, mp->size);
152 free (mp);
153 return (void *)((char *)m+(offsetof (struct memchunk_s, data)));
155 #endif