diff --git a/admin/merge-gnulib b/admin/merge-gnulib index ae852401eaf..61c386c3e35 100755 --- a/admin/merge-gnulib +++ b/admin/merge-gnulib @@ -49,7 +49,7 @@ GNULIB_MODULES=' sig2str sigdescr_np socklen stat-time std-gnu11 stdc_bit_width stdc_count_ones stdc_trailing_zeros stdckdint-h stddef-h stdio-h - stpcpy strnlen strnlen strtoimax symlink sys_stat-h sys_time-h + stpcpy stringeq strnlen strnlen strtoimax symlink sys_stat-h sys_time-h tempname time-h time_r time_rz timegm timer-time timespec-add timespec-sub update-copyright unlocked-io utimensat vla warnings year2038 diff --git a/doc/misc/texinfo.tex b/doc/misc/texinfo.tex index 64dddad8290..d432325279c 100644 --- a/doc/misc/texinfo.tex +++ b/doc/misc/texinfo.tex @@ -3,7 +3,7 @@ % Load plain if necessary, i.e., if running under initex. \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi % -\def\texinfoversion{2025-07-31.19} +\def\texinfoversion{2025-10-25.20} % % Copyright 1985, 1986, 1988, 1990-2025 Free Software Foundation, Inc. % @@ -9952,7 +9952,7 @@ might help (with 'rm \jobname.?? \jobname.??s')% % node and anchor labels. And \xrdef uses it to construct the % lists of floats. % - \edef\tmp{\noexpand\setref{\floatlabel}{Yfloat}% + \edef\tmp{\noexpand\setref{\noexpand\floatlabel}{Yfloat}% {\floatmagic=\safefloattype}}% \tmp }% diff --git a/lib-src/ebrowse.c b/lib-src/ebrowse.c index 61a45622933..391ca1151db 100644 --- a/lib-src/ebrowse.c +++ b/lib-src/ebrowse.c @@ -35,14 +35,6 @@ along with GNU Emacs. If not, see . */ enum { READ_CHUNK_SIZE = 100 * 1024 }; -/* Value is true if strings X and Y compare equal. */ - -static bool -streq (char const *x, char const *y) -{ - return strcmp (x, y) == 0; -} - static bool filename_eq (char const *x, char const *y) { diff --git a/lib-src/etags.c b/lib-src/etags.c index 6dde9c42e13..8c9d7336c8a 100644 --- a/lib-src/etags.c +++ b/lib-src/etags.c @@ -147,12 +147,6 @@ memcpyz (void *dest, void const *src, ptrdiff_t len) *e = '\0'; } -static bool -streq (char const *s, char const *t) -{ - return strcmp (s, t) == 0; -} - static bool strcaseeq (char const *s, char const *t) { diff --git a/lib/acl-internal.c b/lib/acl-internal.c index 6c50feacbb8..b8a6ed06c31 100644 --- a/lib/acl-internal.c +++ b/lib/acl-internal.c @@ -31,7 +31,7 @@ # include #endif -#if USE_ACL && HAVE_ACL_GET_FILE /* Linux, FreeBSD, NetBSD >= 10, Mac OS X, IRIX, Tru64, Cygwin >= 2.5 */ +#if USE_ACL && HAVE_ACL_GET_FILE /* Linux, FreeBSD, NetBSD >= 10, Mac OS X, Cygwin >= 2.5 */ # if HAVE_ACL_TYPE_EXTENDED /* Mac OS X */ @@ -45,7 +45,7 @@ acl_extended_nontrivial (acl_t acl) return (acl_entries (acl) > 0); } -# else /* Linux, FreeBSD, NetBSD >= 10, IRIX, Tru64, Cygwin >= 2.5 */ +# else /* Linux, FreeBSD, NetBSD >= 10, Cygwin >= 2.5 */ /* ACL is an ACL, from a file, stored as type ACL_TYPE_ACCESS. Return 1 if the given ACL is non-trivial. @@ -118,9 +118,9 @@ acl_access_nontrivial (acl_t acl) - S-1-5-32-545 (group "Users") Cf. and look at the output of the 'mkgroup' command. */ - ignorable = (strcmp (group_sid, "S-1-5-18") == 0 - || strcmp (group_sid, "S-1-5-32-544") == 0 - || strcmp (group_sid, "S-1-5-32-545") == 0); + ignorable = (streq (group_sid, "S-1-5-18") + || streq (group_sid, "S-1-5-32-544") + || streq (group_sid, "S-1-5-32-545")); } } if (!ignorable) @@ -137,46 +137,6 @@ acl_access_nontrivial (acl_t acl) } return got_one; -# elif HAVE_ACL_TO_SHORT_TEXT /* IRIX */ - /* Don't use acl_get_entry: it is undocumented. */ - - int count = acl->acl_cnt; - int i; - - for (i = 0; i < count; i++) - { - acl_entry_t ace = &acl->acl_entry[i]; - acl_tag_t tag = ace->ae_tag; - - if (!(tag == ACL_USER_OBJ || tag == ACL_GROUP_OBJ - || tag == ACL_OTHER_OBJ)) - return 1; - } - return 0; - -# elif HAVE_ACL_FREE_TEXT /* Tru64 */ - /* Don't use acl_get_entry: it takes only one argument and does not work. */ - - int count = acl->acl_num; - acl_entry_t ace; - - for (ace = acl->acl_first; count > 0; ace = ace->next, count--) - { - acl_tag_t tag; - acl_perm_t perm; - - tag = ace->entry->acl_type; - if (!(tag == ACL_USER_OBJ || tag == ACL_GROUP_OBJ || tag == ACL_OTHER)) - return 1; - - perm = ace->entry->acl_perm; - /* On Tru64, perm can also contain non-standard bits such as - PERM_INSERT, PERM_DELETE, PERM_MODIFY, PERM_LOOKUP, ... */ - if ((perm & ~(ACL_READ | ACL_WRITE | ACL_EXECUTE)) != 0) - return 1; - } - return 0; - # else errno = ENOSYS; @@ -548,7 +508,7 @@ void free_permission_context (struct permission_context *ctx) { #if USE_ACL -# if HAVE_ACL_GET_FILE /* Linux, FreeBSD, NetBSD >= 10, Mac OS X, IRIX, Tru64, Cygwin >= 2.5 */ +# if HAVE_ACL_GET_FILE /* Linux, FreeBSD, NetBSD >= 10, Mac OS X, Cygwin >= 2.5 */ if (ctx->acl) acl_free (ctx->acl); # if !HAVE_ACL_TYPE_EXTENDED diff --git a/lib/acl-internal.h b/lib/acl-internal.h index cb969e9797e..cf41e050ec4 100644 --- a/lib/acl-internal.h +++ b/lib/acl-internal.h @@ -68,7 +68,7 @@ _GL_INLINE_HEADER_BEGIN # if HAVE_ACL_GET_FILE /* POSIX 1003.1e (draft 17 -- abandoned) specific version. */ -/* Linux, FreeBSD, Mac OS X, IRIX, Tru64, Cygwin >= 2.5 */ +/* Linux, FreeBSD, Mac OS X, Cygwin >= 2.5 */ # ifndef MIN_ACL_ENTRIES # define MIN_ACL_ENTRIES 4 @@ -76,17 +76,7 @@ _GL_INLINE_HEADER_BEGIN /* POSIX 1003.1e (draft 17) */ # ifdef HAVE_ACL_GET_FD -/* Most platforms have a 1-argument acl_get_fd, only OSF/1 has a 2-argument - macro(!). */ -# if HAVE_ACL_FREE_TEXT /* OSF/1 */ -ACL_INTERNAL_INLINE acl_t -rpl_acl_get_fd (int fd) -{ - return acl_get_fd (fd, ACL_TYPE_ACCESS); -} -# undef acl_get_fd -# define acl_get_fd rpl_acl_get_fd -# endif +/* acl_get_fd takes one argument. */ # else # define HAVE_ACL_GET_FD false # undef acl_get_fd @@ -95,17 +85,7 @@ rpl_acl_get_fd (int fd) /* POSIX 1003.1e (draft 17) */ # ifdef HAVE_ACL_SET_FD -/* Most platforms have a 2-argument acl_set_fd, only OSF/1 has a 3-argument - macro(!). */ -# if HAVE_ACL_FREE_TEXT /* OSF/1 */ -ACL_INTERNAL_INLINE int -rpl_acl_set_fd (int fd, acl_t acl) -{ - return acl_set_fd (fd, ACL_TYPE_ACCESS, acl); -} -# undef acl_set_fd -# define acl_set_fd rpl_acl_set_fd -# endif +/* acl_set_fd takes two arguments. */ # else # define HAVE_ACL_SET_FD false # undef acl_set_fd @@ -136,7 +116,7 @@ rpl_acl_set_fd (int fd, acl_t acl) # endif /* Set to 0 if a file's mode is stored independently from the ACL. */ -# if (HAVE_ACL_COPY_EXT_NATIVE && HAVE_ACL_CREATE_ENTRY_NP) || defined __sgi /* Mac OS X, IRIX */ +# if HAVE_ACL_COPY_EXT_NATIVE && HAVE_ACL_CREATE_ENTRY_NP /* Mac OS X */ # define MODE_INSIDE_ACL 0 # endif @@ -260,7 +240,7 @@ extern int acl_nontrivial (int count, struct acl *entries); struct permission_context { mode_t mode; #if USE_ACL -# if HAVE_ACL_GET_FILE /* Linux, FreeBSD, Mac OS X, IRIX, Tru64, Cygwin >= 2.5 */ +# if HAVE_ACL_GET_FILE /* Linux, FreeBSD, Mac OS X, Cygwin >= 2.5 */ acl_t acl; # if !HAVE_ACL_TYPE_EXTENDED acl_t default_acl; diff --git a/lib/acl_entries.c b/lib/acl_entries.c index 57b7b4998c0..b78ba18a656 100644 --- a/lib/acl_entries.c +++ b/lib/acl_entries.c @@ -22,7 +22,7 @@ #include "acl-internal.h" /* This file assumes POSIX-draft like ACLs - (Linux, FreeBSD, NetBSD >= 10, Mac OS X, IRIX, Tru64, Cygwin >= 2.5). */ + (Linux, FreeBSD, NetBSD >= 10, Mac OS X, Cygwin >= 2.5). */ /* Return the number of entries in ACL. Return -1 and set errno upon failure to determine it. */ @@ -34,8 +34,7 @@ acl_entries (acl_t acl) if (acl != NULL) { -#if HAVE_ACL_FIRST_ENTRY /* Linux, FreeBSD, NetBSD >= 10, Mac OS X, Cygwin >= 2.5 */ -# if HAVE_ACL_TYPE_EXTENDED /* Mac OS X */ +#if HAVE_ACL_TYPE_EXTENDED /* Mac OS X */ /* acl_get_entry returns 0 when it successfully fetches an entry, and -1/EINVAL at the end. */ acl_entry_t ace; @@ -45,7 +44,7 @@ acl_entries (acl_t acl) got_one >= 0; got_one = acl_get_entry (acl, ACL_NEXT_ENTRY, &ace)) count++; -# else /* Linux, FreeBSD, NetBSD >= 10, Cygwin >= 2.5 */ +#else /* Linux, FreeBSD, NetBSD >= 10, Cygwin >= 2.5 */ /* acl_get_entry returns 1 when it successfully fetches an entry, and 0 at the end. */ acl_entry_t ace; @@ -57,17 +56,6 @@ acl_entries (acl_t acl) count++; if (got_one < 0) return -1; -# endif -#else /* IRIX, Tru64 */ -# if HAVE_ACL_TO_SHORT_TEXT /* IRIX */ - /* Don't use acl_get_entry: it is undocumented. */ - count = acl->acl_cnt; -# endif -# if HAVE_ACL_FREE_TEXT /* Tru64 */ - /* Don't use acl_get_entry: it takes only one argument and does not - work. */ - count = acl->acl_num; -# endif #endif } diff --git a/lib/boot-time.c b/lib/boot-time.c index 9104bae16ed..65d7aeaa4ac 100644 --- a/lib/boot-time.c +++ b/lib/boot-time.c @@ -88,7 +88,7 @@ get_boot_time_uncached (struct timespec *p_boot_time) /* Try to find the boot time in the /var/run/utmp file. */ -# if defined UTMP_NAME_FUNCTION /* glibc, musl, macOS, FreeBSD, NetBSD, Minix, AIX, IRIX, Solaris, Cygwin, Android */ +# if defined UTMP_NAME_FUNCTION /* glibc, musl, macOS, FreeBSD, NetBSD, Minix, AIX, Solaris, Cygwin, Android */ /* Ignore the return value for now. Solaris' utmpname returns 1 upon success -- which is contrary @@ -120,13 +120,13 @@ get_boot_time_uncached (struct timespec *p_boot_time) found_boot_time = ts; # if defined __linux__ && !defined __ANDROID__ - if (memcmp (UT_USER (ut), "runlevel", strlen ("runlevel") + 1) == 0 - && memcmp (ut->ut_line, "~", strlen ("~") + 1) == 0) + if (memeq (UT_USER (ut), "runlevel", strlen ("runlevel") + 1) + && memeq (ut->ut_line, "~", strlen ("~") + 1)) runlevel_ts = ts; # endif # if defined __minix if (UT_USER (ut)[0] == '\0' - && memcmp (ut->ut_line, "run-level ", strlen ("run-level ")) == 0) + && memeq (ut->ut_line, "run-level ", strlen ("run-level "))) runlevel_ts = ts; # endif } diff --git a/lib/byteswap.in.h b/lib/byteswap.in.h index 1227f01d144..6b4fbabf283 100644 --- a/lib/byteswap.in.h +++ b/lib/byteswap.in.h @@ -23,13 +23,16 @@ #error "Please include config.h first." #endif -#include - -_GL_INLINE_HEADER_BEGIN +/* Define this now, rather than after including stdint.h, in case + stdint.h recursively includes us. This is for Gnulib endian.h. */ #ifndef _GL_BYTESWAP_INLINE # define _GL_BYTESWAP_INLINE _GL_INLINE #endif +#include + +_GL_INLINE_HEADER_BEGIN + #ifdef __cplusplus extern "C" { #endif diff --git a/lib/c++defs.h b/lib/c++defs.h index df98a5ae57c..b77979a3259 100644 --- a/lib/c++defs.h +++ b/lib/c++defs.h @@ -310,7 +310,7 @@ _GL_CXXALIASWARN_1 (func, GNULIB_NAMESPACE) # define _GL_CXXALIASWARN_1(func,namespace) \ _GL_CXXALIASWARN_2 (func, namespace) -/* To work around GCC bug , +/* To work around GCC bug , we enable the warning only when not optimizing. */ # if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__) # define _GL_CXXALIASWARN_2(func,namespace) \ @@ -338,7 +338,7 @@ GNULIB_NAMESPACE) # define _GL_CXXALIASWARN1_1(func,rettype,parameters_and_attributes,namespace) \ _GL_CXXALIASWARN1_2 (func, rettype, parameters_and_attributes, namespace) -/* To work around GCC bug , +/* To work around GCC bug , we enable the warning only when not optimizing. */ # if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__) # define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \ diff --git a/lib/careadlinkat.c b/lib/careadlinkat.c index 9ec3ca33224..8f4a3c1a70f 100644 --- a/lib/careadlinkat.c +++ b/lib/careadlinkat.c @@ -45,7 +45,7 @@ enum { STACK_BUF_SIZE = 1024 }; If GCC_LINT is defined, do not inline this function with GCC 10.1 and later, to avoid creating a pointer to the stack that GCC -Wreturn-local-addr incorrectly complains about. See: - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93644 + https://gcc.gnu.org/PR93644 Although the noinline attribute can hurt performance a bit, no better way to pacify GCC is known; even an explicit #pragma does not pacify GCC. When the GCC bug is fixed this workaround should be limited to the @@ -174,7 +174,7 @@ careadlinkat (int fd, char const *filename, shrinking realloc. */ #ifdef GCC_BOGUS_WRETURN_LOCAL_ADDR #warning "GCC might issue a bogus -Wreturn-local-addr warning here." - #warning "See ." + #warning "See ." #endif char stack_buf[STACK_BUF_SIZE]; return readlink_stk (fd, filename, buffer, buffer_size, alloc, diff --git a/lib/cdefs.h b/lib/cdefs.h index 2682c092f0e..dce5739d235 100644 --- a/lib/cdefs.h +++ b/lib/cdefs.h @@ -277,10 +277,10 @@ */ #endif -/* GCC and clang have various useful declarations that can be made with - the '__attribute__' syntax. All of the ways we use this do fine if - they are omitted for compilers that don't understand it. */ -#if !(defined __GNUC__ || defined __clang__) +/* GCC, clang, and compatible compilers have various useful declarations + that can be made with the '__attribute__' syntax. All of the ways we use + this do fine if they are omitted for compilers that don't understand it. */ +#if !(defined __GNUC__ || defined __clang__ || defined __TINYC__) # define __attribute__(xyz) /* Ignore */ #endif diff --git a/lib/copy-file-range.c b/lib/copy-file-range.c index 2465a558028..208750bca6e 100644 --- a/lib/copy-file-range.c +++ b/lib/copy-file-range.c @@ -76,9 +76,9 @@ copy_file_range (int infd, off_t *pinoff, if (ok) { -# if defined __GLIBC__ && ! (2 < __GLIBC__ + (43 <= __GLIBC_MINOR__)) +# if defined __GLIBC__ && ! (2 < __GLIBC__ + (43 <= __GLIBC_MINOR__)) /* Work around glibc bug 33245 - . + . This bug is present in glibc 2.42 (2025) and fixed in 2.43, so this workaround, and the configure-time check for glibc, can be removed once glibc 2.42 and earlier is no longer a diff --git a/lib/dirent.in.h b/lib/dirent.in.h index 9d3bffa97ff..e6c59e5a41d 100644 --- a/lib/dirent.in.h +++ b/lib/dirent.in.h @@ -101,40 +101,6 @@ static_assert (DT_UNKNOWN != DT_FIFO && DT_UNKNOWN != DT_CHR /* Other optional information about a directory entry. */ #define _GL_DT_NOTDIR 0x100 /* Not a directory */ -/* Conversion between S_IF* and DT_* file types. */ -#if ! (defined IFTODT && defined DTTOIF) -# include -# ifdef S_ISWHT -# define _GL_DIRENT_S_ISWHT(mode) S_ISWHT(mode) -# else -# define _GL_DIRENT_S_ISWHT(mode) 0 -# endif -# ifdef S_IFWHT -# define _GL_DIRENT_S_IFWHT S_IFWHT -# else -# define _GL_DIRENT_S_IFWHT (DT_WHT << 12) /* just a guess */ -# endif -#endif -/* Conversion from a 'stat' mode to a DT_* value. */ -#ifndef IFTODT -# define IFTODT(mode) \ - (S_ISREG (mode) ? DT_REG : S_ISDIR (mode) ? DT_DIR \ - : S_ISLNK (mode) ? DT_LNK : S_ISBLK (mode) ? DT_BLK \ - : S_ISCHR (mode) ? DT_CHR : S_ISFIFO (mode) ? DT_FIFO \ - : S_ISSOCK (mode) ? DT_SOCK \ - : _GL_DIRENT_S_ISWHT (mode) ? DT_WHT : DT_UNKNOWN) -#endif -/* Conversion from a DT_* value to a 'stat' mode. */ -#ifndef DTTOIF -# define DTTOIF(dirtype) \ - ((dirtype) == DT_REG ? S_IFREG : (dirtype) == DT_DIR ? S_IFDIR \ - : (dirtype) == DT_LNK ? S_IFLNK : (dirtype) == DT_BLK ? S_IFBLK \ - : (dirtype) == DT_CHR ? S_IFCHR : dirtype == DT_FIFO ? S_IFIFO \ - : (dirtype) == DT_SOCK ? S_IFSOCK \ - : (dirtype) == DT_WHT ? _GL_DIRENT_S_IFWHT \ - : (dirtype) << 12 /* just a guess */) -#endif - #if !@DIR_HAS_FD_MEMBER@ # if !GNULIB_defined_DIR /* struct gl_directory is a type with a field 'int fd_to_close'. @@ -426,5 +392,44 @@ _GL_WARN_ON_USE (alphasort, "alphasort is unportable - " #endif +/* Includes that provide only macros that don't need to be overridden. + (Includes that are needed for type definitions and function declarations + have their place above, before the function overrides.) */ + +/* Conversion between S_IF* and DT_* file types. */ +#if ! (defined IFTODT && defined DTTOIF) +# include +# ifdef S_ISWHT +# define _GL_DIRENT_S_ISWHT(mode) S_ISWHT(mode) +# else +# define _GL_DIRENT_S_ISWHT(mode) 0 +# endif +# ifdef S_IFWHT +# define _GL_DIRENT_S_IFWHT S_IFWHT +# else +# define _GL_DIRENT_S_IFWHT (DT_WHT << 12) /* just a guess */ +# endif +#endif +/* Conversion from a 'stat' mode to a DT_* value. */ +#ifndef IFTODT +# define IFTODT(mode) \ + (S_ISREG (mode) ? DT_REG : S_ISDIR (mode) ? DT_DIR \ + : S_ISLNK (mode) ? DT_LNK : S_ISBLK (mode) ? DT_BLK \ + : S_ISCHR (mode) ? DT_CHR : S_ISFIFO (mode) ? DT_FIFO \ + : S_ISSOCK (mode) ? DT_SOCK \ + : _GL_DIRENT_S_ISWHT (mode) ? DT_WHT : DT_UNKNOWN) +#endif +/* Conversion from a DT_* value to a 'stat' mode. */ +#ifndef DTTOIF +# define DTTOIF(dirtype) \ + ((dirtype) == DT_REG ? S_IFREG : (dirtype) == DT_DIR ? S_IFDIR \ + : (dirtype) == DT_LNK ? S_IFLNK : (dirtype) == DT_BLK ? S_IFBLK \ + : (dirtype) == DT_CHR ? S_IFCHR : dirtype == DT_FIFO ? S_IFIFO \ + : (dirtype) == DT_SOCK ? S_IFSOCK \ + : (dirtype) == DT_WHT ? _GL_DIRENT_S_IFWHT \ + : (dirtype) << 12 /* just a guess */) +#endif + + #endif /* _@GUARD_PREFIX@_DIRENT_H */ #endif /* _@GUARD_PREFIX@_DIRENT_H */ diff --git a/lib/endian.in.h b/lib/endian.in.h index e81aa7da8ce..03f541967fb 100644 --- a/lib/endian.in.h +++ b/lib/endian.in.h @@ -109,6 +109,15 @@ _GL_INLINE_HEADER_BEGIN extern "C" { #endif +/* These declarations are needed if Gnulib byteswap.h -> stdint.h -> + sys/types.h -> endian.h -> Gnulib byteswap.h, the last of which is blocked + by its include guard so the functions are not yet declared. */ +#ifdef _GL_BYTESWAP_INLINE +_GL_BYTESWAP_INLINE uint_least16_t bswap_16 (uint_least16_t); +_GL_BYTESWAP_INLINE uint_least32_t bswap_32 (uint_least32_t); +_GL_BYTESWAP_INLINE uint_least64_t bswap_64 (uint_least64_t); +#endif + /* Big endian to host. */ _GL_ENDIAN_INLINE uint16_t diff --git a/lib/errno.in.h b/lib/errno.in.h index ba5dd371005..3db2853cf10 100644 --- a/lib/errno.in.h +++ b/lib/errno.in.h @@ -148,27 +148,11 @@ # endif -/* On OSF/1 5.1, when _XOPEN_SOURCE_EXTENDED is not defined, the macros - EMULTIHOP, ENOLINK, EOVERFLOW are not defined. */ -# if @EMULTIHOP_HIDDEN@ -# define EMULTIHOP @EMULTIHOP_VALUE@ -# define GNULIB_defined_EMULTIHOP 1 -# endif -# if @ENOLINK_HIDDEN@ -# define ENOLINK @ENOLINK_VALUE@ -# define GNULIB_defined_ENOLINK 1 -# endif -# if @EOVERFLOW_HIDDEN@ -# define EOVERFLOW @EOVERFLOW_VALUE@ -# define GNULIB_defined_EOVERFLOW 1 -# endif - - /* On OpenBSD 4.0 and on native Windows, the macros ENOMSG, EIDRM, ENOLINK, EPROTO, EMULTIHOP, EBADMSG, EOVERFLOW, ENOTSUP, ECANCELED are not defined. Likewise, on NonStop Kernel, EDQUOT is not defined. Define them here. Values >= 2000 seem safe to use: Solaris ESTALE = 151, - HP-UX EWOULDBLOCK = 246, IRIX EDQUOT = 1133. + HP-UX EWOULDBLOCK = 246. Note: When one of these systems defines some of these macros some day, binaries will have to be recompiled so that they recognizes the new diff --git a/lib/euidaccess.c b/lib/euidaccess.c index 05e1f2a6ddd..67b9a94544f 100644 --- a/lib/euidaccess.c +++ b/lib/euidaccess.c @@ -79,7 +79,7 @@ euidaccess (const char *file, int mode) { #if HAVE_FACCESSAT /* glibc, AIX 7, Solaris 11, Cygwin 1.7 */ return faccessat (AT_FDCWD, file, mode, AT_EACCESS); -#elif defined EFF_ONLY_OK /* IRIX, OSF/1, Interix */ +#elif defined EFF_ONLY_OK /* Interix */ return access (file, mode | EFF_ONLY_OK); #elif defined ACC_SELF /* AIX */ return accessx (file, mode, ACC_SELF); diff --git a/lib/faccessat.c b/lib/faccessat.c index abb912090a9..743f3728871 100644 --- a/lib/faccessat.c +++ b/lib/faccessat.c @@ -22,7 +22,7 @@ #define _GL_INCLUDING_UNISTD_H #include -/* Specification. */ +/* Get the original definition of faccessat. */ #include #include @@ -40,14 +40,8 @@ orig_faccessat (int fd, char const *name, int mode, int flag) } #endif -#ifdef __osf__ -/* Write "unistd.h" here, not , otherwise OSF/1 5.1 DTK cc - eliminates this include because of the preliminary #include - above. */ -# include "unistd.h" -#else -# include -#endif +/* Specification. */ +#include #ifndef HAVE_ACCESS /* Mingw lacks access, but it also lacks real vs. effective ids, so diff --git a/lib/fchmodat.c b/lib/fchmodat.c index 8853d7a3ae8..9151778b8e3 100644 --- a/lib/fchmodat.c +++ b/lib/fchmodat.c @@ -22,7 +22,7 @@ #define __need_system_sys_stat_h #include -/* Specification. */ +/* Get the original definition of fchmodat. */ #include #undef __need_system_sys_stat_h @@ -41,17 +41,13 @@ orig_fchmodat (int dir, char const *file, mode_t mode, int flags) #include #include -#ifdef __osf__ -/* Write "sys/stat.h" here, not , otherwise OSF/1 5.1 DTK cc - eliminates this include because of the preliminary #include - above. */ -# include "sys/stat.h" -#else -# include -#endif +/* Specification. */ +#include #include +#include "issymlink.h" + /* Invoke chmod or lchmod on FILE, using mode MODE, in the directory open on descriptor FD. If possible, do it without changing the working directory. Otherwise, resort to using save_cwd/fchdir, @@ -84,29 +80,30 @@ fchmodat (int dir, char const *file, mode_t mode, int flags) if (flags == AT_SYMLINK_NOFOLLOW) { # if HAVE_READLINKAT - char readlink_buf[1]; - # ifdef O_PATH /* Open a file descriptor with O_NOFOLLOW, to make sure we don't follow symbolic links, if /proc is mounted. O_PATH is used to avoid a failure if the file is not readable. - Cf. */ + Cf. */ int fd = openat (dir, file, O_PATH | O_NOFOLLOW | O_CLOEXEC); if (fd < 0) return fd; int err; - if (0 <= readlinkat (fd, "", readlink_buf, sizeof readlink_buf)) - err = EOPNOTSUPP; - else if (errno == EINVAL) - { - static char const fmt[] = "/proc/self/fd/%d"; - char buf[sizeof fmt - sizeof "%d" + INT_BUFSIZE_BOUND (int)]; - sprintf (buf, fmt, fd); - err = chmod (buf, mode) == 0 ? 0 : errno == ENOENT ? -1 : errno; - } - else - err = errno == ENOENT ? -1 : errno; + { + int ret = issymlinkat (fd, ""); + if (ret > 0) + err = EOPNOTSUPP; + else if (ret == 0) + { + static char const fmt[] = "/proc/self/fd/%d"; + char buf[sizeof fmt - sizeof "%d" + INT_BUFSIZE_BOUND (int)]; + sprintf (buf, fmt, fd); + err = chmod (buf, mode) == 0 ? 0 : errno == ENOENT ? -1 : errno; + } + else + err = errno == ENOENT ? -1 : errno; + } close (fd); @@ -117,7 +114,7 @@ fchmodat (int dir, char const *file, mode_t mode, int flags) /* O_PATH + /proc is not supported. */ - if (0 <= readlinkat (dir, file, readlink_buf, sizeof readlink_buf)) + if (issymlinkat (dir, file) > 0) { errno = EOPNOTSUPP; return -1; diff --git a/lib/fcntl.c b/lib/fcntl.c index 69cac9a5951..f47ebde105c 100644 --- a/lib/fcntl.c +++ b/lib/fcntl.c @@ -376,12 +376,6 @@ fcntl (int fd, int action, /* arg */...) #ifdef F_NOTIFY /* Linux */ case F_NOTIFY: #endif - #ifdef F_OPLKACK /* IRIX */ - case F_OPLKACK: - #endif - #ifdef F_OPLKREG /* IRIX */ - case F_OPLKREG: - #endif #ifdef F_RDAHEAD /* macOS */ case F_RDAHEAD: #endif diff --git a/lib/fcntl.in.h b/lib/fcntl.in.h index c5068ed48a0..3fbbf4b0e4a 100644 --- a/lib/fcntl.in.h +++ b/lib/fcntl.in.h @@ -249,6 +249,46 @@ _GL_WARN_ON_USE (openat, "openat is not portable - " # endif #endif +#if @GNULIB_OPENAT2@ +# if !defined RESOLVE_NO_XDEV && defined __has_include +# if __has_include () +# include +# endif +# endif +# ifndef RESOLVE_NO_XDEV +struct open_how +{ +# ifdef __UINT64_TYPE__ + __UINT64_TYPE__ flags, mode, resolve; +# else + unsigned long long int flags, mode, resolve; +# endif +}; +# define RESOLVE_NO_XDEV 0x01 +# define RESOLVE_NO_MAGICLINKS 0x02 +# define RESOLVE_NO_SYMLINKS 0x04 +# define RESOLVE_BENEATH 0x08 +# define RESOLVE_IN_ROOT 0x10 +# define RESOLVE_CACHED 0x20 +# endif + +# if !@HAVE_OPENAT2@ +_GL_FUNCDECL_SYS (openat2, int, + (int fd, char const *file, struct open_how const *how, + size_t size), + _GL_ARG_NONNULL ((2, 3))); +# endif +_GL_CXXALIAS_SYS (openat2, int, + (int fd, char const *file, struct open_how const *how, + size_t size)); +_GL_CXXALIASWARN (openat2); +#elif defined GNULIB_POSIXCHECK +# undef openat2 +# if HAVE_RAW_DECL_OPENAT2 +_GL_WARN_ON_USE (openat2, "openat2 is not portable - " + "use gnulib module openat2 for portability"); +# endif +#endif /* Fix up the FD_* macros, only known to be missing on mingw. */ @@ -293,11 +333,6 @@ _GL_WARN_ON_USE (openat, "openat is not portable - " # endif #endif -#if !defined O_DIRECT && defined O_DIRECTIO -/* Tru64 spells it 'O_DIRECTIO'. */ -# define O_DIRECT O_DIRECTIO -#endif - #if !defined O_CLOEXEC && defined O_NOINHERIT /* Mingw spells it 'O_NOINHERIT'. */ # define O_CLOEXEC O_NOINHERIT diff --git a/lib/file-has-acl.c b/lib/file-has-acl.c index a9cfbf3a16e..d2fa69a2834 100644 --- a/lib/file-has-acl.c +++ b/lib/file-has-acl.c @@ -261,7 +261,7 @@ get_aclinfo (int fd, char const *name, struct aclinfo *ai, int flags) first case, and ENODATA in the latter. */ if (r == 0) scontext_err = ENOTSUP; - if (r == 10 && memcmp (ai->scontext, "unlabeled", 10) == 0) + if (r == 10 && memeq (ai->scontext, "unlabeled", 10)) { freecon (ai->scontext); scontext_err = ENODATA; @@ -364,9 +364,9 @@ acl_nfs4_nontrivial (uint32_t *xattr, ssize_t nbytes) /* For a trivial ACL, max 6 (typically 3) ACEs, 3 allow, 3 deny. Check that there is at most one ACE of each TYPE and WHO. */ int who2 - = (wholen == 6 && memcmp (xattr, "OWNER@", 6) == 0 ? 0 - : wholen == 6 && memcmp (xattr, "GROUP@", 6) == 0 ? 2 - : wholen == 9 && memcmp (xattr, "EVERYONE@", 9) == 0 ? 4 + = (wholen == 6 && memeq (xattr, "OWNER@", 6) ? 0 + : wholen == 6 && memeq (xattr, "GROUP@", 6) ? 2 + : wholen == 9 && memeq (xattr, "EVERYONE@", 9) ? 4 : -1); if (who2 < 0) return 1; @@ -384,9 +384,9 @@ acl_nfs4_nontrivial (uint32_t *xattr, ssize_t nbytes) #if (!USE_LINUX_XATTR && USE_ACL && HAVE_ACL_GET_FILE \ && !HAVE_ACL_EXTENDED_FILE && !HAVE_ACL_TYPE_EXTENDED) -/* FreeBSD, NetBSD >= 10, IRIX, Tru64, Cygwin >= 2.5 */ +/* FreeBSD, NetBSD >= 10, Cygwin >= 2.5 */ -# if HAVE_ACL_GET_FD && !HAVE_ACL_GET_LINK_NP /* IRIX, Tru64, Cygwin >= 2.5 */ +# if HAVE_ACL_GET_FD && !HAVE_ACL_GET_LINK_NP /* Cygwin >= 2.5 */ # include # ifdef O_PATH # define acl_get_fd_np(fd, type) acl_get_fd (fd) @@ -522,7 +522,7 @@ fdfile_has_aclinfo (MAYBE_UNUSED int fd, { /* POSIX 1003.1e (draft 17 -- abandoned) specific version. */ - /* Linux, FreeBSD, NetBSD >= 10, Mac OS X, IRIX, Tru64, Cygwin >= 2.5 */ + /* Linux, FreeBSD, NetBSD >= 10, Mac OS X, Cygwin >= 2.5 */ int ret; # if HAVE_ACL_EXTENDED_FILE /* Linux */ @@ -553,7 +553,7 @@ fdfile_has_aclinfo (MAYBE_UNUSED int fd, } else ret = -1; -# else /* FreeBSD, NetBSD >= 10, IRIX, Tru64, Cygwin >= 2.5 */ +# else /* FreeBSD, NetBSD >= 10, Cygwin >= 2.5 */ acl_t acl = acl_get_fdfile (fd, name, ACL_TYPE_ACCESS, flags); if (acl) @@ -562,12 +562,7 @@ fdfile_has_aclinfo (MAYBE_UNUSED int fd, int saved_errno = errno; acl_free (acl); errno = saved_errno; -# if HAVE_ACL_FREE_TEXT /* Tru64 */ - /* On OSF/1, acl_get_file (name, ACL_TYPE_DEFAULT) always - returns NULL with errno not set. There is no point in - making this call. */ -# else /* FreeBSD, NetBSD >= 10, IRIX, Cygwin >= 2.5 */ - /* On Linux, FreeBSD, NetBSD, IRIX, + /* On Linux, FreeBSD, NetBSD, acl_get_file (name, ACL_TYPE_ACCESS) and acl_get_file (name, ACL_TYPE_DEFAULT) on a directory either both succeed or both fail; it depends on the @@ -580,26 +575,25 @@ fdfile_has_aclinfo (MAYBE_UNUSED int fd, acl = acl_get_fdfile (fd, name, ACL_TYPE_DEFAULT, flags); if (acl) { -# ifdef __CYGWIN__ /* Cygwin >= 2.5 */ +# ifdef __CYGWIN__ /* Cygwin >= 2.5 */ ret = acl_access_nontrivial (acl); saved_errno = errno; acl_free (acl); errno = saved_errno; -# else +# else ret = (0 < acl_entries (acl)); acl_free (acl); -# endif +# endif } else { ret = -1; -# ifdef __CYGWIN__ /* Cygwin >= 2.5 */ +# ifdef __CYGWIN__ /* Cygwin >= 2.5 */ if (d_type == DT_UNKNOWN) ret = 0; -# endif +# endif } } -# endif } else ret = -1; diff --git a/lib/fpending.c b/lib/fpending.c index 529bc7f6517..5aaa33f58a4 100644 --- a/lib/fpending.c +++ b/lib/fpending.c @@ -25,8 +25,8 @@ #include "stdio-impl.h" /* This file is not used on systems that already have the __fpending function, - namely glibc >= 2.2, Solaris >= 7, UnixWare >= 7.1.4.MP4, Cygwin >= 1.7.34, - Android API >= 23, musl libc, Haiku >= hrev58760. */ + namely glibc >= 2.2, OpenBSD >= 7.6, Solaris >= 7, UnixWare >= 7.1.4.MP4, + Cygwin >= 1.7.34, Android API >= 23, musl libc, Haiku >= hrev58760. */ /* Return the number of pending (aka buffered, unflushed) bytes on the stream, FP, that is open for writing. */ @@ -39,14 +39,14 @@ __fpending (FILE *fp) #if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ return fp->_IO_write_ptr - fp->_IO_write_base; -#elif defined __sferror || defined __OpenBSD__ || defined __DragonFly__ || defined __ANDROID__ - /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin < 1.7.34, Minix 3, Android */ +#elif defined __sferror || defined __DragonFly__ || defined __ANDROID__ + /* FreeBSD, NetBSD, OpenBSD < 7.6, DragonFly, Mac OS X, Cygwin < 1.7.34, Minix 3, Android */ return fp_->_p - fp_->_bf._base; #elif defined __EMX__ /* emx+gcc */ return fp->_ptr - fp->_buffer; #elif defined __minix /* Minix */ return fp_->_ptr - fp_->_buf; -#elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, UnixWare, mingw, MSVC, NonStop Kernel, OpenVMS */ +#elif defined _IOERR /* AIX, HP-UX, Solaris, OpenServer, UnixWare, mingw, MSVC, NonStop Kernel, OpenVMS */ return (fp_->_ptr ? fp_->_ptr - fp_->_base : 0); #elif defined __UCLIBC__ /* uClibc */ return (fp->__modeflags & __FLAG_WRITING ? fp->__bufpos - fp->__bufstart : 0); diff --git a/lib/free.c b/lib/free.c index 98ceafd7da2..394d8d13905 100644 --- a/lib/free.c +++ b/lib/free.c @@ -33,7 +33,7 @@ rpl_free (void *p) { # if defined __GNUC__ && !defined __clang__ /* An invalid GCC optimization - + would optimize away the assignments in the code below, when link-time optimization (LTO) is enabled. Make the code more complicated, so that GCC does not grok how to optimize it. */ diff --git a/lib/fseterr.c b/lib/fseterr.c new file mode 100644 index 00000000000..40aca95c8eb --- /dev/null +++ b/lib/fseterr.c @@ -0,0 +1,84 @@ +/* Set the error indicator of a stream. + Copyright (C) 2007-2025 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include "fseterr.h" + +#include + +#include "stdio-impl.h" + +/* This file is not used on systems that have the __fseterr function, + namely OpenBSD >= 7.6, musl libc, Haiku >= hrev58760. */ + +void +fseterr (FILE *fp) +{ + /* Most systems provide FILE as a struct and the necessary bitmask in + , because they need it for implementing getc() and putc() as + fast macros. */ +#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 + /* GNU libc, BeOS, Haiku, Linux libc5 */ + fp->_flags |= _IO_ERR_SEEN; +#elif defined __sferror || defined __DragonFly__ || defined __ANDROID__ + /* FreeBSD, NetBSD, OpenBSD < 7.6, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ + fp_->_flags |= __SERR; +#elif defined __EMX__ /* emx+gcc */ + fp->_flags |= _IOERR; +#elif defined __minix /* Minix */ + fp->_flags |= _IOERR; +#elif defined _IOERR /* AIX, HP-UX, Solaris, OpenServer, UnixWare, mingw, MSVC, NonStop Kernel, OpenVMS */ + fp_->_flag |= _IOERR; +#elif defined __UCLIBC__ /* uClibc */ + fp->__modeflags |= __FLAG_ERROR; +#elif defined __QNX__ /* QNX */ + fp->_Mode |= 0x200 /* _MERR */; +#elif defined __MINT__ /* Atari FreeMiNT */ + fp->__error = 1; +#elif defined EPLAN9 /* Plan9 */ + if (fp->state != 0 /* CLOSED */) + fp->state = 5 /* ERR */; +#elif 0 /* unknown */ + /* Portable fallback, based on an idea by Rich Felker. + Wow! 6 system calls for something that is just a bit operation! + Not activated on any system, because there is no way to repair FP when + the sequence of system calls fails, and library code should not call + abort(). */ + int saved_errno; + int fd; + int fd2; + + saved_errno = errno; + fflush (fp); + fd = fileno (fp); + fd2 = dup (fd); + if (fd2 >= 0) + { + close (fd); + fputc ('\0', fp); /* This should set the error indicator. */ + fflush (fp); /* Or this. */ + if (dup2 (fd2, fd) < 0) + /* Whee... we botched the stream and now cannot restore it! */ + abort (); + close (fd2); + } + errno = saved_errno; +#else + #error "Please port gnulib fseterr.c to your platform! Look at the definitions of ferror and clearerr on your system, then report this to bug-gnulib." +#endif +} diff --git a/lib/fseterr.h b/lib/fseterr.h new file mode 100644 index 00000000000..57c30ef3d75 --- /dev/null +++ b/lib/fseterr.h @@ -0,0 +1,55 @@ +/* Set the error indicator of a stream. + Copyright (C) 2007, 2009-2025 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#ifndef _FSETERR_H +#define _FSETERR_H + +/* This file uses HAVE___FSETERR. */ +#if !_GL_CONFIG_H_INCLUDED + #error "Please include config.h first." +#endif + +#include + +/* Set the error indicator of the stream FP. + The "error indicator" is set when an I/O operation on the stream fails, and + is cleared (together with the "end-of-file" indicator) by clearerr (FP). */ + +#if HAVE___FSETERR /* musl libc */ + +/* Haiku has __fseterr but does not declare it. */ +# if defined __HAIKU__ +extern void __fseterr (FILE *fp); +# endif + +# include +# define fseterr(fp) __fseterr (fp) + +#else + +# ifdef __cplusplus +extern "C" { +# endif + +extern void fseterr (FILE *fp); + +# ifdef __cplusplus +} +# endif + +#endif + +#endif /* _FSETERR_H */ diff --git a/lib/fstatat.c b/lib/fstatat.c index 36dd5e9a200..6029de78842 100644 --- a/lib/fstatat.c +++ b/lib/fstatat.c @@ -36,14 +36,8 @@ orig_fstatat (int fd, char const *filename, struct stat *buf, int flags) } #endif -#ifdef __osf__ -/* Write "sys/stat.h" here, not , otherwise OSF/1 5.1 DTK cc - eliminates this include because of the preliminary #include - above. */ -# include "sys/stat.h" -#else -# include -#endif +/* Specification. */ +#include #include "stat-time.h" diff --git a/lib/fsusage.c b/lib/fsusage.c index e26bda88aa6..64a12c5d48e 100644 --- a/lib/fsusage.c +++ b/lib/fsusage.c @@ -148,15 +148,6 @@ get_fs_usage (char const *file, char const *disk, struct fs_usage *fsp) ? PROPAGATE_ALL_ONES (fsd.f_frsize) : PROPAGATE_ALL_ONES (fsd.f_bsize)); -#elif defined STAT_STATFS3_OSF1 /* OSF/1 */ - - struct statfs fsd; - - if (statfs (file, &fsd, sizeof (struct statfs)) != 0) - return -1; - - fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_fsize); - #elif defined STAT_STATFS2_FRSIZE /* 2.6 < glibc/Linux < 2.6.36 */ struct statfs fsd; @@ -201,7 +192,7 @@ get_fs_usage (char const *file, char const *disk, struct fs_usage *fsp) fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_fsize); -#elif defined STAT_STATFS4 /* SVR3, old Irix */ +#elif defined STAT_STATFS4 /* SVR3 */ struct statfs fsd; diff --git a/lib/get-permissions.c b/lib/get-permissions.c index f9e96afbe45..9b904e8ca22 100644 --- a/lib/get-permissions.c +++ b/lib/get-permissions.c @@ -38,9 +38,9 @@ get_permissions (const char *name, int desc, mode_t mode, #if USE_ACL && HAVE_ACL_GET_FILE /* POSIX 1003.1e (draft 17 -- abandoned) specific version. */ - /* Linux, FreeBSD, Mac OS X, IRIX, Tru64, Cygwin >= 2.5 */ + /* Linux, FreeBSD, Mac OS X, Cygwin >= 2.5 */ # if !HAVE_ACL_TYPE_EXTENDED - /* Linux, FreeBSD, IRIX, Tru64, Cygwin >= 2.5 */ + /* Linux, FreeBSD, Cygwin >= 2.5 */ if (HAVE_ACL_GET_FD && desc != -1) ctx->acl = acl_get_fd (desc); diff --git a/lib/getdelim.c b/lib/getdelim.c index 2576d376f06..4cd5eca1895 100644 --- a/lib/getdelim.c +++ b/lib/getdelim.c @@ -65,7 +65,13 @@ getdelim (char **lineptr, size_t *n, int delimiter, FILE *fp) ssize_t result; size_t cur_len = 0; - if (lineptr == NULL || n == NULL || fp == NULL) + if (lineptr == NULL || n == NULL + /* glibc already declares this function as __nonnull ((4)). + Avoid a gcc warning "‘nonnull’ argument ‘fp’ compared to NULL". */ +#if !(__GLIBC__ >= 2) + || fp == NULL +#endif + ) { errno = EINVAL; return -1; diff --git a/lib/getloadavg.c b/lib/getloadavg.c index 752ec1f5ae7..1e3e215360b 100644 --- a/lib/getloadavg.c +++ b/lib/getloadavg.c @@ -140,21 +140,6 @@ # define SUNOS_5 # endif -# if defined (__osf__) && defined (__alpha) -# define OSF_ALPHA -# include -# include -# include -# include -/* Tru64 4.0D's table.h redefines sys */ -# undef sys -# endif - -# if defined (__osf__) && (defined (mips) || defined (__mips__)) -# define OSF_MIPS -# include -# endif - /* VAX C can't handle multi-line #ifs, or lines longer than 256 chars. */ # ifndef LOAD_AVE_TYPE @@ -167,31 +152,16 @@ # define LOAD_AVE_TYPE long # endif -# ifdef sgi -# define LOAD_AVE_TYPE long -# endif - # ifdef SVR4 # define LOAD_AVE_TYPE long # endif -# ifdef OSF_ALPHA -# define LOAD_AVE_TYPE long -# endif - # if defined _AIX && ! defined HAVE_LIBPERFSTAT # define LOAD_AVE_TYPE long # endif # endif /* No LOAD_AVE_TYPE. */ -# ifdef OSF_ALPHA -/* defines an incorrect value for FSCALE on Alpha OSF/1, - according to ghazi@noc.rutgers.edu. */ -# undef FSCALE -# define FSCALE 1024.0 -# endif - # ifndef FSCALE @@ -324,10 +294,6 @@ # endif # endif /* NeXT */ -# ifdef sgi -# include -# endif /* sgi */ - # ifdef UMAX # include # include @@ -389,7 +355,7 @@ static bool getloadavg_initialized; /* Offset in kmem to seek to read load average, or 0 means invalid. */ static long offset; -# if ! defined __VMS && ! defined sgi && ! (defined __linux__ || defined __ANDROID__) +# if ! defined __VMS && ! (defined __linux__ || defined __ANDROID__) static struct nlist name_list[2]; # endif @@ -781,18 +747,6 @@ getloadavg (double loadavg[], int nelem) } # endif /* __MSDOS__ || WINDOWS32 */ -# if !defined (LDAV_DONE) && defined (OSF_ALPHA) /* OSF/1 */ -# define LDAV_DONE - - struct tbl_loadavg load_ave; - table (TBL_LOADAVG, 0, &load_ave, 1, sizeof (load_ave)); - for (elem = 0; elem < nelem; elem++) - loadavg[elem] - = (load_ave.tl_lscale == 0 - ? load_ave.tl_avenrun.d[elem] - : (load_ave.tl_avenrun.l[elem] / (double) load_ave.tl_lscale)); -# endif /* OSF_ALPHA */ - # if ! defined LDAV_DONE && defined __VMS /* VMS */ /* VMS specific code -- read from the Load Ave driver. */ @@ -837,7 +791,7 @@ getloadavg (double loadavg[], int nelem) # endif /* ! defined LDAV_DONE && defined __VMS */ # if ! defined LDAV_DONE && defined LOAD_AVE_TYPE && ! defined __VMS - /* IRIX, other old systems */ + /* other old systems */ /* UNIX-specific code -- read the average from /dev/kmem. */ @@ -848,41 +802,35 @@ getloadavg (double loadavg[], int nelem) /* Get the address of LDAV_SYMBOL. */ if (offset == 0) { -# ifndef sgi -# if ! defined NLIST_STRUCT || ! defined N_NAME_POINTER +# if ! defined NLIST_STRUCT || ! defined N_NAME_POINTER strcpy (name_list[0].n_name, LDAV_SYMBOL); strcpy (name_list[1].n_name, ""); -# else /* NLIST_STRUCT */ -# ifdef HAVE_STRUCT_NLIST_N_UN_N_NAME +# else /* NLIST_STRUCT */ +# ifdef HAVE_STRUCT_NLIST_N_UN_N_NAME name_list[0].n_un.n_name = LDAV_SYMBOL; name_list[1].n_un.n_name = 0; -# else /* not HAVE_STRUCT_NLIST_N_UN_N_NAME */ +# else /* not HAVE_STRUCT_NLIST_N_UN_N_NAME */ name_list[0].n_name = LDAV_SYMBOL; name_list[1].n_name = 0; -# endif /* not HAVE_STRUCT_NLIST_N_UN_N_NAME */ -# endif /* NLIST_STRUCT */ +# endif /* not HAVE_STRUCT_NLIST_N_UN_N_NAME */ +# endif /* NLIST_STRUCT */ -# ifndef SUNOS_5 +# ifndef SUNOS_5 if ( -# if !defined (_AIX) +# if !defined (_AIX) nlist (KERNEL_FILE, name_list) -# else /* _AIX */ +# else /* _AIX */ knlist (name_list, 1, sizeof (name_list[0])) -# endif +# endif >= 0) /* Omit "&& name_list[0].n_type != 0 " -- it breaks on Sun386i. */ { -# ifdef FIXUP_KERNEL_SYMBOL_ADDR +# ifdef FIXUP_KERNEL_SYMBOL_ADDR FIXUP_KERNEL_SYMBOL_ADDR (name_list); -# endif +# endif offset = name_list[0].n_value; } -# endif /* !SUNOS_5 */ -# else /* sgi */ - ptrdiff_t ldav_off = sysmp (MP_KERNADDR, MPKA_AVENRUN); - if (ldav_off != -1) - offset = (long int) ldav_off & 0x7fffffff; -# endif /* sgi */ +# endif /* !SUNOS_5 */ } /* Make sure we have /dev/kmem open. */ diff --git a/lib/getopt.c b/lib/getopt.c index 6b155e6c635..d61bf8619c0 100644 --- a/lib/getopt.c +++ b/lib/getopt.c @@ -42,7 +42,7 @@ # define funlockfile(fp) _IO_funlockfile (fp) #else # include "gettext.h" -# define _(msgid) dgettext ("gnulib", msgid) +# define _(msgid) dgettext (GNULIB_TEXT_DOMAIN, msgid) /* When used standalone, flockfile and funlockfile might not be available. */ # if (!defined _POSIX_THREAD_SAFE_FUNCTIONS \ diff --git a/lib/gettext.h b/lib/gettext.h index fd6c62b7eb7..0650abc9a3d 100644 --- a/lib/gettext.h +++ b/lib/gettext.h @@ -70,7 +70,12 @@ # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wbuiltin-declaration-mismatch" # endif -__attribute__ ((__always_inline__, __gnu_inline__)) extern inline +# if __GNUC__ + (__GNUC_MINOR__ >= 2) > 4 +__attribute__ ((__always_inline__, __gnu_inline__)) +# else +__attribute__ ((__always_inline__)) +# endif +extern inline # if !defined(__sun) const # endif @@ -79,7 +84,12 @@ gettext (const char *msgid) { return msgid; } -__attribute__ ((__always_inline__, __gnu_inline__)) extern inline +# if __GNUC__ + (__GNUC_MINOR__ >= 2) > 4 +__attribute__ ((__always_inline__, __gnu_inline__)) +# else +__attribute__ ((__always_inline__)) +# endif +extern inline # if !defined(__sun) const # endif @@ -89,7 +99,12 @@ dgettext (const char *domain, const char *msgid) (void) domain; return msgid; } -__attribute__ ((__always_inline__, __gnu_inline__)) extern inline +# if __GNUC__ + (__GNUC_MINOR__ >= 2) > 4 +__attribute__ ((__always_inline__, __gnu_inline__)) +# else +__attribute__ ((__always_inline__)) +# endif +extern inline # if !defined(__sun) const # endif diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in index fa800300a42..f158acef91f 100644 --- a/lib/gnulib.mk.in +++ b/lib/gnulib.mk.in @@ -269,14 +269,8 @@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EMACSRES = @EMACSRES@ EMACS_MANIFEST = @EMACS_MANIFEST@ -EMULTIHOP_HIDDEN = @EMULTIHOP_HIDDEN@ -EMULTIHOP_VALUE = @EMULTIHOP_VALUE@ ENDIAN_H = @ENDIAN_H@ ENDIAN_H_JUST_MISSING_STDINT = @ENDIAN_H_JUST_MISSING_STDINT@ -ENOLINK_HIDDEN = @ENOLINK_HIDDEN@ -ENOLINK_VALUE = @ENOLINK_VALUE@ -EOVERFLOW_HIDDEN = @EOVERFLOW_HIDDEN@ -EOVERFLOW_VALUE = @EOVERFLOW_VALUE@ ERRNO_H = @ERRNO_H@ EUIDACCESS_LIBGEN = @EUIDACCESS_LIBGEN@ EXECINFO_H = @EXECINFO_H@ @@ -313,6 +307,7 @@ GL_COND_OBJ_FCNTL_CONDITION = @GL_COND_OBJ_FCNTL_CONDITION@ GL_COND_OBJ_FDOPENDIR_CONDITION = @GL_COND_OBJ_FDOPENDIR_CONDITION@ GL_COND_OBJ_FPENDING_CONDITION = @GL_COND_OBJ_FPENDING_CONDITION@ GL_COND_OBJ_FREE_CONDITION = @GL_COND_OBJ_FREE_CONDITION@ +GL_COND_OBJ_FSETERR_CONDITION = @GL_COND_OBJ_FSETERR_CONDITION@ GL_COND_OBJ_FSTATAT_CONDITION = @GL_COND_OBJ_FSTATAT_CONDITION@ GL_COND_OBJ_FSUSAGE_CONDITION = @GL_COND_OBJ_FSUSAGE_CONDITION@ GL_COND_OBJ_FSYNC_CONDITION = @GL_COND_OBJ_FSYNC_CONDITION@ @@ -344,6 +339,7 @@ GL_COND_OBJ_REALLOC_POSIX_CONDITION = @GL_COND_OBJ_REALLOC_POSIX_CONDITION@ GL_COND_OBJ_REGEX_CONDITION = @GL_COND_OBJ_REGEX_CONDITION@ GL_COND_OBJ_SIG2STR_CONDITION = @GL_COND_OBJ_SIG2STR_CONDITION@ GL_COND_OBJ_SIGDESCR_NP_CONDITION = @GL_COND_OBJ_SIGDESCR_NP_CONDITION@ +GL_COND_OBJ_STDIO_CONSOLESAFE_CONDITION = @GL_COND_OBJ_STDIO_CONSOLESAFE_CONDITION@ GL_COND_OBJ_STDIO_READ_CONDITION = @GL_COND_OBJ_STDIO_READ_CONDITION@ GL_COND_OBJ_STDIO_WRITE_CONDITION = @GL_COND_OBJ_STDIO_WRITE_CONDITION@ GL_COND_OBJ_STPCPY_CONDITION = @GL_COND_OBJ_STPCPY_CONDITION@ @@ -352,7 +348,6 @@ GL_COND_OBJ_STRTOIMAX_CONDITION = @GL_COND_OBJ_STRTOIMAX_CONDITION@ GL_COND_OBJ_STRTOLL_CONDITION = @GL_COND_OBJ_STRTOLL_CONDITION@ GL_COND_OBJ_SYMLINK_CONDITION = @GL_COND_OBJ_SYMLINK_CONDITION@ GL_COND_OBJ_TIMEGM_CONDITION = @GL_COND_OBJ_TIMEGM_CONDITION@ -GL_COND_OBJ_TIME_RZ_CONDITION = @GL_COND_OBJ_TIME_RZ_CONDITION@ GL_COND_OBJ_TIME_R_CONDITION = @GL_COND_OBJ_TIME_R_CONDITION@ GL_COND_OBJ_UTIMENSAT_CONDITION = @GL_COND_OBJ_UTIMENSAT_CONDITION@ GL_GENERATE_ALLOCA_H_CONDITION = @GL_GENERATE_ALLOCA_H_CONDITION@ @@ -559,6 +554,7 @@ GL_GNULIB_OBSTACK_PRINTF_POSIX = @GL_GNULIB_OBSTACK_PRINTF_POSIX@ GL_GNULIB_OBSTACK_ZPRINTF = @GL_GNULIB_OBSTACK_ZPRINTF@ GL_GNULIB_OPEN = @GL_GNULIB_OPEN@ GL_GNULIB_OPENAT = @GL_GNULIB_OPENAT@ +GL_GNULIB_OPENAT2 = @GL_GNULIB_OPENAT2@ GL_GNULIB_OPENDIR = @GL_GNULIB_OPENDIR@ GL_GNULIB_OVERRIDES_STRUCT_STAT = @GL_GNULIB_OVERRIDES_STRUCT_STAT@ GL_GNULIB_PCLOSE = @GL_GNULIB_PCLOSE@ @@ -629,6 +625,7 @@ GL_GNULIB_STRERRORNAME_NP = @GL_GNULIB_STRERRORNAME_NP@ GL_GNULIB_STRERROR_L = @GL_GNULIB_STRERROR_L@ GL_GNULIB_STRERROR_R = @GL_GNULIB_STRERROR_R@ GL_GNULIB_STRFTIME = @GL_GNULIB_STRFTIME@ +GL_GNULIB_STRINGEQ = @GL_GNULIB_STRINGEQ@ GL_GNULIB_STRNCAT = @GL_GNULIB_STRNCAT@ GL_GNULIB_STRNDUP = @GL_GNULIB_STRNDUP@ GL_GNULIB_STRNLEN = @GL_GNULIB_STRNLEN@ @@ -769,6 +766,7 @@ HAVE_DECL_IMAXABS = @HAVE_DECL_IMAXABS@ HAVE_DECL_IMAXDIV = @HAVE_DECL_IMAXDIV@ HAVE_DECL_INITSTATE = @HAVE_DECL_INITSTATE@ HAVE_DECL_LOCALTIME_R = @HAVE_DECL_LOCALTIME_R@ +HAVE_DECL_MEMEQ = @HAVE_DECL_MEMEQ@ HAVE_DECL_MEMMEM = @HAVE_DECL_MEMMEM@ HAVE_DECL_MEMRCHR = @HAVE_DECL_MEMRCHR@ HAVE_DECL_OBSTACK_PRINTF = @HAVE_DECL_OBSTACK_PRINTF@ @@ -780,6 +778,7 @@ HAVE_DECL_SETHOSTNAME = @HAVE_DECL_SETHOSTNAME@ HAVE_DECL_SETSTATE = @HAVE_DECL_SETSTATE@ HAVE_DECL_SNPRINTF = @HAVE_DECL_SNPRINTF@ HAVE_DECL_STRDUP = @HAVE_DECL_STRDUP@ +HAVE_DECL_STREQ = @HAVE_DECL_STREQ@ HAVE_DECL_STRERROR_R = @HAVE_DECL_STRERROR_R@ HAVE_DECL_STRNDUP = @HAVE_DECL_STRNDUP@ HAVE_DECL_STRNLEN = @HAVE_DECL_STRNLEN@ @@ -862,6 +861,7 @@ HAVE_NANOSLEEP = @HAVE_NANOSLEEP@ HAVE_NATIVE_COMP = @HAVE_NATIVE_COMP@ HAVE_OFF64_T = @HAVE_OFF64_T@ HAVE_OPENAT = @HAVE_OPENAT@ +HAVE_OPENAT2 = @HAVE_OPENAT2@ HAVE_OPENDIR = @HAVE_OPENDIR@ HAVE_OS_H = @HAVE_OS_H@ HAVE_PCLOSE = @HAVE_PCLOSE@ @@ -886,7 +886,6 @@ HAVE_PWRITE = @HAVE_PWRITE@ HAVE_QSORT_R = @HAVE_QSORT_R@ HAVE_RAISE = @HAVE_RAISE@ HAVE_RANDOM = @HAVE_RANDOM@ -HAVE_RANDOM_H = @HAVE_RANDOM_H@ HAVE_RANDOM_R = @HAVE_RANDOM_R@ HAVE_RAWMEMCHR = @HAVE_RAWMEMCHR@ HAVE_READDIR = @HAVE_READDIR@ @@ -1500,6 +1499,8 @@ gl_GNULIB_ENABLED_fd38c7e463b54744b77b98aeafb4fa7c_CONDITION = @gl_GNULIB_ENABLE gl_GNULIB_ENABLED_getdelim_CONDITION = @gl_GNULIB_ENABLED_getdelim_CONDITION@ gl_GNULIB_ENABLED_getdtablesize_CONDITION = @gl_GNULIB_ENABLED_getdtablesize_CONDITION@ gl_GNULIB_ENABLED_getgroups_CONDITION = @gl_GNULIB_ENABLED_getgroups_CONDITION@ +gl_GNULIB_ENABLED_issymlink_CONDITION = @gl_GNULIB_ENABLED_issymlink_CONDITION@ +gl_GNULIB_ENABLED_issymlinkat_CONDITION = @gl_GNULIB_ENABLED_issymlinkat_CONDITION@ gl_GNULIB_ENABLED_lchmod_CONDITION = @gl_GNULIB_ENABLED_lchmod_CONDITION@ gl_GNULIB_ENABLED_open_CONDITION = @gl_GNULIB_ENABLED_open_CONDITION@ gl_GNULIB_ENABLED_rawmemchr_CONDITION = @gl_GNULIB_ENABLED_rawmemchr_CONDITION@ @@ -2015,12 +2016,6 @@ errno.h: errno.in.h $(top_builddir)/config.status -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ -e 's|@''NEXT_ERRNO_H''@|$(NEXT_ERRNO_H)|g' \ - -e 's|@''EMULTIHOP_HIDDEN''@|$(EMULTIHOP_HIDDEN)|g' \ - -e 's|@''EMULTIHOP_VALUE''@|$(EMULTIHOP_VALUE)|g' \ - -e 's|@''ENOLINK_HIDDEN''@|$(ENOLINK_HIDDEN)|g' \ - -e 's|@''ENOLINK_VALUE''@|$(ENOLINK_VALUE)|g' \ - -e 's|@''EOVERFLOW_HIDDEN''@|$(EOVERFLOW_HIDDEN)|g' \ - -e 's|@''EOVERFLOW_VALUE''@|$(EOVERFLOW_VALUE)|g' \ $(srcdir)/errno.in.h > $@-t $(AM_V_at)mv $@-t $@ else @@ -2129,10 +2124,12 @@ fcntl.h: fcntl.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) -e 's/@''GNULIB_NONBLOCKING''@/$(GL_GNULIB_NONBLOCKING)/g' \ -e 's/@''GNULIB_OPEN''@/$(GL_GNULIB_OPEN)/g' \ -e 's/@''GNULIB_OPENAT''@/$(GL_GNULIB_OPENAT)/g' \ + -e 's/@''GNULIB_OPENAT2''@/$(GL_GNULIB_OPENAT2)/g' \ -e 's/@''GNULIB_MDA_CREAT''@/$(GL_GNULIB_MDA_CREAT)/g' \ -e 's/@''GNULIB_MDA_OPEN''@/$(GL_GNULIB_MDA_OPEN)/g' \ -e 's|@''HAVE_FCNTL''@|$(HAVE_FCNTL)|g' \ -e 's|@''HAVE_OPENAT''@|$(HAVE_OPENAT)|g' \ + -e 's|@''HAVE_OPENAT2''@|$(HAVE_OPENAT2)|g' \ -e 's|@''REPLACE_CREAT''@|$(REPLACE_CREAT)|g' \ -e 's|@''REPLACE_FCNTL''@|$(REPLACE_FCNTL)|g' \ -e 's|@''REPLACE_OPEN''@|$(REPLACE_OPEN)|g' \ @@ -2231,6 +2228,18 @@ endif endif ## end gnulib module free-posix +## begin gnulib module fseterr +ifeq (,$(OMIT_GNULIB_MODULE_fseterr)) + +ifneq (,$(GL_COND_OBJ_FSETERR_CONDITION)) +libgnu_a_SOURCES += fseterr.c +endif + +EXTRA_DIST += fseterr.h stdio-impl.h + +endif +## end gnulib module fseterr + ## begin gnulib module fstatat ifeq (,$(OMIT_GNULIB_MODULE_fstatat)) @@ -2617,6 +2626,30 @@ EXTRA_DIST += inttypes.in.h endif ## end gnulib module inttypes-h-incomplete +## begin gnulib module issymlink +ifeq (,$(OMIT_GNULIB_MODULE_issymlink)) + +ifneq (,$(gl_GNULIB_ENABLED_issymlink_CONDITION)) +libgnu_a_SOURCES += issymlink.c + +endif +EXTRA_DIST += issymlink.h + +endif +## end gnulib module issymlink + +## begin gnulib module issymlinkat +ifeq (,$(OMIT_GNULIB_MODULE_issymlinkat)) + +ifneq (,$(gl_GNULIB_ENABLED_issymlinkat_CONDITION)) +libgnu_a_SOURCES += issymlinkat.c + +endif +EXTRA_DIST += issymlink.h + +endif +## end gnulib module issymlinkat + ## begin gnulib module lchmod ifeq (,$(OMIT_GNULIB_MODULE_lchmod)) @@ -3469,6 +3502,9 @@ stdio.h: stdio.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(AM_V_at)mv $@-t3 $@ MOSTLYCLEANFILES += stdio.h stdio.h-t1 stdio.h-t2 stdio.h-t3 +ifneq (,$(GL_COND_OBJ_STDIO_CONSOLESAFE_CONDITION)) +libgnu_a_SOURCES += stdio-consolesafe.c +endif ifneq (,$(GL_COND_OBJ_STDIO_READ_CONDITION)) libgnu_a_SOURCES += stdio-read.c endif @@ -3576,7 +3612,6 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \ -e 's|@''HAVE_PTSNAME_R''@|$(HAVE_PTSNAME_R)|g' \ -e 's|@''HAVE_QSORT_R''@|$(HAVE_QSORT_R)|g' \ -e 's|@''HAVE_RANDOM''@|$(HAVE_RANDOM)|g' \ - -e 's|@''HAVE_RANDOM_H''@|$(HAVE_RANDOM_H)|g' \ -e 's|@''HAVE_RANDOM_R''@|$(HAVE_RANDOM_R)|g' \ -e 's|@''HAVE_REALLOCARRAY''@|$(HAVE_REALLOCARRAY)|g' \ -e 's|@''HAVE_REALPATH''@|$(HAVE_REALPATH)|g' \ @@ -3708,6 +3743,7 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H -e 's/@''GNULIB_STPNCPY''@/$(GL_GNULIB_STPNCPY)/g' \ -e 's/@''GNULIB_STRCHRNUL''@/$(GL_GNULIB_STRCHRNUL)/g' \ -e 's/@''GNULIB_STRDUP''@/$(GL_GNULIB_STRDUP)/g' \ + -e 's/@''GNULIB_STRINGEQ''@/$(GL_GNULIB_STRINGEQ)/g' \ -e 's/@''GNULIB_STRNCAT''@/$(GL_GNULIB_STRNCAT)/g' \ -e 's/@''GNULIB_STRNDUP''@/$(GL_GNULIB_STRNDUP)/g' \ -e 's/@''GNULIB_STRNLEN''@/$(GL_GNULIB_STRNLEN)/g' \ @@ -3735,6 +3771,7 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H -e 's|@''HAVE_FFSL''@|$(HAVE_FFSL)|g' \ -e 's|@''HAVE_FFSLL''@|$(HAVE_FFSLL)|g' \ -e 's|@''HAVE_MBSLEN''@|$(HAVE_MBSLEN)|g' \ + -e 's|@''HAVE_DECL_MEMEQ''@|$(HAVE_DECL_MEMEQ)|g' \ -e 's|@''HAVE_DECL_MEMMEM''@|$(HAVE_DECL_MEMMEM)|g' \ -e 's|@''HAVE_MEMPCPY''@|$(HAVE_MEMPCPY)|g' \ -e 's|@''HAVE_DECL_MEMRCHR''@|$(HAVE_DECL_MEMRCHR)|g' \ @@ -3744,6 +3781,7 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H -e 's|@''HAVE_STPNCPY''@|$(HAVE_STPNCPY)|g' \ -e 's|@''HAVE_STRCHRNUL''@|$(HAVE_STRCHRNUL)|g' \ -e 's|@''HAVE_DECL_STRDUP''@|$(HAVE_DECL_STRDUP)|g' \ + -e 's|@''HAVE_DECL_STREQ''@|$(HAVE_DECL_STREQ)|g' \ -e 's|@''HAVE_DECL_STRNDUP''@|$(HAVE_DECL_STRNDUP)|g' \ -e 's|@''HAVE_DECL_STRNLEN''@|$(HAVE_DECL_STRNLEN)|g' \ -e 's|@''HAVE_STRPBRK''@|$(HAVE_STRPBRK)|g' \ @@ -3793,6 +3831,14 @@ EXTRA_DIST += string.in.h endif ## end gnulib module string-h +## begin gnulib module stringeq +ifeq (,$(OMIT_GNULIB_MODULE_stringeq)) + +libgnu_a_SOURCES += string.c + +endif +## end gnulib module stringeq + ## begin gnulib module strnlen ifeq (,$(OMIT_GNULIB_MODULE_strnlen)) @@ -4136,9 +4182,7 @@ endif ## begin gnulib module time_rz ifeq (,$(OMIT_GNULIB_MODULE_time_rz)) -ifneq (,$(GL_COND_OBJ_TIME_RZ_CONDITION)) libgnu_a_SOURCES += time_rz.c -endif EXTRA_DIST += time-internal.h diff --git a/lib/intprops-internal.h b/lib/intprops-internal.h index 62de3c889ec..2609803094b 100644 --- a/lib/intprops-internal.h +++ b/lib/intprops-internal.h @@ -29,10 +29,6 @@ Do not evaluate E. */ #define _GL_INT_CONVERT(e, v) ((1 ? 0 : (e)) + (v)) -/* Act like _GL_INT_CONVERT (E, -V) but work around a bug in IRIX 6.5 cc; see - . */ -#define _GL_INT_NEGATE_CONVERT(e, v) ((1 ? 0 : (e)) - (v)) - /* The extra casts in the following macros work around compiler bugs, e.g., in Cray C 5.0.3.0. */ @@ -41,7 +37,7 @@ /* Return 1 if the real expression E, after promotion, has a signed or floating type. Do not evaluate E. */ -#define _GL_EXPR_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0) +#define _GL_EXPR_SIGNED(e) (_GL_INT_CONVERT (e, -1) < 0) /* Minimum and maximum values for integer types and expressions. */ @@ -60,7 +56,7 @@ #define _GL_INT_MAXIMUM(e) \ (_GL_EXPR_SIGNED (e) \ ? _GL_SIGNED_INT_MAXIMUM (e) \ - : _GL_INT_NEGATE_CONVERT (e, 1)) + : _GL_INT_CONVERT (e, -1)) #define _GL_SIGNED_INT_MAXIMUM(e) \ (((_GL_INT_CONVERT (e, 1) << (_GL_TYPE_WIDTH (+ (e)) - 2)) - 1) * 2 + 1) @@ -112,7 +108,7 @@ #elif defined __has_builtin # define _GL_HAS_BUILTIN_ADD_OVERFLOW __has_builtin (__builtin_add_overflow) /* __builtin_{add,sub}_overflow exists but is not reliable in GCC 5.x and 6.x, - see . */ + see . */ #elif 7 <= __GNUC__ # define _GL_HAS_BUILTIN_ADD_OVERFLOW 1 #else @@ -184,7 +180,7 @@ #endif /* Nonzero if this compiler has GCC bug 68193 or Clang bug 25390. See: - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68193 + https://gcc.gnu.org/PR68193 https://llvm.org/bugs/show_bug.cgi?id=25390 For now, assume GCC < 14 and all Clang versions generate bogus warnings for _Generic. This matters only for compilers that diff --git a/lib/intprops.h b/lib/intprops.h index 2f9fa0a0222..72e866ff5bd 100644 --- a/lib/intprops.h +++ b/lib/intprops.h @@ -205,11 +205,11 @@ || INT_MULTIPLY_RANGE_OVERFLOW (a, b, min, max)) #endif #define _GL_DIVIDE_OVERFLOW(a, b, min, max) \ - ((min) < 0 ? (b) == _GL_INT_NEGATE_CONVERT (min, 1) && (a) < - (max) \ + ((min) < 0 ? (b) == _GL_INT_CONVERT (min, -1) && (a) < - (max) \ : (a) < 0 ? (b) <= (a) + (b) - 1 \ : (b) < 0 && (a) + (b) <= (a)) #define _GL_REMAINDER_OVERFLOW(a, b, min, max) \ - ((min) < 0 ? (b) == _GL_INT_NEGATE_CONVERT (min, 1) && (a) < - (max) \ + ((min) < 0 ? (b) == _GL_INT_CONVERT (min, -1) && (a) < - (max) \ : (a) < 0 ? (a) % (b) != ((max) - (b) + 1) % (b) \ : (b) < 0 && ! _GL_UNSIGNED_NEG_MULTIPLE (a, b, max)) diff --git a/lib/issymlink.c b/lib/issymlink.c new file mode 100644 index 00000000000..dbf56c037c4 --- /dev/null +++ b/lib/issymlink.c @@ -0,0 +1,20 @@ +/* Test whether a file is a symbolic link. + Copyright (C) 2025 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include + +#define _GL_ISSYMLINK_INLINE _GL_EXTERN_INLINE +#include "issymlink.h" diff --git a/lib/issymlink.h b/lib/issymlink.h new file mode 100644 index 00000000000..af6dc965645 --- /dev/null +++ b/lib/issymlink.h @@ -0,0 +1,103 @@ +/* Test whether a file is a symbolic link. + Copyright (C) 2025 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#ifndef _ISSYMLINK_H +#define _ISSYMLINK_H + +/* This file uses _GL_ARG_NONNULL, _GL_INLINE. */ +#if !_GL_CONFIG_H_INCLUDED + #error "Please include config.h first." +#endif + +#include +#include /* for readlink, readlinkat */ + + +_GL_INLINE_HEADER_BEGIN + +#ifndef _GL_ISSYMLINK_INLINE +# define _GL_ISSYMLINK_INLINE _GL_INLINE +#endif +#ifndef _GL_ISSYMLINKAT_INLINE +# define _GL_ISSYMLINKAT_INLINE _GL_INLINE +#endif + +#if GNULIB_ISSYMLINK +/* Tests whether FILENAME represents a symbolic link. + This function is more reliable than lstat() / fstatat() followed by S_ISLNK, + because it avoids possible EOVERFLOW errors. + Returns + 1 if FILENAME is a symbolic link, + 0 if FILENAME exists and is not a symbolic link, + -1 with errno set if determination failed, in particular + -1 with errno = ENOENT or ENOTDIR if FILENAME does not exist. */ +# ifdef __cplusplus +extern "C" { +# endif +_GL_ISSYMLINK_INLINE int issymlink (const char *filename) + _GL_ARG_NONNULL ((1)); +_GL_ISSYMLINK_INLINE int +issymlink (const char *filename) +{ + char linkbuf[1]; + if (readlink (filename, linkbuf, sizeof (linkbuf)) >= 0) + return 1; + if (errno == EINVAL) + return 0; + else + return -1; +} +# ifdef __cplusplus +} +# endif +#endif + +#if GNULIB_ISSYMLINKAT +/* Tests whether FILENAME represents a symbolic link. + This function is more reliable than lstat() / fstatat() followed by S_ISLNK, + because it avoids possible EOVERFLOW errors. + If FILENAME is a relative file name, it is interpreted as relative to the + directory referred to by FD (where FD = AT_FDCWD denotes the current + directory). + Returns + 1 if FILENAME is a symbolic link, + 0 if FILENAME exists and is not a symbolic link, + -1 with errno set if determination failed, in particular + -1 with errno = ENOENT or ENOTDIR if FILENAME does not exist. */ +# ifdef __cplusplus +extern "C" { +# endif +_GL_ISSYMLINKAT_INLINE int issymlinkat (int fd, const char *filename) + _GL_ARG_NONNULL ((2)); +_GL_ISSYMLINKAT_INLINE int +issymlinkat (int fd, const char *filename) +{ + char linkbuf[1]; + if (readlinkat (fd, filename, linkbuf, sizeof (linkbuf)) >= 0) + return 1; + if (errno == EINVAL) + return 0; + else + return -1; +} +# ifdef __cplusplus +} +# endif +#endif + +_GL_INLINE_HEADER_END + +#endif /* _ISSYMLINK_H */ diff --git a/lib/issymlinkat.c b/lib/issymlinkat.c new file mode 100644 index 00000000000..8286356c8a2 --- /dev/null +++ b/lib/issymlinkat.c @@ -0,0 +1,20 @@ +/* Test whether a file is a symbolic link. + Copyright (C) 2025 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include + +#define _GL_ISSYMLINKAT_INLINE _GL_EXTERN_INLINE +#include "issymlink.h" diff --git a/lib/lchmod.c b/lib/lchmod.c index 4391a4aa940..deba4c50f5b 100644 --- a/lib/lchmod.c +++ b/lib/lchmod.c @@ -29,6 +29,7 @@ #include #include +#include "issymlink.h" /* Work like chmod, except when FILE is a symbolic link. In that case, on systems where permissions on symbolic links are unsupported @@ -37,29 +38,30 @@ int lchmod (char const *file, mode_t mode) { - char readlink_buf[1]; - #ifdef O_PATH /* Open a file descriptor with O_NOFOLLOW, to make sure we don't follow symbolic links, if /proc is mounted. O_PATH is used to avoid a failure if the file is not readable. - Cf. */ + Cf. */ int fd = open (file, O_PATH | O_NOFOLLOW | O_CLOEXEC); if (fd < 0) return fd; int err; - if (0 <= readlinkat (fd, "", readlink_buf, sizeof readlink_buf)) - err = EOPNOTSUPP; - else if (errno == EINVAL) - { - static char const fmt[] = "/proc/self/fd/%d"; - char buf[sizeof fmt - sizeof "%d" + INT_BUFSIZE_BOUND (int)]; - sprintf (buf, fmt, fd); - err = chmod (buf, mode) == 0 ? 0 : errno == ENOENT ? -1 : errno; - } - else - err = errno == ENOENT ? -1 : errno; + { + int ret = issymlinkat (fd, ""); + if (ret > 0) + err = EOPNOTSUPP; + else if (ret == 0) + { + static char const fmt[] = "/proc/self/fd/%d"; + char buf[sizeof fmt - sizeof "%d" + INT_BUFSIZE_BOUND (int)]; + sprintf (buf, fmt, fd); + err = chmod (buf, mode) == 0 ? 0 : errno == ENOENT ? -1 : errno; + } + else + err = errno == ENOENT ? -1 : errno; + } close (fd); @@ -83,7 +85,7 @@ lchmod (char const *file, mode_t mode) /* O_PATH + /proc is not supported. */ - if (0 <= readlink (file, readlink_buf, sizeof readlink_buf)) + if (issymlink (file) > 0) { errno = EOPNOTSUPP; return -1; diff --git a/lib/limits.in.h b/lib/limits.in.h index c33c59e13bd..693df9984c2 100644 --- a/lib/limits.in.h +++ b/lib/limits.in.h @@ -47,7 +47,7 @@ #ifndef LLONG_MIN # if defined LONG_LONG_MIN /* HP-UX 11.31 */ # define LLONG_MIN LONG_LONG_MIN -# elif defined LONGLONG_MIN /* IRIX 6.5 */ +# elif defined LONGLONG_MIN /* AIX, BeOS */ # define LLONG_MIN LONGLONG_MIN # elif defined __GNUC__ # define LLONG_MIN (- __LONG_LONG_MAX__ - 1LL) @@ -56,7 +56,7 @@ #ifndef LLONG_MAX # if defined LONG_LONG_MAX /* HP-UX 11.31 */ # define LLONG_MAX LONG_LONG_MAX -# elif defined LONGLONG_MAX /* IRIX 6.5 */ +# elif defined LONGLONG_MAX /* AIX, BeOS */ # define LLONG_MAX LONGLONG_MAX # elif defined __GNUC__ # define LLONG_MAX __LONG_LONG_MAX__ @@ -65,7 +65,7 @@ #ifndef ULLONG_MAX # if defined ULONG_LONG_MAX /* HP-UX 11.31 */ # define ULLONG_MAX ULONG_LONG_MAX -# elif defined ULONGLONG_MAX /* IRIX 6.5 */ +# elif defined ULONGLONG_MAX /* AIX, BeOS */ # define ULLONG_MAX ULONGLONG_MAX # elif defined __GNUC__ # define ULLONG_MAX (__LONG_LONG_MAX__ * 2ULL + 1ULL) diff --git a/lib/lstat.c b/lib/lstat.c index bb4a59f1749..f5fda4af771 100644 --- a/lib/lstat.c +++ b/lib/lstat.c @@ -42,14 +42,7 @@ orig_lstat (const char *filename, struct stat *buf) } /* Specification. */ -# ifdef __osf__ -/* Write "sys/stat.h" here, not , otherwise OSF/1 5.1 DTK cc - eliminates this include because of the preliminary #include - above. */ -# include "sys/stat.h" -# else -# include -# endif +# include # include "stat-time.h" diff --git a/lib/md5-stream.c b/lib/md5-stream.c index fdbf97a682b..a5d6a3109a4 100644 --- a/lib/md5-stream.c +++ b/lib/md5-stream.c @@ -87,7 +87,7 @@ md5_stream (FILE *stream, void *resblock) or the fread() in afalg_stream may have gotten EOF. We need to avoid a subsequent fread() as EOF may not be sticky. For details of such systems, see: - https://sourceware.org/bugzilla/show_bug.cgi?id=1190 */ + https://sourceware.org/PR1190 */ if (feof (stream)) goto process_partial_block; diff --git a/lib/mini-gmp.c b/lib/mini-gmp.c index c97dc7e6cfa..9f3812b31bd 100644 --- a/lib/mini-gmp.c +++ b/lib/mini-gmp.c @@ -51,7 +51,11 @@ see https://www.gnu.org/licenses/. */ #include "mini-gmp.h" -#if !defined(MINI_GMP_DONT_USE_FLOAT_H) +#ifndef MINI_GMP_ENABLE_FLOAT +#define MINI_GMP_ENABLE_FLOAT 1 +#endif + +#if MINI_GMP_ENABLE_FLOAT #include #endif @@ -1705,6 +1709,7 @@ mpz_roinit_n (mpz_t x, mp_srcptr xp, mp_size_t xs) } +#if MINI_GMP_ENABLE_FLOAT /* Conversions and comparison to double. */ void mpz_set_d (mpz_t r, double x) @@ -1861,6 +1866,7 @@ mpz_cmp_d (const mpz_t x, double d) return mpz_cmpabs_d (x, d); } } +#endif /* MINI_GMP_ENABLE_FLOAT */ /* MPZ comparisons and the like. */ @@ -4515,6 +4521,11 @@ mpz_import (mpz_t r, size_t count, int order, size_t size, int endian, assert (order == 1 || order == -1); assert (endian >= -1 && endian <= 1); + if (count == 0) + { + r->_mp_size = 0; + return; + } if (endian == 0) endian = gmp_detect_endian (); diff --git a/lib/minmax.h b/lib/minmax.h index 355de4b1c3f..7cafcea3818 100644 --- a/lib/minmax.h +++ b/lib/minmax.h @@ -19,8 +19,8 @@ #define _MINMAX_H /* Note: MIN, MAX are also defined in on some systems - (glibc, IRIX, HP-UX, OSF/1). Therefore you might get warnings about - MIN, MAX macro redefinitions on some systems; the workaround is to + (glibc, HP-UX). Therefore you might get warnings about MIN, MAX + macro redefinitions on some systems; the workaround is to #include this file as the last one among the #include list. */ /* This file uses HAVE_MINMAX_IN_LIMITS_H, HAVE_MINMAX_IN_SYS_PARAM_H. */ diff --git a/lib/nproc.c b/lib/nproc.c index 83439aa0eb2..e899ff17620 100644 --- a/lib/nproc.c +++ b/lib/nproc.c @@ -22,7 +22,12 @@ #include #include +#if HAVE_MNTENT_H +# include +#endif #include +#include +#include #include #if HAVE_PTHREAD_GETAFFINITY_NP && 0 @@ -39,10 +44,6 @@ # include #endif -#if HAVE_SYS_SYSMP_H -# include -#endif - #if HAVE_SYS_PARAM_H # include #endif @@ -62,6 +63,8 @@ #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) +#define NPROC_MINIMUM 1 + /* Return the number of processors available to the current process, based on a modern system call that returns the "affinity" between the current process and each CPU. Return 0 if unknown or if such a system call does @@ -244,7 +247,7 @@ num_processors_via_affinity_mask (void) /* Return the total number of processors. Here QUERY must be one of NPROC_ALL, NPROC_CURRENT. The result is guaranteed to be at least 1. */ static unsigned long int -num_processors_ignoring_omp (enum nproc_query query) +num_processors_available (enum nproc_query query) { /* On systems with a modern affinity mask system call, we have sysconf (_SC_NPROCESSORS_CONF) @@ -258,7 +261,7 @@ num_processors_ignoring_omp (enum nproc_query query) the /sys and /proc file systems (see glibc/sysdeps/unix/sysv/linux/getsysstats.c). In some situations these file systems are not mounted, and the sysconf call - returns 1 or 2 (), + returns 1 or 2 (), which does not reflect the reality. */ if (query == NPROC_CURRENT) @@ -272,8 +275,8 @@ num_processors_ignoring_omp (enum nproc_query query) } #if defined _SC_NPROCESSORS_ONLN - { /* This works on glibc, Mac OS X 10.5, FreeBSD, AIX, OSF/1, Solaris, - Cygwin, Haiku. */ + { /* This works on glibc, Mac OS X 10.5, FreeBSD, AIX, Solaris, Cygwin, + Haiku. */ long int nprocs = sysconf (_SC_NPROCESSORS_ONLN); if (nprocs > 0) return nprocs; @@ -283,8 +286,8 @@ num_processors_ignoring_omp (enum nproc_query query) else /* query == NPROC_ALL */ { #if defined _SC_NPROCESSORS_CONF - { /* This works on glibc, Mac OS X 10.5, FreeBSD, AIX, OSF/1, Solaris, - Cygwin, Haiku. */ + { /* This works on glibc, Mac OS X 10.5, FreeBSD, AIX, Solaris, Cygwin, + Haiku. */ long int nprocs = sysconf (_SC_NPROCESSORS_CONF); # if __GLIBC__ >= 2 && defined __linux__ @@ -330,20 +333,6 @@ num_processors_ignoring_omp (enum nproc_query query) } #endif -#if HAVE_SYSMP && defined MP_NAPROCS && defined MP_NPROCS - { /* This works on IRIX. */ - /* MP_NPROCS yields the number of installed processors. - MP_NAPROCS yields the number of processors available to unprivileged - processes. */ - int nprocs = - sysmp (query == NPROC_CURRENT && getuid () != 0 - ? MP_NAPROCS - : MP_NPROCS); - if (nprocs > 0) - return nprocs; - } -#endif - /* Finally, as fallback, use the APIs that don't distinguish between NPROC_CURRENT and NPROC_ALL. */ @@ -377,7 +366,159 @@ num_processors_ignoring_omp (enum nproc_query query) } #endif - return 1; + return NPROC_MINIMUM; +} + +#if defined __linux__ || defined __ANDROID__ +/* Identify the cgroup2 mount point, + initially at the usual location for efficiency, + resorting to searching mount points otherwise. + Return NULL if the mount point is not found. + The returned string can be freed. */ +static char * +cgroup2_mount (void) +{ + FILE *fp; + char *ret = NULL; + + /* Check the usual location first. */ + if (access ("/sys/fs/cgroup/cgroup.controllers", F_OK) == 0) + return strdup ("/sys/fs/cgroup"); + +#if HAVE_MNTENT_H + /* Otherwise look for the mount point. */ + struct mntent *mnt; + if (! (fp = setmntent ("/proc/mounts", "r"))) + return NULL; + while ((mnt = getmntent (fp)) != NULL) + { + if (streq (mnt->mnt_type, "cgroup2")) + { + ret = strdup (mnt->mnt_dir); + break; + } + } + endmntent (fp); +#endif + + return ret; +} + +/* Return the minimum configured cgroupv2 CPU quota for the current process. + Return ULONG_MAX if quota can't be read. + Returned value will be >= 1. */ +static unsigned long int +get_cgroup2_cpu_quota (void) +{ + unsigned long int cpu_quota = ULONG_MAX; + FILE *fp; + + fp = fopen ("/proc/self/cgroup", "r"); + if (! fp) + return cpu_quota; + + /* Get our cgroupv2 (unififed) hierarchy. */ + char *cgroup = NULL; + char *cgroup_str = NULL; + size_t cgroup_size = 0; + ssize_t read; + while ((read = getline (&cgroup_str, &cgroup_size, fp)) != -1) + { + if (strncmp (cgroup_str, "0::/", 4) == 0) + { + char *end = cgroup_str + read - 1; + if (*end == '\n') + *end = '\0'; + cgroup = cgroup_str + 3; + break; + } + } + fclose (fp); + + char *mount = NULL; + if (cgroup && ! (mount = cgroup2_mount ())) + cgroup = NULL; + + /* Find the lowest quota in the hierarchy. */ + char *quota_str = NULL; + size_t quota_size = 0; + while (cgroup && *cgroup) + { + /* Walk back up the nested cgroup hierarchy + to find the lowest cpu quota as defined in a cpu.max file. + Note this file may not be present if the cpu controller + is not enabled for that part of the hierarchy. */ + + char cpu_max_file[PATH_MAX]; + snprintf (cpu_max_file, sizeof (cpu_max_file), + "%s%s/cpu.max", mount, cgroup); + + if ((fp = fopen (cpu_max_file, "r")) + && getline ("a_str, "a_size, fp) != -1 + && strncmp (quota_str, "max", 3) != 0) + { + long quota, period; + if (sscanf (quota_str, "%ld %ld", "a, &period) == 2 && period) + { + double ncpus = (double)quota / period; + if (cpu_quota == ULONG_MAX || ncpus < cpu_quota) + { + cpu_quota = MAX (1, (long)(ncpus + 0.5)); + /* nproc will return 1 minimum, so no point going lower */ + if (cpu_quota == 1) + *cgroup = '\0'; + } + } + } + + if (fp) + fclose (fp); + + char *last_sep = strrchr (cgroup, '/'); + if (! last_sep) + break; + if (last_sep == cgroup && *(cgroup + 1)) + *(cgroup + 1) = '\0'; /* Iterate on "/" also. */ + else + *last_sep = '\0'; + } + + free (quota_str); + free (mount); + free (cgroup_str); + + return cpu_quota; +} +#endif + + +/* Return the cgroupv2 CPU quota if the current scheduler honors it. + Otherwise return ULONG_MAX. + Returned value will be >= 1. */ +static unsigned long int +cpu_quota (void) +{ + unsigned long int quota = ULONG_MAX; + +#if defined __linux__ || defined __ANDROID__ +# if HAVE_SCHED_GETAFFINITY_LIKE_GLIBC && defined SCHED_DEADLINE + /* We've a new enough sched.h */ + switch (sched_getscheduler (0)) + { + case -1: + case SCHED_FIFO: + case SCHED_RR: + case SCHED_DEADLINE: + quota = ULONG_MAX; + break; + default: + quota = get_cgroup2_cpu_quota (); + break; + } +# endif +#endif + + return quota; } /* Parse OMP environment variables without dependence on OMP. @@ -416,13 +557,13 @@ parse_omp_threads (char const* threads) unsigned long int num_processors (enum nproc_query query) { - unsigned long int omp_env_limit = ULONG_MAX; + unsigned long int nproc_limit = ULONG_MAX; + /* Honor the OpenMP environment variables, recognized also by all + programs that are based on OpenMP. */ if (query == NPROC_CURRENT_OVERRIDABLE) { - unsigned long int omp_env_threads; - /* Honor the OpenMP environment variables, recognized also by all - programs that are based on OpenMP. */ + unsigned long int omp_env_threads, omp_env_limit; omp_env_threads = parse_omp_threads (getenv ("OMP_NUM_THREADS")); omp_env_limit = parse_omp_threads (getenv ("OMP_THREAD_LIMIT")); if (! omp_env_limit) @@ -431,14 +572,22 @@ num_processors (enum nproc_query query) if (omp_env_threads) return MIN (omp_env_threads, omp_env_limit); + nproc_limit = omp_env_limit; query = NPROC_CURRENT; } - /* Here query is one of NPROC_ALL, NPROC_CURRENT. */ - if (omp_env_limit == 1) - /* No need to even call num_processors_ignoring_omp (query). */ - return 1; - { - unsigned long nprocs = num_processors_ignoring_omp (query); - return MIN (nprocs, omp_env_limit); - } + + /* Honor any CPU quotas. */ + if (query == NPROC_CURRENT && nproc_limit > NPROC_MINIMUM) + { + unsigned long int quota = cpu_quota (); + nproc_limit = MIN (quota, nproc_limit); + } + + if (nproc_limit > NPROC_MINIMUM) + { + unsigned long nprocs = num_processors_available (query); + nproc_limit = MIN (nprocs, nproc_limit); + } + + return nproc_limit; } diff --git a/lib/open.c b/lib/open.c index d76372fd603..fceacfcc00f 100644 --- a/lib/open.c +++ b/lib/open.c @@ -38,13 +38,7 @@ orig_open (const char *filename, int flags, mode_t mode) } /* Specification. */ -#ifdef __osf__ -/* Write "fcntl.h" here, not , otherwise OSF/1 5.1 DTK cc eliminates - this include because of the preliminary #include above. */ -# include "fcntl.h" -#else -# include -#endif +#include #include "cloexec.h" @@ -100,7 +94,7 @@ open (const char *filename, int flags, ...) #endif #if defined _WIN32 && ! defined __CYGWIN__ - if (strcmp (filename, "/dev/null") == 0) + if (streq (filename, "/dev/null")) filename = "NUL"; #endif diff --git a/lib/pthread_sigmask.c b/lib/pthread_sigmask.c index a4968f7df40..0d0a5c211da 100644 --- a/lib/pthread_sigmask.c +++ b/lib/pthread_sigmask.c @@ -26,10 +26,6 @@ # include #endif -#if PTHREAD_SIGMASK_UNBLOCK_BUG -# include -#endif - int pthread_sigmask (int how, const sigset_t *new_mask, sigset_t *old_mask) #undef pthread_sigmask @@ -58,7 +54,7 @@ pthread_sigmask (int how, const sigset_t *new_mask, sigset_t *old_mask) Don't cache the information: libpthread.so could be dynamically loaded after the program started and after pthread_sigmask was called for the first time. */ - if (memcmp (&omask_copy, &omask, sizeof omask) == 0 + if (memeq (&omask_copy, &omask, sizeof omask) && pthread_sigmask (1729, &omask_copy, NULL) == 0) { /* pthread_sigmask is currently ineffective. The program is not @@ -73,16 +69,6 @@ pthread_sigmask (int how, const sigset_t *new_mask, sigset_t *old_mask) # if PTHREAD_SIGMASK_FAILS_WITH_ERRNO if (ret == -1) return errno; -# endif -# if PTHREAD_SIGMASK_UNBLOCK_BUG - if (ret == 0 - && new_mask != NULL - && (how == SIG_UNBLOCK || how == SIG_SETMASK)) - { - /* Give the OS the opportunity to raise signals that were pending before - the pthread_sigmask call and have now been unblocked. */ - usleep (1); - } # endif return ret; #else diff --git a/lib/qcopy-acl.c b/lib/qcopy-acl.c index 282f4b2d2a5..e86e15544f6 100644 --- a/lib/qcopy-acl.c +++ b/lib/qcopy-acl.c @@ -50,9 +50,9 @@ is_attr_permissions (const char *name, struct error_context *ctx) { /* We need to explicitly test for the known extended attribute names, because at least on CentOS 7, attr_copy_action does not do it. */ - return strcmp (name, XATTR_NAME_POSIX_ACL_ACCESS) == 0 - || strcmp (name, XATTR_NAME_POSIX_ACL_DEFAULT) == 0 - || strcmp (name, XATTR_NAME_NFSV4_ACL) == 0 + return streq (name, XATTR_NAME_POSIX_ACL_ACCESS) + || streq (name, XATTR_NAME_POSIX_ACL_DEFAULT) + || streq (name, XATTR_NAME_NFSV4_ACL) || attr_copy_action (name, ctx) == ATTR_ACTION_PERMISSIONS; } diff --git a/lib/readutmp.h b/lib/readutmp.h index 60d63df9598..f186d99d68d 100644 --- a/lib/readutmp.h +++ b/lib/readutmp.h @@ -115,19 +115,19 @@ enum { UT_HOST_SIZE = -1 }; Field Type Platforms ---------- ------ --------- - ⎡ ut_user char[] glibc, musl, macOS, FreeBSD, AIX, HP-UX, IRIX, Solaris, Cygwin, Android + ⎡ ut_user char[] glibc, musl, macOS, FreeBSD, AIX, HP-UX, Solaris, Cygwin, Android ⎣ ut_name char[] NetBSD, Minix - ut_id char[] glibc, musl, macOS, FreeBSD, NetBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin, Android - ut_line char[] glibc, musl, macOS, FreeBSD, NetBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin, Android - ut_pid pid_t glibc, musl, macOS, FreeBSD, NetBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin, Android - ut_type short glibc, musl, macOS, FreeBSD, NetBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin, Android - ⎡ ut_tv struct glibc, musl, macOS, FreeBSD, NetBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin, Android + ut_id char[] glibc, musl, macOS, FreeBSD, NetBSD, Minix, AIX, HP-UX, Solaris, Cygwin, Android + ut_line char[] glibc, musl, macOS, FreeBSD, NetBSD, Minix, AIX, HP-UX, Solaris, Cygwin, Android + ut_pid pid_t glibc, musl, macOS, FreeBSD, NetBSD, Minix, AIX, HP-UX, Solaris, Cygwin, Android + ut_type short glibc, musl, macOS, FreeBSD, NetBSD, Minix, AIX, HP-UX, Solaris, Cygwin, Android + ⎡ ut_tv struct glibc, musl, macOS, FreeBSD, NetBSD, Minix, AIX, HP-UX, Solaris, Cygwin, Android ⎢ { tv_sec; tv_usec; } ⎣ ut_time time_t Cygwin - ut_host char[] glibc, musl, macOS, FreeBSD, NetBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin, Android - ut_exit struct glibc, musl, NetBSD, Minix, HP-UX, IRIX, Solaris, Android + ut_host char[] glibc, musl, macOS, FreeBSD, NetBSD, Minix, AIX, HP-UX, Solaris, Cygwin, Android + ut_exit struct glibc, musl, NetBSD, Minix, HP-UX, Solaris, Android { e_termination; e_exit; } - ut_session [long] int glibc, musl, NetBSD, Minix, IRIX, Solaris, Android + ut_session [long] int glibc, musl, NetBSD, Minix, Solaris, Android ⎡ ut_addr [long] int HP-UX, Cygwin ⎢ ut_addr_v6 [u]int[4] glibc, musl, Android ⎣ ut_ss struct sockaddr_storage NetBSD, Minix @@ -174,7 +174,7 @@ struct utmpx32 # define SET_UTMP_ENT setutxent # define GET_UTMP_ENT getutxent # define END_UTMP_ENT endutxent -# ifdef HAVE_UTMPXNAME /* glibc, musl, macOS, NetBSD, Minix, IRIX, Solaris, Cygwin */ +# ifdef HAVE_UTMPXNAME /* glibc, musl, macOS, NetBSD, Minix, Solaris, Cygwin */ # define UTMP_NAME_FUNCTION utmpxname # elif defined UTXDB_ACTIVE /* FreeBSD */ # define UTMP_NAME_FUNCTION(x) setutxdb (UTXDB_ACTIVE, x) @@ -190,17 +190,17 @@ struct utmpx32 Field Type Platforms ---------- ------ --------- - ⎡ ut_user char[] glibc, musl, AIX, HP-UX, IRIX, Solaris, Cygwin, Android + ⎡ ut_user char[] glibc, musl, AIX, HP-UX, Solaris, Cygwin, Android ⎣ ut_name char[] macOS, old FreeBSD, NetBSD, OpenBSD, Minix - ut_id char[] glibc, musl, AIX, HP-UX, IRIX, Solaris, Cygwin, Android - ut_line char[] glibc, musl, macOS, old FreeBSD, NetBSD, OpenBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin, Android - ut_pid pid_t glibc, musl, AIX, HP-UX, IRIX, Solaris, Cygwin, Android - ut_type short glibc, musl, AIX, HP-UX, IRIX, Solaris, Cygwin, Android + ut_id char[] glibc, musl, AIX, HP-UX, Solaris, Cygwin, Android + ut_line char[] glibc, musl, macOS, old FreeBSD, NetBSD, OpenBSD, Minix, AIX, HP-UX, Solaris, Cygwin, Android + ut_pid pid_t glibc, musl, AIX, HP-UX, Solaris, Cygwin, Android + ut_type short glibc, musl, AIX, HP-UX, Solaris, Cygwin, Android ⎡ ut_tv struct glibc, musl, Android ⎢ { tv_sec; tv_usec; } - ⎣ ut_time time_t macOS, old FreeBSD, NetBSD, OpenBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin + ⎣ ut_time time_t macOS, old FreeBSD, NetBSD, OpenBSD, Minix, AIX, HP-UX, Solaris, Cygwin ut_host char[] glibc, musl, macOS, old FreeBSD, NetBSD, OpenBSD, Minix, AIX, HP-UX, Cygwin, Android - ut_exit struct glibc, musl, AIX, HP-UX, IRIX, Solaris, Android + ut_exit struct glibc, musl, AIX, HP-UX, Solaris, Android { e_termination; e_exit; } ut_session [long] int glibc, musl, Android ⎡ ut_addr [long] int HP-UX, Cygwin @@ -211,7 +211,7 @@ struct utmpx32 # define SET_UTMP_ENT setutent # define GET_UTMP_ENT getutent # define END_UTMP_ENT endutent -# ifdef HAVE_UTMPNAME /* glibc, musl, NetBSD, Minix, AIX, HP-UX, IRIX, Solaris, Cygwin, Android */ +# ifdef HAVE_UTMPNAME /* glibc, musl, NetBSD, Minix, AIX, HP-UX, Solaris, Cygwin, Android */ # define UTMP_NAME_FUNCTION utmpname # endif diff --git a/lib/realloc.c b/lib/realloc.c index 42375010975..62efd5a39ff 100644 --- a/lib/realloc.c +++ b/lib/realloc.c @@ -50,7 +50,7 @@ rpl_realloc (void *p, size_t n) undefined behavior even though C17 and earlier partially defined the behavior. Let the programmer know. When the undefined-behaviour sanitizers report this case, i.e. when - and + and have been closed and new releases of GCC and clang have been made, we can revisit this code. */ diff --git a/lib/regex.c b/lib/regex.c index f5f6552670d..1404dac7534 100644 --- a/lib/regex.c +++ b/lib/regex.c @@ -24,6 +24,7 @@ # if __GNUC_PREREQ (4, 6) # pragma GCC diagnostic ignored "-Wsuggest-attribute=pure" +# pragma GCC diagnostic ignored "-Wswitch-enum" # pragma GCC diagnostic ignored "-Wvla" # endif #endif diff --git a/lib/regex_internal.h b/lib/regex_internal.h index 1f2972999ad..03893b8630b 100644 --- a/lib/regex_internal.h +++ b/lib/regex_internal.h @@ -98,24 +98,14 @@ #endif /* This is for other GNU distributions with internationalized messages. */ -#if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC +#ifdef _LIBC # include # undef gettext -# ifdef _LIBC -# define gettext(msgid) \ +# define gettext(msgid) \ __dcgettext (_libc_intl_domainname, msgid, LC_MESSAGES) -# else -# define gettext(msgid) dgettext ("gnulib", msgid) -# endif -#else -# undef gettext -# define gettext(msgid) (msgid) -#endif - -#ifndef gettext_noop -/* This define is so xgettext can find the internationalizable - strings. */ # define gettext_noop(String) String +#else +# include "gettext.h" #endif /* Number of ASCII characters. */ diff --git a/lib/set-permissions.c b/lib/set-permissions.c index 2da2e98e426..af0b5de228d 100644 --- a/lib/set-permissions.c +++ b/lib/set-permissions.c @@ -25,17 +25,13 @@ #include "minmax.h" #if USE_ACL -# if ! defined HAVE_ACL_FROM_MODE && defined HAVE_ACL_FROM_TEXT /* FreeBSD, IRIX, Tru64, Cygwin >= 2.5 */ +# if ! defined HAVE_ACL_FROM_MODE && defined HAVE_ACL_FROM_TEXT /* FreeBSD, Cygwin >= 2.5 */ # if HAVE_ACL_GET_FILE && !HAVE_ACL_TYPE_EXTENDED static acl_t acl_from_mode (mode_t mode) { -# if HAVE_ACL_FREE_TEXT /* Tru64 */ - char acl_text[] = "u::---,g::---,o::---,"; -# else /* FreeBSD, IRIX, Cygwin >= 2.5 */ char acl_text[] = "u::---,g::---,o::---"; -# endif if (mode & S_IRUSR) acl_text[ 3] = 'r'; if (mode & S_IWUSR) acl_text[ 4] = 'w'; @@ -490,9 +486,9 @@ set_acls (struct permission_context *ctx, const char *name, int desc, # if HAVE_ACL_GET_FILE /* POSIX 1003.1e (draft 17 -- abandoned) specific version. */ - /* Linux, FreeBSD, Mac OS X, IRIX, Tru64, Cygwin >= 2.5 */ + /* Linux, FreeBSD, Mac OS X, Cygwin >= 2.5 */ # if !HAVE_ACL_TYPE_EXTENDED - /* Linux, FreeBSD, IRIX, Tru64, Cygwin >= 2.5 */ + /* Linux, FreeBSD, Cygwin >= 2.5 */ # ifndef HAVE_ACL_FROM_TEXT # error Must have acl_from_text (see POSIX 1003.1e draft 17). diff --git a/lib/sig2str.c b/lib/sig2str.c index e8c830c6daf..bf4d009578d 100644 --- a/lib/sig2str.c +++ b/lib/sig2str.c @@ -288,7 +288,7 @@ str2signum (char const *signame) { unsigned int i; for (i = 0; i < NUMNAME_ENTRIES; i++) - if (strcmp (numname_table[i].name, signame) == 0) + if (streq (numname_table[i].name, signame)) return numname_table[i].num; { diff --git a/lib/sigdescr_np.c b/lib/sigdescr_np.c index 46c746ae072..6715269e05e 100644 --- a/lib/sigdescr_np.c +++ b/lib/sigdescr_np.c @@ -26,7 +26,7 @@ const char * sigdescr_np (int sig) { - /* Note: Some platforms (glibc, FreeBSD, NetBSD, OpenBSD, AIX, IRIX, Haiku, + /* Note: Some platforms (glibc, FreeBSD, NetBSD, OpenBSD, AIX, Haiku, Android) have an array 'sys_siglist'. (On AIX, you need to declare it yourself, and it has fewer than NSIG elements.) Its contents varies depending on the OS. @@ -160,12 +160,7 @@ sigdescr_np (int sig) case SIGBREAK: return "Ctrl-Break"; #endif - /* IRIX */ - #if defined SIGCKPT - case SIGCKPT: - return "Checkpoint"; /* See man 1 cpr, man 3C atcheckpoint */ - #endif - /* Linux, IRIX, Cygwin */ + /* Linux, Cygwin */ #if defined SIGCLD && SIGCLD != SIGCHLD case SIGCLD: return "Child stopped or exited"; @@ -182,7 +177,7 @@ sigdescr_np (int sig) /* AIX: "Paging space low". */ return "Swap space nearly exhausted"; #endif - /* Mac OS X, FreeBSD, NetBSD, OpenBSD, Minix, AIX, IRIX, Cygwin, mingw */ + /* Mac OS X, FreeBSD, NetBSD, OpenBSD, Minix, AIX, Cygwin, mingw */ #if defined SIGEMT case SIGEMT: /* glibc/Hurd, *BSD: "EMT trap". Solaris: "Emulation trap". */ @@ -193,12 +188,12 @@ sigdescr_np (int sig) case SIGINFO: return "Information request"; #endif - /* Linux, Mac OS X, FreeBSD, NetBSD, OpenBSD, Minix, AIX, IRIX, Cygwin */ + /* Linux, Mac OS X, FreeBSD, NetBSD, OpenBSD, Minix, AIX, Cygwin */ #if defined SIGIO && SIGIO != SIGPOLL case SIGIO: return "I/O possible"; #endif - /* Linux, IRIX, Cygwin, mingw */ + /* Linux, Cygwin, mingw */ #if defined SIGIOT && SIGIOT != SIGABRT case SIGIOT: return "IOT instruction"; /* a PDP-11 instruction */ @@ -267,17 +262,7 @@ sigdescr_np (int sig) case SIGPRE: return "Programmed exception"; #endif - /* IRIX */ - #if defined SIGPTINTR - case SIGPTINTR: - return "Pthread interrupt"; - #endif - /* IRIX */ - #if defined SIGPTRESCHED - case SIGPTRESCHED: - return "Pthread rescheduling"; - #endif - /* Linux, NetBSD, Minix, AIX, IRIX, Cygwin */ + /* Linux, NetBSD, Minix, AIX, Cygwin */ #if defined SIGPWR case SIGPWR: /* glibc: "Power failure". NetBSD: "Power fail/restart". */ @@ -293,11 +278,6 @@ sigdescr_np (int sig) case SIGRECOVERY: return "Kernel recovery"; #endif - /* IRIX */ - #if defined SIGRESTART - case SIGRESTART: - return "Checkpoint restart"; /* See man 1 cpr, man 3C atrestart */ - #endif /* AIX */ #if defined SIGRETRACT case SIGRETRACT: @@ -347,11 +327,6 @@ sigdescr_np (int sig) /* OpenBSD: "Thread AST". */ return "Thread library interrupt"; #endif - /* IRIX */ - #if defined SIGUME - case SIGUME: - return "Uncorrectable memory error"; - #endif /* AIX */ #if defined SIGVIRT case SIGVIRT: @@ -363,7 +338,7 @@ sigdescr_np (int sig) /* AIX: "No runnable lwp". */ return "Thread waiting"; #endif - /* Linux, Mac OS X, FreeBSD, NetBSD, OpenBSD, Minix, AIX, IRIX, Cygwin, Haiku */ + /* Linux, Mac OS X, FreeBSD, NetBSD, OpenBSD, Minix, AIX, Cygwin, Haiku */ #if defined SIGWINCH case SIGWINCH: /* glibc: "Window changed". *BSD: "Window size changed" or "Window size changes". */ diff --git a/lib/signal.in.h b/lib/signal.in.h index a2549e84235..66e0c310ef8 100644 --- a/lib/signal.in.h +++ b/lib/signal.in.h @@ -66,14 +66,14 @@ # include #endif -/* Mac OS X 10.3, FreeBSD < 8.0, OpenBSD < 5.1, OSF/1 4.0, Solaris 2.6, Android, +/* Mac OS X 10.3, FreeBSD < 8.0, OpenBSD < 5.1, Solaris 2.6, Android, OS/2 kLIBC declare pthread_sigmask in , not in . But avoid namespace pollution on glibc systems.*/ #if (@GNULIB_PTHREAD_SIGMASK@ || defined GNULIB_POSIXCHECK) \ && ((defined __APPLE__ && defined __MACH__) \ || (defined __FreeBSD__ && __FreeBSD__ < 8) \ || (defined __OpenBSD__ && OpenBSD < 201205) \ - || defined __osf__ || defined __sun || defined __ANDROID__ \ + || defined __sun || defined __ANDROID__ \ || defined __KLIBC__) \ && ! defined __GLIBC__ # include diff --git a/lib/stddef.in.h b/lib/stddef.in.h index e8c55ff1cdc..9ad768d785b 100644 --- a/lib/stddef.in.h +++ b/lib/stddef.in.h @@ -32,7 +32,7 @@ || defined __need_wint_t) \ /* Avoid warning triggered by "gcc -std=gnu23 -Wsystem-headers" \ in GCC 13.3 and 14.2 \ - . */ \ + . */ \ && !@STDDEF_NOT_IDEMPOTENT@ /* Special invocation convention inside gcc header files. In particular, in some ancient versions of GCC blindly @@ -91,7 +91,7 @@ typedef long max_align_t; # if !defined _GCC_NULLPTR_T && !@NULLPTR_T_NEEDS_STDDEF@ /* Suppress unwanted nullptr_t typedef. See - . */ + . */ # define _GCC_NULLPTR_T # endif diff --git a/lib/stdint.in.h b/lib/stdint.in.h index ca566b303ee..4df6433338f 100644 --- a/lib/stdint.in.h +++ b/lib/stdint.in.h @@ -51,13 +51,6 @@ in public interfaces due to compiler differences. */ #if @HAVE_STDINT_H@ -# if defined __sgi && ! defined __c99 - /* Bypass IRIX's if in C89 mode, since it merely annoys users - with "This header file is to be used only for c99 mode compilations" - diagnostics. */ -# define __STDINT_H__ -# endif - /* Some pre-C++11 implementations need this. */ # ifdef __cplusplus # ifndef __STDC_CONSTANT_MACROS @@ -94,8 +87,8 @@ #if ! @HAVE_C99_STDINT_H@ -/* defines some of the stdint.h types as well, on glibc, - IRIX 6.5, and OpenBSD 3.8 (via ). +/* defines some of the stdint.h types as well, on glibc and + OpenBSD 3.8 (via ). AIX 5.2 isn't needed and causes troubles. Mac OS X 10.4.6 includes (which is us), but relies on the system definitions, so include @@ -584,11 +577,7 @@ typedef int _verify_intmax_size[sizeof (intmax_t) == sizeof (uintmax_t) # endif /* wchar_t limits */ -/* Get WCHAR_MIN, WCHAR_MAX. - This include is not on the top, above, because on OSF/1 4.0 we have a - sequence of nested includes - -> -> -> , and the latter includes - and assumes its types are already defined. */ +/* Get WCHAR_MIN, WCHAR_MAX. */ # if @HAVE_WCHAR_H@ && ! (defined WCHAR_MIN && defined WCHAR_MAX) # define _GL_JUST_INCLUDE_SYSTEM_WCHAR_H # include diff --git a/lib/stdio-consolesafe.c b/lib/stdio-consolesafe.c new file mode 100644 index 00000000000..fbea20be224 --- /dev/null +++ b/lib/stdio-consolesafe.c @@ -0,0 +1,149 @@ +/* msvcrt workarounds. + Copyright (C) 2025 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include + +#include +#include +#include + +/* Outputs N bytes starting at S to FP. + These N bytes are known to be followed by a NUL. + Finally frees the string at S. + Returns the number of written bytes. */ +static size_t +workaround_fwrite0 (char *s, size_t n, FILE *fp) +{ + const char *ptr = s; + /* Use fputs instead of fwrite, which is buggy in msvcrt. */ + size_t written = 0; + while (n > 0) + { + size_t l = strlen (ptr); /* 0 <= l <= n */ + if (l > 0) + { + if (fputs (ptr, fp) == EOF) + break; + written += l; + n -= l; + } + if (n == 0) + break; + if (fputc ('\0', fp) == EOF) + break; + written++; + n--; + ptr += l + 1; + } + free (s); + return written; +} + +size_t +gl_consolesafe_fwrite (const void *ptr, size_t size, size_t nmemb, FILE *fp) +{ + size_t nbytes; + if (ckd_mul (&nbytes, size, nmemb) || nbytes == 0) + /* Overflow, or nothing to do. */ + return 0; + char *tmp = malloc (nbytes + 1); + if (tmp == NULL) + return 0; + memcpy (tmp, ptr, nbytes); + tmp[nbytes] = '\0'; + size_t written = workaround_fwrite0 (tmp, nbytes, fp); + return written / size; +} + +#if defined __MINGW32__ && __USE_MINGW_ANSI_STDIO + +# include "fseterr.h" + +/* Bypass the functions __mingw_[v][f]printf, that trigger a bug in msvcrt, + but without losing the support for modern format specifiers added by + __mingw_*printf. */ + +int +gl_consolesafe_fprintf (FILE *restrict fp, const char *restrict format, ...) +{ + va_list args; + char *tmpstring; + va_start (args, format); + int result = vasprintf (&tmpstring, format, args); + va_end (args); + if (result >= 0) + { + if (workaround_fwrite0 (tmpstring, result, fp) < result) + result = -1; + } + else + fseterr (fp); + return result; +} + +int +gl_consolesafe_printf (const char *restrict format, ...) +{ + va_list args; + char *tmpstring; + va_start (args, format); + int result = vasprintf (&tmpstring, format, args); + va_end (args); + if (result >= 0) + { + if (workaround_fwrite0 (tmpstring, result, stdout) < result) + result = -1; + } + else + fseterr (stdout); + return result; +} + +int +gl_consolesafe_vfprintf (FILE *restrict fp, + const char *restrict format, va_list args) +{ + char *tmpstring; + int result = vasprintf (&tmpstring, format, args); + if (result >= 0) + { + if (workaround_fwrite0 (tmpstring, result, fp) < result) + result = -1; + } + else + fseterr (fp); + return result; +} + +int +gl_consolesafe_vprintf (const char *restrict format, va_list args) +{ + char *tmpstring; + int result = vasprintf (&tmpstring, format, args); + if (result >= 0) + { + if (workaround_fwrite0 (tmpstring, result, stdout) < result) + result = -1; + } + else + fseterr (stdout); + return result; +} + +#endif diff --git a/lib/stdio-impl.h b/lib/stdio-impl.h index 4abf9e68b23..e4a69a8d11b 100644 --- a/lib/stdio-impl.h +++ b/lib/stdio-impl.h @@ -108,15 +108,59 @@ # define _flags pub._flags # define _r pub._r # define _w pub._w -# elif defined __ANDROID__ || defined __OpenBSD__ /* Android, OpenBSD */ -# if defined __LP64__ && !defined __OpenBSD__ +# elif defined __OpenBSD__ /* OpenBSD */ +# if defined __sferror /* OpenBSD <= 7.7 */ +# define _gl_flags_file_t short +# else /* OpenBSD >= 7.8 */ +# define _gl_flags_file_t int +# endif + /* Up to this commit from 2025-07-16 + + the innards of FILE were public. After this commit, the innards of FILE + are hidden. In this commit + + they were reshuffled. */ +# if defined __sferror /* OpenBSD <= 7.7 */ +# define fp_ ((struct { unsigned char *_p; \ + int _r; \ + int _w; \ + _gl_flags_file_t _flags; \ + _gl_flags_file_t _file; \ + struct { unsigned char *_base; size_t _size; } _bf; \ + int _lbfsize; \ + void *_cookie; \ + void *_close; \ + void *_read; \ + void *_seek; \ + void *_write; \ + struct { unsigned char *_base; size_t _size; } _ext; \ + unsigned char *_up; \ + int _ur; \ + unsigned char _ubuf[3]; \ + unsigned char _nbuf[1]; \ + struct { unsigned char *_base; size_t _size; } _lb; \ + int _blksize; \ + fpos_t _offset; \ + /* More fields, not relevant here. */ \ + } *) fp) +# else /* OpenBSD >= 7.8 */ +# define fp_ ((struct { _gl_flags_file_t _flags; \ + _gl_flags_file_t _file; \ + unsigned char *_p; \ + int _r; \ + int _w; \ + struct { unsigned char *_base; size_t _size; } _bf; \ + int _lbfsize; \ + /* More fields, not relevant here. */ \ + } *) fp) +# endif +# elif defined __ANDROID__ /* Android */ +# if defined __LP64__ # define _gl_flags_file_t int # else # define _gl_flags_file_t short # endif -# if defined __OpenBSD__ -# define _gl_file_offset_t fpos_t -# elif defined __LP64__ +# if defined __LP64__ # define _gl_file_offset_t int64_t # else /* see https://android.googlesource.com/platform/bionic/+/master/docs/32-bit-abi.md */ @@ -127,9 +171,7 @@ the innards of FILE were public, see and . - After this commit, the innards of FILE are hidden. Likewise for OpenBSD - up to this commit from 2025-07-16 - . */ + After this commit, the innards of FILE are hidden. */ # define fp_ ((struct { unsigned char *_p; \ int _r; \ int _w; \ diff --git a/lib/stdio.in.h b/lib/stdio.in.h index e80862125df..cc6010119d0 100644 --- a/lib/stdio.in.h +++ b/lib/stdio.in.h @@ -22,12 +22,7 @@ #if defined __need_FILE || defined __need___FILE || defined _@GUARD_PREFIX@_ALREADY_INCLUDING_STDIO_H || defined _GL_SKIP_GNULIB_STDIO_H /* Special invocation convention: - - Inside glibc header files. - - On OSF/1 5.1 we have a sequence of nested includes - -> -> -> -> - -> -> -> . - In this situation, the functions are not yet declared, therefore we cannot - provide the C++ aliases. */ + - Inside glibc header files. */ #@INCLUDE_NEXT@ @NEXT_STDIO_H@ @@ -269,10 +264,6 @@ - with MSVC ucrt: "[-]nan" or "[-]nan(ind)" or "[-]nan(snan)", - with mingw: "[-]1.#IND" or "[-]1.#QNAN". */ # define _PRINTF_NAN_LEN_MAX 10 -# elif defined __sgi -/* On IRIX, the output typically is "[-]nan0xNNNNNNNN" with 8 hexadecimal - digits. */ -# define _PRINTF_NAN_LEN_MAX 14 # else /* We don't know, but 32 should be a safe maximum. */ # define _PRINTF_NAN_LEN_MAX 32 @@ -280,6 +271,33 @@ #endif +#if (defined _WIN32 && !defined __CYGWIN__) && !defined _UCRT +/* Workarounds against msvcrt bugs. */ +_GL_FUNCDECL_SYS (gl_consolesafe_fwrite, size_t, + (const void *ptr, size_t size, size_t nmemb, FILE *fp), + _GL_ARG_NONNULL ((1, 4))); +# if defined __MINGW32__ +_GL_FUNCDECL_SYS (gl_consolesafe_fprintf, int, + (FILE *restrict fp, const char *restrict format, ...), + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3) + _GL_ARG_NONNULL ((1, 2))); +_GL_FUNCDECL_SYS (gl_consolesafe_printf, int, + (const char *restrict format, ...), + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (1, 2) + _GL_ARG_NONNULL ((1))); +_GL_FUNCDECL_SYS (gl_consolesafe_vfprintf, int, + (FILE *restrict fp, + const char *restrict format, va_list args), + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0) + _GL_ARG_NONNULL ((1, 2))); +_GL_FUNCDECL_SYS (gl_consolesafe_vprintf, int, + (const char *restrict format, va_list args), + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (1, 0) + _GL_ARG_NONNULL ((1))); +# endif +#endif + + #if @GNULIB_DZPRINTF@ /* Prints formatted output to file descriptor FD. Returns the number of bytes written to the file descriptor. Upon @@ -616,6 +634,11 @@ _GL_CXXALIAS_SYS (fprintf, int, # if __GLIBC__ >= 2 _GL_CXXALIASWARN (fprintf); # endif +#elif defined __MINGW32__ && !defined _UCRT && __USE_MINGW_ANSI_STDIO +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef fprintf +# define fprintf gl_consolesafe_fprintf +# endif #endif #if !@GNULIB_FPRINTF_POSIX@ && defined GNULIB_POSIXCHECK # if !GNULIB_overrides_fprintf @@ -945,7 +968,7 @@ _GL_CXXALIAS_SYS (fwrite, size_t, FILE *restrict stream)); /* Work around bug 11959 when fortifying glibc 2.4 through 2.15 - , + , which sometimes causes an unwanted diagnostic for fwrite calls. This affects only function declaration attributes under certain versions of gcc and clang, and is not needed for C++. */ @@ -970,6 +993,11 @@ _GL_EXTERN_C size_t __REDIRECT (rpl_fwrite_unlocked, # if __GLIBC__ >= 2 _GL_CXXALIASWARN (fwrite); # endif +#elif (defined _WIN32 && !defined __CYGWIN__) && !defined _UCRT +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef fwrite +# define fwrite gl_consolesafe_fwrite +# endif #endif #if @GNULIB_GETC@ @@ -1016,6 +1044,17 @@ _GL_CXXALIASWARN (getchar); # undef getdelim # define getdelim rpl_getdelim # endif +# ifndef __has_feature +# define __has_feature(a) 0 +# endif +# if __GLIBC__ >= 2 && !(defined __SANITIZE_ADDRESS__ \ + || __has_feature (address_sanitizer)) +/* Arrange for the inline definition of getline() in + to call our getdelim() override. Do not use the __getdelim symbol + if address sanitizer is in use, otherwise it may be overridden by + __interceptor_trampoline___getdelim. */ +# define rpl_getdelim __getdelim +# endif _GL_FUNCDECL_RPL (getdelim, ssize_t, (char **restrict lineptr, size_t *restrict linesize, int delimiter, @@ -1057,14 +1096,27 @@ _GL_WARN_ON_USE (getdelim, "getdelim is unportable - " Return the number of bytes read and stored at *LINEPTR (not including the NUL terminator), or -1 on error or EOF. */ # if @REPLACE_GETLINE@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef getline -# define getline rpl_getline -# endif _GL_FUNCDECL_RPL (getline, ssize_t, (char **restrict lineptr, size_t *restrict linesize, FILE *restrict stream), _GL_ARG_NONNULL ((1, 2, 3)) _GL_ATTRIBUTE_NODISCARD); +# if defined __cplusplus +/* The C++ standard library defines std::basic_istream::getline in + or . */ +# if !(__GLIBC__ >= 2) +extern "C" { +inline ssize_t +getline (char **restrict lineptr, size_t *restrict linesize, + FILE *restrict stream) +{ + return rpl_getline (lineptr, linesize, stream); +} +} +# endif +# else +# undef getline +# define getline rpl_getline +# endif _GL_CXXALIAS_RPL (getline, ssize_t, (char **restrict lineptr, size_t *restrict linesize, FILE *restrict stream)); @@ -1333,6 +1385,11 @@ _GL_CXXALIAS_SYS (printf, int, (const char *restrict format, ...)); # if __GLIBC__ >= 2 _GL_CXXALIASWARN (printf); # endif +#elif defined __MINGW32__ && !defined _UCRT && __USE_MINGW_ANSI_STDIO +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef printf +# define printf gl_consolesafe_printf +# endif #endif #if !@GNULIB_PRINTF_POSIX@ && defined GNULIB_POSIXCHECK # if !GNULIB_overrides_printf @@ -1885,6 +1942,11 @@ _GL_CXXALIAS_SYS_CAST (vfprintf, int, # if __GLIBC__ >= 2 _GL_CXXALIASWARN (vfprintf); # endif +#elif defined __MINGW32__ && !defined _UCRT && __USE_MINGW_ANSI_STDIO +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef vfprintf +# define vfprintf gl_consolesafe_vfprintf +# endif #endif #if !@GNULIB_VFPRINTF_POSIX@ && defined GNULIB_POSIXCHECK # if !GNULIB_overrides_vfprintf @@ -1966,6 +2028,11 @@ _GL_CXXALIAS_SYS_CAST (vprintf, int, # if __GLIBC__ >= 2 _GL_CXXALIASWARN (vprintf); # endif +#elif defined __MINGW32__ && !defined _UCRT && __USE_MINGW_ANSI_STDIO +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef vprintf +# define vprintf gl_consolesafe_vprintf +# endif #endif #if !@GNULIB_VPRINTF_POSIX@ && defined GNULIB_POSIXCHECK # if !GNULIB_overrides_vprintf diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h index 1342db48772..bef0aaaf92e 100644 --- a/lib/stdlib.in.h +++ b/lib/stdlib.in.h @@ -62,12 +62,6 @@ /* NetBSD 5.0 mis-defines NULL. */ #include -/* MirBSD 10 defines WEXITSTATUS in , not in . - glibc 2.41 defines WCOREDUMP in , not in . */ -#if @GNULIB_SYSTEM_POSIX@ && !(defined WEXITSTATUS && defined WCOREDUMP) -# include -#endif - /* Solaris declares getloadavg() in . */ #if (@GNULIB_GETLOADAVG@ || defined GNULIB_POSIXCHECK) && @HAVE_SYS_LOADAVG_H@ /* OpenIndiana has a bug: must be included before @@ -83,13 +77,6 @@ #if @GNULIB_RANDOM_R@ -/* OSF/1 5.1 declares 'struct random_data' in , which is included - from if _REENTRANT is defined. Include it whenever we need - 'struct random_data'. */ -# if @HAVE_RANDOM_H@ -# include -# endif - # include # if !@HAVE_STRUCT_RANDOM_DATA@ @@ -2027,6 +2014,18 @@ _GL_CXXALIASWARN (wctomb); _GL_INLINE_HEADER_END + +/* Includes that provide only macros that don't need to be overridden. + (Includes that are needed for type definitions and function declarations + have their place above, before the function overrides.) */ + +/* MirBSD 10 defines WEXITSTATUS in , not in . + glibc 2.41 defines WCOREDUMP in , not in . */ +#if @GNULIB_SYSTEM_POSIX@ && !(defined WEXITSTATUS && defined WCOREDUMP) +# include +#endif + + #endif /* _@GUARD_PREFIX@_STDLIB_H */ #endif /* _@GUARD_PREFIX@_STDLIB_H */ #endif diff --git a/lib/strftime.c b/lib/strftime.c index 537172d8be6..6445d6e3d28 100644 --- a/lib/strftime.c +++ b/lib/strftime.c @@ -110,6 +110,7 @@ #include #include #include +#include #include #include @@ -198,17 +199,48 @@ enum pad_style # define mktime(tp) __mktime64 (tp) #endif +/* For functions that fill an in-memory string, the number of bytes fits in a + size_t. For functions that write to a stream, the number of bytes fits in + an off64_t (a type that is always at least 64 bits large). */ #if FPRINTFTIME # define STREAM_OR_CHAR_T FILE # define STRFTIME_ARG(x) /* empty */ +typedef off64_t byte_count_t; +typedef off64_t sbyte_count_t; #else # define STREAM_OR_CHAR_T CHAR_T # define STRFTIME_ARG(x) x, +typedef size_t byte_count_t; +typedef ptrdiff_t sbyte_count_t; +#endif + +/* The functions strftime[_l], wcsftime[_l] defined by glibc have a return type + 'size_t', for compatibility with POSIX, and return 0 upon failure. + The functions defined by Gnulib have a signed return type, and return -1 + upon failure. */ +#ifdef _LIBC +typedef size_t retval_t; +# define FAILURE 0 +#else +typedef sbyte_count_t retval_t; +# define FAILURE (-1) #endif #if FPRINTFTIME +# define FPUTC(Byte, P) \ + do \ + { \ + int _r = fputc (Byte, P); \ + if (_r < 0) \ + return FAILURE; \ + } \ + while (false) + # define memset_byte(P, Len, Byte) \ - do { size_t _i; for (_i = 0; _i < Len; _i++) fputc (Byte, P); } while (0) + do \ + for (byte_count_t _i = Len; 0 < _i; _i--) \ + FPUTC (Byte, P); \ + while (false) # define memset_space(P, Len) memset_byte (P, Len, ' ') # define memset_zero(P, Len) memset_byte (P, Len, '0') #elif defined COMPILE_WIDE @@ -226,22 +258,32 @@ enum pad_style #endif #define add(n, f) width_add (width, n, f) + +/* Add INCR, returning true if I would become too large. + INCR should not have side effects. */ +#if FPRINTFTIME +# define incr_overflow(incr) ckd_add (&i, i, incr) +#else +/* Use <= not <, to leave room for trailing NUL. */ +# define incr_overflow(incr) (maxsize - i <= (incr) || (i += (incr), false)) +#endif + #define width_add(width, n, f) \ do \ { \ - size_t _n = (n); \ - size_t _w = pad == NO_PAD || width < 0 ? 0 : width; \ - size_t _incr = _n < _w ? _w : _n; \ - if (_incr >= maxsize - i) \ + byte_count_t _n = n; \ + byte_count_t _w = pad == NO_PAD || width < 0 ? 0 : width; \ + byte_count_t _incr = _n < _w ? _w : _n; \ + if (incr_overflow (_incr)) \ { \ errno = ERANGE; \ - return 0; \ + return FAILURE; \ } \ if (p) \ { \ if (_n < _w) \ { \ - size_t _delta = _w - _n; \ + byte_count_t _delta = _w - _n; \ if (pad == ALWAYS_ZERO_PAD || pad == SIGN_PAD) \ memset_zero (p, _delta); \ else \ @@ -250,12 +292,11 @@ enum pad_style f; \ advance (p, _n); \ } \ - i += _incr; \ } while (0) #define add1(c) width_add1 (width, c) #if FPRINTFTIME -# define width_add1(width, c) width_add (width, 1, fputc (c, p)) +# define width_add1(width, c) width_add (width, 1, FPUTC (c, p)) #else # define width_add1(width, c) width_add (width, 1, *p = c) #endif @@ -266,19 +307,15 @@ enum pad_style width_add (width, n, \ do \ { \ + CHAR_T const *_s = s; \ if (to_lowcase) \ - fwrite_lowcase (p, (s), _n); \ + for (byte_count_t _i = 0; _i < _n; _i++) \ + FPUTC (TOLOWER ((UCHAR_T) _s[_i], loc), p); \ else if (to_uppcase) \ - fwrite_uppcase (p, (s), _n); \ - else \ - { \ - /* Ignore the value of fwrite. The caller can determine whether \ - an error occurred by inspecting ferror (P). All known fwrite \ - implementations set the stream's error indicator when they \ - fail due to ENOMEM etc., even though C11 and POSIX.1-2008 do \ - not require this. */ \ - fwrite (s, _n, 1, p); \ - } \ + for (byte_count_t _i = 0; _i < _n; _i++) \ + FPUTC (TOUPPER ((UCHAR_T) _s[_i], loc), p); \ + else if (fwrite (_s, _n, 1, p) == 0) \ + return FAILURE; \ } \ while (0) \ ) @@ -355,32 +392,12 @@ enum pad_style /* Avoid false GCC warning "'memset' specified size 18446744073709551615 exceeds maximum object size 9223372036854775807", caused by insufficient data flow analysis and value propagation of the 'width_add' expansion when GCC is not - optimizing. Cf. . */ + optimizing. Cf. . */ #if _GL_GNUC_PREREQ (7, 0) && !__OPTIMIZE__ # pragma GCC diagnostic ignored "-Wstringop-overflow" #endif -#if FPRINTFTIME -static void -fwrite_lowcase (FILE *fp, const CHAR_T *src, size_t len) -{ - while (len-- > 0) - { - fputc (TOLOWER ((UCHAR_T) *src, loc), fp); - ++src; - } -} - -static void -fwrite_uppcase (FILE *fp, const CHAR_T *src, size_t len) -{ - while (len-- > 0) - { - fputc (TOUPPER ((UCHAR_T) *src, loc), fp); - ++src; - } -} -#else +#if !FPRINTFTIME static CHAR_T *memcpy_lowcase (CHAR_T *dest, const CHAR_T *src, size_t len LOCALE_PARAM); @@ -894,12 +911,14 @@ static CHAR_T const c_month_names[][sizeof "September"] = # define ns 0 #endif -static size_t __strftime_internal (STREAM_OR_CHAR_T *, STRFTIME_ARG (size_t) - const CHAR_T *, const struct tm *, - CAL_ARGS (const struct calendar *, - struct calendar_date *) - bool, enum pad_style, int, bool * - extra_args_spec LOCALE_PARAM); +static retval_t __strftime_internal (STREAM_OR_CHAR_T *, + STRFTIME_ARG (size_t) + const CHAR_T *, const struct tm *, + CAL_ARGS (const struct calendar *, + struct calendar_date *) + bool, enum pad_style, + sbyte_count_t, bool * + extra_args_spec LOCALE_PARAM); #if !defined _LIBC \ && (!(HAVE_ONLY_C_LOCALE || (USE_C_LOCALE && !HAVE_STRFTIME_L)) \ @@ -1102,12 +1121,16 @@ get_tm_zone (timezone_t tz, char *ubuf, int ubufsize, int modifier, } /* Write information from TP into S according to the format - string FORMAT, writing no more that MAXSIZE characters - (including the terminating '\0') and returning number of - characters written. If S is NULL, nothing will be written - anywhere, so to determine how many characters would be - written, use NULL for S and (size_t) -1 for MAXSIZE. */ -size_t + string FORMAT. Return the number of bytes written. + Upon failure: + - return 0 for the functions defined by glibc, + - return -1 for the functions defined by Gnulib. + + If !FPRINTFTIME, write no more than MAXSIZE bytes (including the + terminating '\0'), and if S is NULL do not write into S. + To determine how many characters would be written, use NULL for S + and (size_t) -1 for MAXSIZE. */ +retval_t my_strftime (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) const CHAR_T *format, const struct tm *tp extra_args_spec LOCALE_PARAM) @@ -1150,24 +1173,26 @@ libc_hidden_def (my_strftime) UPCASE indicates that the result should be converted to upper case. YR_SPEC and WIDTH specify the padding and width for the year. *TZSET_CALLED indicates whether tzset has been called here. */ -static size_t +static retval_t __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) const CHAR_T *format, const struct tm *tp, CAL_ARGS (const struct calendar *cal, struct calendar_date *caldate) bool upcase, - enum pad_style yr_spec, int width, bool *tzset_called + enum pad_style yr_spec, sbyte_count_t width, + bool *tzset_called extra_args_spec LOCALE_PARAM) { #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL struct __locale_data *const current = loc->__locales[LC_TIME]; #endif -#if FPRINTFTIME - size_t maxsize = (size_t) -1; -#endif - +#if FAILURE == 0 int saved_errno = errno; +#elif !FPRINTFTIME + if (PTRDIFF_MAX < maxsize) + maxsize = PTRDIFF_MAX; +#endif #ifdef _NL_CURRENT /* We cannot make the following values variables since we must delay @@ -1221,7 +1246,7 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) # define ampm (L_("AMPM") + 2 * (tp->tm_hour > 11)) # define ap_len 2 #endif - size_t i = 0; + retval_t i = 0; STREAM_OR_CHAR_T *p = s; const CHAR_T *f; #if DO_MULTIBYTE && !defined COMPILE_WIDE @@ -1260,7 +1285,7 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) size_t colons; bool change_case = false; int format_char; - int subwidth; + sbyte_count_t subwidth; #if DO_MULTIBYTE && !defined COMPILE_WIDE switch (*f) @@ -1384,7 +1409,7 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) { if (ckd_mul (&width, width, 10) || ckd_add (&width, width, *f - L_('0'))) - width = INT_MAX; + return FAILURE; ++f; } while (ISDIGIT (*f)); @@ -1585,12 +1610,15 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) subwidth = -1; subformat_width: { - size_t len = __strftime_internal (NULL, STRFTIME_ARG ((size_t) -1) - subfmt, tp, - CAL_ARGS (cal, caldate) - to_uppcase, pad, subwidth, - tzset_called - extra_args LOCALE_ARG); + retval_t len = + __strftime_internal (NULL, STRFTIME_ARG ((size_t) -1) + subfmt, tp, + CAL_ARGS (cal, caldate) + to_uppcase, pad, subwidth, + tzset_called + extra_args LOCALE_ARG); + if (FAILURE < 0 && len < 0) + return FAILURE; /* errno is set here */ add (len, __strftime_internal (p, STRFTIME_ARG (maxsize - i) subfmt, tp, @@ -1862,8 +1890,9 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) if (digits_base >= 0x100) number_digits = number_bytes / 2; #endif - int shortage = width - !!sign_char - number_digits; - int padding = pad == NO_PAD || shortage <= 0 ? 0 : shortage; + byte_count_t shortage = width - !!sign_char - number_digits; + byte_count_t padding = (pad == NO_PAD || shortage <= 0 + ? 0 : shortage); if (sign_char) { @@ -1871,7 +1900,11 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) { if (p) memset_space (p, padding); - i += padding; + if (ckd_add (&i, i, padding) && FPRINTFTIME) + { + errno = ERANGE; + return FAILURE; + } width -= padding; } width_add1 (0, sign_char); @@ -2033,7 +2066,7 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) if (ltm.tm_yday < 0) { errno = EOVERFLOW; - return 0; + return FAILURE; } /* Generate string value for T using time_t arithmetic; @@ -2252,12 +2285,12 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) mbstate_t st = {0}; size_t len = __mbsrtowcs_l (p, &z, maxsize - i, &st, loc); if (len == (size_t) -1) - return 0; + return FAILURE; size_t incr = len < w ? w : len; if (incr >= maxsize - i) { errno = ERANGE; - return 0; + return FAILURE; } if (p) { @@ -2375,6 +2408,9 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) *p = L_('\0'); #endif +#if FAILURE == 0 errno = saved_errno; +#endif + return i; } diff --git a/lib/strftime.h b/lib/strftime.h index a76c98c9c82..bb2b63b075f 100644 --- a/lib/strftime.h +++ b/lib/strftime.h @@ -15,6 +15,7 @@ You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ +#include #include #ifdef __cplusplus @@ -71,23 +72,32 @@ extern "C" { Store the result, as a string with a trailing NUL character, at the beginning of the array __S[0..__MAXSIZE-1] and return the length of - that string, not counting the trailing NUL, and without changing errno. - If unsuccessful, possibly change the array __S, set errno, and return 0; + that string, not counting the trailing NUL. + If unsuccessful, possibly change the array __S, set errno, and return -1; errno == ERANGE means the string didn't fit. + As a glibc extension if __S is null, do not store anything, and + return the value that would have been returned had __S been non-null. + + A __MAXSIZE greater than PTRDIFF_MAX is silently treated as if + it were PTRDIFF_MAX, so that the caller can safely add 1 to + any return value without overflow. + This function is like strftime, but with two more arguments: * __TZ instead of the local timezone information, - * __NS as the number of nanoseconds in the %N directive. + * __NS as the number of nanoseconds in the %N directive, + and on success it does not preserve errno, + and on failure it returns -1 not 0. */ -size_t nstrftime (char *restrict __s, size_t __maxsize, - char const *__format, - struct tm const *__tp, timezone_t __tz, int __ns); +ptrdiff_t nstrftime (char *restrict __s, size_t __maxsize, + char const *__format, + struct tm const *__tp, timezone_t __tz, int __ns); /* Like nstrftime, except that it uses the "C" locale instead of the current locale. */ -size_t c_nstrftime (char *restrict __s, size_t __maxsize, - char const *__format, - struct tm const *__tp, timezone_t __tz, int __ns); +ptrdiff_t c_nstrftime (char *restrict __s, size_t __maxsize, + char const *__format, + struct tm const *__tp, timezone_t __tz, int __ns); #ifdef __cplusplus } diff --git a/lib/string.c b/lib/string.c new file mode 100644 index 00000000000..cce2eac9c06 --- /dev/null +++ b/lib/string.c @@ -0,0 +1,20 @@ +/* streq and memeq functions. + Copyright (C) 2025 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include + +#define _GL_STRING_INLINE _GL_EXTERN_INLINE +#include diff --git a/lib/string.in.h b/lib/string.in.h index 9a039c7ba06..fdcdd21bed6 100644 --- a/lib/string.in.h +++ b/lib/string.in.h @@ -80,6 +80,12 @@ # include #endif +_GL_INLINE_HEADER_BEGIN + +#ifndef _GL_STRING_INLINE +# define _GL_STRING_INLINE _GL_INLINE +#endif + /* _GL_ATTRIBUTE_DEALLOC (F, I) declares that the function returns pointers that can be freed by passing them as the Ith argument to the function F. */ @@ -96,7 +102,7 @@ /* Applies to: functions. Cannot be used on inline functions. */ #ifndef _GL_ATTRIBUTE_DEALLOC_FREE # if defined __cplusplus && defined __GNUC__ && !defined __clang__ -/* Work around GCC bug */ +/* Work around GCC bug */ # define _GL_ATTRIBUTE_DEALLOC_FREE \ _GL_ATTRIBUTE_DEALLOC ((void (*) (void *)) free, 1) # else @@ -409,6 +415,21 @@ _GL_WARN_ON_USE (memchr, "memchr has platform-specific bugs - " "use gnulib module memchr for portability" ); #endif +/* Are S1 and S2, of size N, bytewise equal? */ +#if @GNULIB_STRINGEQ@ && !@HAVE_DECL_MEMEQ@ +# ifdef __cplusplus +extern "C" { +# endif +_GL_STRING_INLINE bool +memeq (void const *__s1, void const *__s2, size_t __n) +{ + return !memcmp (__s1, __s2, __n); +} +# ifdef __cplusplus +} +# endif +#endif + /* Return the first occurrence of NEEDLE in HAYSTACK. */ #if @GNULIB_MEMMEM@ # if @REPLACE_MEMMEM@ @@ -789,6 +810,21 @@ _GL_CXXALIASWARN (strdup); # endif #endif +/* Are strings S1 and S2 equal? */ +#if @GNULIB_STRINGEQ@ && !@HAVE_DECL_STREQ@ +# ifdef __cplusplus +extern "C" { +# endif +_GL_STRING_INLINE bool +streq (char const *__s1, char const *__s2) +{ + return !strcmp (__s1, __s2); +} +# ifdef __cplusplus +} +# endif +#endif + /* Append no more than N characters from SRC onto DEST. */ #if @GNULIB_STRNCAT@ # if @REPLACE_STRNCAT@ @@ -1208,7 +1244,7 @@ _GL_EXTERN_C bool str_endswith (const char *string, const char *prefix) # ifdef __MirBSD__ /* MirBSD defines mbslen as a macro. Override it. */ # undef mbslen # endif -# if @HAVE_MBSLEN@ /* AIX, OSF/1, MirBSD define mbslen already in libc. */ +# if @HAVE_MBSLEN@ /* AIX, MirBSD define mbslen already in libc. */ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # define mbslen rpl_mbslen # endif @@ -1722,6 +1758,7 @@ _GL_WARN_ON_USE (strverscmp, "strverscmp is unportable - " # endif #endif +_GL_INLINE_HEADER_END #endif /* _@GUARD_PREFIX@_STRING_H */ #endif /* _@GUARD_PREFIX@_STRING_H */ diff --git a/lib/sys-limits.h b/lib/sys-limits.h index a556dfeb6d5..5f074fc7db6 100644 --- a/lib/sys-limits.h +++ b/lib/sys-limits.h @@ -30,10 +30,6 @@ Using this also works around a serious Linux bug before 2.6.16; see . - Using this also works around a Tru64 5.1 bug, where attempting - to read INT_MAX bytes fails with errno == EINVAL. See - . - Using this is likely to work around similar bugs in other operating systems. */ diff --git a/lib/sys_select.in.h b/lib/sys_select.in.h index a06725020d2..69c2fa9fc4e 100644 --- a/lib/sys_select.in.h +++ b/lib/sys_select.in.h @@ -26,17 +26,14 @@ #error "Please include config.h first." #endif -/* On OSF/1 and Solaris 2.6, and - both include . +/* On Solaris 2.6, and both include . On Cygwin and OpenBSD, includes . Simply delegate to the system's header in this case. */ #if (@HAVE_SYS_SELECT_H@ \ && !defined _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_TYPES_H \ - && ((defined __osf__ && defined _SYS_TYPES_H_ \ - && defined _OSF_SOURCE) \ - || (defined __sun && defined _SYS_TYPES_H \ - && (! (defined _XOPEN_SOURCE || defined _POSIX_C_SOURCE) \ - || defined __EXTENSIONS__)))) + && (defined __sun && defined _SYS_TYPES_H \ + && (! (defined _XOPEN_SOURCE || defined _POSIX_C_SOURCE) \ + || defined __EXTENSIONS__))) # define _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_TYPES_H # @INCLUDE_NEXT@ @NEXT_SYS_SELECT_H@ @@ -44,9 +41,7 @@ #elif (@HAVE_SYS_SELECT_H@ \ && (defined _CYGWIN_SYS_TIME_H \ || (!defined _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_TIME_H \ - && ((defined __osf__ && defined _SYS_TIME_H_ \ - && defined _OSF_SOURCE) \ - || (defined __OpenBSD__ && defined _SYS_TIME_H_) \ + && ((defined __OpenBSD__ && defined _SYS_TIME_H_) \ || (defined __sun && defined _SYS_TIME_H \ && (! (defined _XOPEN_SOURCE \ || defined _POSIX_C_SOURCE) \ @@ -55,16 +50,6 @@ # define _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_TIME_H # @INCLUDE_NEXT@ @NEXT_SYS_SELECT_H@ -/* On IRIX 6.5, includes , which includes - , which includes . At this point we cannot - include , because that includes , which - gives a syntax error because has not been completely - processed. Simply delegate to the system's header in this case. */ -#elif @HAVE_SYS_SELECT_H@ && defined __sgi && (defined _SYS_BSD_TYPES_H && !defined _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_BSD_TYPES_H) - -# define _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_BSD_TYPES_H -# @INCLUDE_NEXT@ @NEXT_SYS_SELECT_H@ - /* On OpenBSD 5.0, includes , which includes . At this point we cannot include , because that includes gnulib's pthread.h override, which gives a syntax error because @@ -90,10 +75,7 @@ #if @HAVE_SYS_SELECT_H@ -/* On OSF/1 4.0, provides only a forward declaration - of 'struct timeval', and no definition of this type. - Also, Mac OS X, AIX, HP-UX, IRIX, Solaris, Interix declare select() - in . +/* Mac OS X, AIX, HP-UX, Solaris, Interix declare select() in . But avoid namespace pollution on glibc systems, a circular include -> -> on FreeBSD 13.1, and "unknown type name" problems on Cygwin. */ @@ -101,14 +83,6 @@ # include # endif -/* On AIX 7 and Solaris 10, provides an FD_ZERO implementation - that relies on memset(), but without including . - But in any case avoid namespace pollution on glibc systems. */ -# if (defined __OpenBSD__ || defined _AIX || defined __sun || defined __osf__ || defined __BEOS__) \ - && ! defined __GLIBC__ -# include -# endif - /* The include_next requires a split double-inclusion guard. */ # @INCLUDE_NEXT@ @NEXT_SYS_SELECT_H@ @@ -352,5 +326,20 @@ _GL_WARN_ON_USE (select, "select is not always POSIX compliant - " #endif /* _@GUARD_PREFIX@_SYS_SELECT_H */ + + +/* Includes that provide only macros that don't need to be overridden. + (Includes that are needed for type definitions and function declarations + have their place above, before the function overrides.) */ + +/* On AIX 7 and Solaris 10, provides an FD_ZERO implementation + that relies on memset(), but without including . + But in any case avoid namespace pollution on glibc systems. */ +# if (defined __OpenBSD__ || defined _AIX || defined __sun || defined __BEOS__) \ + && ! defined __GLIBC__ +# include +# endif + + #endif /* _@GUARD_PREFIX@_SYS_SELECT_H */ -#endif /* OSF/1 */ +#endif diff --git a/lib/sys_stat.in.h b/lib/sys_stat.in.h index c3c38fd653e..8f676cb390e 100644 --- a/lib/sys_stat.in.h +++ b/lib/sys_stat.in.h @@ -790,8 +790,7 @@ _GL_CXXALIAS_RPL (mknod, int, (char const *file, mode_t mode, dev_t dev)); _GL_FUNCDECL_SYS (mknod, int, (char const *file, mode_t mode, dev_t dev), _GL_ARG_NONNULL ((1))); # endif -/* Need to cast, because on OSF/1 5.1, the third parameter is '...'. */ -_GL_CXXALIAS_SYS_CAST (mknod, int, (char const *file, mode_t mode, dev_t dev)); +_GL_CXXALIAS_SYS (mknod, int, (char const *file, mode_t mode, dev_t dev)); # endif _GL_CXXALIASWARN (mknod); #elif defined GNULIB_POSIXCHECK diff --git a/lib/time.in.h b/lib/time.in.h index 3ff16e3b3e4..d28702d2f61 100644 --- a/lib/time.in.h +++ b/lib/time.in.h @@ -523,11 +523,18 @@ _GL_CXXALIAS_SYS (tzalloc, timezone_t, (char const *__name)); # endif /* tzfree (tz) - Frees a time zone object. + Free a time zone object, preserving errno. The argument must have been returned by tzalloc(). */ # if !@HAVE_TZALLOC@ _GL_FUNCDECL_SYS (tzfree, void, (timezone_t __tz), ); _GL_CXXALIAS_SYS (tzfree, void, (timezone_t __tz)); +# else +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef tzfree +# define tzfree rpl_tzfree +# endif +_GL_FUNCDECL_RPL (tzfree, void, (timezone_t __tz), ); +_GL_CXXALIAS_RPL (tzfree, void, (timezone_t __tz)); # endif /* localtime_rz (tz, &t, &result) diff --git a/lib/time_rz.c b/lib/time_rz.c index 125f4e272d2..8a8eb44c357 100644 --- a/lib/time_rz.c +++ b/lib/time_rz.c @@ -27,7 +27,10 @@ /* Specification. */ #include -#if NEED_TIMEZONE_NULL_SUPPORT /* Android API level >= 35 */ +#include + +#if HAVE_TZALLOC +# if NEED_TIMEZONE_NULL_SUPPORT /* Android API level >= 35 */ struct tm * localtime_rz (timezone_t tz, time_t const *t, struct tm *tm) @@ -48,10 +51,19 @@ mktime_z (timezone_t tz, struct tm *tm) else return mktime_z (tz, tm); } +# endif + +void +tzfree (timezone_t tz) +# undef tzfree +{ + int err = errno; + tzfree (tz); + errno = err; +} #else -# include # include # include # include @@ -116,7 +128,7 @@ save_abbr (timezone_t tz, struct tm *tm) { zone_copy = tz->abbrs; - while (strcmp (zone_copy, zone) != 0) + while (!streq (zone_copy, zone)) { if (! (*zone_copy || (zone_copy == tz->abbrs && tz->tz_is_set))) { @@ -202,7 +214,7 @@ set_tz (timezone_t tz) { char *env_tz = getenv_TZ (); if (env_tz - ? tz->tz_is_set && strcmp (tz->abbrs, env_tz) == 0 + ? tz->tz_is_set && streq (tz->abbrs, env_tz) : !tz->tz_is_set) return local_tz; else @@ -212,9 +224,7 @@ set_tz (timezone_t tz) return old_tz; if (! change_env (tz)) { - int saved_errno = errno; tzfree (old_tz); - errno = saved_errno; return NULL; } return old_tz; diff --git a/lib/u64.h b/lib/u64.h index 6ea08969c29..b47d65e5033 100644 --- a/lib/u64.h +++ b/lib/u64.h @@ -1,4 +1,4 @@ -/* uint64_t-like operations that work even on hosts lacking uint64_t +/* Unsigned integers with arithmetic modulo 2**64 Copyright (C) 2006, 2009-2025 Free Software Foundation, Inc. @@ -17,11 +17,15 @@ /* Written by Paul Eggert. */ +#ifndef U64_H +#define U64_H 1 + /* This file uses _GL_INLINE_HEADER_BEGIN, _GL_INLINE. */ #if !_GL_CONFIG_H_INCLUDED #error "Please include config.h first." #endif +#include #include #include @@ -37,7 +41,7 @@ extern "C" { #endif -#ifdef UINT64_MAX +#if defined UINT64_MAX && INT_MAX < UINT64_MAX /* Native implementations are trivial. See below for comments on what these operations do. */ @@ -45,7 +49,9 @@ typedef uint64_t u64; # define u64hilo(hi, lo) ((u64) (((u64) (hi) << 32) + (lo))) # define u64init(hi, lo) u64hilo (hi, lo) # define u64lo(x) ((u64) (x)) +# define u64getlo(x) ((uint32_t) ((x) & UINT32_MAX)) # define u64size(x) u64lo (x) +# define u64not(x) (~(x)) # define u64lt(x, y) ((x) < (y)) # define u64and(x, y) ((x) & (y)) # define u64or(x, y) ((x) | (y)) @@ -94,6 +100,13 @@ u64lo (unsigned int lo) return r; } +/* Return the low 32 bits of the u64 value X. */ +_GL_U64_INLINE unsigned int +u64getlo (u64 x) +{ + return x.lo & _GL_U64_MASK32; +} + /* Return a u64 value representing SIZE, where 0 <= SIZE < 2**64. */ _GL_U64_INLINE u64 u64size (size_t size) @@ -104,6 +117,16 @@ u64size (size_t size) return r; } +/* Return the bitwise NOT of X. */ +_GL_U64_INLINE u64 +u64not (u64 x) +{ + u64 r; + r.hi = ~x.hi; + r.lo = ~x.lo; + return r; +} + /* Return X < Y. */ _GL_U64_INLINE bool u64lt (u64 x, u64 y) @@ -209,3 +232,5 @@ u64rol (u64 x, int n) #endif _GL_INLINE_HEADER_END + +#endif diff --git a/lib/unistd.in.h b/lib/unistd.in.h index 9f057d30cdf..5b5838240aa 100644 --- a/lib/unistd.in.h +++ b/lib/unistd.in.h @@ -104,15 +104,12 @@ # include #endif -/* FreeBSD 14.0, NetBSD 10.0, OpenBSD 7.5, Solaris 11.4, and glibc 2.41 - do not define O_CLOEXEC in . */ /* Cygwin 1.7.1 and Android 4.3 declare unlinkat in , not in . */ /* But avoid namespace pollution on glibc systems. */ -#if ! defined O_CLOEXEC \ - || ((@GNULIB_UNLINKAT@ || defined GNULIB_POSIXCHECK) \ - && (defined __CYGWIN__ || defined __ANDROID__) \ - && ! defined __GLIBC__) +#if ((@GNULIB_UNLINKAT@ || defined GNULIB_POSIXCHECK) \ + && (defined __CYGWIN__ || defined __ANDROID__) \ + && ! defined __GLIBC__) # include #endif @@ -120,10 +117,8 @@ /* mingw, MSVC, BeOS, Haiku declare environ in , not in . */ /* Solaris declares getcwd not only in but also in . */ -/* OSF Tru64 Unix cannot see gnulib rpl_strtod when system is - included here. */ /* But avoid namespace pollution on glibc systems. */ -#if !defined __GLIBC__ && !defined __osf__ +#if !defined __GLIBC__ # define __need_system_stdlib_h # include # undef __need_system_stdlib_h @@ -134,10 +129,10 @@ # include #endif -/* AIX and OSF/1 5.1 declare getdomainname in , not in . +/* AIX declares getdomainname in , not in . NonStop Kernel declares gethostname in , not in . */ /* But avoid namespace pollution on glibc systems. */ -#if ((@GNULIB_GETDOMAINNAME@ && (defined _AIX || defined __osf__)) \ +#if ((@GNULIB_GETDOMAINNAME@ && defined _AIX) \ || (@GNULIB_GETHOSTNAME@ && defined __TANDEM)) \ && !defined __GLIBC__ # include @@ -1336,8 +1331,7 @@ _GL_CXXALIAS_RPL (gethostname, int, (char *name, size_t len)); _GL_FUNCDECL_SYS (gethostname, int, (char *name, size_t len), _GL_ARG_NONNULL ((1))); # endif -/* Need to cast, because on Solaris 10 and OSF/1 5.1 systems, the second - parameter is +/* Need to cast, because on Solaris 10 systems, the second parameter is int len. */ _GL_CXXALIAS_SYS_CAST (gethostname, int, (char *name, size_t len)); # endif @@ -2151,9 +2145,9 @@ _GL_FUNCDECL_SYS (sethostname, int, (const char *name, size_t len), _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NODISCARD); # endif -/* Need to cast, because on Solaris 11 2011-10, Mac OS X 10.5, IRIX 6.5 - and FreeBSD 6.4 the second parameter is int. On Solaris 11 - 2011-10, the first parameter is not const. */ +/* Need to cast, because on Solaris 11 2011-10, Mac OS X 10.5, and FreeBSD 6.4 + the second parameter is int. On Solaris 11 2011-10, the first parameter is + not const. */ _GL_CXXALIAS_SYS_CAST (sethostname, int, (const char *name, size_t len)); # endif @@ -2493,6 +2487,18 @@ _GL_CXXALIASWARN (write); _GL_INLINE_HEADER_END + +/* Includes that provide only macros that don't need to be overridden. + (Includes that are needed for type definitions and function declarations + have their place above, before the function overrides.) */ + +/* FreeBSD 14.0, NetBSD 10.0, OpenBSD 7.5, Solaris 11.4, and glibc 2.41 + do not define O_CLOEXEC in . */ +#if ! defined O_CLOEXEC +# include +#endif + + #endif /* _@GUARD_PREFIX@_UNISTD_H */ #endif /* _GL_INCLUDING_UNISTD_H */ #endif /* _@GUARD_PREFIX@_UNISTD_H */ diff --git a/lib/unlocked-io.h b/lib/unlocked-io.h index 69ea6641a3f..8a7719c4876 100644 --- a/lib/unlocked-io.h +++ b/lib/unlocked-io.h @@ -73,6 +73,13 @@ # define fgets_unlocked(x,y,z) fgets (x,y,z) # endif +# if HAVE_DECL_FILENO_UNLOCKED || defined fileno_unlocked +# undef fileno +# define fileno(x) fileno_unlocked (x) +# else +# define fileno_unlocked(x) fileno (x) +# endif + # if HAVE_DECL_FPUTC_UNLOCKED || defined fputc_unlocked # undef fputc # define fputc(x,y) fputc_unlocked (x,y) diff --git a/lib/utimens.c b/lib/utimens.c index 28e4295f025..0387e9f10e9 100644 --- a/lib/utimens.c +++ b/lib/utimens.c @@ -21,6 +21,7 @@ #include +/* Specification. */ #define _GL_UTIMENS_INLINE _GL_EXTERN_INLINE #include "utimens.h" @@ -32,6 +33,7 @@ #include #include +#include "issymlink.h" #include "stat-time.h" #include "timespec.h" @@ -670,9 +672,17 @@ lutimens (char const *file, struct timespec const timespec[2]) # endif /* HAVE_LUTIMES && !HAVE_UTIMENSAT */ /* Out of luck for symlinks, but we still handle regular files. */ - if (!(adjustment_needed || REPLACE_FUNC_STAT_FILE) && lstat (file, &st)) - return -1; - if (!S_ISLNK (st.st_mode)) + bool not_symlink; + if (adjustment_needed || REPLACE_FUNC_STAT_FILE) + not_symlink = !S_ISLNK (st.st_mode); + else + { + int ret = issymlink (file); + if (ret < 0) + return -1; + not_symlink = !ret; + } + if (not_symlink) return fdutimens (-1, file, ts); errno = ENOSYS; return -1; diff --git a/m4/acl.m4 b/m4/acl.m4 index 2dd33497efd..0ab7d34e2d2 100644 --- a/m4/acl.m4 +++ b/m4/acl.m4 @@ -1,5 +1,5 @@ # acl.m4 -# serial 37 +# serial 39 dnl Copyright (C) 2002, 2004-2025 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -35,10 +35,10 @@ AC_DEFUN_ONCE([gl_FUNC_ACL], gl_saved_LIBS=$LIBS dnl Test for POSIX-draft-like API (GNU/Linux, FreeBSD, NetBSD >= 10, - dnl Mac OS X, IRIX, Tru64, Cygwin >= 2.5). - dnl -lacl is needed on GNU/Linux, -lpacl on OSF/1. + dnl Mac OS X, Cygwin >= 2.5). + dnl -lacl is needed on GNU/Linux. if test $use_acl = 0; then - AC_SEARCH_LIBS([acl_get_file], [acl pacl], + AC_SEARCH_LIBS([acl_get_file], [acl], [if test "$ac_cv_search_acl_get_file" != "none required"; then LIB_ACL=$ac_cv_search_acl_get_file fi diff --git a/m4/assert_h.m4 b/m4/assert_h.m4 index e77524caff9..b02cbd6810c 100644 --- a/m4/assert_h.m4 +++ b/m4/assert_h.m4 @@ -1,5 +1,5 @@ # assert_h.m4 -# serial 5 +# serial 6 dnl Copyright (C) 2011-2025 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -56,8 +56,6 @@ AC_DEFUN([gl_ASSERT_H], dnl The seemingly redundant parentheses are necessary for MSVC 14. dnl #undef assert so that programs are not tempted to use it without dnl specifically including assert.h. - dnl #undef __ASSERT_H__ so that on IRIX, when programs later include - dnl , this include actually defines assert. dnl Break the #undef_s apart with a comment so that 'configure' does dnl not comment them out. AH_VERBATIM([zzstatic_assert], @@ -78,9 +76,6 @@ AC_DEFUN([gl_ASSERT_H], && __GNUG__ < 6 && __clang_major__ < 6))) #include #undef/**/assert - #ifdef __sgi - #undef/**/__ASSERT_H__ - #endif /* Solaris 11.4 defines static_assert as a macro with 2 arguments. We need it also to be invocable with a single argument. Haiku 2022 does not define static_assert at all. */ diff --git a/m4/errno_h.m4 b/m4/errno_h.m4 index 420d5bb3e91..623cb7b2360 100644 --- a/m4/errno_h.m4 +++ b/m4/errno_h.m4 @@ -1,5 +1,5 @@ # errno_h.m4 -# serial 18 +# serial 19 dnl Copyright (C) 2004, 2006, 2008-2025 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -83,59 +83,4 @@ booboo gl_NEXT_HEADERS([errno.h]) GL_GENERATE_ERRNO_H=true fi - gl_REPLACE_ERRNO_VALUE([EMULTIHOP]) - gl_REPLACE_ERRNO_VALUE([ENOLINK]) - gl_REPLACE_ERRNO_VALUE([EOVERFLOW]) -]) - -# Assuming $1 = EOVERFLOW. -# The EOVERFLOW errno value ought to be defined in , according to -# POSIX. But some systems (like OpenBSD 4.0 or AIX 3) don't define it, and -# some systems (like OSF/1) define it when _XOPEN_SOURCE_EXTENDED is defined. -# Check for the value of EOVERFLOW. -# Set the variables EOVERFLOW_HIDDEN and EOVERFLOW_VALUE. -AC_DEFUN([gl_REPLACE_ERRNO_VALUE], -[ - if $GL_GENERATE_ERRNO_H; then - AC_CACHE_CHECK([for ]$1[ value], [gl_cv_header_errno_h_]$1, [ - AC_EGREP_CPP([yes],[ -#include -#ifdef ]$1[ -yes -#endif - ], - [gl_cv_header_errno_h_]$1[=yes], - [gl_cv_header_errno_h_]$1[=no]) - if test $gl_cv_header_errno_h_]$1[ = no; then - AC_EGREP_CPP([yes],[ -#define _XOPEN_SOURCE_EXTENDED 1 -#include -#ifdef ]$1[ -yes -#endif - ], [gl_cv_header_errno_h_]$1[=hidden]) - if test $gl_cv_header_errno_h_]$1[ = hidden; then - dnl The macro exists but is hidden. - dnl Define it to the same value. - AC_COMPUTE_INT([gl_cv_header_errno_h_]$1, $1, [ -#define _XOPEN_SOURCE_EXTENDED 1 -#include -/* The following two lines are a workaround against an autoconf-2.52 bug. */ -#include -#include -]) - fi - fi - ]) - case $gl_cv_header_errno_h_]$1[ in - yes | no) - ]$1[_HIDDEN=0; ]$1[_VALUE= - ;; - *) - ]$1[_HIDDEN=1; ]$1[_VALUE="$gl_cv_header_errno_h_]$1[" - ;; - esac - AC_SUBST($1[_HIDDEN]) - AC_SUBST($1[_VALUE]) - fi ]) diff --git a/m4/extern-inline.m4 b/m4/extern-inline.m4 index d4fe6d82a5d..820fbda5ddb 100644 --- a/m4/extern-inline.m4 +++ b/m4/extern-inline.m4 @@ -1,5 +1,5 @@ # extern-inline.m4 -# serial 1 +# serial 2 dnl Copyright 2012-2025 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -43,9 +43,11 @@ AC_DEFUN([gl_EXTERN_INLINE], functions or macros in standard C headers like . For example, if isdigit is mistakenly implemented via a static inline function, a program containing an extern inline function that calls isdigit - may not work since the C standard prohibits extern inline functions - from calling static functions (ISO C 99 section 6.7.4.(3). - This bug is known to occur on: + may not work since C99 through C23 prohibit extern inline functions + from calling static functions (ISO C 23 section 6.7.5.(2)). + Although a future C standard will likely relax this restriction + , + respect it for now. This bug is known to occur on: OS X 10.8 and earlier; see: https://lists.gnu.org/r/bug-gnulib/2012-12/msg00023.html @@ -112,8 +114,8 @@ AC_DEFUN([gl_EXTERN_INLINE], suppress bogus "no previous prototype for 'FOO'" and "no previous declaration for 'FOO'" diagnostics, when FOO is an inline function in the header; see - and - . */ + and + . */ #if __GNUC__ == 4 && 6 <= __GNUC_MINOR__ # if defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__ # define _GL_INLINE_HEADER_CONST_PRAGMA diff --git a/m4/fcntl_h.m4 b/m4/fcntl_h.m4 index 1c9f9cce021..6d6c8ff4de5 100644 --- a/m4/fcntl_h.m4 +++ b/m4/fcntl_h.m4 @@ -1,5 +1,5 @@ # fcntl_h.m4 -# serial 20 +# serial 21 dnl Copyright (C) 2006-2007, 2009-2025 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -26,7 +26,7 @@ AC_DEFUN_ONCE([gl_FCNTL_H], dnl corresponding gnulib module is not in use, if it is not common dnl enough to be declared everywhere. gl_WARN_ON_USE_PREPARE([[#include - ]], [fcntl openat]) + ]], [fcntl openat openat2]) ]) # gl_FCNTL_MODULE_INDICATOR([modulename]) @@ -53,6 +53,7 @@ AC_DEFUN([gl_FCNTL_H_REQUIRE_DEFAULTS], gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_NONBLOCKING]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_OPEN]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_OPENAT]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_OPENAT2]) dnl Support Microsoft deprecated alias function names by default. gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_CREAT], [1]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_OPEN], [1]) @@ -66,6 +67,7 @@ AC_DEFUN([gl_FCNTL_H_DEFAULTS], dnl Assume proper GNU behavior unless another module says otherwise. HAVE_FCNTL=1; AC_SUBST([HAVE_FCNTL]) HAVE_OPENAT=1; AC_SUBST([HAVE_OPENAT]) + HAVE_OPENAT2=0; AC_SUBST([HAVE_OPENAT2]) REPLACE_CREAT=0; AC_SUBST([REPLACE_CREAT]) REPLACE_FCNTL=0; AC_SUBST([REPLACE_FCNTL]) REPLACE_OPEN=0; AC_SUBST([REPLACE_OPEN]) diff --git a/m4/free.m4 b/m4/free.m4 index 485d82433ec..bf03a7d1902 100644 --- a/m4/free.m4 +++ b/m4/free.m4 @@ -14,10 +14,10 @@ AC_DEFUN([gl_FUNC_FREE], dnl In the next release of POSIX, free must preserve errno. dnl https://www.austingroupbugs.net/view.php?id=385 - dnl https://sourceware.org/bugzilla/show_bug.cgi?id=17924 + dnl https://sourceware.org/PR17924 dnl So far, we know of three platforms that do this: dnl * glibc >= 2.33, thanks to the fix for this bug: - dnl + dnl dnl * OpenBSD >= 4.5, thanks to this commit: dnl dnl * Solaris, because its malloc() implementation is based on brk(), diff --git a/m4/fseterr.m4 b/m4/fseterr.m4 new file mode 100644 index 00000000000..3a94c28824f --- /dev/null +++ b/m4/fseterr.m4 @@ -0,0 +1,15 @@ +# fseterr.m4 +# serial 2 +dnl Copyright (C) 2012-2025 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +dnl This file is offered as-is, without any warranty. + +AC_DEFUN([gl_FUNC_FSETERR], +[ + gl_CHECK_FUNCS_ANDROID([__fseterr], + [[#include + #include + ]]) +]) diff --git a/m4/fsusage.m4 b/m4/fsusage.m4 index bb7b6e4303d..546c42d292b 100644 --- a/m4/fsusage.m4 +++ b/m4/fsusage.m4 @@ -1,5 +1,5 @@ # fsusage.m4 -# serial 35 +# serial 37 dnl Copyright (C) 1997-1998, 2000-2001, 2003-2025 Free Software Foundation, dnl Inc. dnl This file is free software; the Free Software Foundation @@ -48,16 +48,12 @@ AC_DEFUN([gl_FILE_SYSTEM_USAGE], # is what it gets when this test fails. if test $ac_fsusage_space = no; then # glibc/{Hurd,kFreeBSD}, FreeBSD >= 5.0, NetBSD >= 3.0, - # OpenBSD >= 4.4, AIX, HP-UX, IRIX, Solaris, Cygwin, Interix, BeOS. + # OpenBSD >= 4.4, AIX, HP-UX, Solaris, Cygwin, Interix, BeOS. AC_CACHE_CHECK([for statvfs function (SVR4)], [fu_cv_sys_stat_statvfs], [AC_LINK_IFELSE( [AC_LANG_PROGRAM([[ #include -#ifdef __osf__ -"Do not use Tru64's statvfs implementation" -#endif - #include struct statvfs fsd; @@ -79,7 +75,7 @@ int check_f_blocks_size[sizeof fsd.f_blocks * CHAR_BIT <= 32 ? -1 : 1]; if test $fu_cv_sys_stat_statvfs = yes; then ac_fsusage_space=yes # AIX >= 5.2 has statvfs64 that has a wider f_blocks field than statvfs. - # glibc, HP-UX, IRIX, Solaris have statvfs64 as well, but on these systems + # glibc, HP-UX, Solaris have statvfs64 as well, but on these systems # statvfs with large-file support is already equivalent to statvfs64. AC_CACHE_CHECK([whether to use statvfs64], [fu_cv_sys_stat_statvfs64], @@ -140,38 +136,10 @@ int check_f_blocks_size[sizeof fsd.f_blocks * CHAR_BIT <= 32 ? -1 : 1]; (glibc/Linux > 2.6)]) fi - if test $ac_fsusage_space = no; then - # DEC Alpha running OSF/1 - AC_CACHE_CHECK([for 3-argument statfs function (DEC OSF/1)], - [fu_cv_sys_stat_statfs3_osf1], - [AC_RUN_IFELSE([AC_LANG_SOURCE([[ -#include -#include -#include - int - main () - { - struct statfs fsd; - fsd.f_fsize = 0; - return statfs (".", &fsd, sizeof (struct statfs)) != 0; - }]])], - [fu_cv_sys_stat_statfs3_osf1=yes], - [fu_cv_sys_stat_statfs3_osf1=no], - [fu_cv_sys_stat_statfs3_osf1=no]) - ]) - if test $fu_cv_sys_stat_statfs3_osf1 = yes; then - ac_fsusage_space=yes - AC_DEFINE([STAT_STATFS3_OSF1], [1], - [Define if statfs takes 3 args. (DEC Alpha running OSF/1)]) - fi - fi - if test $ac_fsusage_space = no; then # glibc/Linux, Mac OS X, FreeBSD < 5.0, NetBSD < 3.0, OpenBSD < 4.4. # (glibc/{Hurd,kFreeBSD}, FreeBSD >= 5.0, NetBSD >= 3.0, - # OpenBSD >= 4.4, AIX, HP-UX, OSF/1, Cygwin already handled above.) - # (On IRIX you need to include , not only and - # .) + # OpenBSD >= 4.4, AIX, HP-UX, Cygwin already handled above.) # (On Solaris, statfs has 4 arguments.) AC_CACHE_CHECK([for two-argument statfs with statfs.f_bsize member (AIX, 4.3BSD)], [fu_cv_sys_stat_statfs2_bsize], @@ -225,13 +193,12 @@ int check_f_blocks_size[sizeof fsd.f_blocks * CHAR_BIT <= 32 ? -1 : 1]; if test $fu_cv_sys_stat_statfs4 = yes; then ac_fsusage_space=yes AC_DEFINE([STAT_STATFS4], [1], - [Define if statfs takes 4 args. (SVR3, old Irix)]) + [Define if statfs takes 4 args. (SVR3)]) fi fi if test $ac_fsusage_space = no; then # 4.4BSD and older NetBSD - # (OSF/1 already handled above.) # (On AIX, you need to include , not only .) # (On Solaris, statfs has 4 arguments and 'struct statfs' is not declared in # .) diff --git a/m4/getdelim.m4 b/m4/getdelim.m4 index 63d8830649a..d1217ab8d95 100644 --- a/m4/getdelim.m4 +++ b/m4/getdelim.m4 @@ -1,5 +1,5 @@ # getdelim.m4 -# serial 19 +# serial 21 dnl Copyright (C) 2005-2007, 2009-2025 Free Software Foundation, Inc. dnl @@ -37,6 +37,7 @@ AC_DEFUN([gl_FUNC_GETDELIM], gl_cv_func_working_getdelim=no ;; *) echo fooNbarN | tr -d '\012' | tr N '\012' > conftest.data + touch conftest.empty AC_RUN_IFELSE([AC_LANG_SOURCE([[ # include # include @@ -44,6 +45,7 @@ AC_DEFUN([gl_FUNC_GETDELIM], int main () { FILE *in = fopen ("./conftest.data", "r"); + int result = 0; if (!in) return 1; { @@ -53,7 +55,7 @@ AC_DEFUN([gl_FUNC_GETDELIM], size_t siz = 0; int len = getdelim (&line, &siz, '\n', in); if (!(len == 4 && line && strcmp (line, "foo\n") == 0)) - { free (line); fclose (in); return 2; } + result |= 2; free (line); } { @@ -62,35 +64,40 @@ AC_DEFUN([gl_FUNC_GETDELIM], char *line = NULL; size_t siz = (size_t)(~0) / 4; if (getdelim (&line, &siz, '\n', in) == -1) - { fclose (in); return 3; } + result |= 4; free (line); } fclose (in); - return 0; + { + /* Test that reading EOF as the first character sets the first byte + in the buffer to NUL. This fails on glibc 2.42 and earlier. */ + in = fopen ("./conftest.empty", "r"); + if (!in) + return 1; + char *line = malloc (1); + line[0] = 'A'; + size_t siz = 1; + if (getdelim (&line, &siz, '\n', in) != -1 || line[0] != '\0') + result |= 8; + free (line); + } + fclose (in); + return result; } ]])], [gl_cv_func_working_getdelim=yes], [gl_cv_func_working_getdelim=no], - [dnl We're cross compiling. - dnl Guess it works on glibc2 systems and musl systems. - AC_EGREP_CPP([Lucky GNU user], - [ -#include -#ifdef __GNU_LIBRARY__ - #if (__GLIBC__ >= 2) && !defined __UCLIBC__ - Lucky GNU user - #endif -#endif - ], - [gl_cv_func_working_getdelim="guessing yes"], - [case "$host_os" in - *-musl* | midipix*) gl_cv_func_working_getdelim="guessing yes" ;; - *) gl_cv_func_working_getdelim="$gl_cross_guess_normal" ;; - esac - ]) + [case "$host_os" in + # Guess yes on musl. + *-musl* | midipix*) gl_cv_func_working_getdelim="guessing yes" ;; + # Guess no on glibc. + *-gnu* | gnu*) gl_cv_func_working_getdelim="guessing no" ;; + *) gl_cv_func_working_getdelim="$gl_cross_guess_normal" ;; + esac ]) ;; esac + rm -f conftest.data conftest.empty ]) case "$gl_cv_func_working_getdelim" in *yes) ;; diff --git a/m4/getline.m4 b/m4/getline.m4 index b97b8011248..e07d6533ddc 100644 --- a/m4/getline.m4 +++ b/m4/getline.m4 @@ -1,5 +1,5 @@ # getline.m4 -# serial 33 +# serial 35 dnl Copyright (C) 1998-2003, 2005-2007, 2009-2025 Free Software Foundation, dnl Inc. @@ -31,6 +31,7 @@ AC_DEFUN([gl_FUNC_GETLINE], AC_CACHE_CHECK([for working getline function], [am_cv_func_working_getline], [echo fooNbarN | tr -d '\012' | tr N '\012' > conftest.data + touch conftest.empty AC_RUN_IFELSE([AC_LANG_SOURCE([[ # include # include @@ -38,6 +39,7 @@ AC_DEFUN([gl_FUNC_GETLINE], int main () { FILE *in = fopen ("./conftest.data", "r"); + int result = 0; if (!in) return 1; { @@ -47,7 +49,7 @@ AC_DEFUN([gl_FUNC_GETLINE], size_t siz = 0; int len = getline (&line, &siz, in); if (!(len == 4 && line && strcmp (line, "foo\n") == 0)) - { free (line); fclose (in); return 2; } + result |= 2; free (line); } { @@ -56,33 +58,38 @@ AC_DEFUN([gl_FUNC_GETLINE], char *line = NULL; size_t siz = (size_t)(~0) / 4; if (getline (&line, &siz, in) == -1) - { fclose (in); return 3; } + result |= 4; free (line); } fclose (in); - return 0; + { + /* Test that reading EOF as the first character sets the first byte + in the buffer to NUL. This fails on glibc 2.42 and earlier. */ + in = fopen ("./conftest.empty", "r"); + if (!in) + return 1; + char *line = malloc (1); + line[0] = 'A'; + size_t siz = 1; + if (getline (&line, &siz, in) != -1 || line[0] != '\0') + result |= 8; + free (line); + } + fclose (in); + return result; } ]])], [am_cv_func_working_getline=yes], [am_cv_func_working_getline=no], - [dnl We're cross compiling. - dnl Guess it works on glibc2 systems and musl systems. - AC_EGREP_CPP([Lucky GNU user], - [ -#include -#ifdef __GNU_LIBRARY__ - #if (__GLIBC__ >= 2) && !defined __UCLIBC__ - Lucky GNU user - #endif -#endif - ], - [am_cv_func_working_getline="guessing yes"], - [case "$host_os" in - *-musl* | midipix*) am_cv_func_working_getline="guessing yes" ;; - *) am_cv_func_working_getline="$gl_cross_guess_normal" ;; - esac - ]) + [case "$host_os" in + # Guess yes on musl. + *-musl* | midipix*) am_cv_func_working_getline="guessing yes" ;; + # Guess no on glibc. + *-gnu* | gnu*) am_cv_func_working_getline="guessing no" ;; + *) am_cv_func_working_getline="$gl_cross_guess_normal" ;; + esac ]) + rm -f conftest.data conftest.empty ]) else am_cv_func_working_getline=no diff --git a/m4/getloadavg.m4 b/m4/getloadavg.m4 index 8ab613db820..0d80b64acd5 100644 --- a/m4/getloadavg.m4 +++ b/m4/getloadavg.m4 @@ -1,5 +1,5 @@ # getloadavg.m4 -# serial 13 +# serial 14 dnl Copyright (C) 1992-1996, 1999-2000, 2002-2003, 2006, 2008-2025 Free dnl Software Foundation, Inc. dnl This file is free software; the Free Software Foundation @@ -124,8 +124,7 @@ if test $gl_func_getloadavg_done = no; then fi # We cannot check for , because Solaris 2 does not use dwarf (it -# uses stabs), but it is still SVR4. We cannot check for because -# Irix 4.0.5F has the header but not the library. +# uses stabs), but it is still SVR4. if test $gl_func_getloadavg_done = no && test "$ac_cv_lib_elf_elf_begin" = yes \ && test "$ac_cv_lib_kvm_kvm_open" = yes; then gl_func_getloadavg_done=yes diff --git a/m4/getopt.m4 b/m4/getopt.m4 index cb344c15d1f..f219ed522ca 100644 --- a/m4/getopt.m4 +++ b/m4/getopt.m4 @@ -1,5 +1,5 @@ # getopt.m4 -# serial 50 +# serial 52 dnl Copyright (C) 2002-2006, 2008-2025 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -88,8 +88,8 @@ AC_DEFUN([gl_GETOPT_CHECK_HEADERS], dnl Merging these three different test programs into a single one dnl would require a reset mechanism. On BSD systems, it can be done dnl through 'optreset'; on some others (glibc), it can be done by - dnl setting 'optind' to 0; on others again (HP-UX, IRIX, OSF/1, - dnl Solaris 9, musl libc), there is no such mechanism. + dnl setting 'optind' to 0; on others again (HP-UX, Solaris 9, + dnl musl libc), there is no such mechanism. if test $cross_compiling = no; then dnl Sanity check. Succeeds everywhere (except on MSVC, dnl which lacks and getopt() entirely). @@ -238,8 +238,7 @@ dnl is ambiguous with environment values that contain newlines. nocrash_init(); /* This code succeeds on glibc 2.8, OpenBSD 4.0, Cygwin, mingw, - and fails on Mac OS X 10.5, AIX 5.2, HP-UX 11, IRIX 6.5, - OSF/1 5.1, Solaris 10. */ + and fails on Mac OS X 10.5, AIX 5.2, HP-UX 11, Solaris 10. */ { static char conftest[] = "conftest"; static char plus[] = "-+"; @@ -250,7 +249,7 @@ dnl is ambiguous with environment values that contain newlines. } /* This code succeeds on glibc 2.8, mingw, and fails on Mac OS X 10.5, OpenBSD 4.0, AIX 5.2, HP-UX 11, - IRIX 6.5, OSF/1 5.1, Solaris 10, Cygwin 1.5.x. */ + Solaris 10, Cygwin 1.5.x. */ { static char program[] = "program"; static char p[] = "-p"; diff --git a/m4/gettext_h.m4 b/m4/gettext_h.m4 new file mode 100644 index 00000000000..b4b1995c762 --- /dev/null +++ b/m4/gettext_h.m4 @@ -0,0 +1,21 @@ +# gettext_h.m4 +# serial 1 +dnl Copyright (C) 2025 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +dnl This file is offered as-is, without any warranty. + +AC_DEFUN_ONCE([gl_GETTEXT_H], +[ + AC_SUBST([LIBINTL]) + AC_SUBST([LTLIBINTL]) + AH_BOTTOM([ +/* The text domainname for Gnulib messages. Ordinarily this is "gnulib", + but packages that do their own translations of Gnulib can use something + different by defining GNULIB_TEXT_DOMAIN in their config.h file. */ +#ifndef GNULIB_TEXT_DOMAIN +# define GNULIB_TEXT_DOMAIN/**/"gnulib" +#endif +]) +]) diff --git a/m4/gnulib-common.m4 b/m4/gnulib-common.m4 index 034dae69e68..134bfba21d0 100644 --- a/m4/gnulib-common.m4 +++ b/m4/gnulib-common.m4 @@ -168,7 +168,7 @@ AC_DEFUN([gl_COMMON_BODY], [ ====================================================================== This gives a syntax error - in C mode with gcc - , and + , and - in C++ mode with clang++ version < 16, and - in C++ mode, inside extern "C" {}, still in newer clang++ versions . @@ -451,7 +451,7 @@ AC_DEFUN([gl_COMMON_BODY], [ yet. */ #ifndef _GL_ATTRIBUTE_DEALLOC_FREE # if defined __cplusplus && defined __GNUC__ && !defined __clang__ -/* Work around GCC bug */ +/* Work around GCC bug */ # define _GL_ATTRIBUTE_DEALLOC_FREE \ _GL_ATTRIBUTE_DEALLOC ((void (*) (void *)) free, 1) # else diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4 index 107b1493617..b80c5c84a0b 100644 --- a/m4/gnulib-comp.m4 +++ b/m4/gnulib-comp.m4 @@ -105,6 +105,7 @@ AC_DEFUN([gl_EARLY], # Code from module fpieee: AC_REQUIRE([gl_FP_IEEE]) # Code from module free-posix: + # Code from module fseterr: # Code from module fstatat: # Code from module fsusage: # Code from module fsync: @@ -131,6 +132,8 @@ AC_DEFUN([gl_EARLY], # Code from module include_next: # Code from module intprops: # Code from module inttypes-h-incomplete: + # Code from module issymlink: + # Code from module issymlinkat: # Code from module largefile: AC_REQUIRE([AC_SYS_LARGEFILE]) # Code from module lchmod: @@ -192,6 +195,7 @@ AC_DEFUN([gl_EARLY], # Code from module stdlib-h: # Code from module stpcpy: # Code from module string-h: + # Code from module stringeq: # Code from module strnlen: # Code from module strtoimax: # Code from module strtoll: @@ -341,6 +345,8 @@ AC_DEFUN([gl_INIT], gl_PREREQ_FREE ]) gl_STDLIB_MODULE_INDICATOR([free-posix]) + gl_FUNC_FSETERR + gl_CONDITIONAL([GL_COND_OBJ_FSETERR], [test $ac_cv_func___fseterr = no]) gl_FUNC_FSTATAT gl_CONDITIONAL([GL_COND_OBJ_FSTATAT], [test $HAVE_FSTATAT = 0 || test $REPLACE_FSTATAT = 1]) @@ -562,6 +568,18 @@ AC_DEFUN([gl_INIT], gl_STDIO_H gl_STDIO_H_REQUIRE_DEFAULTS AC_PROG_MKDIR_P + USES_MSVCRT=0 + case "$host_os" in + mingw* | windows*) + AC_EGREP_CPP([Special], [ + #ifndef _UCRT + Special + #endif + ], + [USES_MSVCRT=1]) + ;; + esac + gl_CONDITIONAL([GL_COND_OBJ_STDIO_CONSOLESAFE], [test $USES_MSVCRT = 1]) gl_CONDITIONAL([GL_COND_OBJ_STDIO_READ], [test $REPLACE_STDIO_READ_FUNCS = 1]) gl_CONDITIONAL([GL_COND_OBJ_STDIO_WRITE], [test $REPLACE_STDIO_WRITE_FUNCS = 1]) dnl No need to create extra modules for these functions. Everyone who uses @@ -600,6 +618,9 @@ AC_DEFUN([gl_INIT], gl_STRING_H gl_STRING_H_REQUIRE_DEFAULTS AC_PROG_MKDIR_P + gl_FUNC_STREQ + gl_FUNC_MEMEQ + gl_STRING_MODULE_INDICATOR([stringeq]) gl_FUNC_STRNLEN gl_CONDITIONAL([GL_COND_OBJ_STRNLEN], [test $HAVE_DECL_STRNLEN = 0 || test $REPLACE_STRNLEN = 1]) @@ -646,8 +667,6 @@ AC_DEFUN([gl_INIT], ]) gl_TIME_MODULE_INDICATOR([time_r]) gl_TIME_RZ - gl_CONDITIONAL([GL_COND_OBJ_TIME_RZ], - [test $HAVE_TZALLOC = 0 || test $REPLACE_LOCALTIME_RZ = 1 || test $REPLACE_MKTIME_Z = 1]) gl_TIME_MODULE_INDICATOR([time_rz]) gl_FUNC_TIMEGM gl_CONDITIONAL([GL_COND_OBJ_TIMEGM], @@ -690,6 +709,8 @@ AC_DEFUN([gl_INIT], gl_gnulib_enabled_fd38c7e463b54744b77b98aeafb4fa7c=false gl_gnulib_enabled_8444034ea779b88768865bb60b4fb8c9=false gl_gnulib_enabled_a9786850e999ae65a836a6041e8e5ed1=false + gl_gnulib_enabled_issymlink=false + gl_gnulib_enabled_issymlinkat=false gl_gnulib_enabled_lchmod=false gl_gnulib_enabled_5264294aa0a5557541b53c8c741f7f31=false gl_gnulib_enabled_open=false @@ -799,8 +820,7 @@ AC_DEFUN([gl_INIT], func_gl_gnulib_m4code_be453cec5eecf5731a274f2de7f2db36 () { if $gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36; then :; else - AC_SUBST([LIBINTL]) - AC_SUBST([LTLIBINTL]) + gl_GETTEXT_H gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36=true fi } @@ -833,6 +853,20 @@ AC_DEFUN([gl_INIT], fi fi } + func_gl_gnulib_m4code_issymlink () + { + if $gl_gnulib_enabled_issymlink; then :; else + gl_MODULE_INDICATOR([issymlink]) + gl_gnulib_enabled_issymlink=true + fi + } + func_gl_gnulib_m4code_issymlinkat () + { + if $gl_gnulib_enabled_issymlinkat; then :; else + gl_MODULE_INDICATOR([issymlinkat]) + gl_gnulib_enabled_issymlinkat=true + fi + } func_gl_gnulib_m4code_lchmod () { if $gl_gnulib_enabled_lchmod; then :; else @@ -843,6 +877,12 @@ AC_DEFUN([gl_INIT], ]) gl_SYS_STAT_MODULE_INDICATOR([lchmod]) gl_gnulib_enabled_lchmod=true + if test $HAVE_LCHMOD = 0; then + func_gl_gnulib_m4code_issymlink + fi + if test $HAVE_LCHMOD = 0; then + func_gl_gnulib_m4code_issymlinkat + fi fi } func_gl_gnulib_m4code_5264294aa0a5557541b53c8c741f7f31 () @@ -913,6 +953,7 @@ AC_DEFUN([gl_INIT], if $gl_gnulib_enabled_utimens; then :; else gl_UTIMENS gl_gnulib_enabled_utimens=true + func_gl_gnulib_m4code_issymlink fi } func_gl_gnulib_m4code_verify () @@ -942,6 +983,9 @@ AC_DEFUN([gl_INIT], if test $HAVE_FCHMODAT = 0; then func_gl_gnulib_m4code_260941c0e5dc67ec9e87d1fb321c300b fi + if test $REPLACE_FCHMODAT = 1; then + func_gl_gnulib_m4code_issymlinkat + fi if test $HAVE_FCHMODAT = 0; then func_gl_gnulib_m4code_lchmod fi @@ -987,6 +1031,9 @@ AC_DEFUN([gl_INIT], if test $HAVE_READLINKAT = 0 || test $REPLACE_READLINKAT = 1; then func_gl_gnulib_m4code_03e0aaad4cb89ca757653bd367a6ccb7 fi + if test $ac_use_included_regex = yes; then + func_gl_gnulib_m4code_be453cec5eecf5731a274f2de7f2db36 + fi if test $ac_use_included_regex = yes; then func_gl_gnulib_m4code_fd38c7e463b54744b77b98aeafb4fa7c fi @@ -1022,6 +1069,8 @@ AC_DEFUN([gl_INIT], AM_CONDITIONAL([gl_GNULIB_ENABLED_fd38c7e463b54744b77b98aeafb4fa7c], [$gl_gnulib_enabled_fd38c7e463b54744b77b98aeafb4fa7c]) AM_CONDITIONAL([gl_GNULIB_ENABLED_8444034ea779b88768865bb60b4fb8c9], [$gl_gnulib_enabled_8444034ea779b88768865bb60b4fb8c9]) AM_CONDITIONAL([gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1], [$gl_gnulib_enabled_a9786850e999ae65a836a6041e8e5ed1]) + AM_CONDITIONAL([gl_GNULIB_ENABLED_issymlink], [$gl_gnulib_enabled_issymlink]) + AM_CONDITIONAL([gl_GNULIB_ENABLED_issymlinkat], [$gl_gnulib_enabled_issymlinkat]) AM_CONDITIONAL([gl_GNULIB_ENABLED_lchmod], [$gl_gnulib_enabled_lchmod]) AM_CONDITIONAL([gl_GNULIB_ENABLED_5264294aa0a5557541b53c8c741f7f31], [$gl_gnulib_enabled_5264294aa0a5557541b53c8c741f7f31]) AM_CONDITIONAL([gl_GNULIB_ENABLED_open], [$gl_gnulib_enabled_open]) @@ -1291,6 +1340,8 @@ AC_DEFUN([gl_FILE_LIST], [ lib/fpending.c lib/fpending.h lib/free.c + lib/fseterr.c + lib/fseterr.h lib/fstatat.c lib/fsusage.c lib/fsusage.h @@ -1325,6 +1376,9 @@ AC_DEFUN([gl_FILE_LIST], [ lib/intprops-internal.h lib/intprops.h lib/inttypes.in.h + lib/issymlink.c + lib/issymlink.h + lib/issymlinkat.c lib/lchmod.c lib/libc-config.h lib/limits.in.h @@ -1404,6 +1458,7 @@ AC_DEFUN([gl_FILE_LIST], [ lib/stdckdint.in.h lib/stddef.in.h lib/stdint.in.h + lib/stdio-consolesafe.c lib/stdio-impl.h lib/stdio-read.c lib/stdio-write.c @@ -1414,6 +1469,7 @@ AC_DEFUN([gl_FILE_LIST], [ lib/str-two-way.h lib/strftime.c lib/strftime.h + lib/string.c lib/string.in.h lib/strnlen.c lib/strtoimax.c @@ -1485,6 +1541,7 @@ AC_DEFUN([gl_FILE_LIST], [ m4/fpending.m4 m4/fpieee.m4 m4/free.m4 + m4/fseterr.m4 m4/fstatat.m4 m4/fsusage.m4 m4/fsync.m4 @@ -1496,6 +1553,7 @@ AC_DEFUN([gl_FILE_LIST], [ m4/getloadavg.m4 m4/getopt.m4 m4/getrandom.m4 + m4/gettext_h.m4 m4/gettime.m4 m4/gettimeofday.m4 m4/gl-openssl.m4 @@ -1565,6 +1623,7 @@ AC_DEFUN([gl_FILE_LIST], [ m4/stdlib_h.m4 m4/stpcpy.m4 m4/string_h.m4 + m4/stringeq.m4 m4/strnlen.m4 m4/strtoimax.m4 m4/strtoll.m4 diff --git a/m4/largefile.m4 b/m4/largefile.m4 index b24f657dec4..6aa07078297 100644 --- a/m4/largefile.m4 +++ b/m4/largefile.m4 @@ -1,5 +1,5 @@ # largefile.m4 -# serial 2 +# serial 4 dnl Copyright 1992-1996, 1998-2025 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -355,8 +355,7 @@ AC_DEFUN([gl_LARGEFILE], *) dnl Nothing to do on gnulib's side. dnl A 64-bit off_t is - dnl - already the default on Mac OS X, FreeBSD, NetBSD, OpenBSD, IRIX, - dnl OSF/1, Cygwin, + dnl - already the default on Mac OS X, FreeBSD, NetBSD, OpenBSD, Cygwin, dnl - enabled by _FILE_OFFSET_BITS=64 (ensured by AC_SYS_LARGEFILE) on dnl glibc, HP-UX, Solaris, dnl - enabled by _LARGE_FILES=1 (ensured by AC_SYS_LARGEFILE) on AIX, diff --git a/m4/lchmod.m4 b/m4/lchmod.m4 index fd768343472..601d1d3da4f 100644 --- a/m4/lchmod.m4 +++ b/m4/lchmod.m4 @@ -1,5 +1,5 @@ # lchmod.m4 -# serial 10 +# serial 11 dnl Copyright (C) 2005-2006, 2008-2025 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -16,7 +16,7 @@ AC_DEFUN([gl_FUNC_LCHMOD], dnl Persuade glibc to declare lchmod(). AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) - AC_CHECK_FUNCS_ONCE([lchmod]) + gl_CHECK_FUNCS_ANDROID([lchmod], [[#include ]]) if test "$ac_cv_func_lchmod" = no; then HAVE_LCHMOD=0 fi diff --git a/m4/malloc.m4 b/m4/malloc.m4 index cb607b61732..688594fe661 100644 --- a/m4/malloc.m4 +++ b/m4/malloc.m4 @@ -1,5 +1,5 @@ # malloc.m4 -# serial 43 +# serial 44 dnl Copyright (C) 2007, 2009-2025 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -186,9 +186,7 @@ AC_DEFUN([gl_CHECK_MALLOC_POSIX], [gl_cv_func_malloc_posix="guessing yes"], [gl_cv_func_malloc_posix="guessing no"]) ;; - irix* | solaris*) - dnl On IRIX 6.5, the three functions return NULL with errno unset - dnl when the argument is larger than PTRDIFF_MAX. + solaris*) dnl On Solaris 11.3, the three functions return NULL with errno set dnl to EAGAIN, not ENOMEM, when the argument is larger than dnl PTRDIFF_MAX. diff --git a/m4/manywarnings.m4 b/m4/manywarnings.m4 index eebba901806..bb5b4e10cd9 100644 --- a/m4/manywarnings.m4 +++ b/m4/manywarnings.m4 @@ -198,7 +198,7 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC(C)], fi # This warning have too many false alarms in GCC 11.2.1. - # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101713 + # https://gcc.gnu.org/PR101713 AS_VAR_APPEND([$1], [' -Wno-analyzer-malloc-leak']) AC_LANG_POP([C]) diff --git a/m4/memmem.m4 b/m4/memmem.m4 index ce5b85990e4..e940f8273f0 100644 --- a/m4/memmem.m4 +++ b/m4/memmem.m4 @@ -23,7 +23,7 @@ AC_DEFUN([gl_FUNC_MEMMEM_SIMPLE], if test $ac_cv_have_decl_memmem = no; then HAVE_DECL_MEMMEM=0 else - dnl Detect https://sourceware.org/bugzilla/show_bug.cgi?id=12092. + dnl Detect https://sourceware.org/PR12092. dnl Also check that we handle empty needles correctly. AC_CACHE_CHECK([whether memmem works], [gl_cv_func_memmem_works_always], diff --git a/m4/mktime.m4 b/m4/mktime.m4 index eca6c4d8924..6d7243e3306 100644 --- a/m4/mktime.m4 +++ b/m4/mktime.m4 @@ -1,5 +1,5 @@ # mktime.m4 -# serial 42 +# serial 43 dnl Copyright (C) 2002-2003, 2005-2007, 2009-2025 Free Software Foundation, dnl Inc. dnl This file is free software; the Free Software Foundation @@ -112,22 +112,6 @@ mktime_test (time_t now) && mktime_test1 ((time_t) (time_t_min + now))); } -static int -irix_6_4_bug () -{ - /* Based on code from Ariel Faigon. */ - struct tm tm; - tm.tm_year = 96; - tm.tm_mon = 3; - tm.tm_mday = 0; - tm.tm_hour = 0; - tm.tm_min = 0; - tm.tm_sec = 0; - tm.tm_isdst = -1; - mktime (&tm); - return tm.tm_mon == 2 && tm.tm_mday == 31; -} - static int bigtime_test (int j) { @@ -255,12 +239,10 @@ main () if ((result & 8) == 0 && ! bigtime_test (INT_MAX)) result |= 8; } - if (! irix_6_4_bug ()) - result |= 16; if (! spring_forward_gap ()) - result |= 32; + result |= 16; if (! year_2050_test () || ! indiana_test ()) - result |= 64; + result |= 32; return result; }]])], [gl_cv_func_working_mktime=yes], diff --git a/m4/nproc.m4 b/m4/nproc.m4 index 48c239be064..9225779585a 100644 --- a/m4/nproc.m4 +++ b/m4/nproc.m4 @@ -1,5 +1,5 @@ # nproc.m4 -# serial 6 +# serial 7 dnl Copyright (C) 2009-2025 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -17,7 +17,7 @@ AC_DEFUN([gl_PREREQ_NPROC], dnl Persuade glibc to declare CPU_SETSIZE, CPU_ISSET etc. AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) - AC_CHECK_HEADERS([sys/pstat.h sys/sysmp.h sys/param.h],,, + AC_CHECK_HEADERS([mntent.h sys/pstat.h sys/param.h],,, [AC_INCLUDES_DEFAULT]) dnl requires on OpenBSD 4.0. AC_CHECK_HEADERS([sys/sysctl.h],,, @@ -27,7 +27,7 @@ AC_DEFUN([gl_PREREQ_NPROC], #endif ]) - AC_CHECK_FUNCS([sched_getaffinity_np pstat_getdynamic sysmp sysctl]) + AC_CHECK_FUNCS([sched_getaffinity_np pstat_getdynamic sysctl]) gl_CHECK_FUNCS_ANDROID([sched_getaffinity], [[#include ]]) dnl Test whether sched_getaffinity has the expected declaration. diff --git a/m4/pthread_sigmask.m4 b/m4/pthread_sigmask.m4 index a9da33c4c38..77991d4f334 100644 --- a/m4/pthread_sigmask.m4 +++ b/m4/pthread_sigmask.m4 @@ -1,5 +1,5 @@ # pthread_sigmask.m4 -# serial 23 +# serial 24 dnl Copyright (C) 2011-2025 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -97,7 +97,7 @@ AC_DEFUN([gl_FUNC_PTHREAD_SIGMASK], HAVE_PTHREAD_SIGMASK=0 dnl Define the symbol rpl_pthread_sigmask, not pthread_sigmask, dnl so as to not accidentally override the system's pthread_sigmask - dnl symbol from libpthread. This is necessary on IRIX 6.5. + dnl symbol from libpthread. REPLACE_PTHREAD_SIGMASK=1 fi ]) @@ -199,76 +199,6 @@ int main () [Define to 1 if pthread_sigmask(), when it fails, returns -1 and sets errno.]) ;; esac - - dnl On IRIX 6.5, in a single-threaded program, pending signals are not - dnl immediately delivered when they are unblocked through pthread_sigmask, - dnl only a little while later. - AC_CACHE_CHECK([whether pthread_sigmask unblocks signals correctly], - [gl_cv_func_pthread_sigmask_unblock_works], - [ - case "$host_os" in - irix*) - gl_cv_func_pthread_sigmask_unblock_works="guessing no";; - *) - gl_cv_func_pthread_sigmask_unblock_works="guessing yes";; - esac - m4_ifdef([gl_][THREADLIB], - [dnl Link against $LIBMULTITHREAD, not only $PTHREAD_SIGMASK_LIB. - dnl Otherwise we get a false positive on those platforms where - dnl $gl_cv_func_pthread_sigmask_in_libc_works is "no". - gl_saved_LIBS=$LIBS - LIBS="$LIBS $LIBMULTITHREAD"]) - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -#include -#include -#include -#include -#include -]GL_MDA_DEFINES[ -static volatile int sigint_occurred; -static void -sigint_handler (int sig) -{ - sigint_occurred++; -} -int main () -{ - sigset_t set; - pid_t pid = getpid (); - char command[80]; - if (LONG_MAX < pid) - return 6; - signal (SIGINT, sigint_handler); - sigemptyset (&set); - sigaddset (&set, SIGINT); - if (!(pthread_sigmask (SIG_BLOCK, &set, NULL) == 0)) - return 1; - sprintf (command, "sh -c 'sleep 1; kill -INT %ld' &", (long) pid); - if (!(system (command) == 0)) - return 2; - sleep (2); - if (!(sigint_occurred == 0)) - return 3; - if (!(pthread_sigmask (SIG_UNBLOCK, &set, NULL) == 0)) - return 4; - if (!(sigint_occurred == 1)) /* This fails on IRIX. */ - return 5; - return 0; -}]])], - [:], - [gl_cv_func_pthread_sigmask_unblock_works=no], - [:]) - m4_ifdef([gl_][THREADLIB], [LIBS=$gl_saved_LIBS]) - ]) - case "$gl_cv_func_pthread_sigmask_unblock_works" in - *no) - REPLACE_PTHREAD_SIGMASK=1 - AC_DEFINE([PTHREAD_SIGMASK_UNBLOCK_BUG], [1], - [Define to 1 if pthread_sigmask() unblocks signals incorrectly.]) - ;; - esac fi ]) diff --git a/m4/readutmp.m4 b/m4/readutmp.m4 index 36c95be3373..418c398b249 100644 --- a/m4/readutmp.m4 +++ b/m4/readutmp.m4 @@ -1,5 +1,5 @@ # readutmp.m4 -# serial 31 +# serial 32 dnl Copyright (C) 2002-2025 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -96,11 +96,9 @@ AC_INCLUDES_DEFAULT AC_CHECK_MEMBERS([struct utmpx.ut_exit],,,[$utmp_includes]) AC_CHECK_MEMBERS([struct utmp.ut_exit],,,[$utmp_includes]) - AC_CHECK_MEMBERS([struct utmpx.ut_exit.ut_exit],,,[$utmp_includes]) AC_CHECK_MEMBERS([struct utmpx.ut_exit.e_exit],,,[$utmp_includes]) AC_CHECK_MEMBERS([struct utmp.ut_exit.e_exit],,,[$utmp_includes]) - AC_CHECK_MEMBERS([struct utmpx.ut_exit.ut_termination],,,[$utmp_includes]) AC_CHECK_MEMBERS([struct utmpx.ut_exit.e_termination],,,[$utmp_includes]) AC_CHECK_MEMBERS([struct utmp.ut_exit.e_termination],,,[$utmp_includes]) fi diff --git a/m4/sig2str.m4 b/m4/sig2str.m4 index d49e363f3ae..4f713724bb6 100644 --- a/m4/sig2str.m4 +++ b/m4/sig2str.m4 @@ -1,5 +1,5 @@ # sig2str.m4 -# serial 8 +# serial 9 dnl Copyright (C) 2002, 2005-2006, 2009-2025 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -9,7 +9,8 @@ dnl This file is offered as-is, without any warranty. AC_DEFUN([gl_FUNC_SIG2STR], [ AC_REQUIRE([gl_SIGNAL_H_DEFAULTS]) - AC_CHECK_FUNCS([sig2str str2sig]) + gl_CHECK_FUNCS_ANDROID([sig2str], [[#include ]]) + gl_CHECK_FUNCS_ANDROID([str2sig], [[#include ]]) if test $ac_cv_func_sig2str = no; then HAVE_SIG2STR=0 fi diff --git a/m4/socklen.m4 b/m4/socklen.m4 index a8ac25b1c35..a4d49bfdc06 100644 --- a/m4/socklen.m4 +++ b/m4/socklen.m4 @@ -1,5 +1,5 @@ # socklen.m4 -# serial 11 +# serial 13 dnl Copyright (C) 2005-2007, 2009-2025 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -11,7 +11,7 @@ dnl From Albert Chin, Windows fixes from Simon Josefsson. dnl Check for socklen_t: historically on BSD it is an int, and in dnl POSIX 1g it is a type of its own, but some platforms use different dnl types for the argument to getsockopt, getpeername, etc.: -dnl HP-UX 10.20, IRIX 6.5, OSF/1 4.0, Interix 3.5, BeOS. +dnl HP-UX 10.20, Interix 3.5, BeOS. dnl So we have to test to find something that will work. AC_DEFUN([gl_TYPE_SOCKLEN_T], diff --git a/m4/stdalign.m4 b/m4/stdalign.m4 index 885feafdd8b..d22360e1075 100644 --- a/m4/stdalign.m4 +++ b/m4/stdalign.m4 @@ -30,7 +30,7 @@ AC_DEFUN([gl_ALIGNASOF], /* Test that alignof yields a result consistent with offsetof. This catches GCC bug 52023 - . */ + . */ #ifdef __cplusplus template struct alignof_helper { char a; t b; }; # define ao(type) offsetof (alignof_helper, b) @@ -103,7 +103,7 @@ AC_DEFUN([gl_ALIGNASOF], want to be portable to HP-UX 10.20 cc and AIX 3.2.5 xlc. */ /* GCC releases before GCC 4.9 had a bug in _Alignof. See GCC bug 52023 - . + . clang versions < 8.0.0 have the same bug. IBM XL C V16.1.0 cc (non-clang) has the same bug. */ # if (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112 \ diff --git a/m4/stddef_h.m4 b/m4/stddef_h.m4 index 127ec05b60d..d52d549489f 100644 --- a/m4/stddef_h.m4 +++ b/m4/stddef_h.m4 @@ -85,7 +85,7 @@ AC_DEFUN_ONCE([gl_STDDEF_H], dnl Provide gl_unreachable() unconditionally. GL_GENERATE_STDDEF_H=true - dnl https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114869 + dnl https://gcc.gnu.org/PR114869 AC_CACHE_CHECK([whether nullptr_t needs ], [gl_cv_nullptr_t_needs_stddef], [AC_COMPILE_IFELSE([AC_LANG_DEFINES_PROVIDED[nullptr_t x;]], @@ -96,7 +96,7 @@ AC_DEFUN_ONCE([gl_STDDEF_H], GL_GENERATE_STDDEF_H=true fi - dnl https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114870 + dnl https://gcc.gnu.org/PR114870 dnl affects GCC 13.3 and 14.2. AC_CACHE_CHECK([whether is idempotent], [gl_cv_stddef_idempotent], diff --git a/m4/stdint.m4 b/m4/stdint.m4 index 2d69088b676..5a289e6df4d 100644 --- a/m4/stdint.m4 +++ b/m4/stdint.m4 @@ -1,5 +1,5 @@ # stdint.m4 -# serial 64 +# serial 65 dnl Copyright (C) 2001-2025 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -391,9 +391,9 @@ AC_DEFUN([gl_STDINT_BITSIZEOF], ]) eval result=\$gl_cv_bitsizeof_${gltype} if test $result = unknown; then - dnl Use a nonempty default, because some compilers, such as IRIX 5 cc, - dnl do a syntax check even on unused #if conditions and give an error - dnl on valid C code like this: + dnl Use a nonempty default, because some old compilers do a syntax check + dnl even on unused #if conditions and give an error on valid C code like + dnl this: dnl #if 0 dnl # if > 32 dnl # endif diff --git a/m4/stdlib_h.m4 b/m4/stdlib_h.m4 index 2d25da37b53..ab2e87019bb 100644 --- a/m4/stdlib_h.m4 +++ b/m4/stdlib_h.m4 @@ -1,5 +1,5 @@ # stdlib_h.m4 -# serial 84 +# serial 85 dnl Copyright (C) 2007-2025 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -205,7 +205,6 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS], HAVE_PTSNAME_R=1; AC_SUBST([HAVE_PTSNAME_R]) HAVE_QSORT_R=1; AC_SUBST([HAVE_QSORT_R]) HAVE_RANDOM=1; AC_SUBST([HAVE_RANDOM]) - HAVE_RANDOM_H=1; AC_SUBST([HAVE_RANDOM_H]) HAVE_RANDOM_R=1; AC_SUBST([HAVE_RANDOM_R]) HAVE_REALLOCARRAY=1; AC_SUBST([HAVE_REALLOCARRAY]) HAVE_REALPATH=1; AC_SUBST([HAVE_REALPATH]) diff --git a/m4/string_h.m4 b/m4/string_h.m4 index bdcd6ef2b67..b5324e3a37e 100644 --- a/m4/string_h.m4 +++ b/m4/string_h.m4 @@ -1,5 +1,5 @@ # string_h.m4 -# serial 44 +# serial 45 dnl Copyright (C) 2007-2025 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -63,6 +63,7 @@ AC_DEFUN([gl_STRING_H_REQUIRE_DEFAULTS], gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STPNCPY]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRCHRNUL]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRDUP]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRINGEQ]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRNCAT]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRNDUP]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRNLEN]) @@ -114,6 +115,7 @@ AC_DEFUN([gl_STRING_H_DEFAULTS], HAVE_EXPLICIT_BZERO=1; AC_SUBST([HAVE_EXPLICIT_BZERO]) HAVE_FFSL=1; AC_SUBST([HAVE_FFSL]) HAVE_FFSLL=1; AC_SUBST([HAVE_FFSLL]) + HAVE_DECL_MEMEQ=0; AC_SUBST([HAVE_DECL_MEMEQ]) HAVE_DECL_MEMMEM=1; AC_SUBST([HAVE_DECL_MEMMEM]) HAVE_MEMPCPY=1; AC_SUBST([HAVE_MEMPCPY]) HAVE_MEMSET_EXPLICIT=1; AC_SUBST([HAVE_MEMSET_EXPLICIT]) @@ -123,6 +125,7 @@ AC_DEFUN([gl_STRING_H_DEFAULTS], HAVE_STPNCPY=1; AC_SUBST([HAVE_STPNCPY]) HAVE_STRCHRNUL=1; AC_SUBST([HAVE_STRCHRNUL]) HAVE_DECL_STRDUP=1; AC_SUBST([HAVE_DECL_STRDUP]) + HAVE_DECL_STREQ=0; AC_SUBST([HAVE_DECL_STREQ]) HAVE_DECL_STRNDUP=1; AC_SUBST([HAVE_DECL_STRNDUP]) HAVE_DECL_STRNLEN=1; AC_SUBST([HAVE_DECL_STRNLEN]) HAVE_STRPBRK=1; AC_SUBST([HAVE_STRPBRK]) diff --git a/m4/stringeq.m4 b/m4/stringeq.m4 new file mode 100644 index 00000000000..de6d66c12d0 --- /dev/null +++ b/m4/stringeq.m4 @@ -0,0 +1,25 @@ +# stringeq.m4 +# serial 1 +dnl Copyright (C) 2025 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +dnl This file is offered as-is, without any warranty. + +AC_DEFUN([gl_FUNC_STREQ], +[ + AC_REQUIRE([gl_STRING_H_DEFAULTS]) + AC_CHECK_DECLS_ONCE([streq]) + if test $ac_cv_have_decl_streq != no; then + HAVE_DECL_STREQ=1 + fi +]) + +AC_DEFUN([gl_FUNC_MEMEQ], +[ + AC_REQUIRE([gl_STRING_H_DEFAULTS]) + AC_CHECK_DECLS_ONCE([memeq]) + if test $ac_cv_have_decl_memeq != no; then + HAVE_DECL_MEMEQ=1 + fi +]) diff --git a/m4/sys_select_h.m4 b/m4/sys_select_h.m4 index b02f470d95c..f154bc5f1e6 100644 --- a/m4/sys_select_h.m4 +++ b/m4/sys_select_h.m4 @@ -1,5 +1,5 @@ # sys_select_h.m4 -# serial 23 +# serial 24 dnl Copyright (C) 2006-2025 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -13,17 +13,14 @@ AC_DEFUN_ONCE([gl_SYS_SELECT_H], AC_CACHE_CHECK([whether is self-contained], [gl_cv_header_sys_select_h_selfcontained], [ - dnl Test against two bugs: + dnl Test against a bug: dnl 1. On many platforms, assumes prior inclusion of dnl . - dnl 2. On OSF/1 4.0, provides only a forward declaration - dnl of 'struct timeval', and no definition of this type. - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], - [[struct timeval b;]])], + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [])], [gl_cv_header_sys_select_h_selfcontained=yes], [gl_cv_header_sys_select_h_selfcontained=no]) dnl Test against another bug: - dnl 3. On Solaris 10, provides an FD_ZERO implementation + dnl 2. On Solaris 10, provides an FD_ZERO implementation dnl that relies on memset(), but without including . if test $gl_cv_header_sys_select_h_selfcontained = yes; then AC_COMPILE_IFELSE( diff --git a/m4/sys_socket_h.m4 b/m4/sys_socket_h.m4 index fb69209b4dc..da3c6804c6f 100644 --- a/m4/sys_socket_h.m4 +++ b/m4/sys_socket_h.m4 @@ -1,5 +1,5 @@ # sys_socket_h.m4 -# serial 31 +# serial 32 dnl Copyright (C) 2005-2025 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -13,17 +13,6 @@ AC_DEFUN_ONCE([gl_SYS_SOCKET_H], AC_REQUIRE([gl_SYS_SOCKET_H_DEFAULTS]) AC_REQUIRE([AC_CANONICAL_HOST]) - dnl On OSF/1, the functions recv(), send(), recvfrom(), sendto() have - dnl old-style declarations (with return type 'int' instead of 'ssize_t') - dnl unless _POSIX_PII_SOCKET is defined. - case "$host_os" in - osf*) - AC_DEFINE([_POSIX_PII_SOCKET], [1], - [Define to 1 in order to get the POSIX compatible declarations - of socket functions.]) - ;; - esac - GL_GENERATE_SYS_SOCKET_H=false AC_CACHE_CHECK([whether is self-contained], [gl_cv_header_sys_socket_h_selfcontained], diff --git a/m4/sys_stat_h.m4 b/m4/sys_stat_h.m4 index fdcc89545bc..10636923b17 100644 --- a/m4/sys_stat_h.m4 +++ b/m4/sys_stat_h.m4 @@ -1,5 +1,5 @@ # sys_stat_h.m4 -# serial 42 -*- Autoconf -*- +# serial 44 -*- Autoconf -*- dnl Copyright (C) 2006-2025 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, diff --git a/m4/time_rz.m4 b/m4/time_rz.m4 index b85e6d0cbb5..885463a03b9 100644 --- a/m4/time_rz.m4 +++ b/m4/time_rz.m4 @@ -1,5 +1,5 @@ # time_rz.m4 -# serial 3 +# serial 4 dnl Copyright (C) 2015-2025 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -58,7 +58,8 @@ AC_DEFUN([gl_TIME_RZ], if test $ac_cv_func_tzalloc = yes; then HAVE_TZALLOC=1 fi - dnl Assume that tzalloc, localtime_rz, mktime_z are all defined together. + dnl Assume that tzalloc, tzfree, localtime_rz, mktime_z + dnl are all defined together. case "$gl_cv_onwards_func_tzalloc" in yes) case "$host_os" in diff --git a/m4/unlocked-io.m4 b/m4/unlocked-io.m4 index 97f43f4b6c4..a5eacecc61c 100644 --- a/m4/unlocked-io.m4 +++ b/m4/unlocked-io.m4 @@ -1,5 +1,5 @@ # unlocked-io.m4 -# serial 16 +# serial 17 dnl Copyright (C) 1998-2006, 2009-2025 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -25,6 +25,7 @@ AC_DEFUN([gl_FUNC_GLIBC_UNLOCKED_IO], AC_CHECK_DECLS_ONCE([ferror_unlocked]) AC_CHECK_DECLS_ONCE([fflush_unlocked]) AC_CHECK_DECLS_ONCE([fgets_unlocked]) + AC_CHECK_DECLS_ONCE([fileno_unlocked]) AC_CHECK_DECLS_ONCE([fputc_unlocked]) AC_CHECK_DECLS_ONCE([fputs_unlocked]) AC_CHECK_DECLS_ONCE([fread_unlocked]) diff --git a/src/conf_post.h b/src/conf_post.h index 4a88f46455d..cf2e6dca4e5 100644 --- a/src/conf_post.h +++ b/src/conf_post.h @@ -402,8 +402,8 @@ extern int emacs_setenv_TZ (char const *); #include #undef _GL_TIME_H -/* Redefine tzalloc and tzfree so as not to conflict with their - system-provided versions, which are incompatible. */ +/* Redefine tzalloc so as not to conflict with its + system-provided version, which is incompatible. + Do not redefine tzfree, as Gnulib does that. */ #define tzalloc rpl_tzalloc -#define tzfree rpl_tzfree #endif /* defined __ANDROID__ && __ANDROID_API__ >= 35 */ diff --git a/src/timefns.c b/src/timefns.c index b4baeaaff82..75efea3560d 100644 --- a/src/timefns.c +++ b/src/timefns.c @@ -1323,21 +1323,23 @@ or (if you need time as a string) `format-time-string'. */) /* Write information into buffer S of size MAXSIZE, according to the FORMAT of length FORMAT_LEN, using time information taken from *TP. + FORMAT[FORMATLEN] must be NUL. Use the time zone specified by TZ. Use NS as the number of nanoseconds in the %N directive. - Return the number of bytes written, not including the terminating - '\0'. If S is NULL, nothing will be written anywhere; so to + Return the number of bytes written, not including the terminating NUL. + On error return -1, setting errno and possibly writing some bytes. + + If S is NULL, nothing will be written anywhere; so to determine how many bytes would be written, use NULL for S and - ((size_t) -1) for MAXSIZE. + SIZE_MAX for MAXSIZE. This function behaves like nstrftime, except it allows null bytes in FORMAT. */ -static size_t +static ptrdiff_t emacs_nmemftime (char *s, size_t maxsize, const char *format, size_t format_len, const struct tm *tp, timezone_t tz, int ns) { - int saved_errno = errno; - size_t total = 0; + ptrdiff_t total = 0; /* Loop through all the null-terminated strings in the format argument. Normally there's just one null-terminated string, but @@ -1346,24 +1348,24 @@ emacs_nmemftime (char *s, size_t maxsize, const char *format, '\0' byte so we must invoke it separately for each such string. */ for (;;) { - errno = 0; - size_t result = nstrftime (s, maxsize, format, tp, tz, ns); - if (result == 0 && errno != 0) + ptrdiff_t result = nstrftime (s, maxsize, format, tp, tz, ns); + if (result < 0) return result; - if (s) - s += result + 1; - - maxsize -= result + 1; - total += result; size_t len = strlen (format); + if (ckd_add (&total, total, result + (len != format_len))) + { + errno = ERANGE; + return -1; + } if (len == format_len) break; - total++; + if (s) + s += result + 1; + maxsize -= result + 1; format += len + 1; format_len -= len + 1; } - errno = saved_errno; return total; } @@ -1373,9 +1375,7 @@ format_time_string (char const *format, ptrdiff_t formatlen, { char buffer[4000]; char *buf = buffer; - ptrdiff_t size = sizeof buffer; - size_t len; - int ns = t.tv_nsec; + ptrdiff_t len = -1; USE_SAFE_ALLOCA; timezone_t tz = tzlookup (zone, false); @@ -1384,34 +1384,29 @@ format_time_string (char const *format, ptrdiff_t formatlen, expects a pointer to time_t value. */ time_t tsec = t.tv_sec; tmp = emacs_localtime_rz (tz, &tsec, tmp); - if (! tmp) + if (tmp) { - int localtime_errno = errno; - xtzfree (tz); - time_error (localtime_errno); - } - synchronize_system_time_locale (); - - while (true) - { - errno = 0; - len = emacs_nmemftime (buf, size, format, formatlen, tmp, tz, ns); - if (len != 0 || errno == 0) - break; - eassert (errno == ERANGE); - - /* Buffer was too small, so make it bigger and try again. */ - len = emacs_nmemftime (NULL, SIZE_MAX, format, formatlen, tmp, tz, ns); - if (STRING_BYTES_BOUND <= len) + synchronize_system_time_locale (); + int ns = t.tv_nsec; + len = emacs_nmemftime (buffer, sizeof buffer, format, formatlen, + tmp, tz, ns); + if (len < 0 && errno == ERANGE) { - xtzfree (tz); - string_overflow (); + /* Buffer was too small, so make it bigger and try again. */ + len = emacs_nmemftime (NULL, SIZE_MAX, format, formatlen, + tmp, tz, ns); + if (0 <= len && len < STRING_BYTES_BOUND) + { + buf = SAFE_ALLOCA (len + 1); + len = emacs_nmemftime (buf, len + 1, format, formatlen, + tmp, tz, ns); + } } - size = len + 1; - buf = SAFE_ALLOCA (size); } xtzfree (tz); + if (len < 0) + time_error (errno); AUTO_STRING_WITH_LEN (bufstring, buf, len); Lisp_Object result = code_convert_string_norecord (bufstring, Vlocale_coding_system, 0);