diff options
| author | Paul Eggert | 2021-01-22 11:45:38 -0800 |
|---|---|---|
| committer | Paul Eggert | 2021-01-22 12:02:55 -0800 |
| commit | a900e641fa1fd765799f12a7f699f768ebfccfe8 (patch) | |
| tree | a874eba952d3e51190a2bfe26cfe6c1635e9fda1 /lib | |
| parent | 9143eba0c6861f467c18bc52d66e6f5c573be56b (diff) | |
| download | emacs-a900e641fa1fd765799f12a7f699f768ebfccfe8.tar.gz emacs-a900e641fa1fd765799f12a7f699f768ebfccfe8.zip | |
Update from Gnulib by running admin/merge-gnulib
Diffstat (limited to 'lib')
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. */ | ||
| 90 | enum { 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 |
| 149 | static char const dir_suffix[] = "/"; | 145 | static char const dir_suffix[] = "/"; |
| 150 | #else | 146 | # else |
| 151 | static char const dir_suffix[] = "/./"; | 147 | static 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 | ||
| 201 | static char * | 197 | static char * |
| 202 | realpath_stk (const char *name, char *resolved, | 198 | realpath_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 | } |
| 444 | libc_hidden_def (__realpath) | 440 | libc_hidden_def (__realpath) |
| 445 | versioned_symbol (libc, __realpath, realpath, GLIBC_2_3); | 441 | versioned_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) | |||
| 63 | int | 64 | int |
| 64 | fchmodat (int dir, char const *file, mode_t mode, int flags) | 65 | fchmodat (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 | |||
| 27 | rpl_free (void *p) | 27 | rpl_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@ | |||
| 516 | GNULIB_SYMLINKAT = @GNULIB_SYMLINKAT@ | 516 | GNULIB_SYMLINKAT = @GNULIB_SYMLINKAT@ |
| 517 | GNULIB_SYSTEM_POSIX = @GNULIB_SYSTEM_POSIX@ | 517 | GNULIB_SYSTEM_POSIX = @GNULIB_SYSTEM_POSIX@ |
| 518 | GNULIB_TIMEGM = @GNULIB_TIMEGM@ | 518 | GNULIB_TIMEGM = @GNULIB_TIMEGM@ |
| 519 | GNULIB_TIMESPEC_GET = @GNULIB_TIMESPEC_GET@ | ||
| 519 | GNULIB_TIME_R = @GNULIB_TIME_R@ | 520 | GNULIB_TIME_R = @GNULIB_TIME_R@ |
| 520 | GNULIB_TIME_RZ = @GNULIB_TIME_RZ@ | 521 | GNULIB_TIME_RZ = @GNULIB_TIME_RZ@ |
| 521 | GNULIB_TMPFILE = @GNULIB_TMPFILE@ | 522 | GNULIB_TMPFILE = @GNULIB_TMPFILE@ |
| @@ -746,6 +747,7 @@ HAVE_SYS_SELECT_H = @HAVE_SYS_SELECT_H@ | |||
| 746 | HAVE_SYS_TIME_H = @HAVE_SYS_TIME_H@ | 747 | HAVE_SYS_TIME_H = @HAVE_SYS_TIME_H@ |
| 747 | HAVE_SYS_TYPES_H = @HAVE_SYS_TYPES_H@ | 748 | HAVE_SYS_TYPES_H = @HAVE_SYS_TYPES_H@ |
| 748 | HAVE_TIMEGM = @HAVE_TIMEGM@ | 749 | HAVE_TIMEGM = @HAVE_TIMEGM@ |
| 750 | HAVE_TIMESPEC_GET = @HAVE_TIMESPEC_GET@ | ||
| 749 | HAVE_TIMEZONE_T = @HAVE_TIMEZONE_T@ | 751 | HAVE_TIMEZONE_T = @HAVE_TIMEZONE_T@ |
| 750 | HAVE_TYPE_VOLATILE_SIG_ATOMIC_T = @HAVE_TYPE_VOLATILE_SIG_ATOMIC_T@ | 752 | HAVE_TYPE_VOLATILE_SIG_ATOMIC_T = @HAVE_TYPE_VOLATILE_SIG_ATOMIC_T@ |
| 751 | HAVE_UNISTD_H = @HAVE_UNISTD_H@ | 753 | HAVE_UNISTD_H = @HAVE_UNISTD_H@ |
| @@ -949,6 +951,7 @@ REPLACE_FCNTL = @REPLACE_FCNTL@ | |||
| 949 | REPLACE_FDOPEN = @REPLACE_FDOPEN@ | 951 | REPLACE_FDOPEN = @REPLACE_FDOPEN@ |
| 950 | REPLACE_FDOPENDIR = @REPLACE_FDOPENDIR@ | 952 | REPLACE_FDOPENDIR = @REPLACE_FDOPENDIR@ |
| 951 | REPLACE_FFLUSH = @REPLACE_FFLUSH@ | 953 | REPLACE_FFLUSH = @REPLACE_FFLUSH@ |
| 954 | REPLACE_FFSLL = @REPLACE_FFSLL@ | ||
| 952 | REPLACE_FOPEN = @REPLACE_FOPEN@ | 955 | REPLACE_FOPEN = @REPLACE_FOPEN@ |
| 953 | REPLACE_FPRINTF = @REPLACE_FPRINTF@ | 956 | REPLACE_FPRINTF = @REPLACE_FPRINTF@ |
| 954 | REPLACE_FPURGE = @REPLACE_FPURGE@ | 957 | REPLACE_FPURGE = @REPLACE_FPURGE@ |
| @@ -989,7 +992,9 @@ REPLACE_MEMCHR = @REPLACE_MEMCHR@ | |||
| 989 | REPLACE_MEMMEM = @REPLACE_MEMMEM@ | 992 | REPLACE_MEMMEM = @REPLACE_MEMMEM@ |
| 990 | REPLACE_MKDIR = @REPLACE_MKDIR@ | 993 | REPLACE_MKDIR = @REPLACE_MKDIR@ |
| 991 | REPLACE_MKFIFO = @REPLACE_MKFIFO@ | 994 | REPLACE_MKFIFO = @REPLACE_MKFIFO@ |
| 995 | REPLACE_MKFIFOAT = @REPLACE_MKFIFOAT@ | ||
| 992 | REPLACE_MKNOD = @REPLACE_MKNOD@ | 996 | REPLACE_MKNOD = @REPLACE_MKNOD@ |
| 997 | REPLACE_MKNODAT = @REPLACE_MKNODAT@ | ||
| 993 | REPLACE_MKSTEMP = @REPLACE_MKSTEMP@ | 998 | REPLACE_MKSTEMP = @REPLACE_MKSTEMP@ |
| 994 | REPLACE_MKTIME = @REPLACE_MKTIME@ | 999 | REPLACE_MKTIME = @REPLACE_MKTIME@ |
| 995 | REPLACE_NANOSLEEP = @REPLACE_NANOSLEEP@ | 1000 | REPLACE_NANOSLEEP = @REPLACE_NANOSLEEP@ |
| @@ -1087,6 +1092,7 @@ SYSTEM_TYPE = @SYSTEM_TYPE@ | |||
| 1087 | SYS_TIME_H_DEFINES_STRUCT_TIMESPEC = @SYS_TIME_H_DEFINES_STRUCT_TIMESPEC@ | 1092 | SYS_TIME_H_DEFINES_STRUCT_TIMESPEC = @SYS_TIME_H_DEFINES_STRUCT_TIMESPEC@ |
| 1088 | TERMCAP_OBJ = @TERMCAP_OBJ@ | 1093 | TERMCAP_OBJ = @TERMCAP_OBJ@ |
| 1089 | TIME_H_DEFINES_STRUCT_TIMESPEC = @TIME_H_DEFINES_STRUCT_TIMESPEC@ | 1094 | TIME_H_DEFINES_STRUCT_TIMESPEC = @TIME_H_DEFINES_STRUCT_TIMESPEC@ |
| 1095 | TIME_H_DEFINES_TIME_UTC = @TIME_H_DEFINES_TIME_UTC@ | ||
| 1090 | TOOLKIT_LIBW = @TOOLKIT_LIBW@ | 1096 | TOOLKIT_LIBW = @TOOLKIT_LIBW@ |
| 1091 | UINT32_MAX_LT_UINTMAX_MAX = @UINT32_MAX_LT_UINTMAX_MAX@ | 1097 | UINT32_MAX_LT_UINTMAX_MAX = @UINT32_MAX_LT_UINTMAX_MAX@ |
| 1092 | UINT64_MAX_EQ_ULONG_MAX = @UINT64_MAX_EQ_ULONG_MAX@ | 1098 | UINT64_MAX_EQ_ULONG_MAX = @UINT64_MAX_EQ_ULONG_MAX@ |
| @@ -1171,6 +1177,7 @@ gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1 = @gl_GNULIB_ENABLED_a9786850 | |||
| 1171 | gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36 = @gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36@ | 1177 | gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36 = @gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36@ |
| 1172 | gl_GNULIB_ENABLED_cloexec = @gl_GNULIB_ENABLED_cloexec@ | 1178 | gl_GNULIB_ENABLED_cloexec = @gl_GNULIB_ENABLED_cloexec@ |
| 1173 | gl_GNULIB_ENABLED_dirfd = @gl_GNULIB_ENABLED_dirfd@ | 1179 | gl_GNULIB_ENABLED_dirfd = @gl_GNULIB_ENABLED_dirfd@ |
| 1180 | gl_GNULIB_ENABLED_dynarray = @gl_GNULIB_ENABLED_dynarray@ | ||
| 1174 | gl_GNULIB_ENABLED_euidaccess = @gl_GNULIB_ENABLED_euidaccess@ | 1181 | gl_GNULIB_ENABLED_euidaccess = @gl_GNULIB_ENABLED_euidaccess@ |
| 1175 | gl_GNULIB_ENABLED_getdtablesize = @gl_GNULIB_ENABLED_getdtablesize@ | 1182 | gl_GNULIB_ENABLED_getdtablesize = @gl_GNULIB_ENABLED_getdtablesize@ |
| 1176 | gl_GNULIB_ENABLED_getgroups = @gl_GNULIB_ENABLED_getgroups@ | 1183 | gl_GNULIB_ENABLED_getgroups = @gl_GNULIB_ENABLED_getgroups@ |
| @@ -1584,6 +1591,20 @@ EXTRA_libgnu_a_SOURCES += dup2.c | |||
| 1584 | endif | 1591 | endif |
| 1585 | ## end gnulib module dup2 | 1592 | ## end gnulib module dup2 |
| 1586 | 1593 | ||
| 1594 | ## begin gnulib module dynarray | ||
| 1595 | ifeq (,$(OMIT_GNULIB_MODULE_dynarray)) | ||
| 1596 | |||
| 1597 | ifneq (,$(gl_GNULIB_ENABLED_dynarray)) | ||
| 1598 | libgnu_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 | |||
| 1600 | endif | ||
| 1601 | EXTRA_DIST += dynarray.h malloc/dynarray-skeleton.c malloc/dynarray.h | ||
| 1602 | |||
| 1603 | EXTRA_libgnu_a_SOURCES += malloc/dynarray-skeleton.c | ||
| 1604 | |||
| 1605 | endif | ||
| 1606 | ## end gnulib module dynarray | ||
| 1607 | |||
| 1587 | ## begin gnulib module eloop-threshold | 1608 | ## begin gnulib module eloop-threshold |
| 1588 | ifeq (,$(OMIT_GNULIB_MODULE_eloop-threshold)) | 1609 | ifeq (,$(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. */ | ||
| 126 | struct 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. */ | ||
| 169 | static inline void | ||
| 170 | DYNARRAY_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. */ | ||
| 180 | static inline void | ||
| 181 | DYNARRAY_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)) | ||
| 196 | static void | ||
| 197 | DYNARRAY_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)) | ||
| 206 | static void | ||
| 207 | DYNARRAY_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)) | ||
| 217 | static inline bool | ||
| 218 | DYNARRAY_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)) | ||
| 226 | static void | ||
| 227 | DYNARRAY_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)) | ||
| 240 | static inline size_t | ||
| 241 | DYNARRAY_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)) | ||
| 249 | static inline DYNARRAY_ELEMENT * | ||
| 250 | DYNARRAY_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)) | ||
| 261 | static inline DYNARRAY_ELEMENT * | ||
| 262 | DYNARRAY_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)) | ||
| 271 | static inline DYNARRAY_ELEMENT * | ||
| 272 | DYNARRAY_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. */ | ||
| 278 | static void | ||
| 279 | DYNARRAY_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)) | ||
| 298 | static inline void | ||
| 299 | DYNARRAY_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. */ | ||
| 319 | static inline DYNARRAY_ELEMENT * | ||
| 320 | DYNARRAY_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. */ | ||
| 334 | static DYNARRAY_ELEMENT * | ||
| 335 | DYNARRAY_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)) | ||
| 352 | static | ||
| 353 | /* Avoid inlining with the larger initialization code. */ | ||
| 354 | #if !(defined (DYNARRAY_ELEMENT_INIT) || defined (DYNARRAY_ELEMENT_FREE)) | ||
| 355 | inline | ||
| 356 | #endif | ||
| 357 | DYNARRAY_ELEMENT * | ||
| 358 | DYNARRAY_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)) | ||
| 376 | static bool | ||
| 377 | DYNARRAY_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)) | ||
| 421 | static void | ||
| 422 | DYNARRAY_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)) | ||
| 438 | static void | ||
| 439 | DYNARRAY_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)) | ||
| 456 | static bool | ||
| 457 | DYNARRAY_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)) | ||
| 487 | static DYNARRAY_ELEMENT * | ||
| 488 | DYNARRAY_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 | |||
| 101 | struct 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. */ | ||
| 110 | static 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. */ | ||
| 118 | static 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. */ | ||
| 129 | bool __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. */ | ||
| 138 | bool __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. */ | ||
| 143 | bool __libc_dynarray_resize_clear (struct dynarray_header *, size_t size, | ||
| 144 | void *scratch, size_t element_size); | ||
| 145 | |||
| 146 | /* Internal type. */ | ||
| 147 | struct 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. */ | ||
| 160 | bool __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 | ||
| 171 | libc_hidden_proto (__libc_dynarray_emplace_enlarge) | ||
| 172 | libc_hidden_proto (__libc_dynarray_resize) | ||
| 173 | libc_hidden_proto (__libc_dynarray_resize_clear) | ||
| 174 | libc_hidden_proto (__libc_dynarray_finalize) | ||
| 175 | libc_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 | |||
| 23 | void | ||
| 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 | } | ||
| 35 | libc_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 | |||
| 25 | bool | ||
| 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 | } | ||
| 73 | libc_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 | |||
| 23 | bool | ||
| 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 | } | ||
| 62 | libc_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 | |||
| 25 | bool | ||
| 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 | } | ||
| 64 | libc_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 | |||
| 22 | bool | ||
| 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 | } | ||
| 35 | libc_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 | ||
| 3254 | static bool | 3250 | static bool __attribute_noinline__ |
| 3255 | build_trtable (const re_dfa_t *dfa, re_dfastate_t *state) | 3251 | build_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) |
| 3335 | out_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. */ | ||
| 58 | typedef 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. */ | ||
| 62 | typedef 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 | ||
| 78 | static random_value | 80 | static random_value |
| 79 | random_bits (random_value var) | 81 | random_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 | |||
| 96 | direxists (const char *dir) | 99 | direxists (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. */ |
| 89 | static bool | 89 | static bool |
| 90 | save_abbr (timezone_t tz, struct tm *tm) | 90 | save_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. */ | ||
| 37 | int | ||
| 38 | rpl_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 | ||
| 44 | static int local_utimensat (int, char const *, struct timespec const[2], int); | 70 | static 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 | ||
| 49 | int | 75 | int |
| 50 | rpl_utimensat (int fd, char const *file, struct timespec const times[2], | 76 | rpl_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 |