diff options
author | RincewindsHat <12514511+RincewindsHat@users.noreply.github.com> | 2021-11-17 01:05:54 +0100 |
---|---|---|
committer | RincewindsHat <12514511+RincewindsHat@users.noreply.github.com> | 2022-07-24 19:35:11 +0200 |
commit | a405fc138596f552581d2011fd6de02d5c8186c4 (patch) | |
tree | 4c084700b5cb5e9fcedf982a2d921bbc41d9935a /gl/xalloc.h | |
parent | 9f2a9ca3d72023ff9b5707d1872c54d65edc9017 (diff) | |
download | monitoring-plugins-a405fc1.tar.gz |
Sync with the latest Gnulib code (1a268176f)
Diffstat (limited to 'gl/xalloc.h')
-rw-r--r-- | gl/xalloc.h | 231 |
1 files changed, 92 insertions, 139 deletions
diff --git a/gl/xalloc.h b/gl/xalloc.h index da7c4b6b..7f2c3fb8 100644 --- a/gl/xalloc.h +++ b/gl/xalloc.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* xalloc.h -- malloc with out-of-memory checking | 1 | /* xalloc.h -- malloc with out-of-memory checking |
2 | 2 | ||
3 | Copyright (C) 1990-2000, 2003-2004, 2006-2013 Free Software Foundation, Inc. | 3 | Copyright (C) 1990-2000, 2003-2004, 2006-2021 Free Software Foundation, Inc. |
4 | 4 | ||
5 | This program is free software: you can redistribute it and/or modify | 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 | 6 | it under the terms of the GNU General Public License as published by |
@@ -13,57 +13,94 @@ | |||
13 | GNU General Public License for more details. | 13 | GNU General Public License for more details. |
14 | 14 | ||
15 | You should have received a copy of the GNU General Public License | 15 | You should have received a copy of the GNU General Public License |
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ |
17 | 17 | ||
18 | #ifndef XALLOC_H_ | 18 | #ifndef XALLOC_H_ |
19 | #define XALLOC_H_ | 19 | #define XALLOC_H_ |
20 | 20 | ||
21 | #include <stddef.h> | 21 | #include <stddef.h> |
22 | #include <stdlib.h> | ||
23 | #include <stdint.h> | ||
22 | 24 | ||
23 | #include "xalloc-oversized.h" | 25 | #if GNULIB_XALLOC |
26 | # include "idx.h" | ||
27 | # include "intprops.h" | ||
28 | #endif | ||
24 | 29 | ||
30 | #ifndef _GL_INLINE_HEADER_BEGIN | ||
31 | #error "Please include config.h first." | ||
32 | #endif | ||
25 | _GL_INLINE_HEADER_BEGIN | 33 | _GL_INLINE_HEADER_BEGIN |
26 | #ifndef XALLOC_INLINE | 34 | #ifndef XALLOC_INLINE |
27 | # define XALLOC_INLINE _GL_INLINE | 35 | # define XALLOC_INLINE _GL_INLINE |
28 | #endif | 36 | #endif |
29 | 37 | ||
38 | |||
30 | #ifdef __cplusplus | 39 | #ifdef __cplusplus |
31 | extern "C" { | 40 | extern "C" { |
32 | #endif | 41 | #endif |
33 | 42 | ||
34 | 43 | ||
35 | #if __GNUC__ >= 3 | 44 | #if GNULIB_XALLOC_DIE |
36 | # define _GL_ATTRIBUTE_MALLOC __attribute__ ((__malloc__)) | ||
37 | #else | ||
38 | # define _GL_ATTRIBUTE_MALLOC | ||
39 | #endif | ||
40 | |||
41 | #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) | ||
42 | # define _GL_ATTRIBUTE_ALLOC_SIZE(args) __attribute__ ((__alloc_size__ args)) | ||
43 | #else | ||
44 | # define _GL_ATTRIBUTE_ALLOC_SIZE(args) | ||
45 | #endif | ||
46 | 45 | ||
47 | /* This function is always triggered when memory is exhausted. | 46 | /* This function is always triggered when memory is exhausted. |
48 | It must be defined by the application, either explicitly | 47 | It must be defined by the application, either explicitly |
49 | or by using gnulib's xalloc-die module. This is the | 48 | or by using gnulib's xalloc-die module. This is the |
50 | function to call when one wants the program to die because of a | 49 | function to call when one wants the program to die because of a |
51 | memory allocation failure. */ | 50 | memory allocation failure. */ |
52 | extern _Noreturn void xalloc_die (void); | 51 | /*extern*/ _Noreturn void xalloc_die (void); |
52 | |||
53 | #endif /* GNULIB_XALLOC_DIE */ | ||
54 | |||
55 | #if GNULIB_XALLOC | ||
53 | 56 | ||
54 | void *xmalloc (size_t s) | 57 | void *xmalloc (size_t s) |
55 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1)); | 58 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE |
59 | _GL_ATTRIBUTE_ALLOC_SIZE ((1)) _GL_ATTRIBUTE_RETURNS_NONNULL; | ||
60 | void *ximalloc (idx_t s) | ||
61 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE | ||
62 | _GL_ATTRIBUTE_ALLOC_SIZE ((1)) _GL_ATTRIBUTE_RETURNS_NONNULL; | ||
63 | void *xinmalloc (idx_t n, idx_t s) | ||
64 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE | ||
65 | _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2)) _GL_ATTRIBUTE_RETURNS_NONNULL; | ||
56 | void *xzalloc (size_t s) | 66 | void *xzalloc (size_t s) |
57 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1)); | 67 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE |
68 | _GL_ATTRIBUTE_ALLOC_SIZE ((1)) _GL_ATTRIBUTE_RETURNS_NONNULL; | ||
69 | void *xizalloc (idx_t s) | ||
70 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE | ||
71 | _GL_ATTRIBUTE_ALLOC_SIZE ((1)) _GL_ATTRIBUTE_RETURNS_NONNULL; | ||
58 | void *xcalloc (size_t n, size_t s) | 72 | void *xcalloc (size_t n, size_t s) |
59 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2)); | 73 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE |
74 | _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2)) _GL_ATTRIBUTE_RETURNS_NONNULL; | ||
75 | void *xicalloc (idx_t n, idx_t s) | ||
76 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE | ||
77 | _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2)) _GL_ATTRIBUTE_RETURNS_NONNULL; | ||
60 | void *xrealloc (void *p, size_t s) | 78 | void *xrealloc (void *p, size_t s) |
61 | _GL_ATTRIBUTE_ALLOC_SIZE ((2)); | 79 | _GL_ATTRIBUTE_ALLOC_SIZE ((2)); |
62 | void *x2realloc (void *p, size_t *pn); | 80 | void *xirealloc (void *p, idx_t s) |
81 | _GL_ATTRIBUTE_ALLOC_SIZE ((2)) _GL_ATTRIBUTE_RETURNS_NONNULL; | ||
82 | void *xreallocarray (void *p, size_t n, size_t s) | ||
83 | _GL_ATTRIBUTE_ALLOC_SIZE ((2, 3)); | ||
84 | void *xireallocarray (void *p, idx_t n, idx_t s) | ||
85 | _GL_ATTRIBUTE_ALLOC_SIZE ((2, 3)) _GL_ATTRIBUTE_RETURNS_NONNULL; | ||
86 | void *x2realloc (void *p, size_t *ps) /* superseded by xpalloc */ | ||
87 | _GL_ATTRIBUTE_RETURNS_NONNULL; | ||
88 | void *x2nrealloc (void *p, size_t *pn, size_t s) /* superseded by xpalloc */ | ||
89 | _GL_ATTRIBUTE_RETURNS_NONNULL; | ||
90 | void *xpalloc (void *pa, idx_t *pn, idx_t n_incr_min, ptrdiff_t n_max, idx_t s) | ||
91 | _GL_ATTRIBUTE_RETURNS_NONNULL; | ||
63 | void *xmemdup (void const *p, size_t s) | 92 | void *xmemdup (void const *p, size_t s) |
64 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((2)); | 93 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE |
94 | _GL_ATTRIBUTE_ALLOC_SIZE ((2)) _GL_ATTRIBUTE_RETURNS_NONNULL; | ||
95 | void *ximemdup (void const *p, idx_t s) | ||
96 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE | ||
97 | _GL_ATTRIBUTE_ALLOC_SIZE ((2)) _GL_ATTRIBUTE_RETURNS_NONNULL; | ||
98 | char *ximemdup0 (void const *p, idx_t s) | ||
99 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE | ||
100 | _GL_ATTRIBUTE_RETURNS_NONNULL; | ||
65 | char *xstrdup (char const *str) | 101 | char *xstrdup (char const *str) |
66 | _GL_ATTRIBUTE_MALLOC; | 102 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE |
103 | _GL_ATTRIBUTE_RETURNS_NONNULL; | ||
67 | 104 | ||
68 | /* In the following macros, T must be an elementary or structure/union or | 105 | /* In the following macros, T must be an elementary or structure/union or |
69 | typedef'ed type, or a pointer to such a type. To apply one of the | 106 | typedef'ed type, or a pointer to such a type. To apply one of the |
@@ -72,153 +109,60 @@ char *xstrdup (char const *str) | |||
72 | 109 | ||
73 | /* Allocate an object of type T dynamically, with error checking. */ | 110 | /* Allocate an object of type T dynamically, with error checking. */ |
74 | /* extern t *XMALLOC (typename t); */ | 111 | /* extern t *XMALLOC (typename t); */ |
75 | #define XMALLOC(t) ((t *) xmalloc (sizeof (t))) | 112 | # define XMALLOC(t) ((t *) xmalloc (sizeof (t))) |
76 | 113 | ||
77 | /* Allocate memory for N elements of type T, with error checking. */ | 114 | /* Allocate memory for N elements of type T, with error checking. */ |
78 | /* extern t *XNMALLOC (size_t n, typename t); */ | 115 | /* extern t *XNMALLOC (size_t n, typename t); */ |
79 | #define XNMALLOC(n, t) \ | 116 | # define XNMALLOC(n, t) \ |
80 | ((t *) (sizeof (t) == 1 ? xmalloc (n) : xnmalloc (n, sizeof (t)))) | 117 | ((t *) (sizeof (t) == 1 ? xmalloc (n) : xnmalloc (n, sizeof (t)))) |
81 | 118 | ||
82 | /* Allocate an object of type T dynamically, with error checking, | 119 | /* Allocate an object of type T dynamically, with error checking, |
83 | and zero it. */ | 120 | and zero it. */ |
84 | /* extern t *XZALLOC (typename t); */ | 121 | /* extern t *XZALLOC (typename t); */ |
85 | #define XZALLOC(t) ((t *) xzalloc (sizeof (t))) | 122 | # define XZALLOC(t) ((t *) xzalloc (sizeof (t))) |
86 | 123 | ||
87 | /* Allocate memory for N elements of type T, with error checking, | 124 | /* Allocate memory for N elements of type T, with error checking, |
88 | and zero it. */ | 125 | and zero it. */ |
89 | /* extern t *XCALLOC (size_t n, typename t); */ | 126 | /* extern t *XCALLOC (size_t n, typename t); */ |
90 | #define XCALLOC(n, t) \ | 127 | # define XCALLOC(n, t) \ |
91 | ((t *) (sizeof (t) == 1 ? xzalloc (n) : xcalloc (n, sizeof (t)))) | 128 | ((t *) (sizeof (t) == 1 ? xzalloc (n) : xcalloc (n, sizeof (t)))) |
92 | 129 | ||
93 | 130 | ||
94 | /* Allocate an array of N objects, each with S bytes of memory, | 131 | /* Allocate an array of N objects, each with S bytes of memory, |
95 | dynamically, with error checking. S must be nonzero. */ | 132 | dynamically, with error checking. S must be nonzero. */ |
96 | 133 | ||
97 | XALLOC_INLINE void *xnmalloc (size_t n, size_t s) | 134 | void *xnmalloc (size_t n, size_t s) |
98 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2)); | 135 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE |
99 | XALLOC_INLINE void * | 136 | _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2)) _GL_ATTRIBUTE_RETURNS_NONNULL; |
100 | xnmalloc (size_t n, size_t s) | ||
101 | { | ||
102 | if (xalloc_oversized (n, s)) | ||
103 | xalloc_die (); | ||
104 | return xmalloc (n * s); | ||
105 | } | ||
106 | 137 | ||
138 | /* FIXME: Deprecate this in favor of xreallocarray? */ | ||
107 | /* Change the size of an allocated block of memory P to an array of N | 139 | /* Change the size of an allocated block of memory P to an array of N |
108 | objects each of S bytes, with error checking. S must be nonzero. */ | 140 | objects each of S bytes, with error checking. S must be nonzero. */ |
109 | 141 | ||
110 | XALLOC_INLINE void *xnrealloc (void *p, size_t n, size_t s) | 142 | XALLOC_INLINE void *xnrealloc (void *p, size_t n, size_t s) |
111 | _GL_ATTRIBUTE_ALLOC_SIZE ((2, 3)); | 143 | _GL_ATTRIBUTE_ALLOC_SIZE ((2, 3)); |
112 | XALLOC_INLINE void * | 144 | XALLOC_INLINE void * |
113 | xnrealloc (void *p, size_t n, size_t s) | 145 | xnrealloc (void *p, size_t n, size_t s) |
114 | { | 146 | { |
115 | if (xalloc_oversized (n, s)) | 147 | return xreallocarray (p, n, s); |
116 | xalloc_die (); | ||
117 | return xrealloc (p, n * s); | ||
118 | } | ||
119 | |||
120 | /* If P is null, allocate a block of at least *PN such objects; | ||
121 | otherwise, reallocate P so that it contains more than *PN objects | ||
122 | each of S bytes. *PN must be nonzero unless P is null, and S must | ||
123 | be nonzero. Set *PN to the new number of objects, and return the | ||
124 | pointer to the new block. *PN is never set to zero, and the | ||
125 | returned pointer is never null. | ||
126 | |||
127 | Repeated reallocations are guaranteed to make progress, either by | ||
128 | allocating an initial block with a nonzero size, or by allocating a | ||
129 | larger block. | ||
130 | |||
131 | In the following implementation, nonzero sizes are increased by a | ||
132 | factor of approximately 1.5 so that repeated reallocations have | ||
133 | O(N) overall cost rather than O(N**2) cost, but the | ||
134 | specification for this function does not guarantee that rate. | ||
135 | |||
136 | Here is an example of use: | ||
137 | |||
138 | int *p = NULL; | ||
139 | size_t used = 0; | ||
140 | size_t allocated = 0; | ||
141 | |||
142 | void | ||
143 | append_int (int value) | ||
144 | { | ||
145 | if (used == allocated) | ||
146 | p = x2nrealloc (p, &allocated, sizeof *p); | ||
147 | p[used++] = value; | ||
148 | } | ||
149 | |||
150 | This causes x2nrealloc to allocate a block of some nonzero size the | ||
151 | first time it is called. | ||
152 | |||
153 | To have finer-grained control over the initial size, set *PN to a | ||
154 | nonzero value before calling this function with P == NULL. For | ||
155 | example: | ||
156 | |||
157 | int *p = NULL; | ||
158 | size_t used = 0; | ||
159 | size_t allocated = 0; | ||
160 | size_t allocated1 = 1000; | ||
161 | |||
162 | void | ||
163 | append_int (int value) | ||
164 | { | ||
165 | if (used == allocated) | ||
166 | { | ||
167 | p = x2nrealloc (p, &allocated1, sizeof *p); | ||
168 | allocated = allocated1; | ||
169 | } | ||
170 | p[used++] = value; | ||
171 | } | ||
172 | |||
173 | */ | ||
174 | |||
175 | XALLOC_INLINE void * | ||
176 | x2nrealloc (void *p, size_t *pn, size_t s) | ||
177 | { | ||
178 | size_t n = *pn; | ||
179 | |||
180 | if (! p) | ||
181 | { | ||
182 | if (! n) | ||
183 | { | ||
184 | /* The approximate size to use for initial small allocation | ||
185 | requests, when the invoking code specifies an old size of | ||
186 | zero. This is the largest "small" request for the GNU C | ||
187 | library malloc. */ | ||
188 | enum { DEFAULT_MXFAST = 64 * sizeof (size_t) / 4 }; | ||
189 | |||
190 | n = DEFAULT_MXFAST / s; | ||
191 | n += !n; | ||
192 | } | ||
193 | } | ||
194 | else | ||
195 | { | ||
196 | /* Set N = ceil (1.5 * N) so that progress is made if N == 1. | ||
197 | Check for overflow, so that N * S stays in size_t range. | ||
198 | The check is slightly conservative, but an exact check isn't | ||
199 | worth the trouble. */ | ||
200 | if ((size_t) -1 / 3 * 2 / s <= n) | ||
201 | xalloc_die (); | ||
202 | n += (n + 1) / 2; | ||
203 | } | ||
204 | |||
205 | *pn = n; | ||
206 | return xrealloc (p, n * s); | ||
207 | } | 148 | } |
208 | 149 | ||
209 | /* Return a pointer to a new buffer of N bytes. This is like xmalloc, | 150 | /* Return a pointer to a new buffer of N bytes. This is like xmalloc, |
210 | except it returns char *. */ | 151 | except it returns char *. */ |
211 | 152 | ||
212 | XALLOC_INLINE char *xcharalloc (size_t n) | 153 | char *xcharalloc (size_t n) |
213 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1)); | 154 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE |
214 | XALLOC_INLINE char * | 155 | _GL_ATTRIBUTE_ALLOC_SIZE ((1)) _GL_ATTRIBUTE_RETURNS_NONNULL; |
215 | xcharalloc (size_t n) | 156 | |
216 | { | 157 | #endif /* GNULIB_XALLOC */ |
217 | return XNMALLOC (n, char); | 158 | |
218 | } | ||
219 | 159 | ||
220 | #ifdef __cplusplus | 160 | #ifdef __cplusplus |
221 | } | 161 | } |
162 | #endif | ||
163 | |||
164 | |||
165 | #if GNULIB_XALLOC && defined __cplusplus | ||
222 | 166 | ||
223 | /* C++ does not allow conversions from void * to other pointer types | 167 | /* C++ does not allow conversions from void * to other pointer types |
224 | without a cast. Use templates to work around the problem when | 168 | without a cast. Use templates to work around the problem when |
@@ -231,9 +175,16 @@ xrealloc (T *p, size_t s) | |||
231 | } | 175 | } |
232 | 176 | ||
233 | template <typename T> inline T * | 177 | template <typename T> inline T * |
178 | xreallocarray (T *p, size_t n, size_t s) | ||
179 | { | ||
180 | return (T *) xreallocarray ((void *) p, n, s); | ||
181 | } | ||
182 | |||
183 | /* FIXME: Deprecate this in favor of xreallocarray? */ | ||
184 | template <typename T> inline T * | ||
234 | xnrealloc (T *p, size_t n, size_t s) | 185 | xnrealloc (T *p, size_t n, size_t s) |
235 | { | 186 | { |
236 | return (T *) xnrealloc ((void *) p, n, s); | 187 | return xreallocarray (p, n, s); |
237 | } | 188 | } |
238 | 189 | ||
239 | template <typename T> inline T * | 190 | template <typename T> inline T * |
@@ -254,7 +205,9 @@ xmemdup (T const *p, size_t s) | |||
254 | return (T *) xmemdup ((void const *) p, s); | 205 | return (T *) xmemdup ((void const *) p, s); |
255 | } | 206 | } |
256 | 207 | ||
257 | #endif | 208 | #endif /* GNULIB_XALLOC && C++ */ |
209 | |||
258 | 210 | ||
211 | _GL_INLINE_HEADER_END | ||
259 | 212 | ||
260 | #endif /* !XALLOC_H_ */ | 213 | #endif /* !XALLOC_H_ */ |