Remove string*_large() and add string_large().
[pwmd.git] / src / mem.c
blobd00e124979ac2238ca5a7ac3a80a6b0d8fe9e840
1 /*
2 Copyright (C) 2006-2021 Ben Kibbey <bjk@luxsci.net>
4 This file is part of pwmd.
6 Pwmd is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License version 2 as
8 published by the Free Software Foundation.
10 Pwmd 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 Pwmd. If not, see <http://www.gnu.org/licenses/>.
18 #ifdef HAVE_CONFIG_H
19 #include <config.h>
20 #endif
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <string.h>
26 #include <stddef.h>
28 #include "mem.h"
30 void *
31 xrealloc_gpgrt (void *p, size_t n)
33 if (n)
35 if (p)
36 return xrealloc (p, n);
38 return xmalloc (n);
41 xfree (p);
42 return NULL;
45 /* Borrowed from g10code:
46 * https://lists.gnupg.org/pipermail/gnupg-devel/2018-November/034060.html
48 void
49 wipememory (void *ptr, int c, size_t len)
51 #if defined(HAVE_W32_SYSTEM) && defined(SecureZeroMemory)
52 (void)c;
53 SecureZeroMemory (ptr, len);
54 #elif defined(HAVE_EXPLICIT_BZERO)
55 (void)c;
56 explicit_bzero (ptr, len);
57 #elif defined(HAVE_MEMSET_S)
58 memset_s (ptr, len, c, len);
59 #else
60 /* Prevent compiler from optimizing away the call to memset by accessing
61 memset through volatile pointer. */
62 static void *(*volatile memset_ptr)(void *, int, size_t) = (void *)memset;
63 memset_ptr (ptr, c, len);
64 #endif
67 #ifndef MEM_DEBUG
68 struct memchunk_s
70 size_t size;
71 char data[1];
72 } __attribute ((packed));
74 void
75 xfree (void *ptr)
77 struct memchunk_s *m;
78 void *p;
80 if (!ptr)
81 return;
83 m = (struct memchunk_s *)((char *)ptr-(offsetof (struct memchunk_s, data)));
84 p = (void *)((char *)m+(offsetof (struct memchunk_s, data)));
85 wipememory (p, 0, m->size);
86 free (m);
89 void *
90 xmalloc (size_t size)
92 struct memchunk_s *m;
94 if (!size)
95 return NULL;
97 m = malloc (sizeof (struct memchunk_s)+size);
98 if (!m)
99 return NULL;
101 m->size = size;
102 return (void *)((char *)m+(offsetof (struct memchunk_s, data)));
105 void *
106 xcalloc (size_t nmemb, size_t size)
108 void *p;
109 struct memchunk_s *m;
111 m = malloc (sizeof (struct memchunk_s)+(nmemb*size));
112 if (!m)
113 return NULL;
115 m->size = nmemb*size;
116 p = (void *)((char *)m+(offsetof (struct memchunk_s, data)));
117 memset (p, 0, m->size);
118 return p;
121 void *
122 xrealloc (void *ptr, size_t size)
124 void *p, *np;
125 struct memchunk_s *m, *mp;
126 size_t n;
128 if (!size && ptr)
130 m = (struct memchunk_s *)((char *)ptr-(offsetof (struct memchunk_s, data)));
131 p = (void *)((char *)m+(offsetof (struct memchunk_s, data)));
132 wipememory (p, 0, m->size);
133 free (m);
134 return NULL;
136 else if (!ptr)
137 return xmalloc (size);
139 m = malloc (sizeof (struct memchunk_s)+size);
140 if (!m)
141 return NULL;
143 m->size = size;
144 np = (void *)((char *)m+(offsetof (struct memchunk_s, data)));
146 mp = (struct memchunk_s *)((char *)ptr-(offsetof (struct memchunk_s, data)));
147 p = (void *)((char *)mp+(offsetof (struct memchunk_s, data)));
149 n = size > mp->size ? mp->size : size;
150 memcpy (np, p, n);
151 wipememory (p, 0, mp->size);
153 free (mp);
154 return (void *)((char *)m+(offsetof (struct memchunk_s, data)));
157 #endif