aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorPaul Eggert2021-01-22 11:45:38 -0800
committerPaul Eggert2021-01-22 12:02:55 -0800
commita900e641fa1fd765799f12a7f699f768ebfccfe8 (patch)
treea874eba952d3e51190a2bfe26cfe6c1635e9fda1 /lib
parent9143eba0c6861f467c18bc52d66e6f5c573be56b (diff)
downloademacs-a900e641fa1fd765799f12a7f699f768ebfccfe8.tar.gz
emacs-a900e641fa1fd765799f12a7f699f768ebfccfe8.zip
Update from Gnulib by running admin/merge-gnulib
Diffstat (limited to 'lib')
-rw-r--r--lib/_Noreturn.h16
-rw-r--r--lib/canonicalize-lgpl.c25
-rw-r--r--lib/cdefs.h186
-rw-r--r--lib/dirent.in.h3
-rw-r--r--lib/dynarray.h31
-rw-r--r--lib/fchmodat.c17
-rw-r--r--lib/free.c14
-rw-r--r--lib/gnulib.mk.in27
-rw-r--r--lib/libc-config.h171
-rw-r--r--lib/malloc/dynarray-skeleton.c525
-rw-r--r--lib/malloc/dynarray.h178
-rw-r--r--lib/malloc/dynarray_at_failure.c35
-rw-r--r--lib/malloc/dynarray_emplace_enlarge.c73
-rw-r--r--lib/malloc/dynarray_finalize.c62
-rw-r--r--lib/malloc/dynarray_resize.c64
-rw-r--r--lib/malloc/dynarray_resize_clear.c35
-rw-r--r--lib/malloc/scratch_buffer_grow.c2
-rw-r--r--lib/malloc/scratch_buffer_grow_preserve.c2
-rw-r--r--lib/malloc/scratch_buffer_set_array_size.c2
-rw-r--r--lib/mini-gmp.c2
-rw-r--r--lib/mktime-internal.h2
-rw-r--r--lib/nstrftime.c6
-rw-r--r--lib/regex.c2
-rw-r--r--lib/regex_internal.h26
-rw-r--r--lib/regexec.c117
-rw-r--r--lib/scratch_buffer.h1
-rw-r--r--lib/stddef.in.h23
-rw-r--r--lib/string.in.h20
-rw-r--r--lib/sys_stat.in.h30
-rw-r--r--lib/tempname.c27
-rw-r--r--lib/time-internal.h2
-rw-r--r--lib/time.in.h19
-rw-r--r--lib/time_rz.c16
-rw-r--r--lib/timegm.c2
-rw-r--r--lib/utimens.c19
-rw-r--r--lib/utimensat.c101
-rw-r--r--lib/verify.h28
37 files changed, 1558 insertions, 353 deletions
diff --git a/lib/_Noreturn.h b/lib/_Noreturn.h
index 38afe1d5672..fb718bc0691 100644
--- a/lib/_Noreturn.h
+++ b/lib/_Noreturn.h
@@ -26,14 +26,16 @@
26 AIX system header files and several gnulib header files use precisely 26 AIX system header files and several gnulib header files use precisely
27 this syntax with 'extern'. */ 27 this syntax with 'extern'. */
28# define _Noreturn [[noreturn]] 28# define _Noreturn [[noreturn]]
29# elif ((!defined __cplusplus || defined __clang__) \ 29# elif ((!defined __cplusplus || defined __clang__) \
30 && (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \ 30 && (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \
31 || 4 < __GNUC__ + (7 <= __GNUC_MINOR__) \ 31 || (!defined __STRICT_ANSI__ \
32 || (defined __apple_build_version__ \ 32 && (__4 < __GNUC__ + (7 <= __GNUC_MINOR__) \
33 ? 6000000 <= __apple_build_version__ \ 33 || (defined __apple_build_version__ \
34 : 3 < __clang_major__ + (5 <= __clang_minor__)))) 34 ? 6000000 <= __apple_build_version__ \
35 : 3 < __clang_major__ + (5 <= __clang_minor__))))))
35 /* _Noreturn works as-is. */ 36 /* _Noreturn works as-is. */
36# elif 2 < __GNUC__ + (8 <= __GNUC_MINOR__) || 0x5110 <= __SUNPRO_C 37# elif (2 < __GNUC__ + (8 <= __GNUC_MINOR__) || defined __clang__ \
38 || 0x5110 <= __SUNPRO_C)
37# define _Noreturn __attribute__ ((__noreturn__)) 39# define _Noreturn __attribute__ ((__noreturn__))
38# elif 1200 <= (defined _MSC_VER ? _MSC_VER : 0) 40# elif 1200 <= (defined _MSC_VER ? _MSC_VER : 0)
39# define _Noreturn __declspec (noreturn) 41# define _Noreturn __declspec (noreturn)
diff --git a/lib/canonicalize-lgpl.c b/lib/canonicalize-lgpl.c
index b6dc3a447ab..b7dba08994d 100644
--- a/lib/canonicalize-lgpl.c
+++ b/lib/canonicalize-lgpl.c
@@ -85,10 +85,6 @@
85# define IF_LINT(Code) /* empty */ 85# define IF_LINT(Code) /* empty */
86#endif 86#endif
87 87
88/* True if adding two valid object sizes might overflow idx_t.
89 As a practical matter, this cannot happen on 64-bit machines. */
90enum { NARROW_ADDRESSES = IDX_MAX >> 31 >> 31 == 0 };
91
92#ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT 88#ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT
93# define DOUBLE_SLASH_IS_DISTINCT_ROOT false 89# define DOUBLE_SLASH_IS_DISTINCT_ROOT false
94#endif 90#endif
@@ -145,11 +141,11 @@ suffix_requires_dir_check (char const *end)
145 macOS 10.13 <https://bugs.gnu.org/30350>, and should also work on 141 macOS 10.13 <https://bugs.gnu.org/30350>, and should also work on
146 platforms like AIX 7.2 that need at least "/.". */ 142 platforms like AIX 7.2 that need at least "/.". */
147 143
148#if defined _LIBC || defined LSTAT_FOLLOWS_SLASHED_SYMLINK 144# if defined _LIBC || defined LSTAT_FOLLOWS_SLASHED_SYMLINK
149static char const dir_suffix[] = "/"; 145static char const dir_suffix[] = "/";
150#else 146# else
151static char const dir_suffix[] = "/./"; 147static char const dir_suffix[] = "/./";
152#endif 148# endif
153 149
154/* Return true if DIR is a searchable dir, false (setting errno) otherwise. 150/* Return true if DIR is a searchable dir, false (setting errno) otherwise.
155 DIREND points to the NUL byte at the end of the DIR string. 151 DIREND points to the NUL byte at the end of the DIR string.
@@ -191,13 +187,13 @@ get_path_max (void)
191 to pacify GCC is known; even an explicit #pragma does not pacify GCC. 187 to pacify GCC is known; even an explicit #pragma does not pacify GCC.
192 When the GCC bug is fixed this workaround should be limited to the 188 When the GCC bug is fixed this workaround should be limited to the
193 broken GCC versions. */ 189 broken GCC versions. */
194#if __GNUC_PREREQ (10, 1) 190# if __GNUC_PREREQ (10, 1)
195# if defined GCC_LINT || defined lint 191# if defined GCC_LINT || defined lint
196__attribute__ ((__noinline__)) 192__attribute__ ((__noinline__))
197# elif __OPTIMIZE__ && !__NO_INLINE__ 193# elif __OPTIMIZE__ && !__NO_INLINE__
198# define GCC_BOGUS_WRETURN_LOCAL_ADDR 194# define GCC_BOGUS_WRETURN_LOCAL_ADDR
195# endif
199# endif 196# endif
200#endif
201static char * 197static char *
202realpath_stk (const char *name, char *resolved, 198realpath_stk (const char *name, char *resolved,
203 struct scratch_buffer *rname_buf) 199 struct scratch_buffer *rname_buf)
@@ -343,7 +339,7 @@ realpath_stk (const char *name, char *resolved,
343 if (end_in_extra_buffer) 339 if (end_in_extra_buffer)
344 end_idx = end - extra_buf; 340 end_idx = end - extra_buf;
345 size_t len = strlen (end); 341 size_t len = strlen (end);
346 if (NARROW_ADDRESSES && INT_ADD_OVERFLOW (len, n)) 342 if (INT_ADD_OVERFLOW (len, n))
347 { 343 {
348 __set_errno (ENOMEM); 344 __set_errno (ENOMEM);
349 goto error_nomem; 345 goto error_nomem;
@@ -443,7 +439,8 @@ __realpath (const char *name, char *resolved)
443} 439}
444libc_hidden_def (__realpath) 440libc_hidden_def (__realpath)
445versioned_symbol (libc, __realpath, realpath, GLIBC_2_3); 441versioned_symbol (libc, __realpath, realpath, GLIBC_2_3);
446#endif /* !FUNC_REALPATH_WORKS || defined _LIBC */ 442
443#endif /* defined _LIBC || !FUNC_REALPATH_WORKS */
447 444
448 445
449#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_3) 446#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_3)
diff --git a/lib/cdefs.h b/lib/cdefs.h
index 2a3dc9666b9..de74f4211cf 100644
--- a/lib/cdefs.h
+++ b/lib/cdefs.h
@@ -25,7 +25,7 @@
25 25
26/* The GNU libc does not support any K&R compilers or the traditional mode 26/* The GNU libc does not support any K&R compilers or the traditional mode
27 of ISO C compilers anymore. Check for some of the combinations not 27 of ISO C compilers anymore. Check for some of the combinations not
28 anymore supported. */ 28 supported anymore. */
29#if defined __GNUC__ && !defined __STDC__ 29#if defined __GNUC__ && !defined __STDC__
30# error "You need a ISO C conforming compiler to use the glibc headers" 30# error "You need a ISO C conforming compiler to use the glibc headers"
31#endif 31#endif
@@ -34,31 +34,26 @@
34#undef __P 34#undef __P
35#undef __PMT 35#undef __PMT
36 36
37/* Compilers that are not clang may object to 37/* Compilers that lack __has_attribute may object to
38 #if defined __clang__ && __has_attribute(...) 38 #if defined __has_attribute && __has_attribute (...)
39 even though they do not need to evaluate the right-hand side of the &&. */ 39 even though they do not need to evaluate the right-hand side of the &&.
40#if defined __clang__ && defined __has_attribute 40 Similarly for __has_builtin, etc. */
41# define __glibc_clang_has_attribute(name) __has_attribute (name) 41#if (defined __has_attribute \
42 && (!defined __clang_minor__ \
43 || 3 < __clang_major__ + (5 <= __clang_minor__)))
44# define __glibc_has_attribute(attr) __has_attribute (attr)
42#else 45#else
43# define __glibc_clang_has_attribute(name) 0 46# define __glibc_has_attribute(attr) 0
44#endif 47#endif
45 48#ifdef __has_builtin
46/* Compilers that are not clang may object to 49# define __glibc_has_builtin(name) __has_builtin (name)
47 #if defined __clang__ && __has_builtin(...)
48 even though they do not need to evaluate the right-hand side of the &&. */
49#if defined __clang__ && defined __has_builtin
50# define __glibc_clang_has_builtin(name) __has_builtin (name)
51#else 50#else
52# define __glibc_clang_has_builtin(name) 0 51# define __glibc_has_builtin(name) 0
53#endif 52#endif
54 53#ifdef __has_extension
55/* Compilers that are not clang may object to 54# define __glibc_has_extension(ext) __has_extension (ext)
56 #if defined __clang__ && __has_extension(...)
57 even though they do not need to evaluate the right-hand side of the &&. */
58#if defined __clang__ && defined __has_extension
59# define __glibc_clang_has_extension(ext) __has_extension (ext)
60#else 55#else
61# define __glibc_clang_has_extension(ext) 0 56# define __glibc_has_extension(ext) 0
62#endif 57#endif
63 58
64#if defined __GNUC__ || defined __clang__ 59#if defined __GNUC__ || defined __clang__
@@ -74,22 +69,26 @@
74# endif 69# endif
75 70
76/* GCC can always grok prototypes. For C++ programs we add throw() 71/* GCC can always grok prototypes. For C++ programs we add throw()
77 to help it optimize the function calls. But this works only with 72 to help it optimize the function calls. But this only works with
78 gcc 2.8.x and egcs. For gcc 3.4 and up we even mark C functions 73 gcc 2.8.x and egcs. For gcc 3.4 and up we even mark C functions
79 as non-throwing using a function attribute since programs can use 74 as non-throwing using a function attribute since programs can use
80 the -fexceptions options for C code as well. */ 75 the -fexceptions options for C code as well. */
81# if !defined __cplusplus \ 76# if !defined __cplusplus \
82 && (__GNUC_PREREQ (3, 4) || __glibc_clang_has_attribute (__nothrow__)) 77 && (__GNUC_PREREQ (3, 4) || __glibc_has_attribute (__nothrow__))
83# define __THROW __attribute__ ((__nothrow__ __LEAF)) 78# define __THROW __attribute__ ((__nothrow__ __LEAF))
84# define __THROWNL __attribute__ ((__nothrow__)) 79# define __THROWNL __attribute__ ((__nothrow__))
85# define __NTH(fct) __attribute__ ((__nothrow__ __LEAF)) fct 80# define __NTH(fct) __attribute__ ((__nothrow__ __LEAF)) fct
86# define __NTHNL(fct) __attribute__ ((__nothrow__)) fct 81# define __NTHNL(fct) __attribute__ ((__nothrow__)) fct
87# else 82# else
88# if defined __cplusplus && (__GNUC_PREREQ (2,8) || __clang_major >= 4) 83# if defined __cplusplus && (__GNUC_PREREQ (2,8) || __clang_major >= 4)
89# define __THROW throw () 84# if __cplusplus >= 201103L
90# define __THROWNL throw () 85# define __THROW noexcept (true)
91# define __NTH(fct) __LEAF_ATTR fct throw () 86# else
92# define __NTHNL(fct) fct throw () 87# define __THROW throw ()
88# endif
89# define __THROWNL __THROW
90# define __NTH(fct) __LEAF_ATTR fct __THROW
91# define __NTHNL(fct) fct __THROW
93# else 92# else
94# define __THROW 93# define __THROW
95# define __THROWNL 94# define __THROWNL
@@ -142,24 +141,20 @@
142#define __bos(ptr) __builtin_object_size (ptr, __USE_FORTIFY_LEVEL > 1) 141#define __bos(ptr) __builtin_object_size (ptr, __USE_FORTIFY_LEVEL > 1)
143#define __bos0(ptr) __builtin_object_size (ptr, 0) 142#define __bos0(ptr) __builtin_object_size (ptr, 0)
144 143
144/* Use __builtin_dynamic_object_size at _FORTIFY_SOURCE=3 when available. */
145#if __USE_FORTIFY_LEVEL == 3 && __glibc_clang_prereq (9, 0)
146# define __glibc_objsize0(__o) __builtin_dynamic_object_size (__o, 0)
147# define __glibc_objsize(__o) __builtin_dynamic_object_size (__o, 1)
148#else
149# define __glibc_objsize0(__o) __bos0 (__o)
150# define __glibc_objsize(__o) __bos (__o)
151#endif
152
145#if __GNUC_PREREQ (4,3) 153#if __GNUC_PREREQ (4,3)
146# define __warndecl(name, msg) \
147 extern void name (void) __attribute__((__warning__ (msg)))
148# define __warnattr(msg) __attribute__((__warning__ (msg))) 154# define __warnattr(msg) __attribute__((__warning__ (msg)))
149# define __errordecl(name, msg) \ 155# define __errordecl(name, msg) \
150 extern void name (void) __attribute__((__error__ (msg))) 156 extern void name (void) __attribute__((__error__ (msg)))
151#elif __glibc_clang_has_attribute (__diagnose_if__) && 0
152/* These definitions are not enabled, because they produce bogus warnings
153 in the glibc Fortify functions. These functions are written in a style
154 that works with GCC. In order to work with clang, these functions would
155 need to be modified. */
156# define __warndecl(name, msg) \
157 extern void name (void) __attribute__((__diagnose_if__ (1, msg, "warning")))
158# define __warnattr(msg) __attribute__((__diagnose_if__ (1, msg, "warning")))
159# define __errordecl(name, msg) \
160 extern void name (void) __attribute__((__diagnose_if__ (1, msg, "error")))
161#else 157#else
162# define __warndecl(name, msg) extern void name (void)
163# define __warnattr(msg) 158# define __warnattr(msg)
164# define __errordecl(name, msg) extern void name (void) 159# define __errordecl(name, msg) extern void name (void)
165#endif 160#endif
@@ -233,7 +228,7 @@
233/* At some point during the gcc 2.96 development the `malloc' attribute 228/* At some point during the gcc 2.96 development the `malloc' attribute
234 for functions was introduced. We don't want to use it unconditionally 229 for functions was introduced. We don't want to use it unconditionally
235 (although this would be possible) since it generates warnings. */ 230 (although this would be possible) since it generates warnings. */
236#if __GNUC_PREREQ (2,96) || __glibc_clang_has_attribute (__malloc__) 231#if __GNUC_PREREQ (2,96) || __glibc_has_attribute (__malloc__)
237# define __attribute_malloc__ __attribute__ ((__malloc__)) 232# define __attribute_malloc__ __attribute__ ((__malloc__))
238#else 233#else
239# define __attribute_malloc__ /* Ignore */ 234# define __attribute_malloc__ /* Ignore */
@@ -251,23 +246,31 @@
251/* At some point during the gcc 2.96 development the `pure' attribute 246/* At some point during the gcc 2.96 development the `pure' attribute
252 for functions was introduced. We don't want to use it unconditionally 247 for functions was introduced. We don't want to use it unconditionally
253 (although this would be possible) since it generates warnings. */ 248 (although this would be possible) since it generates warnings. */
254#if __GNUC_PREREQ (2,96) || __glibc_clang_has_attribute (__pure__) 249#if __GNUC_PREREQ (2,96) || __glibc_has_attribute (__pure__)
255# define __attribute_pure__ __attribute__ ((__pure__)) 250# define __attribute_pure__ __attribute__ ((__pure__))
256#else 251#else
257# define __attribute_pure__ /* Ignore */ 252# define __attribute_pure__ /* Ignore */
258#endif 253#endif
259 254
260/* This declaration tells the compiler that the value is constant. */ 255/* This declaration tells the compiler that the value is constant. */
261#if __GNUC_PREREQ (2,5) || __glibc_clang_has_attribute (__const__) 256#if __GNUC_PREREQ (2,5) || __glibc_has_attribute (__const__)
262# define __attribute_const__ __attribute__ ((__const__)) 257# define __attribute_const__ __attribute__ ((__const__))
263#else 258#else
264# define __attribute_const__ /* Ignore */ 259# define __attribute_const__ /* Ignore */
265#endif 260#endif
266 261
262#if defined __STDC_VERSION__ && 201710L < __STDC_VERSION__
263# define __attribute_maybe_unused__ [[__maybe_unused__]]
264#elif __GNUC_PREREQ (2,7) || __glibc_has_attribute (__unused__)
265# define __attribute_maybe_unused__ __attribute__ ((__unused__))
266#else
267# define __attribute_maybe_unused__ /* Ignore */
268#endif
269
267/* At some point during the gcc 3.1 development the `used' attribute 270/* At some point during the gcc 3.1 development the `used' attribute
268 for functions was introduced. We don't want to use it unconditionally 271 for functions was introduced. We don't want to use it unconditionally
269 (although this would be possible) since it generates warnings. */ 272 (although this would be possible) since it generates warnings. */
270#if __GNUC_PREREQ (3,1) || __glibc_clang_has_attribute (__used__) 273#if __GNUC_PREREQ (3,1) || __glibc_has_attribute (__used__)
271# define __attribute_used__ __attribute__ ((__used__)) 274# define __attribute_used__ __attribute__ ((__used__))
272# define __attribute_noinline__ __attribute__ ((__noinline__)) 275# define __attribute_noinline__ __attribute__ ((__noinline__))
273#else 276#else
@@ -276,7 +279,7 @@
276#endif 279#endif
277 280
278/* Since version 3.2, gcc allows marking deprecated functions. */ 281/* Since version 3.2, gcc allows marking deprecated functions. */
279#if __GNUC_PREREQ (3,2) || __glibc_clang_has_attribute (__deprecated__) 282#if __GNUC_PREREQ (3,2) || __glibc_has_attribute (__deprecated__)
280# define __attribute_deprecated__ __attribute__ ((__deprecated__)) 283# define __attribute_deprecated__ __attribute__ ((__deprecated__))
281#else 284#else
282# define __attribute_deprecated__ /* Ignore */ 285# define __attribute_deprecated__ /* Ignore */
@@ -285,8 +288,8 @@
285/* Since version 4.5, gcc also allows one to specify the message printed 288/* Since version 4.5, gcc also allows one to specify the message printed
286 when a deprecated function is used. clang claims to be gcc 4.2, but 289 when a deprecated function is used. clang claims to be gcc 4.2, but
287 may also support this feature. */ 290 may also support this feature. */
288#if __GNUC_PREREQ (4,5) || \ 291#if __GNUC_PREREQ (4,5) \
289 __glibc_clang_has_extension (__attribute_deprecated_with_message__) 292 || __glibc_has_extension (__attribute_deprecated_with_message__)
290# define __attribute_deprecated_msg__(msg) \ 293# define __attribute_deprecated_msg__(msg) \
291 __attribute__ ((__deprecated__ (msg))) 294 __attribute__ ((__deprecated__ (msg)))
292#else 295#else
@@ -299,7 +302,7 @@
299 If several `format_arg' attributes are given for the same function, in 302 If several `format_arg' attributes are given for the same function, in
300 gcc-3.0 and older, all but the last one are ignored. In newer gccs, 303 gcc-3.0 and older, all but the last one are ignored. In newer gccs,
301 all designated arguments are considered. */ 304 all designated arguments are considered. */
302#if __GNUC_PREREQ (2,8) || __glibc_clang_has_attribute (__format_arg__) 305#if __GNUC_PREREQ (2,8) || __glibc_has_attribute (__format_arg__)
303# define __attribute_format_arg__(x) __attribute__ ((__format_arg__ (x))) 306# define __attribute_format_arg__(x) __attribute__ ((__format_arg__ (x)))
304#else 307#else
305# define __attribute_format_arg__(x) /* Ignore */ 308# define __attribute_format_arg__(x) /* Ignore */
@@ -309,7 +312,7 @@
309 attribute for functions was introduced. We don't want to use it 312 attribute for functions was introduced. We don't want to use it
310 unconditionally (although this would be possible) since it 313 unconditionally (although this would be possible) since it
311 generates warnings. */ 314 generates warnings. */
312#if __GNUC_PREREQ (2,97) || __glibc_clang_has_attribute (__format__) 315#if __GNUC_PREREQ (2,97) || __glibc_has_attribute (__format__)
313# define __attribute_format_strfmon__(a,b) \ 316# define __attribute_format_strfmon__(a,b) \
314 __attribute__ ((__format__ (__strfmon__, a, b))) 317 __attribute__ ((__format__ (__strfmon__, a, b)))
315#else 318#else
@@ -320,7 +323,7 @@
320 must not be NULL. Do not define __nonnull if it is already defined, 323 must not be NULL. Do not define __nonnull if it is already defined,
321 for portability when this file is used in Gnulib. */ 324 for portability when this file is used in Gnulib. */
322#ifndef __nonnull 325#ifndef __nonnull
323# if __GNUC_PREREQ (3,3) || __glibc_clang_has_attribute (__nonnull__) 326# if __GNUC_PREREQ (3,3) || __glibc_has_attribute (__nonnull__)
324# define __nonnull(params) __attribute__ ((__nonnull__ params)) 327# define __nonnull(params) __attribute__ ((__nonnull__ params))
325# else 328# else
326# define __nonnull(params) 329# define __nonnull(params)
@@ -329,7 +332,7 @@
329 332
330/* If fortification mode, we warn about unused results of certain 333/* If fortification mode, we warn about unused results of certain
331 function calls which can lead to problems. */ 334 function calls which can lead to problems. */
332#if __GNUC_PREREQ (3,4) || __glibc_clang_has_attribute (__warn_unused_result__) 335#if __GNUC_PREREQ (3,4) || __glibc_has_attribute (__warn_unused_result__)
333# define __attribute_warn_unused_result__ \ 336# define __attribute_warn_unused_result__ \
334 __attribute__ ((__warn_unused_result__)) 337 __attribute__ ((__warn_unused_result__))
335# if defined __USE_FORTIFY_LEVEL && __USE_FORTIFY_LEVEL > 0 338# if defined __USE_FORTIFY_LEVEL && __USE_FORTIFY_LEVEL > 0
@@ -343,7 +346,7 @@
343#endif 346#endif
344 347
345/* Forces a function to be always inlined. */ 348/* Forces a function to be always inlined. */
346#if __GNUC_PREREQ (3,2) || __glibc_clang_has_attribute (__always_inline__) 349#if __GNUC_PREREQ (3,2) || __glibc_has_attribute (__always_inline__)
347/* The Linux kernel defines __always_inline in stddef.h (283d7573), and 350/* The Linux kernel defines __always_inline in stddef.h (283d7573), and
348 it conflicts with this definition. Therefore undefine it first to 351 it conflicts with this definition. Therefore undefine it first to
349 allow either header to be included first. */ 352 allow either header to be included first. */
@@ -356,7 +359,7 @@
356 359
357/* Associate error messages with the source location of the call site rather 360/* Associate error messages with the source location of the call site rather
358 than with the source location inside the function. */ 361 than with the source location inside the function. */
359#if __GNUC_PREREQ (4,3) || __glibc_clang_has_attribute (__artificial__) 362#if __GNUC_PREREQ (4,3) || __glibc_has_attribute (__artificial__)
360# define __attribute_artificial__ __attribute__ ((__artificial__)) 363# define __attribute_artificial__ __attribute__ ((__artificial__))
361#else 364#else
362# define __attribute_artificial__ /* Ignore */ 365# define __attribute_artificial__ /* Ignore */
@@ -433,7 +436,7 @@
433# endif 436# endif
434#endif 437#endif
435 438
436#if (__GNUC__ >= 3) || __glibc_clang_has_builtin (__builtin_expect) 439#if (__GNUC__ >= 3) || __glibc_has_builtin (__builtin_expect)
437# define __glibc_unlikely(cond) __builtin_expect ((cond), 0) 440# define __glibc_unlikely(cond) __builtin_expect ((cond), 0)
438# define __glibc_likely(cond) __builtin_expect ((cond), 1) 441# define __glibc_likely(cond) __builtin_expect ((cond), 1)
439#else 442#else
@@ -441,12 +444,6 @@
441# define __glibc_likely(cond) (cond) 444# define __glibc_likely(cond) (cond)
442#endif 445#endif
443 446
444#ifdef __has_attribute
445# define __glibc_has_attribute(attr) __has_attribute (attr)
446#else
447# define __glibc_has_attribute(attr) 0
448#endif
449
450#if (!defined _Noreturn \ 447#if (!defined _Noreturn \
451 && (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \ 448 && (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \
452 && !(__GNUC_PREREQ (4,7) \ 449 && !(__GNUC_PREREQ (4,7) \
@@ -467,6 +464,16 @@
467# define __attribute_nonstring__ 464# define __attribute_nonstring__
468#endif 465#endif
469 466
467/* Undefine (also defined in libc-symbols.h). */
468#undef __attribute_copy__
469#if __GNUC_PREREQ (9, 0)
470/* Copies attributes from the declaration or type referenced by
471 the argument. */
472# define __attribute_copy__(arg) __attribute__ ((__copy__ (arg)))
473#else
474# define __attribute_copy__(arg)
475#endif
476
470#if (!defined _Static_assert && !defined __cplusplus \ 477#if (!defined _Static_assert && !defined __cplusplus \
471 && (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \ 478 && (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \
472 && (!(__GNUC_PREREQ (4, 6) || __clang_major__ >= 4) \ 479 && (!(__GNUC_PREREQ (4, 6) || __clang_major__ >= 4) \
@@ -483,7 +490,37 @@
483# include <bits/long-double.h> 490# include <bits/long-double.h>
484#endif 491#endif
485 492
486#if defined __LONG_DOUBLE_MATH_OPTIONAL && defined __NO_LONG_DOUBLE_MATH 493#if __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1
494# ifdef __REDIRECT
495
496/* Alias name defined automatically. */
497# define __LDBL_REDIR(name, proto) ... unused__ldbl_redir
498# define __LDBL_REDIR_DECL(name) \
499 extern __typeof (name) name __asm (__ASMNAME ("__" #name "ieee128"));
500
501/* Alias name defined automatically, with leading underscores. */
502# define __LDBL_REDIR2_DECL(name) \
503 extern __typeof (__##name) __##name \
504 __asm (__ASMNAME ("__" #name "ieee128"));
505
506/* Alias name defined manually. */
507# define __LDBL_REDIR1(name, proto, alias) ... unused__ldbl_redir1
508# define __LDBL_REDIR1_DECL(name, alias) \
509 extern __typeof (name) name __asm (__ASMNAME (#alias));
510
511# define __LDBL_REDIR1_NTH(name, proto, alias) \
512 __REDIRECT_NTH (name, proto, alias)
513# define __REDIRECT_NTH_LDBL(name, proto, alias) \
514 __LDBL_REDIR1_NTH (name, proto, __##alias##ieee128)
515
516/* Unused. */
517# define __REDIRECT_LDBL(name, proto, alias) ... unused__redirect_ldbl
518# define __LDBL_REDIR_NTH(name, proto) ... unused__ldbl_redir_nth
519
520# else
521_Static_assert (0, "IEEE 128-bits long double requires redirection on this platform");
522# endif
523#elif defined __LONG_DOUBLE_MATH_OPTIONAL && defined __NO_LONG_DOUBLE_MATH
487# define __LDBL_COMPAT 1 524# define __LDBL_COMPAT 1
488# ifdef __REDIRECT 525# ifdef __REDIRECT
489# define __LDBL_REDIR1(name, proto, alias) __REDIRECT (name, proto, alias) 526# define __LDBL_REDIR1(name, proto, alias) __REDIRECT (name, proto, alias)
@@ -492,6 +529,8 @@
492# define __LDBL_REDIR1_NTH(name, proto, alias) __REDIRECT_NTH (name, proto, alias) 529# define __LDBL_REDIR1_NTH(name, proto, alias) __REDIRECT_NTH (name, proto, alias)
493# define __LDBL_REDIR_NTH(name, proto) \ 530# define __LDBL_REDIR_NTH(name, proto) \
494 __LDBL_REDIR1_NTH (name, proto, __nldbl_##name) 531 __LDBL_REDIR1_NTH (name, proto, __nldbl_##name)
532# define __LDBL_REDIR2_DECL(name) \
533 extern __typeof (__##name) __##name __asm (__ASMNAME ("__nldbl___" #name));
495# define __LDBL_REDIR1_DECL(name, alias) \ 534# define __LDBL_REDIR1_DECL(name, alias) \
496 extern __typeof (name) name __asm (__ASMNAME (#alias)); 535 extern __typeof (name) name __asm (__ASMNAME (#alias));
497# define __LDBL_REDIR_DECL(name) \ 536# define __LDBL_REDIR_DECL(name) \
@@ -502,11 +541,13 @@
502 __LDBL_REDIR1_NTH (name, proto, __nldbl_##alias) 541 __LDBL_REDIR1_NTH (name, proto, __nldbl_##alias)
503# endif 542# endif
504#endif 543#endif
505#if !defined __LDBL_COMPAT || !defined __REDIRECT 544#if (!defined __LDBL_COMPAT && __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 0) \
545 || !defined __REDIRECT
506# define __LDBL_REDIR1(name, proto, alias) name proto 546# define __LDBL_REDIR1(name, proto, alias) name proto
507# define __LDBL_REDIR(name, proto) name proto 547# define __LDBL_REDIR(name, proto) name proto
508# define __LDBL_REDIR1_NTH(name, proto, alias) name proto __THROW 548# define __LDBL_REDIR1_NTH(name, proto, alias) name proto __THROW
509# define __LDBL_REDIR_NTH(name, proto) name proto __THROW 549# define __LDBL_REDIR_NTH(name, proto) name proto __THROW
550# define __LDBL_REDIR2_DECL(name)
510# define __LDBL_REDIR_DECL(name) 551# define __LDBL_REDIR_DECL(name)
511# ifdef __REDIRECT 552# ifdef __REDIRECT
512# define __REDIRECT_LDBL(name, proto, alias) __REDIRECT (name, proto, alias) 553# define __REDIRECT_LDBL(name, proto, alias) __REDIRECT (name, proto, alias)
@@ -537,7 +578,7 @@
537 check is required to enable the use of generic selection. */ 578 check is required to enable the use of generic selection. */
538#if !defined __cplusplus \ 579#if !defined __cplusplus \
539 && (__GNUC_PREREQ (4, 9) \ 580 && (__GNUC_PREREQ (4, 9) \
540 || __glibc_clang_has_extension (c_generic_selections) \ 581 || __glibc_has_extension (c_generic_selections) \
541 || (!defined __GNUC__ && defined __STDC_VERSION__ \ 582 || (!defined __GNUC__ && defined __STDC_VERSION__ \
542 && __STDC_VERSION__ >= 201112L)) 583 && __STDC_VERSION__ >= 201112L))
543# define __HAVE_GENERIC_SELECTION 1 584# define __HAVE_GENERIC_SELECTION 1
@@ -545,4 +586,23 @@
545# define __HAVE_GENERIC_SELECTION 0 586# define __HAVE_GENERIC_SELECTION 0
546#endif 587#endif
547 588
589#if __GNUC_PREREQ (10, 0)
590/* Designates a 1-based positional argument ref-index of pointer type
591 that can be used to access size-index elements of the pointed-to
592 array according to access mode, or at least one element when
593 size-index is not provided:
594 access (access-mode, <ref-index> [, <size-index>]) */
595#define __attr_access(x) __attribute__ ((__access__ x))
596#else
597# define __attr_access(x)
598#endif
599
600/* Specify that a function such as setjmp or vfork may return
601 twice. */
602#if __GNUC_PREREQ (4, 1)
603# define __attribute_returns_twice__ __attribute__ ((__returns_twice__))
604#else
605# define __attribute_returns_twice__ /* Ignore. */
606#endif
607
548#endif /* sys/cdefs.h */ 608#endif /* sys/cdefs.h */
diff --git a/lib/dirent.in.h b/lib/dirent.in.h
index 2e2c5119a11..4666972b150 100644
--- a/lib/dirent.in.h
+++ b/lib/dirent.in.h
@@ -154,7 +154,8 @@ _GL_WARN_ON_USE (closedir, "closedir is not portable - "
154/* Return the file descriptor associated with the given directory stream, 154/* Return the file descriptor associated with the given directory stream,
155 or -1 if none exists. */ 155 or -1 if none exists. */
156# if @REPLACE_DIRFD@ 156# if @REPLACE_DIRFD@
157# if !(defined __cplusplus && defined GNULIB_NAMESPACE) 157/* On kLIBC, dirfd() is a macro that does not work. Undefine it. */
158# if !(defined __cplusplus && defined GNULIB_NAMESPACE) || defined dirfd
158# undef dirfd 159# undef dirfd
159# define dirfd rpl_dirfd 160# define dirfd rpl_dirfd
160# endif 161# endif
diff --git a/lib/dynarray.h b/lib/dynarray.h
new file mode 100644
index 00000000000..6da3e87e55f
--- /dev/null
+++ b/lib/dynarray.h
@@ -0,0 +1,31 @@
1/* Type-safe arrays which grow dynamically.
2 Copyright 2021 Free Software Foundation, Inc.
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
16
17/* Written by Paul Eggert, 2021. */
18
19#ifndef _GL_DYNARRAY_H
20#define _GL_DYNARRAY_H
21
22#include <libc-config.h>
23
24#define __libc_dynarray_at_failure gl_dynarray_at_failure
25#define __libc_dynarray_emplace_enlarge gl_dynarray_emplace_enlarge
26#define __libc_dynarray_finalize gl_dynarray_finalize
27#define __libc_dynarray_resize_clear gl_dynarray_resize_clear
28#define __libc_dynarray_resize gl_dynarray_resize
29#include <malloc/dynarray.h>
30
31#endif /* _GL_DYNARRAY_H */
diff --git a/lib/fchmodat.c b/lib/fchmodat.c
index d27c0d7734a..eb6e2242fdd 100644
--- a/lib/fchmodat.c
+++ b/lib/fchmodat.c
@@ -38,6 +38,7 @@ orig_fchmodat (int dir, char const *file, mode_t mode, int flags)
38#include <fcntl.h> 38#include <fcntl.h>
39#include <stdio.h> 39#include <stdio.h>
40#include <stdlib.h> 40#include <stdlib.h>
41#include <string.h>
41#include <unistd.h> 42#include <unistd.h>
42 43
43#ifdef __osf__ 44#ifdef __osf__
@@ -63,6 +64,22 @@ orig_fchmodat (int dir, char const *file, mode_t mode, int flags)
63int 64int
64fchmodat (int dir, char const *file, mode_t mode, int flags) 65fchmodat (int dir, char const *file, mode_t mode, int flags)
65{ 66{
67# if HAVE_NEARLY_WORKING_FCHMODAT
68 /* Correct the trailing slash handling. */
69 size_t len = strlen (file);
70 if (len && file[len - 1] == '/')
71 {
72 struct stat st;
73 if (fstatat (dir, file, &st, flags & AT_SYMLINK_NOFOLLOW) < 0)
74 return -1;
75 if (!S_ISDIR (st.st_mode))
76 {
77 errno = ENOTDIR;
78 return -1;
79 }
80 }
81# endif
82
66# if NEED_FCHMODAT_NONSYMLINK_FIX 83# if NEED_FCHMODAT_NONSYMLINK_FIX
67 if (flags == AT_SYMLINK_NOFOLLOW) 84 if (flags == AT_SYMLINK_NOFOLLOW)
68 { 85 {
diff --git a/lib/free.c b/lib/free.c
index 135c3eb16bc..5c89787aba1 100644
--- a/lib/free.c
+++ b/lib/free.c
@@ -27,7 +27,21 @@ void
27rpl_free (void *p) 27rpl_free (void *p)
28#undef free 28#undef free
29{ 29{
30#if defined __GNUC__ && !defined __clang__
31 /* An invalid GCC optimization
32 <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98396>
33 would optimize away the assignments in the code below, when link-time
34 optimization (LTO) is enabled. Make the code more complicated, so that
35 GCC does not grok how to optimize it. */
36 int err[2];
37 err[0] = errno;
38 err[1] = errno;
39 errno = 0;
40 free (p);
41 errno = err[errno == 0];
42#else
30 int err = errno; 43 int err = errno;
31 free (p); 44 free (p);
32 errno = err; 45 errno = err;
46#endif
33} 47}
diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in
index c457ac61209..07736f9b8bc 100644
--- a/lib/gnulib.mk.in
+++ b/lib/gnulib.mk.in
@@ -516,6 +516,7 @@ GNULIB_SYMLINK = @GNULIB_SYMLINK@
516GNULIB_SYMLINKAT = @GNULIB_SYMLINKAT@ 516GNULIB_SYMLINKAT = @GNULIB_SYMLINKAT@
517GNULIB_SYSTEM_POSIX = @GNULIB_SYSTEM_POSIX@ 517GNULIB_SYSTEM_POSIX = @GNULIB_SYSTEM_POSIX@
518GNULIB_TIMEGM = @GNULIB_TIMEGM@ 518GNULIB_TIMEGM = @GNULIB_TIMEGM@
519GNULIB_TIMESPEC_GET = @GNULIB_TIMESPEC_GET@
519GNULIB_TIME_R = @GNULIB_TIME_R@ 520GNULIB_TIME_R = @GNULIB_TIME_R@
520GNULIB_TIME_RZ = @GNULIB_TIME_RZ@ 521GNULIB_TIME_RZ = @GNULIB_TIME_RZ@
521GNULIB_TMPFILE = @GNULIB_TMPFILE@ 522GNULIB_TMPFILE = @GNULIB_TMPFILE@
@@ -746,6 +747,7 @@ HAVE_SYS_SELECT_H = @HAVE_SYS_SELECT_H@
746HAVE_SYS_TIME_H = @HAVE_SYS_TIME_H@ 747HAVE_SYS_TIME_H = @HAVE_SYS_TIME_H@
747HAVE_SYS_TYPES_H = @HAVE_SYS_TYPES_H@ 748HAVE_SYS_TYPES_H = @HAVE_SYS_TYPES_H@
748HAVE_TIMEGM = @HAVE_TIMEGM@ 749HAVE_TIMEGM = @HAVE_TIMEGM@
750HAVE_TIMESPEC_GET = @HAVE_TIMESPEC_GET@
749HAVE_TIMEZONE_T = @HAVE_TIMEZONE_T@ 751HAVE_TIMEZONE_T = @HAVE_TIMEZONE_T@
750HAVE_TYPE_VOLATILE_SIG_ATOMIC_T = @HAVE_TYPE_VOLATILE_SIG_ATOMIC_T@ 752HAVE_TYPE_VOLATILE_SIG_ATOMIC_T = @HAVE_TYPE_VOLATILE_SIG_ATOMIC_T@
751HAVE_UNISTD_H = @HAVE_UNISTD_H@ 753HAVE_UNISTD_H = @HAVE_UNISTD_H@
@@ -949,6 +951,7 @@ REPLACE_FCNTL = @REPLACE_FCNTL@
949REPLACE_FDOPEN = @REPLACE_FDOPEN@ 951REPLACE_FDOPEN = @REPLACE_FDOPEN@
950REPLACE_FDOPENDIR = @REPLACE_FDOPENDIR@ 952REPLACE_FDOPENDIR = @REPLACE_FDOPENDIR@
951REPLACE_FFLUSH = @REPLACE_FFLUSH@ 953REPLACE_FFLUSH = @REPLACE_FFLUSH@
954REPLACE_FFSLL = @REPLACE_FFSLL@
952REPLACE_FOPEN = @REPLACE_FOPEN@ 955REPLACE_FOPEN = @REPLACE_FOPEN@
953REPLACE_FPRINTF = @REPLACE_FPRINTF@ 956REPLACE_FPRINTF = @REPLACE_FPRINTF@
954REPLACE_FPURGE = @REPLACE_FPURGE@ 957REPLACE_FPURGE = @REPLACE_FPURGE@
@@ -989,7 +992,9 @@ REPLACE_MEMCHR = @REPLACE_MEMCHR@
989REPLACE_MEMMEM = @REPLACE_MEMMEM@ 992REPLACE_MEMMEM = @REPLACE_MEMMEM@
990REPLACE_MKDIR = @REPLACE_MKDIR@ 993REPLACE_MKDIR = @REPLACE_MKDIR@
991REPLACE_MKFIFO = @REPLACE_MKFIFO@ 994REPLACE_MKFIFO = @REPLACE_MKFIFO@
995REPLACE_MKFIFOAT = @REPLACE_MKFIFOAT@
992REPLACE_MKNOD = @REPLACE_MKNOD@ 996REPLACE_MKNOD = @REPLACE_MKNOD@
997REPLACE_MKNODAT = @REPLACE_MKNODAT@
993REPLACE_MKSTEMP = @REPLACE_MKSTEMP@ 998REPLACE_MKSTEMP = @REPLACE_MKSTEMP@
994REPLACE_MKTIME = @REPLACE_MKTIME@ 999REPLACE_MKTIME = @REPLACE_MKTIME@
995REPLACE_NANOSLEEP = @REPLACE_NANOSLEEP@ 1000REPLACE_NANOSLEEP = @REPLACE_NANOSLEEP@
@@ -1087,6 +1092,7 @@ SYSTEM_TYPE = @SYSTEM_TYPE@
1087SYS_TIME_H_DEFINES_STRUCT_TIMESPEC = @SYS_TIME_H_DEFINES_STRUCT_TIMESPEC@ 1092SYS_TIME_H_DEFINES_STRUCT_TIMESPEC = @SYS_TIME_H_DEFINES_STRUCT_TIMESPEC@
1088TERMCAP_OBJ = @TERMCAP_OBJ@ 1093TERMCAP_OBJ = @TERMCAP_OBJ@
1089TIME_H_DEFINES_STRUCT_TIMESPEC = @TIME_H_DEFINES_STRUCT_TIMESPEC@ 1094TIME_H_DEFINES_STRUCT_TIMESPEC = @TIME_H_DEFINES_STRUCT_TIMESPEC@
1095TIME_H_DEFINES_TIME_UTC = @TIME_H_DEFINES_TIME_UTC@
1090TOOLKIT_LIBW = @TOOLKIT_LIBW@ 1096TOOLKIT_LIBW = @TOOLKIT_LIBW@
1091UINT32_MAX_LT_UINTMAX_MAX = @UINT32_MAX_LT_UINTMAX_MAX@ 1097UINT32_MAX_LT_UINTMAX_MAX = @UINT32_MAX_LT_UINTMAX_MAX@
1092UINT64_MAX_EQ_ULONG_MAX = @UINT64_MAX_EQ_ULONG_MAX@ 1098UINT64_MAX_EQ_ULONG_MAX = @UINT64_MAX_EQ_ULONG_MAX@
@@ -1171,6 +1177,7 @@ gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1 = @gl_GNULIB_ENABLED_a9786850
1171gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36 = @gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36@ 1177gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36 = @gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36@
1172gl_GNULIB_ENABLED_cloexec = @gl_GNULIB_ENABLED_cloexec@ 1178gl_GNULIB_ENABLED_cloexec = @gl_GNULIB_ENABLED_cloexec@
1173gl_GNULIB_ENABLED_dirfd = @gl_GNULIB_ENABLED_dirfd@ 1179gl_GNULIB_ENABLED_dirfd = @gl_GNULIB_ENABLED_dirfd@
1180gl_GNULIB_ENABLED_dynarray = @gl_GNULIB_ENABLED_dynarray@
1174gl_GNULIB_ENABLED_euidaccess = @gl_GNULIB_ENABLED_euidaccess@ 1181gl_GNULIB_ENABLED_euidaccess = @gl_GNULIB_ENABLED_euidaccess@
1175gl_GNULIB_ENABLED_getdtablesize = @gl_GNULIB_ENABLED_getdtablesize@ 1182gl_GNULIB_ENABLED_getdtablesize = @gl_GNULIB_ENABLED_getdtablesize@
1176gl_GNULIB_ENABLED_getgroups = @gl_GNULIB_ENABLED_getgroups@ 1183gl_GNULIB_ENABLED_getgroups = @gl_GNULIB_ENABLED_getgroups@
@@ -1584,6 +1591,20 @@ EXTRA_libgnu_a_SOURCES += dup2.c
1584endif 1591endif
1585## end gnulib module dup2 1592## end gnulib module dup2
1586 1593
1594## begin gnulib module dynarray
1595ifeq (,$(OMIT_GNULIB_MODULE_dynarray))
1596
1597ifneq (,$(gl_GNULIB_ENABLED_dynarray))
1598libgnu_a_SOURCES += malloc/dynarray_at_failure.c malloc/dynarray_emplace_enlarge.c malloc/dynarray_finalize.c malloc/dynarray_resize.c malloc/dynarray_resize_clear.c
1599
1600endif
1601EXTRA_DIST += dynarray.h malloc/dynarray-skeleton.c malloc/dynarray.h
1602
1603EXTRA_libgnu_a_SOURCES += malloc/dynarray-skeleton.c
1604
1605endif
1606## end gnulib module dynarray
1607
1587## begin gnulib module eloop-threshold 1608## begin gnulib module eloop-threshold
1588ifeq (,$(OMIT_GNULIB_MODULE_eloop-threshold)) 1609ifeq (,$(OMIT_GNULIB_MODULE_eloop-threshold))
1589 1610
@@ -3036,6 +3057,7 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
3036 -e 's|@''HAVE_SIGDESCR_NP''@|$(HAVE_SIGDESCR_NP)|g' \ 3057 -e 's|@''HAVE_SIGDESCR_NP''@|$(HAVE_SIGDESCR_NP)|g' \
3037 -e 's|@''HAVE_DECL_STRSIGNAL''@|$(HAVE_DECL_STRSIGNAL)|g' \ 3058 -e 's|@''HAVE_DECL_STRSIGNAL''@|$(HAVE_DECL_STRSIGNAL)|g' \
3038 -e 's|@''HAVE_STRVERSCMP''@|$(HAVE_STRVERSCMP)|g' \ 3059 -e 's|@''HAVE_STRVERSCMP''@|$(HAVE_STRVERSCMP)|g' \
3060 -e 's|@''REPLACE_FFSLL''@|$(REPLACE_FFSLL)|g' \
3039 -e 's|@''REPLACE_MEMCHR''@|$(REPLACE_MEMCHR)|g' \ 3061 -e 's|@''REPLACE_MEMCHR''@|$(REPLACE_MEMCHR)|g' \
3040 -e 's|@''REPLACE_MEMMEM''@|$(REPLACE_MEMMEM)|g' \ 3062 -e 's|@''REPLACE_MEMMEM''@|$(REPLACE_MEMMEM)|g' \
3041 -e 's|@''REPLACE_STPNCPY''@|$(REPLACE_STPNCPY)|g' \ 3063 -e 's|@''REPLACE_STPNCPY''@|$(REPLACE_STPNCPY)|g' \
@@ -3237,7 +3259,9 @@ sys/stat.h: sys_stat.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNU
3237 -e 's|@''REPLACE_LSTAT''@|$(REPLACE_LSTAT)|g' \ 3259 -e 's|@''REPLACE_LSTAT''@|$(REPLACE_LSTAT)|g' \
3238 -e 's|@''REPLACE_MKDIR''@|$(REPLACE_MKDIR)|g' \ 3260 -e 's|@''REPLACE_MKDIR''@|$(REPLACE_MKDIR)|g' \
3239 -e 's|@''REPLACE_MKFIFO''@|$(REPLACE_MKFIFO)|g' \ 3261 -e 's|@''REPLACE_MKFIFO''@|$(REPLACE_MKFIFO)|g' \
3262 -e 's|@''REPLACE_MKFIFOAT''@|$(REPLACE_MKFIFOAT)|g' \
3240 -e 's|@''REPLACE_MKNOD''@|$(REPLACE_MKNOD)|g' \ 3263 -e 's|@''REPLACE_MKNOD''@|$(REPLACE_MKNOD)|g' \
3264 -e 's|@''REPLACE_MKNODAT''@|$(REPLACE_MKNODAT)|g' \
3241 -e 's|@''REPLACE_STAT''@|$(REPLACE_STAT)|g' \ 3265 -e 's|@''REPLACE_STAT''@|$(REPLACE_STAT)|g' \
3242 -e 's|@''REPLACE_UTIMENSAT''@|$(REPLACE_UTIMENSAT)|g' \ 3266 -e 's|@''REPLACE_UTIMENSAT''@|$(REPLACE_UTIMENSAT)|g' \
3243 -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ 3267 -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
@@ -3350,6 +3374,7 @@ time.h: time.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(
3350 -e 's/@''GNULIB_STRFTIME''@/$(GNULIB_STRFTIME)/g' \ 3374 -e 's/@''GNULIB_STRFTIME''@/$(GNULIB_STRFTIME)/g' \
3351 -e 's/@''GNULIB_STRPTIME''@/$(GNULIB_STRPTIME)/g' \ 3375 -e 's/@''GNULIB_STRPTIME''@/$(GNULIB_STRPTIME)/g' \
3352 -e 's/@''GNULIB_TIMEGM''@/$(GNULIB_TIMEGM)/g' \ 3376 -e 's/@''GNULIB_TIMEGM''@/$(GNULIB_TIMEGM)/g' \
3377 -e 's/@''GNULIB_TIMESPEC_GET''@/$(GNULIB_TIMESPEC_GET)/g' \
3353 -e 's/@''GNULIB_TIME_R''@/$(GNULIB_TIME_R)/g' \ 3378 -e 's/@''GNULIB_TIME_R''@/$(GNULIB_TIME_R)/g' \
3354 -e 's/@''GNULIB_TIME_RZ''@/$(GNULIB_TIME_RZ)/g' \ 3379 -e 's/@''GNULIB_TIME_RZ''@/$(GNULIB_TIME_RZ)/g' \
3355 -e 's/@''GNULIB_TZSET''@/$(GNULIB_TZSET)/g' \ 3380 -e 's/@''GNULIB_TZSET''@/$(GNULIB_TZSET)/g' \
@@ -3358,6 +3383,7 @@ time.h: time.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(
3358 -e 's|@''HAVE_NANOSLEEP''@|$(HAVE_NANOSLEEP)|g' \ 3383 -e 's|@''HAVE_NANOSLEEP''@|$(HAVE_NANOSLEEP)|g' \
3359 -e 's|@''HAVE_STRPTIME''@|$(HAVE_STRPTIME)|g' \ 3384 -e 's|@''HAVE_STRPTIME''@|$(HAVE_STRPTIME)|g' \
3360 -e 's|@''HAVE_TIMEGM''@|$(HAVE_TIMEGM)|g' \ 3385 -e 's|@''HAVE_TIMEGM''@|$(HAVE_TIMEGM)|g' \
3386 -e 's|@''HAVE_TIMESPEC_GET''@|$(HAVE_TIMESPEC_GET)|g' \
3361 -e 's|@''HAVE_TIMEZONE_T''@|$(HAVE_TIMEZONE_T)|g' \ 3387 -e 's|@''HAVE_TIMEZONE_T''@|$(HAVE_TIMEZONE_T)|g' \
3362 -e 's|@''REPLACE_CTIME''@|$(REPLACE_CTIME)|g' \ 3388 -e 's|@''REPLACE_CTIME''@|$(REPLACE_CTIME)|g' \
3363 -e 's|@''REPLACE_GMTIME''@|$(REPLACE_GMTIME)|g' \ 3389 -e 's|@''REPLACE_GMTIME''@|$(REPLACE_GMTIME)|g' \
@@ -3372,6 +3398,7 @@ time.h: time.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(
3372 -e 's|@''SYS_TIME_H_DEFINES_STRUCT_TIMESPEC''@|$(SYS_TIME_H_DEFINES_STRUCT_TIMESPEC)|g' \ 3398 -e 's|@''SYS_TIME_H_DEFINES_STRUCT_TIMESPEC''@|$(SYS_TIME_H_DEFINES_STRUCT_TIMESPEC)|g' \
3373 -e 's|@''TIME_H_DEFINES_STRUCT_TIMESPEC''@|$(TIME_H_DEFINES_STRUCT_TIMESPEC)|g' \ 3399 -e 's|@''TIME_H_DEFINES_STRUCT_TIMESPEC''@|$(TIME_H_DEFINES_STRUCT_TIMESPEC)|g' \
3374 -e 's|@''UNISTD_H_DEFINES_STRUCT_TIMESPEC''@|$(UNISTD_H_DEFINES_STRUCT_TIMESPEC)|g' \ 3400 -e 's|@''UNISTD_H_DEFINES_STRUCT_TIMESPEC''@|$(UNISTD_H_DEFINES_STRUCT_TIMESPEC)|g' \
3401 -e 's|@''TIME_H_DEFINES_TIME_UTC''@|$(TIME_H_DEFINES_TIME_UTC)|g' \
3375 -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ 3402 -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
3376 -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ 3403 -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
3377 -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ 3404 -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
diff --git a/lib/libc-config.h b/lib/libc-config.h
index d4e29951f35..c0eac707cfd 100644
--- a/lib/libc-config.h
+++ b/lib/libc-config.h
@@ -71,107 +71,112 @@
71# endif 71# endif
72#endif 72#endif
73 73
74 74#ifndef __attribute_maybe_unused__
75/* Prepare to include <cdefs.h>, which is our copy of glibc 75/* <sys/cdefs.h> either does not exist, or is too old for Gnulib.
76 <sys/cdefs.h>. */ 76 Prepare to include <cdefs.h>, which is Gnulib's version of a
77 more-recent glibc <sys/cdefs.h>. */
77 78
78/* Define _FEATURES_H so that <cdefs.h> does not include <features.h>. */ 79/* Define _FEATURES_H so that <cdefs.h> does not include <features.h>. */
79#ifndef _FEATURES_H 80# ifndef _FEATURES_H
80# define _FEATURES_H 1 81# define _FEATURES_H 1
81#endif 82# endif
82/* Define __WORDSIZE so that <cdefs.h> does not attempt to include 83/* Define __WORDSIZE so that <cdefs.h> does not attempt to include
83 nonexistent files. Make it a syntax error, since Gnulib does not 84 nonexistent files. Make it a syntax error, since Gnulib does not
84 use __WORDSIZE now, and if Gnulib uses it later the syntax error 85 use __WORDSIZE now, and if Gnulib uses it later the syntax error
85 will let us know that __WORDSIZE needs configuring. */ 86 will let us know that __WORDSIZE needs configuring. */
86#ifndef __WORDSIZE 87# ifndef __WORDSIZE
87# define __WORDSIZE %%% 88# define __WORDSIZE %%%
88#endif 89# endif
89/* Undef the macros unconditionally defined by our copy of glibc 90/* Undef the macros unconditionally defined by our copy of glibc
90 <sys/cdefs.h>, so that they do not clash with any system-defined 91 <sys/cdefs.h>, so that they do not clash with any system-defined
91 versions. */ 92 versions. */
92#undef _SYS_CDEFS_H 93# undef _SYS_CDEFS_H
93#undef __ASMNAME 94# undef __ASMNAME
94#undef __ASMNAME2 95# undef __ASMNAME2
95#undef __BEGIN_DECLS 96# undef __BEGIN_DECLS
96#undef __CONCAT 97# undef __CONCAT
97#undef __END_DECLS 98# undef __END_DECLS
98#undef __HAVE_GENERIC_SELECTION 99# undef __HAVE_GENERIC_SELECTION
99#undef __LDBL_COMPAT 100# undef __LDBL_COMPAT
100#undef __LDBL_REDIR 101# undef __LDBL_REDIR
101#undef __LDBL_REDIR1 102# undef __LDBL_REDIR1
102#undef __LDBL_REDIR1_DECL 103# undef __LDBL_REDIR1_DECL
103#undef __LDBL_REDIR1_NTH 104# undef __LDBL_REDIR1_NTH
104#undef __LDBL_REDIR_DECL 105# undef __LDBL_REDIR2_DECL
105#undef __LDBL_REDIR_NTH 106# undef __LDBL_REDIR_DECL
106#undef __LEAF 107# undef __LDBL_REDIR_NTH
107#undef __LEAF_ATTR 108# undef __LEAF
108#undef __NTH 109# undef __LEAF_ATTR
109#undef __NTHNL 110# undef __NTH
110#undef __P 111# undef __NTHNL
111#undef __PMT 112# undef __REDIRECT
112#undef __REDIRECT 113# undef __REDIRECT_LDBL
113#undef __REDIRECT_LDBL 114# undef __REDIRECT_NTH
114#undef __REDIRECT_NTH 115# undef __REDIRECT_NTHNL
115#undef __REDIRECT_NTHNL 116# undef __REDIRECT_NTH_LDBL
116#undef __REDIRECT_NTH_LDBL 117# undef __STRING
117#undef __STRING 118# undef __THROW
118#undef __THROW 119# undef __THROWNL
119#undef __THROWNL 120# undef __attr_access
120#undef __always_inline 121# undef __attribute__
121#undef __attribute__ 122# undef __attribute_alloc_size__
122#undef __attribute_alloc_size__ 123# undef __attribute_artificial__
123#undef __attribute_artificial__ 124# undef __attribute_const__
124#undef __attribute_const__ 125# undef __attribute_deprecated__
125#undef __attribute_deprecated__ 126# undef __attribute_deprecated_msg__
126#undef __attribute_deprecated_msg__ 127# undef __attribute_format_arg__
127#undef __attribute_format_arg__ 128# undef __attribute_format_strfmon__
128#undef __attribute_format_strfmon__ 129# undef __attribute_malloc__
129#undef __attribute_malloc__ 130# undef __attribute_noinline__
130#undef __attribute_noinline__ 131# undef __attribute_nonstring__
131#undef __attribute_nonstring__ 132# undef __attribute_pure__
132#undef __attribute_pure__ 133# undef __attribute_returns_twice__
133#undef __attribute_used__ 134# undef __attribute_used__
134#undef __attribute_warn_unused_result__ 135# undef __attribute_warn_unused_result__
135#undef __bos 136# undef __bos
136#undef __bos0 137# undef __bos0
137#undef __errordecl 138# undef __errordecl
138#undef __extension__ 139# undef __extension__
139#undef __extern_always_inline 140# undef __extern_always_inline
140#undef __extern_inline 141# undef __extern_inline
141#undef __flexarr 142# undef __flexarr
142#undef __fortify_function 143# undef __fortify_function
143#undef __glibc_c99_flexarr_available 144# undef __glibc_c99_flexarr_available
144#undef __glibc_clang_has_extension 145# undef __glibc_has_attribute
145#undef __glibc_likely 146# undef __glibc_has_builtin
146#undef __glibc_macro_warning 147# undef __glibc_has_extension
147#undef __glibc_macro_warning1 148# undef __glibc_macro_warning
148#undef __glibc_unlikely 149# undef __glibc_macro_warning1
149#undef __inline 150# undef __glibc_objsize
150#undef __ptr_t 151# undef __glibc_objsize0
151#undef __restrict 152# undef __glibc_unlikely
152#undef __restrict_arr 153# undef __inline
153#undef __va_arg_pack 154# undef __ptr_t
154#undef __va_arg_pack_len 155# undef __restrict
155#undef __warnattr 156# undef __restrict_arr
156#undef __warndecl 157# undef __va_arg_pack
158# undef __va_arg_pack_len
159# undef __warnattr
157 160
158/* Include our copy of glibc <sys/cdefs.h>. */ 161/* Include our copy of glibc <sys/cdefs.h>. */
159#include <cdefs.h> 162# include <cdefs.h>
160 163
161/* <cdefs.h> __inline is too pessimistic for non-GCC. */ 164/* <cdefs.h> __inline is too pessimistic for non-GCC. */
162#undef __inline 165# undef __inline
163#ifndef HAVE___INLINE 166# ifndef HAVE___INLINE
164# if 199901 <= __STDC_VERSION__ || defined inline 167# if 199901 <= __STDC_VERSION__ || defined inline
165# define __inline inline 168# define __inline inline
166# else 169# else
167# define __inline 170# define __inline
171# endif
168# endif 172# endif
169#endif 173
174#endif /* defined __glibc_likely */
170 175
171 176
172/* A substitute for glibc <libc-symbols.h>, good enough for Gnulib. */ 177/* A substitute for glibc <libc-symbols.h>, good enough for Gnulib. */
173#define attribute_hidden 178#define attribute_hidden
174#define libc_hidden_proto(name, ...) 179#define libc_hidden_proto(name)
175#define libc_hidden_def(name) 180#define libc_hidden_def(name)
176#define libc_hidden_weak(name) 181#define libc_hidden_weak(name)
177#define libc_hidden_ver(local, name) 182#define libc_hidden_ver(local, name)
diff --git a/lib/malloc/dynarray-skeleton.c b/lib/malloc/dynarray-skeleton.c
new file mode 100644
index 00000000000..4995fd1c049
--- /dev/null
+++ b/lib/malloc/dynarray-skeleton.c
@@ -0,0 +1,525 @@
1/* Type-safe arrays which grow dynamically.
2 Copyright (C) 2017-2021 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public
7 License as published by the Free Software Foundation; either
8 version 3 of the License, or (at your option) any later version.
9
10 The GNU C 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 General Public License for more details.
14
15 You should have received a copy of the GNU General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
18
19/* Pre-processor macros which act as parameters:
20
21 DYNARRAY_STRUCT
22 The struct tag of dynamic array to be defined.
23 DYNARRAY_ELEMENT
24 The type name of the element type. Elements are copied
25 as if by memcpy, and can change address as the dynamic
26 array grows.
27 DYNARRAY_PREFIX
28 The prefix of the functions which are defined.
29
30 The following parameters are optional:
31
32 DYNARRAY_ELEMENT_FREE
33 DYNARRAY_ELEMENT_FREE (E) is evaluated to deallocate the
34 contents of elements. E is of type DYNARRAY_ELEMENT *.
35 DYNARRAY_ELEMENT_INIT
36 DYNARRAY_ELEMENT_INIT (E) is evaluated to initialize a new
37 element. E is of type DYNARRAY_ELEMENT *.
38 If DYNARRAY_ELEMENT_FREE but not DYNARRAY_ELEMENT_INIT is
39 defined, new elements are automatically zero-initialized.
40 Otherwise, new elements have undefined contents.
41 DYNARRAY_INITIAL_SIZE
42 The size of the statically allocated array (default:
43 at least 2, more elements if they fit into 128 bytes).
44 Must be a preprocessor constant. If DYNARRAY_INITIAL_SIZE is 0,
45 there is no statically allocated array at, and all non-empty
46 arrays are heap-allocated.
47 DYNARRAY_FINAL_TYPE
48 The name of the type which holds the final array. If not
49 defined, is PREFIX##finalize not provided. DYNARRAY_FINAL_TYPE
50 must be a struct type, with members of type DYNARRAY_ELEMENT and
51 size_t at the start (in this order).
52
53 These macros are undefined after this header file has been
54 included.
55
56 The following types are provided (their members are private to the
57 dynarray implementation):
58
59 struct DYNARRAY_STRUCT
60
61 The following functions are provided:
62
63 void DYNARRAY_PREFIX##init (struct DYNARRAY_STRUCT *);
64 void DYNARRAY_PREFIX##free (struct DYNARRAY_STRUCT *);
65 bool DYNARRAY_PREFIX##has_failed (const struct DYNARRAY_STRUCT *);
66 void DYNARRAY_PREFIX##mark_failed (struct DYNARRAY_STRUCT *);
67 size_t DYNARRAY_PREFIX##size (const struct DYNARRAY_STRUCT *);
68 DYNARRAY_ELEMENT *DYNARRAY_PREFIX##begin (const struct DYNARRAY_STRUCT *);
69 DYNARRAY_ELEMENT *DYNARRAY_PREFIX##end (const struct DYNARRAY_STRUCT *);
70 DYNARRAY_ELEMENT *DYNARRAY_PREFIX##at (struct DYNARRAY_STRUCT *, size_t);
71 void DYNARRAY_PREFIX##add (struct DYNARRAY_STRUCT *, DYNARRAY_ELEMENT);
72 DYNARRAY_ELEMENT *DYNARRAY_PREFIX##emplace (struct DYNARRAY_STRUCT *);
73 bool DYNARRAY_PREFIX##resize (struct DYNARRAY_STRUCT *, size_t);
74 void DYNARRAY_PREFIX##remove_last (struct DYNARRAY_STRUCT *);
75 void DYNARRAY_PREFIX##clear (struct DYNARRAY_STRUCT *);
76
77 The following functions are provided are provided if the
78 prerequisites are met:
79
80 bool DYNARRAY_PREFIX##finalize (struct DYNARRAY_STRUCT *,
81 DYNARRAY_FINAL_TYPE *);
82 (if DYNARRAY_FINAL_TYPE is defined)
83 DYNARRAY_ELEMENT *DYNARRAY_PREFIX##finalize (struct DYNARRAY_STRUCT *,
84 size_t *);
85 (if DYNARRAY_FINAL_TYPE is not defined)
86*/
87
88#include <malloc/dynarray.h>
89
90#include <errno.h>
91#include <stdlib.h>
92#include <string.h>
93
94#ifndef DYNARRAY_STRUCT
95# error "DYNARRAY_STRUCT must be defined"
96#endif
97
98#ifndef DYNARRAY_ELEMENT
99# error "DYNARRAY_ELEMENT must be defined"
100#endif
101
102#ifndef DYNARRAY_PREFIX
103# error "DYNARRAY_PREFIX must be defined"
104#endif
105
106#ifdef DYNARRAY_INITIAL_SIZE
107# if DYNARRAY_INITIAL_SIZE < 0
108# error "DYNARRAY_INITIAL_SIZE must be non-negative"
109# endif
110# if DYNARRAY_INITIAL_SIZE > 0
111# define DYNARRAY_HAVE_SCRATCH 1
112# else
113# define DYNARRAY_HAVE_SCRATCH 0
114# endif
115#else
116/* Provide a reasonable default which limits the size of
117 DYNARRAY_STRUCT. */
118# define DYNARRAY_INITIAL_SIZE \
119 (sizeof (DYNARRAY_ELEMENT) > 64 ? 2 : 128 / sizeof (DYNARRAY_ELEMENT))
120# define DYNARRAY_HAVE_SCRATCH 1
121#endif
122
123/* Public type definitions. */
124
125/* All fields of this struct are private to the implementation. */
126struct DYNARRAY_STRUCT
127{
128 union
129 {
130 struct dynarray_header dynarray_abstract;
131 struct
132 {
133 /* These fields must match struct dynarray_header. */
134 size_t used;
135 size_t allocated;
136 DYNARRAY_ELEMENT *array;
137 } dynarray_header;
138 } u;
139
140#if DYNARRAY_HAVE_SCRATCH
141 /* Initial inline allocation. */
142 DYNARRAY_ELEMENT scratch[DYNARRAY_INITIAL_SIZE];
143#endif
144};
145
146/* Internal use only: Helper macros. */
147
148/* Ensure macro-expansion of DYNARRAY_PREFIX. */
149#define DYNARRAY_CONCAT0(prefix, name) prefix##name
150#define DYNARRAY_CONCAT1(prefix, name) DYNARRAY_CONCAT0(prefix, name)
151#define DYNARRAY_NAME(name) DYNARRAY_CONCAT1(DYNARRAY_PREFIX, name)
152
153/* Use DYNARRAY_FREE instead of DYNARRAY_NAME (free),
154 so that Gnulib does not change 'free' to 'rpl_free'. */
155#define DYNARRAY_FREE DYNARRAY_CONCAT1 (DYNARRAY_NAME (f), ree)
156
157/* Address of the scratch buffer if any. */
158#if DYNARRAY_HAVE_SCRATCH
159# define DYNARRAY_SCRATCH(list) (list)->scratch
160#else
161# define DYNARRAY_SCRATCH(list) NULL
162#endif
163
164/* Internal use only: Helper functions. */
165
166/* Internal function. Call DYNARRAY_ELEMENT_FREE with the array
167 elements. Name mangling needed due to the DYNARRAY_ELEMENT_FREE
168 macro expansion. */
169static inline void
170DYNARRAY_NAME (free__elements__) (DYNARRAY_ELEMENT *__dynarray_array,
171 size_t __dynarray_used)
172{
173#ifdef DYNARRAY_ELEMENT_FREE
174 for (size_t __dynarray_i = 0; __dynarray_i < __dynarray_used; ++__dynarray_i)
175 DYNARRAY_ELEMENT_FREE (&__dynarray_array[__dynarray_i]);
176#endif /* DYNARRAY_ELEMENT_FREE */
177}
178
179/* Internal function. Free the non-scratch array allocation. */
180static inline void
181DYNARRAY_NAME (free__array__) (struct DYNARRAY_STRUCT *list)
182{
183#if DYNARRAY_HAVE_SCRATCH
184 if (list->u.dynarray_header.array != list->scratch)
185 free (list->u.dynarray_header.array);
186#else
187 free (list->u.dynarray_header.array);
188#endif
189}
190
191/* Public functions. */
192
193/* Initialize a dynamic array object. This must be called before any
194 use of the object. */
195__nonnull ((1))
196static void
197DYNARRAY_NAME (init) (struct DYNARRAY_STRUCT *list)
198{
199 list->u.dynarray_header.used = 0;
200 list->u.dynarray_header.allocated = DYNARRAY_INITIAL_SIZE;
201 list->u.dynarray_header.array = DYNARRAY_SCRATCH (list);
202}
203
204/* Deallocate the dynamic array and its elements. */
205__attribute_maybe_unused__ __nonnull ((1))
206static void
207DYNARRAY_FREE (struct DYNARRAY_STRUCT *list)
208{
209 DYNARRAY_NAME (free__elements__)
210 (list->u.dynarray_header.array, list->u.dynarray_header.used);
211 DYNARRAY_NAME (free__array__) (list);
212 DYNARRAY_NAME (init) (list);
213}
214
215/* Return true if the dynamic array is in an error state. */
216__nonnull ((1))
217static inline bool
218DYNARRAY_NAME (has_failed) (const struct DYNARRAY_STRUCT *list)
219{
220 return list->u.dynarray_header.allocated == __dynarray_error_marker ();
221}
222
223/* Mark the dynamic array as failed. All elements are deallocated as
224 a side effect. */
225__nonnull ((1))
226static void
227DYNARRAY_NAME (mark_failed) (struct DYNARRAY_STRUCT *list)
228{
229 DYNARRAY_NAME (free__elements__)
230 (list->u.dynarray_header.array, list->u.dynarray_header.used);
231 DYNARRAY_NAME (free__array__) (list);
232 list->u.dynarray_header.array = DYNARRAY_SCRATCH (list);
233 list->u.dynarray_header.used = 0;
234 list->u.dynarray_header.allocated = __dynarray_error_marker ();
235}
236
237/* Return the number of elements which have been added to the dynamic
238 array. */
239__nonnull ((1))
240static inline size_t
241DYNARRAY_NAME (size) (const struct DYNARRAY_STRUCT *list)
242{
243 return list->u.dynarray_header.used;
244}
245
246/* Return a pointer to the array element at INDEX. Terminate the
247 process if INDEX is out of bounds. */
248__nonnull ((1))
249static inline DYNARRAY_ELEMENT *
250DYNARRAY_NAME (at) (struct DYNARRAY_STRUCT *list, size_t index)
251{
252 if (__glibc_unlikely (index >= DYNARRAY_NAME (size) (list)))
253 __libc_dynarray_at_failure (DYNARRAY_NAME (size) (list), index);
254 return list->u.dynarray_header.array + index;
255}
256
257/* Return a pointer to the first array element, if any. For a
258 zero-length array, the pointer can be NULL even though the dynamic
259 array has not entered the failure state. */
260__nonnull ((1))
261static inline DYNARRAY_ELEMENT *
262DYNARRAY_NAME (begin) (struct DYNARRAY_STRUCT *list)
263{
264 return list->u.dynarray_header.array;
265}
266
267/* Return a pointer one element past the last array element. For a
268 zero-length array, the pointer can be NULL even though the dynamic
269 array has not entered the failure state. */
270__nonnull ((1))
271static inline DYNARRAY_ELEMENT *
272DYNARRAY_NAME (end) (struct DYNARRAY_STRUCT *list)
273{
274 return list->u.dynarray_header.array + list->u.dynarray_header.used;
275}
276
277/* Internal function. Slow path for the add function below. */
278static void
279DYNARRAY_NAME (add__) (struct DYNARRAY_STRUCT *list, DYNARRAY_ELEMENT item)
280{
281 if (__glibc_unlikely
282 (!__libc_dynarray_emplace_enlarge (&list->u.dynarray_abstract,
283 DYNARRAY_SCRATCH (list),
284 sizeof (DYNARRAY_ELEMENT))))
285 {
286 DYNARRAY_NAME (mark_failed) (list);
287 return;
288 }
289
290 /* Copy the new element and increase the array length. */
291 list->u.dynarray_header.array[list->u.dynarray_header.used++] = item;
292}
293
294/* Add ITEM at the end of the array, enlarging it by one element.
295 Mark *LIST as failed if the dynamic array allocation size cannot be
296 increased. */
297__nonnull ((1))
298static inline void
299DYNARRAY_NAME (add) (struct DYNARRAY_STRUCT *list, DYNARRAY_ELEMENT item)
300{
301 /* Do nothing in case of previous error. */
302 if (DYNARRAY_NAME (has_failed) (list))
303 return;
304
305 /* Enlarge the array if necessary. */
306 if (__glibc_unlikely (list->u.dynarray_header.used
307 == list->u.dynarray_header.allocated))
308 {
309 DYNARRAY_NAME (add__) (list, item);
310 return;
311 }
312
313 /* Copy the new element and increase the array length. */
314 list->u.dynarray_header.array[list->u.dynarray_header.used++] = item;
315}
316
317/* Internal function. Building block for the emplace functions below.
318 Assumes space for one more element in *LIST. */
319static inline DYNARRAY_ELEMENT *
320DYNARRAY_NAME (emplace__tail__) (struct DYNARRAY_STRUCT *list)
321{
322 DYNARRAY_ELEMENT *result
323 = &list->u.dynarray_header.array[list->u.dynarray_header.used];
324 ++list->u.dynarray_header.used;
325#if defined (DYNARRAY_ELEMENT_INIT)
326 DYNARRAY_ELEMENT_INIT (result);
327#elif defined (DYNARRAY_ELEMENT_FREE)
328 memset (result, 0, sizeof (*result));
329#endif
330 return result;
331}
332
333/* Internal function. Slow path for the emplace function below. */
334static DYNARRAY_ELEMENT *
335DYNARRAY_NAME (emplace__) (struct DYNARRAY_STRUCT *list)
336{
337 if (__glibc_unlikely
338 (!__libc_dynarray_emplace_enlarge (&list->u.dynarray_abstract,
339 DYNARRAY_SCRATCH (list),
340 sizeof (DYNARRAY_ELEMENT))))
341 {
342 DYNARRAY_NAME (mark_failed) (list);
343 return NULL;
344 }
345 return DYNARRAY_NAME (emplace__tail__) (list);
346}
347
348/* Allocate a place for a new element in *LIST and return a pointer to
349 it. The pointer can be NULL if the dynamic array cannot be
350 enlarged due to a memory allocation failure. */
351__attribute_maybe_unused__ __attribute_warn_unused_result__ __nonnull ((1))
352static
353/* Avoid inlining with the larger initialization code. */
354#if !(defined (DYNARRAY_ELEMENT_INIT) || defined (DYNARRAY_ELEMENT_FREE))
355inline
356#endif
357DYNARRAY_ELEMENT *
358DYNARRAY_NAME (emplace) (struct DYNARRAY_STRUCT *list)
359{
360 /* Do nothing in case of previous error. */
361 if (DYNARRAY_NAME (has_failed) (list))
362 return NULL;
363
364 /* Enlarge the array if necessary. */
365 if (__glibc_unlikely (list->u.dynarray_header.used
366 == list->u.dynarray_header.allocated))
367 return (DYNARRAY_NAME (emplace__) (list));
368 return DYNARRAY_NAME (emplace__tail__) (list);
369}
370
371/* Change the size of *LIST to SIZE. If SIZE is larger than the
372 existing size, new elements are added (which can be initialized).
373 Otherwise, the list is truncated, and elements are freed. Return
374 false on memory allocation failure (and mark *LIST as failed). */
375__attribute_maybe_unused__ __nonnull ((1))
376static bool
377DYNARRAY_NAME (resize) (struct DYNARRAY_STRUCT *list, size_t size)
378{
379 if (size > list->u.dynarray_header.used)
380 {
381 bool ok;
382#if defined (DYNARRAY_ELEMENT_INIT)
383 /* The new elements have to be initialized. */
384 size_t old_size = list->u.dynarray_header.used;
385 ok = __libc_dynarray_resize (&list->u.dynarray_abstract,
386 size, DYNARRAY_SCRATCH (list),
387 sizeof (DYNARRAY_ELEMENT));
388 if (ok)
389 for (size_t i = old_size; i < size; ++i)
390 {
391 DYNARRAY_ELEMENT_INIT (&list->u.dynarray_header.array[i]);
392 }
393#elif defined (DYNARRAY_ELEMENT_FREE)
394 /* Zero initialization is needed so that the elements can be
395 safely freed. */
396 ok = __libc_dynarray_resize_clear
397 (&list->u.dynarray_abstract, size,
398 DYNARRAY_SCRATCH (list), sizeof (DYNARRAY_ELEMENT));
399#else
400 ok = __libc_dynarray_resize (&list->u.dynarray_abstract,
401 size, DYNARRAY_SCRATCH (list),
402 sizeof (DYNARRAY_ELEMENT));
403#endif
404 if (__glibc_unlikely (!ok))
405 DYNARRAY_NAME (mark_failed) (list);
406 return ok;
407 }
408 else
409 {
410 /* The list has shrunk in size. Free the removed elements. */
411 DYNARRAY_NAME (free__elements__)
412 (list->u.dynarray_header.array + size,
413 list->u.dynarray_header.used - size);
414 list->u.dynarray_header.used = size;
415 return true;
416 }
417}
418
419/* Remove the last element of LIST if it is present. */
420__attribute_maybe_unused__ __nonnull ((1))
421static void
422DYNARRAY_NAME (remove_last) (struct DYNARRAY_STRUCT *list)
423{
424 /* used > 0 implies that the array is the non-failed state. */
425 if (list->u.dynarray_header.used > 0)
426 {
427 size_t new_length = list->u.dynarray_header.used - 1;
428#ifdef DYNARRAY_ELEMENT_FREE
429 DYNARRAY_ELEMENT_FREE (&list->u.dynarray_header.array[new_length]);
430#endif
431 list->u.dynarray_header.used = new_length;
432 }
433}
434
435/* Remove all elements from the list. The elements are freed, but the
436 list itself is not. */
437__attribute_maybe_unused__ __nonnull ((1))
438static void
439DYNARRAY_NAME (clear) (struct DYNARRAY_STRUCT *list)
440{
441 /* free__elements__ does nothing if the list is in the failed
442 state. */
443 DYNARRAY_NAME (free__elements__)
444 (list->u.dynarray_header.array, list->u.dynarray_header.used);
445 list->u.dynarray_header.used = 0;
446}
447
448#ifdef DYNARRAY_FINAL_TYPE
449/* Transfer the dynamic array to a permanent location at *RESULT.
450 Returns true on success on false on allocation failure. In either
451 case, *LIST is re-initialized and can be reused. A NULL pointer is
452 stored in *RESULT if LIST refers to an empty list. On success, the
453 pointer in *RESULT is heap-allocated and must be deallocated using
454 free. */
455__attribute_maybe_unused__ __attribute_warn_unused_result__ __nonnull ((1, 2))
456static bool
457DYNARRAY_NAME (finalize) (struct DYNARRAY_STRUCT *list,
458 DYNARRAY_FINAL_TYPE *result)
459{
460 struct dynarray_finalize_result res;
461 if (__libc_dynarray_finalize (&list->u.dynarray_abstract,
462 DYNARRAY_SCRATCH (list),
463 sizeof (DYNARRAY_ELEMENT), &res))
464 {
465 /* On success, the result owns all the data. */
466 DYNARRAY_NAME (init) (list);
467 *result = (DYNARRAY_FINAL_TYPE) { res.array, res.length };
468 return true;
469 }
470 else
471 {
472 /* On error, we need to free all data. */
473 DYNARRAY_FREE (list);
474 errno = ENOMEM;
475 return false;
476 }
477}
478#else /* !DYNARRAY_FINAL_TYPE */
479/* Transfer the dynamic array to a heap-allocated array and return a
480 pointer to it. The pointer is NULL if memory allocation fails, or
481 if the array is empty, so this function should be used only for
482 arrays which are known not be empty (usually because they always
483 have a sentinel at the end). If LENGTHP is not NULL, the array
484 length is written to *LENGTHP. *LIST is re-initialized and can be
485 reused. */
486__attribute_maybe_unused__ __attribute_warn_unused_result__ __nonnull ((1))
487static DYNARRAY_ELEMENT *
488DYNARRAY_NAME (finalize) (struct DYNARRAY_STRUCT *list, size_t *lengthp)
489{
490 struct dynarray_finalize_result res;
491 if (__libc_dynarray_finalize (&list->u.dynarray_abstract,
492 DYNARRAY_SCRATCH (list),
493 sizeof (DYNARRAY_ELEMENT), &res))
494 {
495 /* On success, the result owns all the data. */
496 DYNARRAY_NAME (init) (list);
497 if (lengthp != NULL)
498 *lengthp = res.length;
499 return res.array;
500 }
501 else
502 {
503 /* On error, we need to free all data. */
504 DYNARRAY_FREE (list);
505 errno = ENOMEM;
506 return NULL;
507 }
508}
509#endif /* !DYNARRAY_FINAL_TYPE */
510
511/* Undo macro definitions. */
512
513#undef DYNARRAY_CONCAT0
514#undef DYNARRAY_CONCAT1
515#undef DYNARRAY_NAME
516#undef DYNARRAY_SCRATCH
517#undef DYNARRAY_HAVE_SCRATCH
518
519#undef DYNARRAY_STRUCT
520#undef DYNARRAY_ELEMENT
521#undef DYNARRAY_PREFIX
522#undef DYNARRAY_ELEMENT_FREE
523#undef DYNARRAY_ELEMENT_INIT
524#undef DYNARRAY_INITIAL_SIZE
525#undef DYNARRAY_FINAL_TYPE
diff --git a/lib/malloc/dynarray.h b/lib/malloc/dynarray.h
new file mode 100644
index 00000000000..84e4394bf32
--- /dev/null
+++ b/lib/malloc/dynarray.h
@@ -0,0 +1,178 @@
1/* Type-safe arrays which grow dynamically. Shared definitions.
2 Copyright (C) 2017-2021 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public
7 License as published by the Free Software Foundation; either
8 version 3 of the License, or (at your option) any later version.
9
10 The GNU C 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 General Public License for more details.
14
15 You should have received a copy of the GNU General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
18
19/* To use the dynarray facility, you need to include
20 <malloc/dynarray-skeleton.c> and define the parameter macros
21 documented in that file.
22
23 A minimal example which provides a growing list of integers can be
24 defined like this:
25
26 struct int_array
27 {
28 // Pointer to result array followed by its length,
29 // as required by DYNARRAY_FINAL_TYPE.
30 int *array;
31 size_t length;
32 };
33
34 #define DYNARRAY_STRUCT dynarray_int
35 #define DYNARRAY_ELEMENT int
36 #define DYNARRAY_PREFIX dynarray_int_
37 #define DYNARRAY_FINAL_TYPE struct int_array
38 #include <malloc/dynarray-skeleton.c>
39
40 To create a three-element array with elements 1, 2, 3, use this
41 code:
42
43 struct dynarray_int dyn;
44 dynarray_int_init (&dyn);
45 for (int i = 1; i <= 3; ++i)
46 {
47 int *place = dynarray_int_emplace (&dyn);
48 assert (place != NULL);
49 *place = i;
50 }
51 struct int_array result;
52 bool ok = dynarray_int_finalize (&dyn, &result);
53 assert (ok);
54 assert (result.length == 3);
55 assert (result.array[0] == 1);
56 assert (result.array[1] == 2);
57 assert (result.array[2] == 3);
58 free (result.array);
59
60 If the elements contain resources which must be freed, define
61 DYNARRAY_ELEMENT_FREE appropriately, like this:
62
63 struct str_array
64 {
65 char **array;
66 size_t length;
67 };
68
69 #define DYNARRAY_STRUCT dynarray_str
70 #define DYNARRAY_ELEMENT char *
71 #define DYNARRAY_ELEMENT_FREE(ptr) free (*ptr)
72 #define DYNARRAY_PREFIX dynarray_str_
73 #define DYNARRAY_FINAL_TYPE struct str_array
74 #include <malloc/dynarray-skeleton.c>
75
76 Compared to scratch buffers, dynamic arrays have the following
77 features:
78
79 - They have an element type, and are not just an untyped buffer of
80 bytes.
81
82 - When growing, previously stored elements are preserved. (It is
83 expected that scratch_buffer_grow_preserve and
84 scratch_buffer_set_array_size eventually go away because all
85 current users are moved to dynamic arrays.)
86
87 - Scratch buffers have a more aggressive growth policy because
88 growing them typically means a retry of an operation (across an
89 NSS service module boundary), which is expensive.
90
91 - For the same reason, scratch buffers have a much larger initial
92 stack allocation. */
93
94#ifndef _DYNARRAY_H
95#define _DYNARRAY_H
96
97#include <stdbool.h>
98#include <stddef.h>
99#include <string.h>
100
101struct dynarray_header
102{
103 size_t used;
104 size_t allocated;
105 void *array;
106};
107
108/* Marker used in the allocated member to indicate that an error was
109 encountered. */
110static inline size_t
111__dynarray_error_marker (void)
112{
113 return -1;
114}
115
116/* Internal function. See the has_failed function in
117 dynarray-skeleton.c. */
118static inline bool
119__dynarray_error (struct dynarray_header *list)
120{
121 return list->allocated == __dynarray_error_marker ();
122}
123
124/* Internal function. Enlarge the dynamically allocated area of the
125 array to make room for one more element. SCRATCH is a pointer to
126 the scratch area (which is not heap-allocated and must not be
127 freed). ELEMENT_SIZE is the size, in bytes, of one element.
128 Return false on failure, true on success. */
129bool __libc_dynarray_emplace_enlarge (struct dynarray_header *,
130 void *scratch, size_t element_size);
131
132/* Internal function. Enlarge the dynamically allocated area of the
133 array to make room for at least SIZE elements (which must be larger
134 than the existing used part of the dynamic array). SCRATCH is a
135 pointer to the scratch area (which is not heap-allocated and must
136 not be freed). ELEMENT_SIZE is the size, in bytes, of one element.
137 Return false on failure, true on success. */
138bool __libc_dynarray_resize (struct dynarray_header *, size_t size,
139 void *scratch, size_t element_size);
140
141/* Internal function. Like __libc_dynarray_resize, but clear the new
142 part of the dynamic array. */
143bool __libc_dynarray_resize_clear (struct dynarray_header *, size_t size,
144 void *scratch, size_t element_size);
145
146/* Internal type. */
147struct dynarray_finalize_result
148{
149 void *array;
150 size_t length;
151};
152
153/* Internal function. Copy the dynamically-allocated area to an
154 explicitly-sized heap allocation. SCRATCH is a pointer to the
155 embedded scratch space. ELEMENT_SIZE is the size, in bytes, of the
156 element type. On success, true is returned, and pointer and length
157 are written to *RESULT. On failure, false is returned. The caller
158 has to take care of some of the memory management; this function is
159 expected to be called from dynarray-skeleton.c. */
160bool __libc_dynarray_finalize (struct dynarray_header *list, void *scratch,
161 size_t element_size,
162 struct dynarray_finalize_result *result);
163
164
165/* Internal function. Terminate the process after an index error.
166 SIZE is the number of elements of the dynamic array. INDEX is the
167 lookup index which triggered the failure. */
168_Noreturn void __libc_dynarray_at_failure (size_t size, size_t index);
169
170#ifndef _ISOMAC
171libc_hidden_proto (__libc_dynarray_emplace_enlarge)
172libc_hidden_proto (__libc_dynarray_resize)
173libc_hidden_proto (__libc_dynarray_resize_clear)
174libc_hidden_proto (__libc_dynarray_finalize)
175libc_hidden_proto (__libc_dynarray_at_failure)
176#endif
177
178#endif /* _DYNARRAY_H */
diff --git a/lib/malloc/dynarray_at_failure.c b/lib/malloc/dynarray_at_failure.c
new file mode 100644
index 00000000000..a4424593748
--- /dev/null
+++ b/lib/malloc/dynarray_at_failure.c
@@ -0,0 +1,35 @@
1/* Report an dynamic array index out of bounds condition.
2 Copyright (C) 2017-2021 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public
7 License as published by the Free Software Foundation; either
8 version 3 of the License, or (at your option) any later version.
9
10 The GNU C 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 General Public License for more details.
14
15 You should have received a copy of the GNU General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
18
19#include <dynarray.h>
20#include <stdio.h>
21#include <stdlib.h>
22
23void
24__libc_dynarray_at_failure (size_t size, size_t index)
25{
26#ifdef _LIBC
27 char buf[200];
28 __snprintf (buf, sizeof (buf), "Fatal glibc error: "
29 "array index %zu not less than array length %zu\n",
30 index, size);
31#else
32 abort ();
33#endif
34}
35libc_hidden_def (__libc_dynarray_at_failure)
diff --git a/lib/malloc/dynarray_emplace_enlarge.c b/lib/malloc/dynarray_emplace_enlarge.c
new file mode 100644
index 00000000000..7ac4b6db403
--- /dev/null
+++ b/lib/malloc/dynarray_emplace_enlarge.c
@@ -0,0 +1,73 @@
1/* Increase the size of a dynamic array in preparation of an emplace operation.
2 Copyright (C) 2017-2021 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public
7 License as published by the Free Software Foundation; either
8 version 3 of the License, or (at your option) any later version.
9
10 The GNU C 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 General Public License for more details.
14
15 You should have received a copy of the GNU General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
18
19#include <dynarray.h>
20#include <errno.h>
21#include <intprops.h>
22#include <stdlib.h>
23#include <string.h>
24
25bool
26__libc_dynarray_emplace_enlarge (struct dynarray_header *list,
27 void *scratch, size_t element_size)
28{
29 size_t new_allocated;
30 if (list->allocated == 0)
31 {
32 /* No scratch buffer provided. Choose a reasonable default
33 size. */
34 if (element_size < 4)
35 new_allocated = 16;
36 else if (element_size < 8)
37 new_allocated = 8;
38 else
39 new_allocated = 4;
40 }
41 else
42 /* Increase the allocated size, using an exponential growth
43 policy. */
44 {
45 new_allocated = list->allocated + list->allocated / 2 + 1;
46 if (new_allocated <= list->allocated)
47 {
48 /* Overflow. */
49 __set_errno (ENOMEM);
50 return false;
51 }
52 }
53
54 size_t new_size;
55 if (INT_MULTIPLY_WRAPV (new_allocated, element_size, &new_size))
56 return false;
57 void *new_array;
58 if (list->array == scratch)
59 {
60 /* The previous array was not heap-allocated. */
61 new_array = malloc (new_size);
62 if (new_array != NULL && list->array != NULL)
63 memcpy (new_array, list->array, list->used * element_size);
64 }
65 else
66 new_array = realloc (list->array, new_size);
67 if (new_array == NULL)
68 return false;
69 list->array = new_array;
70 list->allocated = new_allocated;
71 return true;
72}
73libc_hidden_def (__libc_dynarray_emplace_enlarge)
diff --git a/lib/malloc/dynarray_finalize.c b/lib/malloc/dynarray_finalize.c
new file mode 100644
index 00000000000..be9441e313d
--- /dev/null
+++ b/lib/malloc/dynarray_finalize.c
@@ -0,0 +1,62 @@
1/* Copy the dynamically-allocated area to an explicitly-sized heap allocation.
2 Copyright (C) 2017-2021 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public
7 License as published by the Free Software Foundation; either
8 version 3 of the License, or (at your option) any later version.
9
10 The GNU C 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 General Public License for more details.
14
15 You should have received a copy of the GNU General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
18
19#include <dynarray.h>
20#include <stdlib.h>
21#include <string.h>
22
23bool
24__libc_dynarray_finalize (struct dynarray_header *list,
25 void *scratch, size_t element_size,
26 struct dynarray_finalize_result *result)
27{
28 if (__dynarray_error (list))
29 /* The caller will reported the deferred error. */
30 return false;
31
32 size_t used = list->used;
33
34 /* Empty list. */
35 if (used == 0)
36 {
37 /* An empty list could still be backed by a heap-allocated
38 array. Free it if necessary. */
39 if (list->array != scratch)
40 free (list->array);
41 *result = (struct dynarray_finalize_result) { NULL, 0 };
42 return true;
43 }
44
45 size_t allocation_size = used * element_size;
46 void *heap_array = malloc (allocation_size);
47 if (heap_array != NULL)
48 {
49 /* The new array takes ownership of the strings. */
50 if (list->array != NULL)
51 memcpy (heap_array, list->array, allocation_size);
52 if (list->array != scratch)
53 free (list->array);
54 *result = (struct dynarray_finalize_result)
55 { .array = heap_array, .length = used };
56 return true;
57 }
58 else
59 /* The caller will perform the freeing operation. */
60 return false;
61}
62libc_hidden_def (__libc_dynarray_finalize)
diff --git a/lib/malloc/dynarray_resize.c b/lib/malloc/dynarray_resize.c
new file mode 100644
index 00000000000..92bbddd4461
--- /dev/null
+++ b/lib/malloc/dynarray_resize.c
@@ -0,0 +1,64 @@
1/* Increase the size of a dynamic array.
2 Copyright (C) 2017-2021 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public
7 License as published by the Free Software Foundation; either
8 version 3 of the License, or (at your option) any later version.
9
10 The GNU C 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 General Public License for more details.
14
15 You should have received a copy of the GNU General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
18
19#include <dynarray.h>
20#include <errno.h>
21#include <intprops.h>
22#include <stdlib.h>
23#include <string.h>
24
25bool
26__libc_dynarray_resize (struct dynarray_header *list, size_t size,
27 void *scratch, size_t element_size)
28{
29 /* The existing allocation provides sufficient room. */
30 if (size <= list->allocated)
31 {
32 list->used = size;
33 return true;
34 }
35
36 /* Otherwise, use size as the new allocation size. The caller is
37 expected to provide the final size of the array, so there is no
38 over-allocation here. */
39
40 size_t new_size_bytes;
41 if (INT_MULTIPLY_WRAPV (size, element_size, &new_size_bytes))
42 {
43 /* Overflow. */
44 __set_errno (ENOMEM);
45 return false;
46 }
47 void *new_array;
48 if (list->array == scratch)
49 {
50 /* The previous array was not heap-allocated. */
51 new_array = malloc (new_size_bytes);
52 if (new_array != NULL && list->array != NULL)
53 memcpy (new_array, list->array, list->used * element_size);
54 }
55 else
56 new_array = realloc (list->array, new_size_bytes);
57 if (new_array == NULL)
58 return false;
59 list->array = new_array;
60 list->allocated = size;
61 list->used = size;
62 return true;
63}
64libc_hidden_def (__libc_dynarray_resize)
diff --git a/lib/malloc/dynarray_resize_clear.c b/lib/malloc/dynarray_resize_clear.c
new file mode 100644
index 00000000000..99c2cc87c31
--- /dev/null
+++ b/lib/malloc/dynarray_resize_clear.c
@@ -0,0 +1,35 @@
1/* Increase the size of a dynamic array and clear the new part.
2 Copyright (C) 2017-2021 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public
7 License as published by the Free Software Foundation; either
8 version 3 of the License, or (at your option) any later version.
9
10 The GNU C 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 General Public License for more details.
14
15 You should have received a copy of the GNU General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
18
19#include <dynarray.h>
20#include <string.h>
21
22bool
23__libc_dynarray_resize_clear (struct dynarray_header *list, size_t size,
24 void *scratch, size_t element_size)
25{
26 size_t old_size = list->used;
27 if (!__libc_dynarray_resize (list, size, scratch, element_size))
28 return false;
29 /* __libc_dynarray_resize already checked for overflow. */
30 char *array = list->array;
31 memset (array + (old_size * element_size), 0,
32 (size - old_size) * element_size);
33 return true;
34}
35libc_hidden_def (__libc_dynarray_resize_clear)
diff --git a/lib/malloc/scratch_buffer_grow.c b/lib/malloc/scratch_buffer_grow.c
index 41befe3d65f..e7606d81cd7 100644
--- a/lib/malloc/scratch_buffer_grow.c
+++ b/lib/malloc/scratch_buffer_grow.c
@@ -1,5 +1,5 @@
1/* Variable-sized buffer with on-stack default allocation. 1/* Variable-sized buffer with on-stack default allocation.
2 Copyright (C) 2015-2020 Free Software Foundation, Inc. 2 Copyright (C) 2015-2021 Free Software Foundation, Inc.
3 This file is part of the GNU C Library. 3 This file is part of the GNU C Library.
4 4
5 The GNU C Library is free software; you can redistribute it and/or 5 The GNU C Library is free software; you can redistribute it and/or
diff --git a/lib/malloc/scratch_buffer_grow_preserve.c b/lib/malloc/scratch_buffer_grow_preserve.c
index aef232938d5..59f8c710001 100644
--- a/lib/malloc/scratch_buffer_grow_preserve.c
+++ b/lib/malloc/scratch_buffer_grow_preserve.c
@@ -1,5 +1,5 @@
1/* Variable-sized buffer with on-stack default allocation. 1/* Variable-sized buffer with on-stack default allocation.
2 Copyright (C) 2015-2020 Free Software Foundation, Inc. 2 Copyright (C) 2015-2021 Free Software Foundation, Inc.
3 This file is part of the GNU C Library. 3 This file is part of the GNU C Library.
4 4
5 The GNU C Library is free software; you can redistribute it and/or 5 The GNU C Library is free software; you can redistribute it and/or
diff --git a/lib/malloc/scratch_buffer_set_array_size.c b/lib/malloc/scratch_buffer_set_array_size.c
index 5f5e4c24f5a..e2b9f31211a 100644
--- a/lib/malloc/scratch_buffer_set_array_size.c
+++ b/lib/malloc/scratch_buffer_set_array_size.c
@@ -1,5 +1,5 @@
1/* Variable-sized buffer with on-stack default allocation. 1/* Variable-sized buffer with on-stack default allocation.
2 Copyright (C) 2015-2020 Free Software Foundation, Inc. 2 Copyright (C) 2015-2021 Free Software Foundation, Inc.
3 This file is part of the GNU C Library. 3 This file is part of the GNU C Library.
4 4
5 The GNU C Library is free software; you can redistribute it and/or 5 The GNU C Library is free software; you can redistribute it and/or
diff --git a/lib/mini-gmp.c b/lib/mini-gmp.c
index d34fe525e4c..de061e673ac 100644
--- a/lib/mini-gmp.c
+++ b/lib/mini-gmp.c
@@ -4521,7 +4521,7 @@ mpz_export (void *r, size_t *countp, int order, size_t size, int endian,
4521 mp_size_t un; 4521 mp_size_t un;
4522 4522
4523 if (nails != 0) 4523 if (nails != 0)
4524 gmp_die ("mpz_import: Nails not supported."); 4524 gmp_die ("mpz_export: Nails not supported.");
4525 4525
4526 assert (order == 1 || order == -1); 4526 assert (order == 1 || order == -1);
4527 assert (endian >= -1 && endian <= 1); 4527 assert (endian >= -1 && endian <= 1);
diff --git a/lib/mktime-internal.h b/lib/mktime-internal.h
index b765a37ee34..9c447bd7b05 100644
--- a/lib/mktime-internal.h
+++ b/lib/mktime-internal.h
@@ -1,5 +1,5 @@
1/* Internals of mktime and related functions 1/* Internals of mktime and related functions
2 Copyright 2016-2020 Free Software Foundation, Inc. 2 Copyright 2016-2021 Free Software Foundation, Inc.
3 This file is part of the GNU C Library. 3 This file is part of the GNU C Library.
4 Contributed by Paul Eggert <eggert@cs.ucla.edu>. 4 Contributed by Paul Eggert <eggert@cs.ucla.edu>.
5 5
diff --git a/lib/nstrftime.c b/lib/nstrftime.c
index 8ba6975552b..2f5e4fbe639 100644
--- a/lib/nstrftime.c
+++ b/lib/nstrftime.c
@@ -19,7 +19,7 @@
19# define USE_IN_EXTENDED_LOCALE_MODEL 1 19# define USE_IN_EXTENDED_LOCALE_MODEL 1
20# define HAVE_STRUCT_ERA_ENTRY 1 20# define HAVE_STRUCT_ERA_ENTRY 1
21# define HAVE_TM_GMTOFF 1 21# define HAVE_TM_GMTOFF 1
22# define HAVE_TM_ZONE 1 22# define HAVE_STRUCT_TM_TM_ZONE 1
23# define HAVE_TZNAME 1 23# define HAVE_TZNAME 1
24# include "../locale/localeinfo.h" 24# include "../locale/localeinfo.h"
25#else 25#else
@@ -499,7 +499,7 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
499#endif 499#endif
500 500
501 zone = NULL; 501 zone = NULL;
502#if HAVE_TM_ZONE 502#if HAVE_STRUCT_TM_TM_ZONE
503 /* The POSIX test suite assumes that setting 503 /* The POSIX test suite assumes that setting
504 the environment variable TZ to a new value before calling strftime() 504 the environment variable TZ to a new value before calling strftime()
505 will influence the result (the %Z format) even if the information in 505 will influence the result (the %Z format) even if the information in
@@ -516,7 +516,7 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
516 } 516 }
517 else 517 else
518 { 518 {
519# if !HAVE_TM_ZONE 519# if !HAVE_STRUCT_TM_TM_ZONE
520 /* Infer the zone name from *TZ instead of from TZNAME. */ 520 /* Infer the zone name from *TZ instead of from TZNAME. */
521 tzname_vec = tz->tzname_copy; 521 tzname_vec = tz->tzname_copy;
522# endif 522# endif
diff --git a/lib/regex.c b/lib/regex.c
index 88173bb1052..f76a416b3b5 100644
--- a/lib/regex.c
+++ b/lib/regex.c
@@ -1,5 +1,5 @@
1/* Extended regular expression matching and search library. 1/* Extended regular expression matching and search library.
2 Copyright (C) 2002-2020 Free Software Foundation, Inc. 2 Copyright (C) 2002-2021 Free Software Foundation, Inc.
3 This file is part of the GNU C Library. 3 This file is part of the GNU C Library.
4 Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>. 4 Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
5 5
diff --git a/lib/regex_internal.h b/lib/regex_internal.h
index be2fa4fe78e..4c634edcbfa 100644
--- a/lib/regex_internal.h
+++ b/lib/regex_internal.h
@@ -32,6 +32,7 @@
32#include <stdbool.h> 32#include <stdbool.h>
33#include <stdint.h> 33#include <stdint.h>
34 34
35#include <dynarray.h>
35#include <intprops.h> 36#include <intprops.h>
36#include <verify.h> 37#include <verify.h>
37 38
@@ -444,25 +445,6 @@ typedef struct re_dfa_t re_dfa_t;
444#define re_string_skip_bytes(pstr,idx) ((pstr)->cur_idx += (idx)) 445#define re_string_skip_bytes(pstr,idx) ((pstr)->cur_idx += (idx))
445#define re_string_set_index(pstr,idx) ((pstr)->cur_idx = (idx)) 446#define re_string_set_index(pstr,idx) ((pstr)->cur_idx = (idx))
446 447
447#if defined _LIBC || HAVE_ALLOCA
448# include <alloca.h>
449#endif
450
451#ifndef _LIBC
452# if HAVE_ALLOCA
453/* The OS usually guarantees only one guard page at the bottom of the stack,
454 and a page size can be as small as 4096 bytes. So we cannot safely
455 allocate anything larger than 4096 bytes. Also care for the possibility
456 of a few compiler-allocated temporary stack slots. */
457# define __libc_use_alloca(n) ((n) < 4032)
458# else
459/* alloca is implemented with malloc, so just use malloc. */
460# define __libc_use_alloca(n) 0
461# undef alloca
462# define alloca(n) malloc (n)
463# endif
464#endif
465
466#ifdef _LIBC 448#ifdef _LIBC
467# define MALLOC_0_IS_NONNULL 1 449# define MALLOC_0_IS_NONNULL 1
468#elif !defined MALLOC_0_IS_NONNULL 450#elif !defined MALLOC_0_IS_NONNULL
@@ -848,12 +830,14 @@ re_string_elem_size_at (const re_string_t *pstr, Idx idx)
848} 830}
849#endif /* RE_ENABLE_I18N */ 831#endif /* RE_ENABLE_I18N */
850 832
851#ifndef FALLTHROUGH 833#ifdef _LIBC
852# if (__GNUC__ >= 7) || (__clang_major__ >= 10) 834# if __GNUC__ >= 7
853# define FALLTHROUGH __attribute__ ((__fallthrough__)) 835# define FALLTHROUGH __attribute__ ((__fallthrough__))
854# else 836# else
855# define FALLTHROUGH ((void) 0) 837# define FALLTHROUGH ((void) 0)
856# endif 838# endif
839#else
840# include "attribute.h"
857#endif 841#endif
858 842
859#endif /* _REGEX_INTERNAL_H */ 843#endif /* _REGEX_INTERNAL_H */
diff --git a/lib/regexec.c b/lib/regexec.c
index 395e37db591..15dc57bd0e6 100644
--- a/lib/regexec.c
+++ b/lib/regexec.c
@@ -1,5 +1,5 @@
1/* Extended regular expression matching and search library. 1/* Extended regular expression matching and search library.
2 Copyright (C) 2002-2020 Free Software Foundation, Inc. 2 Copyright (C) 2002-2021 Free Software Foundation, Inc.
3 This file is part of the GNU C Library. 3 This file is part of the GNU C Library.
4 Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>. 4 Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
5 5
@@ -1355,6 +1355,12 @@ pop_fail_stack (struct re_fail_stack_t *fs, Idx *pidx, Idx nregs,
1355 return fs->stack[num].node; 1355 return fs->stack[num].node;
1356} 1356}
1357 1357
1358
1359#define DYNARRAY_STRUCT regmatch_list
1360#define DYNARRAY_ELEMENT regmatch_t
1361#define DYNARRAY_PREFIX regmatch_list_
1362#include <malloc/dynarray-skeleton.c>
1363
1358/* Set the positions where the subexpressions are starts/ends to registers 1364/* Set the positions where the subexpressions are starts/ends to registers
1359 PMATCH. 1365 PMATCH.
1360 Note: We assume that pmatch[0] is already set, and 1366 Note: We assume that pmatch[0] is already set, and
@@ -1370,8 +1376,8 @@ set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch,
1370 re_node_set eps_via_nodes; 1376 re_node_set eps_via_nodes;
1371 struct re_fail_stack_t *fs; 1377 struct re_fail_stack_t *fs;
1372 struct re_fail_stack_t fs_body = { 0, 2, NULL }; 1378 struct re_fail_stack_t fs_body = { 0, 2, NULL };
1373 regmatch_t *prev_idx_match; 1379 struct regmatch_list prev_match;
1374 bool prev_idx_match_malloced = false; 1380 regmatch_list_init (&prev_match);
1375 1381
1376 DEBUG_ASSERT (nmatch > 1); 1382 DEBUG_ASSERT (nmatch > 1);
1377 DEBUG_ASSERT (mctx->state_log != NULL); 1383 DEBUG_ASSERT (mctx->state_log != NULL);
@@ -1388,18 +1394,13 @@ set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch,
1388 cur_node = dfa->init_node; 1394 cur_node = dfa->init_node;
1389 re_node_set_init_empty (&eps_via_nodes); 1395 re_node_set_init_empty (&eps_via_nodes);
1390 1396
1391 if (__libc_use_alloca (nmatch * sizeof (regmatch_t))) 1397 if (!regmatch_list_resize (&prev_match, nmatch))
1392 prev_idx_match = (regmatch_t *) alloca (nmatch * sizeof (regmatch_t));
1393 else
1394 { 1398 {
1395 prev_idx_match = re_malloc (regmatch_t, nmatch); 1399 regmatch_list_free (&prev_match);
1396 if (prev_idx_match == NULL) 1400 free_fail_stack_return (fs);
1397 { 1401 return REG_ESPACE;
1398 free_fail_stack_return (fs);
1399 return REG_ESPACE;
1400 }
1401 prev_idx_match_malloced = true;
1402 } 1402 }
1403 regmatch_t *prev_idx_match = regmatch_list_begin (&prev_match);
1403 memcpy (prev_idx_match, pmatch, sizeof (regmatch_t) * nmatch); 1404 memcpy (prev_idx_match, pmatch, sizeof (regmatch_t) * nmatch);
1404 1405
1405 for (idx = pmatch[0].rm_so; idx <= pmatch[0].rm_eo ;) 1406 for (idx = pmatch[0].rm_so; idx <= pmatch[0].rm_eo ;)
@@ -1417,8 +1418,7 @@ set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch,
1417 if (reg_idx == nmatch) 1418 if (reg_idx == nmatch)
1418 { 1419 {
1419 re_node_set_free (&eps_via_nodes); 1420 re_node_set_free (&eps_via_nodes);
1420 if (prev_idx_match_malloced) 1421 regmatch_list_free (&prev_match);
1421 re_free (prev_idx_match);
1422 return free_fail_stack_return (fs); 1422 return free_fail_stack_return (fs);
1423 } 1423 }
1424 cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch, 1424 cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch,
@@ -1427,8 +1427,7 @@ set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch,
1427 else 1427 else
1428 { 1428 {
1429 re_node_set_free (&eps_via_nodes); 1429 re_node_set_free (&eps_via_nodes);
1430 if (prev_idx_match_malloced) 1430 regmatch_list_free (&prev_match);
1431 re_free (prev_idx_match);
1432 return REG_NOERROR; 1431 return REG_NOERROR;
1433 } 1432 }
1434 } 1433 }
@@ -1442,8 +1441,7 @@ set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch,
1442 if (__glibc_unlikely (cur_node == -2)) 1441 if (__glibc_unlikely (cur_node == -2))
1443 { 1442 {
1444 re_node_set_free (&eps_via_nodes); 1443 re_node_set_free (&eps_via_nodes);
1445 if (prev_idx_match_malloced) 1444 regmatch_list_free (&prev_match);
1446 re_free (prev_idx_match);
1447 free_fail_stack_return (fs); 1445 free_fail_stack_return (fs);
1448 return REG_ESPACE; 1446 return REG_ESPACE;
1449 } 1447 }
@@ -1453,15 +1451,13 @@ set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch,
1453 else 1451 else
1454 { 1452 {
1455 re_node_set_free (&eps_via_nodes); 1453 re_node_set_free (&eps_via_nodes);
1456 if (prev_idx_match_malloced) 1454 regmatch_list_free (&prev_match);
1457 re_free (prev_idx_match);
1458 return REG_NOMATCH; 1455 return REG_NOMATCH;
1459 } 1456 }
1460 } 1457 }
1461 } 1458 }
1462 re_node_set_free (&eps_via_nodes); 1459 re_node_set_free (&eps_via_nodes);
1463 if (prev_idx_match_malloced) 1460 regmatch_list_free (&prev_match);
1464 re_free (prev_idx_match);
1465 return free_fail_stack_return (fs); 1461 return free_fail_stack_return (fs);
1466} 1462}
1467 1463
@@ -3251,7 +3247,7 @@ expand_bkref_cache (re_match_context_t *mctx, re_node_set *cur_nodes,
3251/* Build transition table for the state. 3247/* Build transition table for the state.
3252 Return true if successful. */ 3248 Return true if successful. */
3253 3249
3254static bool 3250static bool __attribute_noinline__
3255build_trtable (const re_dfa_t *dfa, re_dfastate_t *state) 3251build_trtable (const re_dfa_t *dfa, re_dfastate_t *state)
3256{ 3252{
3257 reg_errcode_t err; 3253 reg_errcode_t err;
@@ -3259,36 +3255,20 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state)
3259 int ch; 3255 int ch;
3260 bool need_word_trtable = false; 3256 bool need_word_trtable = false;
3261 bitset_word_t elem, mask; 3257 bitset_word_t elem, mask;
3262 bool dests_node_malloced = false;
3263 bool dest_states_malloced = false;
3264 Idx ndests; /* Number of the destination states from 'state'. */ 3258 Idx ndests; /* Number of the destination states from 'state'. */
3265 re_dfastate_t **trtable; 3259 re_dfastate_t **trtable;
3266 re_dfastate_t **dest_states = NULL, **dest_states_word, **dest_states_nl; 3260 re_dfastate_t *dest_states[SBC_MAX];
3267 re_node_set follows, *dests_node; 3261 re_dfastate_t *dest_states_word[SBC_MAX];
3268 bitset_t *dests_ch; 3262 re_dfastate_t *dest_states_nl[SBC_MAX];
3263 re_node_set follows;
3269 bitset_t acceptable; 3264 bitset_t acceptable;
3270 3265
3271 struct dests_alloc
3272 {
3273 re_node_set dests_node[SBC_MAX];
3274 bitset_t dests_ch[SBC_MAX];
3275 } *dests_alloc;
3276
3277 /* We build DFA states which corresponds to the destination nodes 3266 /* We build DFA states which corresponds to the destination nodes
3278 from 'state'. 'dests_node[i]' represents the nodes which i-th 3267 from 'state'. 'dests_node[i]' represents the nodes which i-th
3279 destination state contains, and 'dests_ch[i]' represents the 3268 destination state contains, and 'dests_ch[i]' represents the
3280 characters which i-th destination state accepts. */ 3269 characters which i-th destination state accepts. */
3281 if (__libc_use_alloca (sizeof (struct dests_alloc))) 3270 re_node_set dests_node[SBC_MAX];
3282 dests_alloc = (struct dests_alloc *) alloca (sizeof (struct dests_alloc)); 3271 bitset_t dests_ch[SBC_MAX];
3283 else
3284 {
3285 dests_alloc = re_malloc (struct dests_alloc, 1);
3286 if (__glibc_unlikely (dests_alloc == NULL))
3287 return false;
3288 dests_node_malloced = true;
3289 }
3290 dests_node = dests_alloc->dests_node;
3291 dests_ch = dests_alloc->dests_ch;
3292 3272
3293 /* Initialize transition table. */ 3273 /* Initialize transition table. */
3294 state->word_trtable = state->trtable = NULL; 3274 state->word_trtable = state->trtable = NULL;
@@ -3298,8 +3278,6 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state)
3298 ndests = group_nodes_into_DFAstates (dfa, state, dests_node, dests_ch); 3278 ndests = group_nodes_into_DFAstates (dfa, state, dests_node, dests_ch);
3299 if (__glibc_unlikely (ndests <= 0)) 3279 if (__glibc_unlikely (ndests <= 0))
3300 { 3280 {
3301 if (dests_node_malloced)
3302 re_free (dests_alloc);
3303 /* Return false in case of an error, true otherwise. */ 3281 /* Return false in case of an error, true otherwise. */
3304 if (ndests == 0) 3282 if (ndests == 0)
3305 { 3283 {
@@ -3314,38 +3292,14 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state)
3314 3292
3315 err = re_node_set_alloc (&follows, ndests + 1); 3293 err = re_node_set_alloc (&follows, ndests + 1);
3316 if (__glibc_unlikely (err != REG_NOERROR)) 3294 if (__glibc_unlikely (err != REG_NOERROR))
3317 goto out_free;
3318
3319 /* Avoid arithmetic overflow in size calculation. */
3320 size_t ndests_max
3321 = ((SIZE_MAX - (sizeof (re_node_set) + sizeof (bitset_t)) * SBC_MAX)
3322 / (3 * sizeof (re_dfastate_t *)));
3323 if (__glibc_unlikely (ndests_max < ndests))
3324 goto out_free;
3325
3326 if (__libc_use_alloca ((sizeof (re_node_set) + sizeof (bitset_t)) * SBC_MAX
3327 + ndests * 3 * sizeof (re_dfastate_t *)))
3328 dest_states = (re_dfastate_t **)
3329 alloca (ndests * 3 * sizeof (re_dfastate_t *));
3330 else
3331 { 3295 {
3332 dest_states = re_malloc (re_dfastate_t *, ndests * 3); 3296 out_free:
3333 if (__glibc_unlikely (dest_states == NULL)) 3297 re_node_set_free (&follows);
3334 { 3298 for (i = 0; i < ndests; ++i)
3335out_free: 3299 re_node_set_free (dests_node + i);
3336 if (dest_states_malloced) 3300 return false;
3337 re_free (dest_states);
3338 re_node_set_free (&follows);
3339 for (i = 0; i < ndests; ++i)
3340 re_node_set_free (dests_node + i);
3341 if (dests_node_malloced)
3342 re_free (dests_alloc);
3343 return false;
3344 }
3345 dest_states_malloced = true;
3346 } 3301 }
3347 dest_states_word = dest_states + ndests; 3302
3348 dest_states_nl = dest_states_word + ndests;
3349 bitset_empty (acceptable); 3303 bitset_empty (acceptable);
3350 3304
3351 /* Then build the states for all destinations. */ 3305 /* Then build the states for all destinations. */
@@ -3470,16 +3424,9 @@ out_free:
3470 } 3424 }
3471 } 3425 }
3472 3426
3473 if (dest_states_malloced)
3474 re_free (dest_states);
3475
3476 re_node_set_free (&follows); 3427 re_node_set_free (&follows);
3477 for (i = 0; i < ndests; ++i) 3428 for (i = 0; i < ndests; ++i)
3478 re_node_set_free (dests_node + i); 3429 re_node_set_free (dests_node + i);
3479
3480 if (dests_node_malloced)
3481 re_free (dests_alloc);
3482
3483 return true; 3430 return true;
3484} 3431}
3485 3432
diff --git a/lib/scratch_buffer.h b/lib/scratch_buffer.h
index 3e2b5ef27db..603b0d65d0a 100644
--- a/lib/scratch_buffer.h
+++ b/lib/scratch_buffer.h
@@ -21,6 +21,7 @@
21 21
22#include <libc-config.h> 22#include <libc-config.h>
23 23
24#define __libc_scratch_buffer_dupfree gl_scratch_buffer_dupfree
24#define __libc_scratch_buffer_grow gl_scratch_buffer_grow 25#define __libc_scratch_buffer_grow gl_scratch_buffer_grow
25#define __libc_scratch_buffer_grow_preserve gl_scratch_buffer_grow_preserve 26#define __libc_scratch_buffer_grow_preserve gl_scratch_buffer_grow_preserve
26#define __libc_scratch_buffer_set_array_size gl_scratch_buffer_set_array_size 27#define __libc_scratch_buffer_set_array_size gl_scratch_buffer_set_array_size
diff --git a/lib/stddef.in.h b/lib/stddef.in.h
index ba7195a9102..0f506a5b18b 100644
--- a/lib/stddef.in.h
+++ b/lib/stddef.in.h
@@ -49,6 +49,23 @@
49 49
50# ifndef _@GUARD_PREFIX@_STDDEF_H 50# ifndef _@GUARD_PREFIX@_STDDEF_H
51 51
52/* On AIX 7.2, with xlc in 64-bit mode, <stddef.h> defines max_align_t to a
53 type with alignment 4, but 'long' has alignment 8. */
54# if defined _AIX && defined _ARCH_PPC64
55# if !GNULIB_defined_max_align_t
56# ifdef _MAX_ALIGN_T
57/* /usr/include/stddef.h has already defined max_align_t. Override it. */
58typedef long rpl_max_align_t;
59# define max_align_t rpl_max_align_t
60# else
61/* Prevent /usr/include/stddef.h from defining max_align_t. */
62typedef long max_align_t;
63# define _MAX_ALIGN_T
64# endif
65# define GNULIB_defined_max_align_t 1
66# endif
67# endif
68
52/* The include_next requires a split double-inclusion guard. */ 69/* The include_next requires a split double-inclusion guard. */
53 70
54# @INCLUDE_NEXT@ @NEXT_STDDEF_H@ 71# @INCLUDE_NEXT@ @NEXT_STDDEF_H@
@@ -86,8 +103,10 @@
86 we are currently compiling with gcc. 103 we are currently compiling with gcc.
87 On MSVC, max_align_t is defined only in C++ mode, after <cstddef> was 104 On MSVC, max_align_t is defined only in C++ mode, after <cstddef> was
88 included. Its definition is good since it has an alignment of 8 (on x86 105 included. Its definition is good since it has an alignment of 8 (on x86
89 and x86_64). */ 106 and x86_64).
90#if defined _MSC_VER && defined __cplusplus 107 Similarly on OS/2 kLIBC. */
108#if (defined _MSC_VER || (defined __KLIBC__ && !defined __LIBCN__)) \
109 && defined __cplusplus
91# include <cstddef> 110# include <cstddef>
92#else 111#else
93# if ! (@HAVE_MAX_ALIGN_T@ || defined _GCC_MAX_ALIGN_T) 112# if ! (@HAVE_MAX_ALIGN_T@ || defined _GCC_MAX_ALIGN_T)
diff --git a/lib/string.in.h b/lib/string.in.h
index 9f68e77c767..c76c1820b36 100644
--- a/lib/string.in.h
+++ b/lib/string.in.h
@@ -69,6 +69,14 @@
69# include <unistd.h> 69# include <unistd.h>
70#endif 70#endif
71 71
72/* AIX 7.2 declares ffsl and ffsll in <strings.h>, not in <string.h>. */
73/* But in any case avoid namespace pollution on glibc systems. */
74#if ((@GNULIB_FFSL@ || @GNULIB_FFSLL@ || defined GNULIB_POSIXCHECK) \
75 && defined _AIX) \
76 && ! defined __GLIBC__
77# include <strings.h>
78#endif
79
72/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ 80/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
73 81
74/* The definition of _GL_ARG_NONNULL is copied here. */ 82/* The definition of _GL_ARG_NONNULL is copied here. */
@@ -110,10 +118,18 @@ _GL_WARN_ON_USE (ffsl, "ffsl is not portable - use the ffsl module");
110 118
111/* Find the index of the least-significant set bit. */ 119/* Find the index of the least-significant set bit. */
112#if @GNULIB_FFSLL@ 120#if @GNULIB_FFSLL@
113# if !@HAVE_FFSLL@ 121# if @REPLACE_FFSLL@
122# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
123# define ffsll rpl_ffsll
124# endif
125_GL_FUNCDECL_RPL (ffsll, int, (long long int i));
126_GL_CXXALIAS_RPL (ffsll, int, (long long int i));
127# else
128# if !@HAVE_FFSLL@
114_GL_FUNCDECL_SYS (ffsll, int, (long long int i)); 129_GL_FUNCDECL_SYS (ffsll, int, (long long int i));
115# endif 130# endif
116_GL_CXXALIAS_SYS (ffsll, int, (long long int i)); 131_GL_CXXALIAS_SYS (ffsll, int, (long long int i));
132# endif
117_GL_CXXALIASWARN (ffsll); 133_GL_CXXALIASWARN (ffsll);
118#elif defined GNULIB_POSIXCHECK 134#elif defined GNULIB_POSIXCHECK
119# undef ffsll 135# undef ffsll
diff --git a/lib/sys_stat.in.h b/lib/sys_stat.in.h
index ccdb5cbd143..13d12943cd0 100644
--- a/lib/sys_stat.in.h
+++ b/lib/sys_stat.in.h
@@ -713,11 +713,21 @@ _GL_WARN_ON_USE (mkfifo, "mkfifo is not portable - "
713 713
714 714
715#if @GNULIB_MKFIFOAT@ 715#if @GNULIB_MKFIFOAT@
716# if !@HAVE_MKFIFOAT@ 716# if @REPLACE_MKFIFOAT@
717# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
718# undef mkfifoat
719# define mkfifoat rpl_mkfifoat
720# endif
721_GL_FUNCDECL_RPL (mkfifoat, int, (int fd, char const *file, mode_t mode)
722 _GL_ARG_NONNULL ((2)));
723_GL_CXXALIAS_RPL (mkfifoat, int, (int fd, char const *file, mode_t mode));
724# else
725# if !@HAVE_MKFIFOAT@
717_GL_FUNCDECL_SYS (mkfifoat, int, (int fd, char const *file, mode_t mode) 726_GL_FUNCDECL_SYS (mkfifoat, int, (int fd, char const *file, mode_t mode)
718 _GL_ARG_NONNULL ((2))); 727 _GL_ARG_NONNULL ((2)));
719# endif 728# endif
720_GL_CXXALIAS_SYS (mkfifoat, int, (int fd, char const *file, mode_t mode)); 729_GL_CXXALIAS_SYS (mkfifoat, int, (int fd, char const *file, mode_t mode));
730# endif
721_GL_CXXALIASWARN (mkfifoat); 731_GL_CXXALIASWARN (mkfifoat);
722#elif defined GNULIB_POSIXCHECK 732#elif defined GNULIB_POSIXCHECK
723# undef mkfifoat 733# undef mkfifoat
@@ -756,13 +766,25 @@ _GL_WARN_ON_USE (mknod, "mknod is not portable - "
756 766
757 767
758#if @GNULIB_MKNODAT@ 768#if @GNULIB_MKNODAT@
759# if !@HAVE_MKNODAT@ 769# if @REPLACE_MKNODAT@
770# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
771# undef mknodat
772# define mknodat rpl_mknodat
773# endif
774_GL_FUNCDECL_RPL (mknodat, int,
775 (int fd, char const *file, mode_t mode, dev_t dev)
776 _GL_ARG_NONNULL ((2)));
777_GL_CXXALIAS_RPL (mknodat, int,
778 (int fd, char const *file, mode_t mode, dev_t dev));
779# else
780# if !@HAVE_MKNODAT@
760_GL_FUNCDECL_SYS (mknodat, int, 781_GL_FUNCDECL_SYS (mknodat, int,
761 (int fd, char const *file, mode_t mode, dev_t dev) 782 (int fd, char const *file, mode_t mode, dev_t dev)
762 _GL_ARG_NONNULL ((2))); 783 _GL_ARG_NONNULL ((2)));
763# endif 784# endif
764_GL_CXXALIAS_SYS (mknodat, int, 785_GL_CXXALIAS_SYS (mknodat, int,
765 (int fd, char const *file, mode_t mode, dev_t dev)); 786 (int fd, char const *file, mode_t mode, dev_t dev));
787# endif
766_GL_CXXALIASWARN (mknodat); 788_GL_CXXALIASWARN (mknodat);
767#elif defined GNULIB_POSIXCHECK 789#elif defined GNULIB_POSIXCHECK
768# undef mknodat 790# undef mknodat
diff --git a/lib/tempname.c b/lib/tempname.c
index 3d91deef1e1..e243483eaf8 100644
--- a/lib/tempname.c
+++ b/lib/tempname.c
@@ -22,6 +22,7 @@
22 22
23#include <sys/types.h> 23#include <sys/types.h>
24#include <assert.h> 24#include <assert.h>
25#include <stdbool.h>
25 26
26#include <errno.h> 27#include <errno.h>
27 28
@@ -61,7 +62,8 @@
61# define __gen_tempname gen_tempname 62# define __gen_tempname gen_tempname
62# define __mkdir mkdir 63# define __mkdir mkdir
63# define __open open 64# define __open open
64# define __lxstat64(version, file, buf) lstat (file, buf) 65# define __lstat64(file, buf) lstat (file, buf)
66# define __stat64(file, buf) stat (file, buf)
65# define __getrandom getrandom 67# define __getrandom getrandom
66# define __clock_gettime64 clock_gettime 68# define __clock_gettime64 clock_gettime
67# define __timespec64 timespec 69# define __timespec64 timespec
@@ -76,13 +78,14 @@ typedef uint_fast64_t random_value;
76#define BASE_62_POWER (62LL * 62 * 62 * 62 * 62 * 62 * 62 * 62 * 62 * 62) 78#define BASE_62_POWER (62LL * 62 * 62 * 62 * 62 * 62 * 62 * 62 * 62 * 62)
77 79
78static random_value 80static random_value
79random_bits (random_value var) 81random_bits (random_value var, bool use_getrandom)
80{ 82{
81 random_value r; 83 random_value r;
82 if (__getrandom (&r, sizeof r, 0) == sizeof r) 84 /* Without GRND_NONBLOCK it can be blocked for minutes on some systems. */
85 if (use_getrandom && __getrandom (&r, sizeof r, GRND_NONBLOCK) == sizeof r)
83 return r; 86 return r;
84#if _LIBC || (defined CLOCK_MONOTONIC && HAVE_CLOCK_GETTIME) 87#if _LIBC || (defined CLOCK_MONOTONIC && HAVE_CLOCK_GETTIME)
85 /* Add entropy if getrandom is not supported. */ 88 /* Add entropy if getrandom did not work. */
86 struct __timespec64 tv; 89 struct __timespec64 tv;
87 __clock_gettime64 (CLOCK_MONOTONIC, &tv); 90 __clock_gettime64 (CLOCK_MONOTONIC, &tv);
88 var ^= tv.tv_nsec; 91 var ^= tv.tv_nsec;
@@ -96,7 +99,7 @@ static int
96direxists (const char *dir) 99direxists (const char *dir)
97{ 100{
98 struct_stat64 buf; 101 struct_stat64 buf;
99 return __xstat64 (_STAT_VER, dir, &buf) == 0 && S_ISDIR (buf.st_mode); 102 return __stat64 (dir, &buf) == 0 && S_ISDIR (buf.st_mode);
100} 103}
101 104
102/* Path search algorithm, for tmpnam, tmpfile, etc. If DIR is 105/* Path search algorithm, for tmpnam, tmpfile, etc. If DIR is
@@ -188,7 +191,7 @@ try_nocreate (char *tmpl, void *flags _GL_UNUSED)
188{ 191{
189 struct_stat64 st; 192 struct_stat64 st;
190 193
191 if (__lxstat64 (_STAT_VER, tmpl, &st) == 0 || errno == EOVERFLOW) 194 if (__lstat64 (tmpl, &st) == 0 || errno == EOVERFLOW)
192 __set_errno (EEXIST); 195 __set_errno (EEXIST);
193 return errno == ENOENT ? 0 : -1; 196 return errno == ENOENT ? 0 : -1;
194} 197}
@@ -267,6 +270,13 @@ try_tempname_len (char *tmpl, int suffixlen, void *args,
267 /* How many random base-62 digits can currently be extracted from V. */ 270 /* How many random base-62 digits can currently be extracted from V. */
268 int vdigits = 0; 271 int vdigits = 0;
269 272
273 /* Whether to consume entropy when acquiring random bits. On the
274 first try it's worth the entropy cost with __GT_NOCREATE, which
275 is inherently insecure and can use the entropy to make it a bit
276 less secure. On the (rare) second and later attempts it might
277 help against DoS attacks. */
278 bool use_getrandom = tryfunc == try_nocreate;
279
270 /* Least unfair value for V. If V is less than this, V can generate 280 /* Least unfair value for V. If V is less than this, V can generate
271 BASE_62_DIGITS digits fairly. Otherwise it might be biased. */ 281 BASE_62_DIGITS digits fairly. Otherwise it might be biased. */
272 random_value const unfair_min 282 random_value const unfair_min
@@ -290,7 +300,10 @@ try_tempname_len (char *tmpl, int suffixlen, void *args,
290 if (vdigits == 0) 300 if (vdigits == 0)
291 { 301 {
292 do 302 do
293 v = random_bits (v); 303 {
304 v = random_bits (v, use_getrandom);
305 use_getrandom = true;
306 }
294 while (unfair_min <= v); 307 while (unfair_min <= v);
295 308
296 vdigits = BASE_62_DIGITS; 309 vdigits = BASE_62_DIGITS;
diff --git a/lib/time-internal.h b/lib/time-internal.h
index 63a3f9e3db1..067ee729eda 100644
--- a/lib/time-internal.h
+++ b/lib/time-internal.h
@@ -24,7 +24,7 @@ struct tm_zone
24 members are zero. */ 24 members are zero. */
25 struct tm_zone *next; 25 struct tm_zone *next;
26 26
27#if HAVE_TZNAME && !HAVE_TM_ZONE 27#if HAVE_TZNAME && !HAVE_STRUCT_TM_TM_ZONE
28 /* Copies of recent strings taken from tzname[0] and tzname[1]. 28 /* Copies of recent strings taken from tzname[0] and tzname[1].
29 The copies are in ABBRS, so that they survive tzset. Null if unknown. */ 29 The copies are in ABBRS, so that they survive tzset. Null if unknown. */
30 char *tzname_copy[2]; 30 char *tzname_copy[2];
diff --git a/lib/time.in.h b/lib/time.in.h
index 958dc0bd292..1385980cdf5 100644
--- a/lib/time.in.h
+++ b/lib/time.in.h
@@ -101,6 +101,25 @@ struct __time_t_must_be_integral {
101# define GNULIB_defined_struct_time_t_must_be_integral 1 101# define GNULIB_defined_struct_time_t_must_be_integral 1
102# endif 102# endif
103 103
104/* Define TIME_UTC, a positive integer constant used for timespec_get(). */
105# if ! @TIME_H_DEFINES_TIME_UTC@
106# if !GNULIB_defined_TIME_UTC
107# define TIME_UTC 1
108# define GNULIB_defined_TIME_UTC 1
109# endif
110# endif
111
112/* Set *TS to the current time, and return BASE.
113 Upon failure, return 0. */
114# if @GNULIB_TIMESPEC_GET@
115# if ! @HAVE_TIMESPEC_GET@
116_GL_FUNCDECL_SYS (timespec_get, int, (struct timespec *ts, int base)
117 _GL_ARG_NONNULL ((1)));
118# endif
119_GL_CXXALIAS_SYS (timespec_get, int, (struct timespec *ts, int base));
120_GL_CXXALIASWARN (timespec_get);
121# endif
122
104/* Sleep for at least RQTP seconds unless interrupted, If interrupted, 123/* Sleep for at least RQTP seconds unless interrupted, If interrupted,
105 return -1 and store the remaining time into RMTP. See 124 return -1 and store the remaining time into RMTP. See
106 <https://pubs.opengroup.org/onlinepubs/9699919799/functions/nanosleep.html>. */ 125 <https://pubs.opengroup.org/onlinepubs/9699919799/functions/nanosleep.html>. */
diff --git a/lib/time_rz.c b/lib/time_rz.c
index 65e20cc5661..3ac053c6219 100644
--- a/lib/time_rz.c
+++ b/lib/time_rz.c
@@ -71,7 +71,7 @@ tzalloc (char const *name)
71 if (tz) 71 if (tz)
72 { 72 {
73 tz->next = NULL; 73 tz->next = NULL;
74#if HAVE_TZNAME && !HAVE_TM_ZONE 74#if HAVE_TZNAME && !HAVE_STRUCT_TM_TM_ZONE
75 tz->tzname_copy[0] = tz->tzname_copy[1] = NULL; 75 tz->tzname_copy[0] = tz->tzname_copy[1] = NULL;
76#endif 76#endif
77 tz->tz_is_set = !!name; 77 tz->tz_is_set = !!name;
@@ -83,13 +83,13 @@ tzalloc (char const *name)
83} 83}
84 84
85/* Save into TZ any nontrivial time zone abbreviation used by TM, and 85/* Save into TZ any nontrivial time zone abbreviation used by TM, and
86 update *TM (if HAVE_TM_ZONE) or *TZ (if !HAVE_TM_ZONE && 86 update *TM (if HAVE_STRUCT_TM_TM_ZONE) or *TZ (if
87 HAVE_TZNAME) if they use the abbreviation. Return true if 87 !HAVE_STRUCT_TM_TM_ZONE && HAVE_TZNAME) if they use the abbreviation.
88 successful, false (setting errno) otherwise. */ 88 Return true if successful, false (setting errno) otherwise. */
89static bool 89static bool
90save_abbr (timezone_t tz, struct tm *tm) 90save_abbr (timezone_t tz, struct tm *tm)
91{ 91{
92#if HAVE_TM_ZONE || HAVE_TZNAME 92#if HAVE_STRUCT_TM_TM_ZONE || HAVE_TZNAME
93 char const *zone = NULL; 93 char const *zone = NULL;
94 char *zone_copy = (char *) ""; 94 char *zone_copy = (char *) "";
95 95
@@ -97,7 +97,7 @@ save_abbr (timezone_t tz, struct tm *tm)
97 int tzname_index = -1; 97 int tzname_index = -1;
98# endif 98# endif
99 99
100# if HAVE_TM_ZONE 100# if HAVE_STRUCT_TM_TM_ZONE
101 zone = tm->tm_zone; 101 zone = tm->tm_zone;
102# endif 102# endif
103 103
@@ -145,7 +145,7 @@ save_abbr (timezone_t tz, struct tm *tm)
145 } 145 }
146 146
147 /* Replace the zone name so that its lifetime matches that of TZ. */ 147 /* Replace the zone name so that its lifetime matches that of TZ. */
148# if HAVE_TM_ZONE 148# if HAVE_STRUCT_TM_TM_ZONE
149 tm->tm_zone = zone_copy; 149 tm->tm_zone = zone_copy;
150# else 150# else
151 if (0 <= tzname_index) 151 if (0 <= tzname_index)
@@ -303,7 +303,7 @@ mktime_z (timezone_t tz, struct tm *tm)
303 tm_1.tm_isdst = tm->tm_isdst; 303 tm_1.tm_isdst = tm->tm_isdst;
304 time_t t = mktime (&tm_1); 304 time_t t = mktime (&tm_1);
305 bool ok = 0 <= tm_1.tm_yday; 305 bool ok = 0 <= tm_1.tm_yday;
306#if HAVE_TM_ZONE || HAVE_TZNAME 306#if HAVE_STRUCT_TM_TM_ZONE || HAVE_TZNAME
307 ok = ok && save_abbr (tz, &tm_1); 307 ok = ok && save_abbr (tz, &tm_1);
308#endif 308#endif
309 if (revert_tz (old_tz) && ok) 309 if (revert_tz (old_tz) && ok)
diff --git a/lib/timegm.c b/lib/timegm.c
index fa30943084d..e4127e71c0b 100644
--- a/lib/timegm.c
+++ b/lib/timegm.c
@@ -1,6 +1,6 @@
1/* Convert UTC calendar time to simple time. Like mktime but assumes UTC. 1/* Convert UTC calendar time to simple time. Like mktime but assumes UTC.
2 2
3 Copyright (C) 1994-2020 Free Software Foundation, Inc. 3 Copyright (C) 1994-2021 Free Software Foundation, Inc.
4 This file is part of the GNU C Library. 4 This file is part of the GNU C Library.
5 5
6 The GNU C Library is free software; you can redistribute it and/or 6 The GNU C Library is free software; you can redistribute it and/or
diff --git a/lib/utimens.c b/lib/utimens.c
index 5bbae058132..44d1ea003e2 100644
--- a/lib/utimens.c
+++ b/lib/utimens.c
@@ -27,6 +27,7 @@
27#include <errno.h> 27#include <errno.h>
28#include <fcntl.h> 28#include <fcntl.h>
29#include <stdbool.h> 29#include <stdbool.h>
30#include <string.h>
30#include <sys/stat.h> 31#include <sys/stat.h>
31#include <sys/time.h> 32#include <sys/time.h>
32#include <unistd.h> 33#include <unistd.h>
@@ -52,7 +53,9 @@
52 53
53/* Avoid recursion with rpl_futimens or rpl_utimensat. */ 54/* Avoid recursion with rpl_futimens or rpl_utimensat. */
54#undef futimens 55#undef futimens
55#undef utimensat 56#if !HAVE_NEARLY_WORKING_UTIMENSAT
57# undef utimensat
58#endif
56 59
57/* Solaris 9 mistakenly succeeds when given a non-directory with a 60/* Solaris 9 mistakenly succeeds when given a non-directory with a
58 trailing slash. Force the use of rpl_stat for a fix. */ 61 trailing slash. Force the use of rpl_stat for a fix. */
@@ -246,6 +249,20 @@ fdutimens (int fd, char const *file, struct timespec const timespec[2])
246# if HAVE_UTIMENSAT 249# if HAVE_UTIMENSAT
247 if (fd < 0) 250 if (fd < 0)
248 { 251 {
252# if defined __APPLE__ && defined __MACH__
253 size_t len = strlen (file);
254 if (len > 0 && file[len - 1] == '/')
255 {
256 struct stat statbuf;
257 if (stat (file, &statbuf) < 0)
258 return -1;
259 if (!S_ISDIR (statbuf.st_mode))
260 {
261 errno = ENOTDIR;
262 return -1;
263 }
264 }
265# endif
249 result = utimensat (AT_FDCWD, file, ts, 0); 266 result = utimensat (AT_FDCWD, file, ts, 0);
250# ifdef __linux__ 267# ifdef __linux__
251 /* Work around a kernel bug: 268 /* Work around a kernel bug:
diff --git a/lib/utimensat.c b/lib/utimensat.c
index 2cea64f6982..9fdecd681f6 100644
--- a/lib/utimensat.c
+++ b/lib/utimensat.c
@@ -24,14 +24,40 @@
24#include <errno.h> 24#include <errno.h>
25#include <fcntl.h> 25#include <fcntl.h>
26#include <stdlib.h> 26#include <stdlib.h>
27#include <string.h>
28#include <sys/stat.h>
27 29
28#include "stat-time.h" 30#include "stat-time.h"
29#include "timespec.h" 31#include "timespec.h"
30#include "utimens.h" 32#include "utimens.h"
31 33
32#if HAVE_UTIMENSAT 34#if HAVE_NEARLY_WORKING_UTIMENSAT
33 35
36/* Use the original utimensat(), but correct the trailing slash handling. */
37int
38rpl_utimensat (int fd, char const *file, struct timespec const times[2],
39 int flag)
34# undef utimensat 40# undef utimensat
41{
42 size_t len = strlen (file);
43 if (len && file[len - 1] == '/')
44 {
45 struct stat st;
46 if (fstatat (fd, file, &st, flag & AT_SYMLINK_NOFOLLOW) < 0)
47 return -1;
48 if (!S_ISDIR (st.st_mode))
49 {
50 errno = ENOTDIR;
51 return -1;
52 }
53 }
54
55 return utimensat (fd, file, times, flag);
56}
57
58#else
59
60# if HAVE_UTIMENSAT
35 61
36/* If we have a native utimensat, but are compiling this file, then 62/* If we have a native utimensat, but are compiling this file, then
37 utimensat was defined to rpl_utimensat by our replacement 63 utimensat was defined to rpl_utimensat by our replacement
@@ -42,24 +68,25 @@
42 local_utimensat provides the fallback manipulation. */ 68 local_utimensat provides the fallback manipulation. */
43 69
44static int local_utimensat (int, char const *, struct timespec const[2], int); 70static int local_utimensat (int, char const *, struct timespec const[2], int);
45# define AT_FUNC_NAME local_utimensat 71# define AT_FUNC_NAME local_utimensat
46 72
47/* Like utimensat, but work around native bugs. */ 73/* Like utimensat, but work around native bugs. */
48 74
49int 75int
50rpl_utimensat (int fd, char const *file, struct timespec const times[2], 76rpl_utimensat (int fd, char const *file, struct timespec const times[2],
51 int flag) 77 int flag)
78# undef utimensat
52{ 79{
53# if defined __linux__ || defined __sun 80# if defined __linux__ || defined __sun
54 struct timespec ts[2]; 81 struct timespec ts[2];
55# endif 82# endif
56 83
57 /* See comments in utimens.c for details. */ 84 /* See comments in utimens.c for details. */
58 static int utimensat_works_really; /* 0 = unknown, 1 = yes, -1 = no. */ 85 static int utimensat_works_really; /* 0 = unknown, 1 = yes, -1 = no. */
59 if (0 <= utimensat_works_really) 86 if (0 <= utimensat_works_really)
60 { 87 {
61 int result; 88 int result;
62# if defined __linux__ || defined __sun 89# if defined __linux__ || defined __sun
63 struct stat st; 90 struct stat st;
64 /* As recently as Linux kernel 2.6.32 (Dec 2009), several file 91 /* As recently as Linux kernel 2.6.32 (Dec 2009), several file
65 systems (xfs, ntfs-3g) have bugs with a single UTIME_OMIT, 92 systems (xfs, ntfs-3g) have bugs with a single UTIME_OMIT,
@@ -90,7 +117,7 @@ rpl_utimensat (int fd, char const *file, struct timespec const times[2],
90 ts[1] = times[1]; 117 ts[1] = times[1];
91 times = ts; 118 times = ts;
92 } 119 }
93# ifdef __hppa__ 120# ifdef __hppa__
94 /* Linux kernel 2.6.22.19 on hppa does not reject invalid tv_nsec 121 /* Linux kernel 2.6.22.19 on hppa does not reject invalid tv_nsec
95 values. */ 122 values. */
96 else if (times 123 else if (times
@@ -104,8 +131,36 @@ rpl_utimensat (int fd, char const *file, struct timespec const times[2],
104 errno = EINVAL; 131 errno = EINVAL;
105 return -1; 132 return -1;
106 } 133 }
134# endif
135# endif
136# if defined __APPLE__ && defined __MACH__
137 /* macOS 10.13 does not reject invalid tv_nsec values either. */
138 if (times
139 && ((times[0].tv_nsec != UTIME_OMIT
140 && times[0].tv_nsec != UTIME_NOW
141 && ! (0 <= times[0].tv_nsec
142 && times[0].tv_nsec < TIMESPEC_HZ))
143 || (times[1].tv_nsec != UTIME_OMIT
144 && times[1].tv_nsec != UTIME_NOW
145 && ! (0 <= times[1].tv_nsec
146 && times[1].tv_nsec < TIMESPEC_HZ))))
147 {
148 errno = EINVAL;
149 return -1;
150 }
151 size_t len = strlen (file);
152 if (len > 0 && file[len - 1] == '/')
153 {
154 struct stat statbuf;
155 if (fstatat (fd, file, &statbuf, 0) < 0)
156 return -1;
157 if (!S_ISDIR (statbuf.st_mode))
158 {
159 errno = ENOTDIR;
160 return -1;
161 }
162 }
107# endif 163# endif
108# endif
109 result = utimensat (fd, file, times, flag); 164 result = utimensat (fd, file, times, flag);
110 /* Linux kernel 2.6.25 has a bug where it returns EINVAL for 165 /* Linux kernel 2.6.25 has a bug where it returns EINVAL for
111 UTIME_NOW or UTIME_OMIT with non-zero tv_sec, which 166 UTIME_NOW or UTIME_OMIT with non-zero tv_sec, which
@@ -129,11 +184,11 @@ rpl_utimensat (int fd, char const *file, struct timespec const times[2],
129 return local_utimensat (fd, file, times, flag); 184 return local_utimensat (fd, file, times, flag);
130} 185}
131 186
132#else /* !HAVE_UTIMENSAT */ 187# else /* !HAVE_UTIMENSAT */
133 188
134# define AT_FUNC_NAME utimensat 189# define AT_FUNC_NAME utimensat
135 190
136#endif /* !HAVE_UTIMENSAT */ 191# endif /* !HAVE_UTIMENSAT */
137 192
138/* Set the access and modification timestamps of FILE to be 193/* Set the access and modification timestamps of FILE to be
139 TIMESPEC[0] and TIMESPEC[1], respectively; relative to directory 194 TIMESPEC[0] and TIMESPEC[1], respectively; relative to directory
@@ -146,15 +201,17 @@ rpl_utimensat (int fd, char const *file, struct timespec const times[2],
146 Return 0 on success, -1 (setting errno) on failure. */ 201 Return 0 on success, -1 (setting errno) on failure. */
147 202
148/* AT_FUNC_NAME is now utimensat or local_utimensat. */ 203/* AT_FUNC_NAME is now utimensat or local_utimensat. */
149#define AT_FUNC_F1 lutimens 204# define AT_FUNC_F1 lutimens
150#define AT_FUNC_F2 utimens 205# define AT_FUNC_F2 utimens
151#define AT_FUNC_USE_F1_COND AT_SYMLINK_NOFOLLOW 206# define AT_FUNC_USE_F1_COND AT_SYMLINK_NOFOLLOW
152#define AT_FUNC_POST_FILE_PARAM_DECLS , struct timespec const ts[2], int flag 207# define AT_FUNC_POST_FILE_PARAM_DECLS , struct timespec const ts[2], int flag
153#define AT_FUNC_POST_FILE_ARGS , ts 208# define AT_FUNC_POST_FILE_ARGS , ts
154#include "at-func.c" 209# include "at-func.c"
155#undef AT_FUNC_NAME 210# undef AT_FUNC_NAME
156#undef AT_FUNC_F1 211# undef AT_FUNC_F1
157#undef AT_FUNC_F2 212# undef AT_FUNC_F2
158#undef AT_FUNC_USE_F1_COND 213# undef AT_FUNC_USE_F1_COND
159#undef AT_FUNC_POST_FILE_PARAM_DECLS 214# undef AT_FUNC_POST_FILE_PARAM_DECLS
160#undef AT_FUNC_POST_FILE_ARGS 215# undef AT_FUNC_POST_FILE_ARGS
216
217#endif /* !HAVE_NEARLY_WORKING_UTIMENSAT */
diff --git a/lib/verify.h b/lib/verify.h
index 3cdcdca5671..65514c34b9e 100644
--- a/lib/verify.h
+++ b/lib/verify.h
@@ -22,16 +22,10 @@
22 22
23 23
24/* Define _GL_HAVE__STATIC_ASSERT to 1 if _Static_assert (R, DIAGNOSTIC) 24/* Define _GL_HAVE__STATIC_ASSERT to 1 if _Static_assert (R, DIAGNOSTIC)
25 works as per C11. This is supported by GCC 4.6.0 and later, in C 25 works as per C11. This is supported by GCC 4.6.0+ and by clang 4+.
26 mode, and by clang (also in C++ mode).
27 26
28 Define _GL_HAVE__STATIC_ASSERT1 to 1 if _Static_assert (R) works as 27 Define _GL_HAVE__STATIC_ASSERT1 to 1 if _Static_assert (R) works as
29 per C2X. This is supported by GCC 9.1 and later, and by clang in 28 per C2X. This is supported by GCC 9.1+.
30 C++1z mode.
31
32 Define _GL_HAVE_STATIC_ASSERT1 if static_assert (R) works as per
33 C++17. This is supported by GCC 9.1 and later, and by clang in
34 C++1z mode.
35 29
36 Support compilers claiming conformance to the relevant standard, 30 Support compilers claiming conformance to the relevant standard,
37 and also support GCC when not pedantic. If we were willing to slow 31 and also support GCC when not pedantic. If we were willing to slow
@@ -47,18 +41,6 @@
47 || (!defined __STRICT_ANSI__ && 9 <= __GNUC__)) 41 || (!defined __STRICT_ANSI__ && 9 <= __GNUC__))
48# define _GL_HAVE__STATIC_ASSERT1 1 42# define _GL_HAVE__STATIC_ASSERT1 1
49# endif 43# endif
50#else
51# if 4 <= __clang_major__
52# define _GL_HAVE__STATIC_ASSERT 1
53# endif
54# if 4 <= __clang_major__ && 201411 <= __cpp_static_assert
55# define _GL_HAVE__STATIC_ASSERT1 1
56# endif
57# if 201703L <= __cplusplus \
58 || 9 <= __GNUC__ \
59 || (4 <= __clang_major__ && 201411 <= __cpp_static_assert)
60# define _GL_HAVE_STATIC_ASSERT1 1
61# endif
62#endif 44#endif
63 45
64/* FreeBSD 9.1 <sys/cdefs.h>, included by <stddef.h> and lots of other 46/* FreeBSD 9.1 <sys/cdefs.h>, included by <stddef.h> and lots of other
@@ -225,7 +207,9 @@ template <int w>
225 Unfortunately, unlike C11, this implementation must appear as an 207 Unfortunately, unlike C11, this implementation must appear as an
226 ordinary declaration, and cannot appear inside struct { ... }. */ 208 ordinary declaration, and cannot appear inside struct { ... }. */
227 209
228#if defined _GL_HAVE__STATIC_ASSERT 210#if 200410 <= __cpp_static_assert
211# define _GL_VERIFY(R, DIAGNOSTIC, ...) static_assert (R, DIAGNOSTIC)
212#elif defined _GL_HAVE__STATIC_ASSERT
229# define _GL_VERIFY(R, DIAGNOSTIC, ...) _Static_assert (R, DIAGNOSTIC) 213# define _GL_VERIFY(R, DIAGNOSTIC, ...) _Static_assert (R, DIAGNOSTIC)
230#else 214#else
231# define _GL_VERIFY(R, DIAGNOSTIC, ...) \ 215# define _GL_VERIFY(R, DIAGNOSTIC, ...) \
@@ -239,7 +223,7 @@ template <int w>
239# define _Static_assert(...) \ 223# define _Static_assert(...) \
240 _GL_VERIFY (__VA_ARGS__, "static assertion failed", -) 224 _GL_VERIFY (__VA_ARGS__, "static assertion failed", -)
241# endif 225# endif
242# if !defined _GL_HAVE_STATIC_ASSERT1 && !defined static_assert 226# if __cpp_static_assert < 201411 && !defined static_assert
243# define static_assert _Static_assert /* C11 requires this #define. */ 227# define static_assert _Static_assert /* C11 requires this #define. */
244# endif 228# endif
245#endif 229#endif