Update copyright year.
[pwmd.git] / src / mem.c
blob8f8f4891130c9c08ab63907b3ddd3efd236453a1
1 /*
2 Copyright (C) 2006-2019 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 as published by
8 the Free Software Foundation, either version 2 of the License, or
9 (at your option) any later version.
11 Pwmd is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with Pwmd. If not, see <http://www.gnu.org/licenses/>.
19 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <unistd.h>
26 #include <string.h>
27 #include <stddef.h>
29 #include "mem.h"
31 void *
32 xrealloc_gpgrt (void *p, size_t n)
34 if (n)
36 if (p)
37 return xrealloc (p, n);
39 return xmalloc (n);
42 xfree (p);
43 return NULL;
46 /* Borrowed from g10code:
47 * https://lists.gnupg.org/pipermail/gnupg-devel/2018-November/034060.html
49 void
50 wipememory (void *ptr, int c, size_t len)
52 #if defined(HAVE_W32_SYSTEM) && defined(SecureZeroMemory)
53 (void)c;
54 SecureZeroMemory (ptr, len);
55 #elif defined(HAVE_EXPLICIT_BZERO)
56 (void)c;
57 explicit_bzero (ptr, len);
58 #elif defined(HAVE_MEMSET_S)
59 memset_s (ptr, len, c, len);
60 #else
61 /* Prevent compiler from optimizing away the call to memset by accessing
62 memset through volatile pointer. */
63 static void *(*volatile memset_ptr)(void *, int, size_t) = (void *)memset;
64 memset_ptr (ptr, c, len);
65 #endif
68 #ifndef MEM_DEBUG
69 struct memchunk_s
71 size_t size;
72 char data[1];
73 } __attribute ((packed));
75 void
76 xfree (void *ptr)
78 struct memchunk_s *m;
79 void *p;
81 if (!ptr)
82 return;
84 m = (struct memchunk_s *)((char *)ptr-(offsetof (struct memchunk_s, data)));
85 p = (void *)((char *)m+(offsetof (struct memchunk_s, data)));
86 wipememory (p, 0, m->size);
87 free (m);
90 void *
91 xmalloc (size_t size)
93 struct memchunk_s *m;
95 if (!size)
96 return NULL;
98 m = malloc (sizeof (struct memchunk_s)+size);
99 if (!m)
100 return NULL;
102 m->size = size;
103 return (void *)((char *)m+(offsetof (struct memchunk_s, data)));
106 void *
107 xcalloc (size_t nmemb, size_t size)
109 void *p;
110 struct memchunk_s *m;
112 m = malloc (sizeof (struct memchunk_s)+(nmemb*size));
113 if (!m)
114 return NULL;
116 m->size = nmemb*size;
117 p = (void *)((char *)m+(offsetof (struct memchunk_s, data)));
118 memset (p, 0, m->size);
119 return p;
122 void *
123 xrealloc (void *ptr, size_t size)
125 void *p, *np;
126 struct memchunk_s *m, *mp;
127 size_t n;
129 if (!size && ptr)
131 m = (struct memchunk_s *)((char *)ptr-(offsetof (struct memchunk_s, data)));
132 p = (void *)((char *)m+(offsetof (struct memchunk_s, data)));
133 wipememory (p, 0, m->size);
134 free (m);
135 return NULL;
137 else if (!ptr)
138 return xmalloc (size);
140 m = malloc (sizeof (struct memchunk_s)+size);
141 if (!m)
142 return NULL;
144 m->size = size;
145 np = (void *)((char *)m+(offsetof (struct memchunk_s, data)));
147 mp = (struct memchunk_s *)((char *)ptr-(offsetof (struct memchunk_s, data)));
148 p = (void *)((char *)mp+(offsetof (struct memchunk_s, data)));
150 n = size > mp->size ? mp->size : size;
151 memcpy (np, p, n);
152 wipememory (p, 0, mp->size);
154 free (mp);
155 return (void *)((char *)m+(offsetof (struct memchunk_s, data)));
158 #endif