Update from Gnulib by running admin/merge-gnulib

This commit is contained in:
Paul Eggert 2025-06-27 22:32:33 -07:00
parent 68100ca656
commit dbdf761187
30 changed files with 711 additions and 275 deletions

View file

@ -35,7 +35,7 @@
eval 'exec perl -wSx "$0" "$@"' eval 'exec perl -wSx "$0" "$@"'
if 0; if 0;
my $VERSION = '2024-07-17 02:20'; # UTC my $VERSION = '2025-06-10 02:43'; # UTC
# The definition above must lie within the first 8 lines in order # The definition above must lie within the first 8 lines in order
# for the Emacs time-stamp write hook (at end) to update it. # for the Emacs time-stamp write hook (at end) to update it.
# If you change this file with Emacs, please let the write hook # If you change this file with Emacs, please let the write hook
@ -544,7 +544,7 @@ sub git_dir_option($)
# eval: (add-hook 'before-save-hook 'time-stamp nil t) # eval: (add-hook 'before-save-hook 'time-stamp nil t)
# time-stamp-line-limit: 50 # time-stamp-line-limit: 50
# time-stamp-start: "my $VERSION = '" # time-stamp-start: "my $VERSION = '"
# time-stamp-format: "%:y-%02m-%02d %02H:%02M" # time-stamp-format: "%Y-%02m-%02d %02H:%02M"
# time-stamp-time-zone: "UTC0" # time-stamp-time-zone: "UTC0"
# time-stamp-end: "'; # UTC" # time-stamp-end: "'; # UTC"
# End: # End:

View file

@ -1,7 +1,7 @@
#!/bin/sh #!/bin/sh
# install - install a program, script, or datafile # install - install a program, script, or datafile
scriptversion=2024-12-03.03; # UTC scriptversion=2025-06-18.21; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was # This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the # later released in X11R6 (xc/config/util/install.sh) with the
@ -535,7 +535,7 @@ done
# Local variables: # Local variables:
# eval: (add-hook 'before-save-hook 'time-stamp nil t) # eval: (add-hook 'before-save-hook 'time-stamp nil t)
# time-stamp-start: "scriptversion=" # time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-format: "%Y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0" # time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC" # time-stamp-end: "; # UTC"
# End: # End:

View file

@ -2,7 +2,7 @@
# Like mv $1 $2, but if the files are the same, just delete $1. # Like mv $1 $2, but if the files are the same, just delete $1.
# Status is zero if successful, nonzero otherwise. # Status is zero if successful, nonzero otherwise.
VERSION='2024-07-04 10:56'; # UTC VERSION='2025-06-10 02:42'; # UTC
# The definition above must lie within the first 8 lines in order # The definition above must lie within the first 8 lines in order
# for the Emacs time-stamp write hook (at end) to update it. # for the Emacs time-stamp write hook (at end) to update it.
# If you change this file with Emacs, please let the write hook # If you change this file with Emacs, please let the write hook
@ -78,7 +78,7 @@ fi
## Local Variables: ## Local Variables:
## eval: (add-hook 'before-save-hook 'time-stamp nil t) ## eval: (add-hook 'before-save-hook 'time-stamp nil t)
## time-stamp-start: "VERSION='" ## time-stamp-start: "VERSION='"
## time-stamp-format: "%:y-%02m-%02d %02H:%02M" ## time-stamp-format: "%Y-%02m-%02d %02H:%02M"
## time-stamp-time-zone: "UTC0" ## time-stamp-time-zone: "UTC0"
## time-stamp-end: "'; # UTC" ## time-stamp-end: "'; # UTC"
## End: ## End:

View file

@ -138,7 +138,7 @@
eval 'exec perl -wSx -0777 -pi "$0" "$@"' eval 'exec perl -wSx -0777 -pi "$0" "$@"'
if 0; if 0;
my $VERSION = '2025-01-01.07:36'; # UTC my $VERSION = '2025-06-10.02:42'; # UTC
# The definition above must lie within the first 8 lines in order # The definition above must lie within the first 8 lines in order
# for the Emacs time-stamp write hook (at end) to update it. # for the Emacs time-stamp write hook (at end) to update it.
# If you change this file with Emacs, please let the write hook # If you change this file with Emacs, please let the write hook
@ -301,7 +301,7 @@ if (!$found)
# eval: (add-hook 'before-save-hook 'time-stamp nil t) # eval: (add-hook 'before-save-hook 'time-stamp nil t)
# time-stamp-line-limit: 200 # time-stamp-line-limit: 200
# time-stamp-start: "my $VERSION = '" # time-stamp-start: "my $VERSION = '"
# time-stamp-format: "%:y-%02m-%02d.%02H:%02M" # time-stamp-format: "%Y-%02m-%02d.%02H:%02M"
# time-stamp-time-zone: "UTC0" # time-stamp-time-zone: "UTC0"
# time-stamp-end: "'; # UTC" # time-stamp-end: "'; # UTC"
# End: # End:

View file

@ -3,7 +3,7 @@
% Load plain if necessary, i.e., if running under initex. % Load plain if necessary, i.e., if running under initex.
\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
% %
\def\texinfoversion{2025-03-22.08} \def\texinfoversion{2025-06-18.21}
% %
% Copyright 1985, 1986, 1988, 1990-2025 Free Software Foundation, Inc. % Copyright 1985, 1986, 1988, 1990-2025 Free Software Foundation, Inc.
% %
@ -9419,6 +9419,7 @@
\expandafter\xdef\csname floatlist\iffloattype\endcsname{\the\toks0 \expandafter\xdef\csname floatlist\iffloattype\endcsname{\the\toks0
{\safexrefname}}% {\safexrefname}}%
\fi \fi
\ignorespaces % ignore ends of line in aux file
} }
% If working on a large document in chapters, it is convenient to % If working on a large document in chapters, it is convenient to

View file

@ -14,33 +14,25 @@
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */ along with this program. If not, see <https://www.gnu.org/licenses/>. */
/* The _Noreturn keyword of C11.
Do not use [[noreturn]], because with it the syntax
extern _Noreturn void func (...);
would not be valid; such a declaration would be valid only with 'extern'
and '_Noreturn' swapped, or without the 'extern' keyword. However, some
AIX system header files and several gnulib header files use precisely
this syntax with 'extern'. So even though C23 deprecates _Noreturn,
it is currently more portable to prefer it to [[noreturn]].
Also, do not try to work around LLVM bug 59792 (clang 15 or earlier).
This rare bug can be worked around by compiling with 'clang -D_Noreturn=',
though the workaround may generate many false-alarm warnings. */
#ifndef _Noreturn #ifndef _Noreturn
# if (defined __cplusplus \ # if 201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0)
&& ((201103 <= __cplusplus && !(__GNUC__ == 4 && __GNUC_MINOR__ == 7)) \
|| (defined _MSC_VER && 1900 <= _MSC_VER)) \
&& 0)
/* [[noreturn]] is not practically usable, because with it the syntax
extern _Noreturn void func (...);
would not be valid; such a declaration would only be valid with 'extern'
and '_Noreturn' swapped, or without the 'extern' keyword. However, some
AIX system header files and several gnulib header files use precisely
this syntax with 'extern'. */
# define _Noreturn [[noreturn]]
# elif (defined __clang__ && __clang_major__ < 16 \
&& defined _GL_WORK_AROUND_LLVM_BUG_59792)
/* Compile with -D_GL_WORK_AROUND_LLVM_BUG_59792 to work around
that rare LLVM bug, though you may get many false-alarm warnings. */
# define _Noreturn
# elif ((!defined __cplusplus || defined __clang__) \
&& (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \
|| (!defined __STRICT_ANSI__ \
&& (4 < __GNUC__ + (7 <= __GNUC_MINOR__) && !defined __clang__ \
|| (defined __apple_build_version__ \
? 6000000 <= __apple_build_version__ \
: 3 < __clang_major__ + (5 <= __clang_minor__))))))
/* _Noreturn works as-is. */ /* _Noreturn works as-is. */
# elif (2 < __GNUC__ + (8 <= __GNUC_MINOR__) || defined __clang__ \ # elif (2 < __GNUC__ + (8 <= __GNUC_MINOR__) || defined __clang__ \
|| 0x5110 <= __SUNPRO_C) || 0x5110 <= __SUNPRO_C)
/* Prefer __attribute__ ((__noreturn__)) to plain _Noreturn even if the
latter works, as 'gcc -std=gnu99 -Wpedantic' warns about _Noreturn. */
# define _Noreturn __attribute__ ((__noreturn__)) # define _Noreturn __attribute__ ((__noreturn__))
# elif 1200 <= (defined _MSC_VER ? _MSC_VER : 0) # elif 1200 <= (defined _MSC_VER ? _MSC_VER : 0)
# define _Noreturn __declspec (noreturn) # define _Noreturn __declspec (noreturn)

View file

@ -79,6 +79,8 @@ struct aclinfo
bool acl_errno_valid (int) _GL_ATTRIBUTE_CONST; bool acl_errno_valid (int) _GL_ATTRIBUTE_CONST;
int file_has_acl (char const *, struct stat const *); int file_has_acl (char const *, struct stat const *);
int file_has_aclinfo (char const *restrict, struct aclinfo *restrict, int); int file_has_aclinfo (char const *restrict, struct aclinfo *restrict, int);
int fdfile_has_aclinfo (int, char const *restrict,
struct aclinfo *restrict, int);
#if HAVE_LINUX_XATTR_H && HAVE_LISTXATTR #if HAVE_LINUX_XATTR_H && HAVE_LISTXATTR
bool aclinfo_has_xattr (struct aclinfo const *, char const *) bool aclinfo_has_xattr (struct aclinfo const *, char const *)

View file

@ -50,8 +50,9 @@
- In a function declaration/definition with a storage-class - In a function declaration/definition with a storage-class
specifier: between the storage-class specifier and the return specifier: between the storage-class specifier and the return
type. type.
- Or after the parameter list, - Or, in a function declaration:
but after ATTRIBUTE_NOTHROW if present. after the parameter list,
but after ATTRIBUTE_NOTHROW if present.
In other declarations, such as variable declarations: In other declarations, such as variable declarations:

View file

@ -29,11 +29,16 @@ extern "C" {
/* Store the approximate time when the machine last booted in *P_BOOT_TIME, /* Store the approximate time when the machine last booted in *P_BOOT_TIME,
and return 0. If it cannot be determined, return -1. and return 0. If it cannot be determined, return -1.
If the machine is a container inside another host machine,
return the boot time of the container, not the host.
The difference can matter in GNU/Linux, where times in /proc/stat
might be relative to boot time of the host, not the container.
This function is not multithread-safe, since on many platforms it This function is not multithread-safe, since on many platforms it
invokes the functions setutxent, getutxent, endutxent. These invokes the functions setutxent, getutxent, endutxent.
functions are needed because they may lock FILE (so that we don't These functions may lock a file like /var/log/wtmp (so that we
read garbage when a concurrent process writes to FILE), but their don't read garbage when a concurrent process writes to that file),
drawback is that they have a common global state. */ but their drawback is that they have a common global state. */
extern int get_boot_time (struct timespec *p_boot_time); extern int get_boot_time (struct timespec *p_boot_time);

View file

@ -209,7 +209,9 @@ _GL_WARN_ON_USE (open, "open is not always POSIX compliant - "
# undef open # undef open
# define open _open # define open _open
# endif # endif
_GL_CXXALIAS_MDA (open, int, (const char *filename, int flags, ...)); /* Need to cast, because in MSVC the parameter list of _open as a C++ function
is (const char *, int, int = 0). */
_GL_CXXALIAS_MDA_CAST (open, int, (const char *filename, int flags, ...));
# else # else
_GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...)); _GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...));
# endif # endif
@ -313,7 +315,7 @@ _GL_WARN_ON_USE (openat, "openat is not portable - "
#endif #endif
#ifndef O_DIRECTORY #ifndef O_DIRECTORY
# define O_DIRECTORY 0 # define O_DIRECTORY 0x20000000 /* Try to not collide with system O_* flags. */
#endif #endif
#ifndef O_DSYNC #ifndef O_DSYNC

View file

@ -85,6 +85,13 @@ smack_new_label_from_path (MAYBE_UNUSED const char *path,
{ {
return -1; return -1;
} }
static ssize_t
smack_new_label_from_file (MAYBE_UNUSED int fd,
MAYBE_UNUSED const char *xattr,
MAYBE_UNUSED char **label)
{
return -1;
}
# endif # endif
static bool static bool
is_smack_enabled (void) is_smack_enabled (void)
@ -115,14 +122,16 @@ aclinfo_may_indicate_xattr (struct aclinfo const *ai)
static bool static bool
has_xattr (char const *xattr, struct aclinfo const *ai, has_xattr (char const *xattr, struct aclinfo const *ai,
MAYBE_UNUSED char const *restrict name, MAYBE_UNUSED int flags) int fd, char const *restrict name, int flags)
{ {
if (ai && aclinfo_has_xattr (ai, xattr)) if (ai && aclinfo_has_xattr (ai, xattr))
return true; return true;
else if (!ai || aclinfo_may_indicate_xattr (ai)) else if (!ai || aclinfo_may_indicate_xattr (ai))
{ {
int ret = ((flags & ACL_SYMLINK_FOLLOW ? getxattr : lgetxattr) int ret = (fd < 0
(name, xattr, NULL, 0)); ? ((flags & ACL_SYMLINK_FOLLOW ? getxattr : lgetxattr)
(name, xattr, NULL, 0))
: fgetxattr (fd, xattr, NULL, 0));
if (0 <= ret || (errno == ERANGE || errno == E2BIG)) if (0 <= ret || (errno == ERANGE || errno == E2BIG))
return true; return true;
} }
@ -145,11 +154,12 @@ aclinfo_has_xattr (struct aclinfo const *ai, char const *xattr)
return false; return false;
} }
/* Get attributes of the file NAME into AI, if USE_ACL. /* Get attributes of the file FD aka NAME into AI, if USE_ACL.
Ignore FD if it is negative.
If FLAGS & ACL_GET_SCONTEXT, also get security context. If FLAGS & ACL_GET_SCONTEXT, also get security context.
If FLAGS & ACL_SYMLINK_FOLLOW, follow symbolic links. */ If FLAGS & ACL_SYMLINK_FOLLOW, follow symbolic links. */
static void static void
get_aclinfo (char const *name, struct aclinfo *ai, int flags) get_aclinfo (int fd, char const *name, struct aclinfo *ai, int flags)
{ {
int scontext_err = ENOTSUP; int scontext_err = ENOTSUP;
ai->buf = ai->u.__gl_acl_ch; ai->buf = ai->u.__gl_acl_ch;
@ -163,7 +173,9 @@ get_aclinfo (char const *name, struct aclinfo *ai, int flags)
= (flags & ACL_SYMLINK_FOLLOW ? listxattr : llistxattr); = (flags & ACL_SYMLINK_FOLLOW ? listxattr : llistxattr);
while (true) while (true)
{ {
ai->size = lsxattr (name, ai->buf, acl_alloc); ai->size = (fd < 0
? lsxattr (name, ai->buf, acl_alloc)
: flistxattr (fd, ai->buf, acl_alloc));
if (0 < ai->size) if (0 < ai->size)
break; break;
ai->u.err = ai->size < 0 ? errno : 0; ai->u.err = ai->size < 0 ? errno : 0;
@ -171,7 +183,9 @@ get_aclinfo (char const *name, struct aclinfo *ai, int flags)
break; break;
/* The buffer was too small. Find how large it should have been. */ /* The buffer was too small. Find how large it should have been. */
ssize_t size = lsxattr (name, NULL, 0); ssize_t size = (fd < 0
? lsxattr (name, NULL, 0)
: flistxattr (fd, NULL, 0));
if (size <= 0) if (size <= 0)
{ {
ai->size = size; ai->size = size;
@ -214,9 +228,13 @@ get_aclinfo (char const *name, struct aclinfo *ai, int flags)
{ {
if (ai->size < 0 || aclinfo_has_xattr (ai, XATTR_NAME_SMACK)) if (ai->size < 0 || aclinfo_has_xattr (ai, XATTR_NAME_SMACK))
{ {
ssize_t r = smack_new_label_from_path (name, "security.SMACK64", static char const SMACK64[] = "security.SMACK64";
flags & ACL_SYMLINK_FOLLOW, ssize_t r =
&ai->scontext); (fd < 0
? smack_new_label_from_path (name, SMACK64,
flags & ACL_SYMLINK_FOLLOW,
&ai->scontext)
: smack_new_label_from_file (fd, SMACK64, &ai->scontext));
scontext_err = r < 0 ? errno : 0; scontext_err = r < 0 ? errno : 0;
} }
} }
@ -226,8 +244,10 @@ get_aclinfo (char const *name, struct aclinfo *ai, int flags)
if (ai->size < 0 || aclinfo_has_xattr (ai, XATTR_NAME_SELINUX)) if (ai->size < 0 || aclinfo_has_xattr (ai, XATTR_NAME_SELINUX))
{ {
ssize_t r = ssize_t r =
((flags & ACL_SYMLINK_FOLLOW ? getfilecon : lgetfilecon) (fd < 0
(name, &ai->scontext)); ? ((flags & ACL_SYMLINK_FOLLOW ? getfilecon : lgetfilecon)
(name, &ai->scontext))
: fgetfilecon (fd, &ai->scontext));
scontext_err = r < 0 ? errno : 0; scontext_err = r < 0 ? errno : 0;
# ifndef SE_SELINUX_INLINE # ifndef SE_SELINUX_INLINE
/* Gnulib's selinux-h module is not in use, so getfilecon and /* Gnulib's selinux-h module is not in use, so getfilecon and
@ -362,11 +382,14 @@ acl_nfs4_nontrivial (uint32_t *xattr, ssize_t nbytes)
} }
#endif #endif
#if (!USE_LINUX_XATTR && USE_ACL && HAVE_ACL_GET_FD \ #if (!USE_LINUX_XATTR && USE_ACL && HAVE_ACL_GET_FILE \
&& !HAVE_ACL_EXTENDED_FILE && !HAVE_ACL_TYPE_EXTENDED \ && !HAVE_ACL_EXTENDED_FILE && !HAVE_ACL_TYPE_EXTENDED)
&& !HAVE_ACL_GET_LINK_NP) /* FreeBSD, NetBSD >= 10, IRIX, Tru64, Cygwin >= 2.5 */
# include <fcntl.h>
# ifdef O_PATH # if HAVE_ACL_GET_FD && !HAVE_ACL_GET_LINK_NP /* IRIX, Tru64, Cygwin >= 2.5 */
# include <fcntl.h>
# ifdef O_PATH
# define acl_get_fd_np(fd, type) acl_get_fd (fd)
/* Like acl_get_file, but do not follow symbolic links. */ /* Like acl_get_file, but do not follow symbolic links. */
static acl_t static acl_t
@ -381,8 +404,24 @@ acl_get_link_np (char const *name, acl_type_t type)
errno = err; errno = err;
return r; return r;
} }
# define HAVE_ACL_GET_LINK_NP 1 # define HAVE_ACL_GET_LINK_NP 1
# endif
# endif # endif
static acl_t
acl_get_fdfile (int fd, char const *name, acl_type_t type, int flags)
{
acl_t (*get) (char const *, acl_type_t) = acl_get_file;
# if HAVE_ACL_GET_LINK_NP /* FreeBSD, NetBSD >= 10, Cygwin >= 2.5 */
if (0 <= fd)
return acl_get_fd_np (fd, type);
if (! (flags & ACL_SYMLINK_FOLLOW))
get = acl_get_link_np;
# else
/* Ignore FD and FLAGS, unfortunately. */
# endif
return get (name, type);
}
#endif #endif
/* Return 1 if NAME has a nontrivial access control list, /* Return 1 if NAME has a nontrivial access control list,
@ -398,14 +437,35 @@ acl_get_link_np (char const *name, acl_type_t type)
If the d_type value is not known, use DT_UNKNOWN though this may be less If the d_type value is not known, use DT_UNKNOWN though this may be less
efficient. */ efficient. */
int int
file_has_aclinfo (MAYBE_UNUSED char const *restrict name, file_has_aclinfo (char const *restrict name,
struct aclinfo *restrict ai, int flags) struct aclinfo *restrict ai, int flags)
{
return fdfile_has_aclinfo (-1, name, ai, flags);
}
/* Return 1 if FD aka NAME has a nontrivial access control list,
0 if ACLs are not supported, or if NAME has no or only a base ACL,
and -1 (setting errno) on error. Note callers can determine
if ACLs are not supported as errno is set in that case also.
Ignore FD if it is negative.
Set *AI to ACL info regardless of return value.
FLAGS should be a <dirent.h> d_type value, optionally ORed with
- _GL_DT_NOTDIR if it is known that NAME is not a directory,
- ACL_GET_SCONTEXT to retrieve security context and return 1 if present,
- ACL_SYMLINK_FOLLOW to follow the link if NAME is a symbolic link;
otherwise do not follow them if possible.
If the d_type value is not known, use DT_UNKNOWN though this may be less
efficient. */
int
fdfile_has_aclinfo (MAYBE_UNUSED int fd,
MAYBE_UNUSED char const *restrict name,
struct aclinfo *restrict ai, int flags)
{ {
MAYBE_UNUSED unsigned char d_type = flags & UCHAR_MAX; MAYBE_UNUSED unsigned char d_type = flags & UCHAR_MAX;
#if USE_LINUX_XATTR #if USE_LINUX_XATTR
int initial_errno = errno; int initial_errno = errno;
get_aclinfo (name, ai, flags); get_aclinfo (fd, name, ai, flags);
if (!aclinfo_may_indicate_xattr (ai) && ai->size <= 0) if (!aclinfo_may_indicate_xattr (ai) && ai->size <= 0)
{ {
@ -418,11 +478,11 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name,
In earlier Fedora the two types of ACLs were mutually exclusive. In earlier Fedora the two types of ACLs were mutually exclusive.
Attempt to work correctly on both kinds of systems. */ Attempt to work correctly on both kinds of systems. */
if (!has_xattr (XATTR_NAME_NFSV4_ACL, ai, name, flags)) if (!has_xattr (XATTR_NAME_NFSV4_ACL, ai, fd, name, flags))
return return
(has_xattr (XATTR_NAME_POSIX_ACL_ACCESS, ai, name, flags) (has_xattr (XATTR_NAME_POSIX_ACL_ACCESS, ai, fd, name, flags)
|| ((d_type == DT_DIR || d_type == DT_UNKNOWN) || ((d_type == DT_DIR || d_type == DT_UNKNOWN)
&& has_xattr (XATTR_NAME_POSIX_ACL_DEFAULT, ai, name, flags))); && has_xattr (XATTR_NAME_POSIX_ACL_DEFAULT, ai, fd, name, flags)));
/* A buffer large enough to hold any trivial NFSv4 ACL. /* A buffer large enough to hold any trivial NFSv4 ACL.
The max length of a trivial NFSv4 ACL is 6 words for owner, The max length of a trivial NFSv4 ACL is 6 words for owner,
@ -432,8 +492,10 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name,
everyone is another word to hold "EVERYONE@". */ everyone is another word to hold "EVERYONE@". */
uint32_t buf[2 * (6 + 6 + 7)]; uint32_t buf[2 * (6 + 6 + 7)];
int ret = ((flags & ACL_SYMLINK_FOLLOW ? getxattr : lgetxattr) int ret = (fd < 0
(name, XATTR_NAME_NFSV4_ACL, buf, sizeof buf)); ? ((flags & ACL_SYMLINK_FOLLOW ? getxattr : lgetxattr)
(name, XATTR_NAME_NFSV4_ACL, buf, sizeof buf))
: fgetxattr (fd, XATTR_NAME_NFSV4_ACL, buf, sizeof buf));
if (ret < 0) if (ret < 0)
switch (errno) switch (errno)
{ {
@ -467,20 +529,23 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name,
/* On Linux, acl_extended_file is an optimized function: It only /* On Linux, acl_extended_file is an optimized function: It only
makes two calls to getxattr(), one for ACL_TYPE_ACCESS, one for makes two calls to getxattr(), one for ACL_TYPE_ACCESS, one for
ACL_TYPE_DEFAULT. */ ACL_TYPE_DEFAULT. */
ret = ((flags & ACL_SYMLINK_FOLLOW ret = (fd < 0
? acl_extended_file ? ((flags & ACL_SYMLINK_FOLLOW
: acl_extended_file_nofollow) ? acl_extended_file
(name)); : acl_extended_file_nofollow)
(name))
: acl_extended_fd (fd));
# elif HAVE_ACL_TYPE_EXTENDED /* Mac OS X */ # elif HAVE_ACL_TYPE_EXTENDED /* Mac OS X */
/* On Mac OS X, acl_get_file (name, ACL_TYPE_ACCESS) /* On Mac OS X, acl_get_file (name, ACL_TYPE_ACCESS)
and acl_get_file (name, ACL_TYPE_DEFAULT) and acl_get_file (name, ACL_TYPE_DEFAULT)
always return NULL / EINVAL. There is no point in making always return NULL / EINVAL. There is no point in making
these two useless calls. The real ACL is retrieved through these two useless calls. The real ACL is retrieved through
acl_get_file (name, ACL_TYPE_EXTENDED). */ ACL_TYPE_EXTENDED. */
acl_t acl = ((flags & ACL_SYMLINK_FOLLOW acl_t acl =
? acl_get_file (fd < 0
: acl_get_link_np) ? ((flags & ACL_SYMLINK_FOLLOW ? acl_get_file : acl_get_link_np)
(name, ACL_TYPE_EXTENDED)); (name, ACL_TYPE_EXTENDED))
: acl_get_fd_np (fd, ACL_TYPE_EXTENDED));
if (acl) if (acl)
{ {
ret = acl_extended_nontrivial (acl); ret = acl_extended_nontrivial (acl);
@ -489,13 +554,8 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name,
else else
ret = -1; ret = -1;
# else /* FreeBSD, NetBSD >= 10, IRIX, Tru64, Cygwin >= 2.5 */ # else /* FreeBSD, NetBSD >= 10, IRIX, Tru64, Cygwin >= 2.5 */
acl_t (*acl_get_file_or_link) (char const *, acl_type_t) = acl_get_file;
# if HAVE_ACL_GET_LINK_NP /* FreeBSD, NetBSD >= 10, Cygwin >= 2.5 */
if (! (flags & ACL_SYMLINK_FOLLOW))
acl_get_file_or_link = acl_get_link_np;
# endif
acl_t acl = acl_get_file_or_link (name, ACL_TYPE_ACCESS); acl_t acl = acl_get_fdfile (fd, name, ACL_TYPE_ACCESS, flags);
if (acl) if (acl)
{ {
ret = acl_access_nontrivial (acl); ret = acl_access_nontrivial (acl);
@ -517,7 +577,7 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name,
&& (d_type == DT_DIR && (d_type == DT_DIR
|| (d_type == DT_UNKNOWN && !(flags & _GL_DT_NOTDIR)))) || (d_type == DT_UNKNOWN && !(flags & _GL_DT_NOTDIR))))
{ {
acl = acl_get_file_or_link (name, ACL_TYPE_DEFAULT); acl = acl_get_fdfile (fd, name, ACL_TYPE_DEFAULT, flags);
if (acl) if (acl)
{ {
# ifdef __CYGWIN__ /* Cygwin >= 2.5 */ # ifdef __CYGWIN__ /* Cygwin >= 2.5 */
@ -562,7 +622,10 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name,
/* Solaris 10 (newer version), which has additional API declared in /* Solaris 10 (newer version), which has additional API declared in
<sys/acl.h> (acl_t) and implemented in libsec (acl_set, acl_trivial, <sys/acl.h> (acl_t) and implemented in libsec (acl_set, acl_trivial,
acl_fromtext, ...). */ acl_fromtext, ...).
Ignore FD, unfortunately. That is better than mishandling
ZFS-style ACLs, as the general case code does. */
return acl_trivial (name); return acl_trivial (name);
# else /* Solaris, Cygwin, general case */ # else /* Solaris, Cygwin, general case */
@ -586,7 +649,9 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name,
for (;;) for (;;)
{ {
count = acl (name, GETACL, alloc, entries); count = (fd < 0
? acl (name, GETACL, alloc, entries)
: facl (fd, GETACL, alloc, entries));
if (count < 0 && errno == ENOSPC) if (count < 0 && errno == ENOSPC)
{ {
/* Increase the size of the buffer. */ /* Increase the size of the buffer. */
@ -657,7 +722,9 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name,
for (;;) for (;;)
{ {
count = acl (name, ACE_GETACL, alloc, entries); count = (fd < 0
? acl (name, ACE_GETACL, alloc, entries)
: facl (fd, ACE_GETACL, alloc, entries));
if (count < 0 && errno == ENOSPC) if (count < 0 && errno == ENOSPC)
{ {
/* Increase the size of the buffer. */ /* Increase the size of the buffer. */
@ -722,7 +789,9 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name,
struct acl_entry entries[NACLENTRIES]; struct acl_entry entries[NACLENTRIES];
int count; int count;
count = getacl (name, NACLENTRIES, entries); count = (fd < 0
? getacl (name, NACLENTRIES, entries)
: fgetacl (fd, NACLENTRIES, entries));
if (count < 0) if (count < 0)
{ {
@ -751,7 +820,8 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name,
{ {
struct stat statbuf; struct stat statbuf;
if (stat (name, &statbuf) == -1 && errno != EOVERFLOW) if ((fd < 0 ? stat (name, &statbuf) : fstat (fd, &statbuf)) < 0
&& errno != EOVERFLOW)
return -1; return -1;
return acl_nontrivial (count, entries); return acl_nontrivial (count, entries);
@ -765,6 +835,7 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name,
struct acl entries[NACLVENTRIES]; struct acl entries[NACLVENTRIES];
int count; int count;
/* Ignore FD, unfortunately. */
count = acl ((char *) name, ACL_GET, NACLVENTRIES, entries); count = acl ((char *) name, ACL_GET, NACLVENTRIES, entries);
if (count < 0) if (count < 0)
@ -809,7 +880,9 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name,
/* The docs say that type being 0 is equivalent to ACL_ANY, but it /* The docs say that type being 0 is equivalent to ACL_ANY, but it
is not true, in AIX 5.3. */ is not true, in AIX 5.3. */
type.u64 = ACL_ANY; type.u64 = ACL_ANY;
if (aclx_get (name, 0, &type, aclbuf, &aclsize, &mode) >= 0) if (0 <= (fd < 0
? aclx_get (name, 0, &type, aclbuf, &aclsize, &mode)
: aclx_fget (fd, 0, &type, aclbuf, &aclsize, &mode)))
break; break;
if (errno == ENOSYS) if (errno == ENOSYS)
return 0; return 0;
@ -855,7 +928,10 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name,
union { struct acl a; char room[4096]; } u; union { struct acl a; char room[4096]; } u;
if (statacl ((char *) name, STX_NORMAL, &u.a, sizeof (u)) < 0) if ((fd < 0
? statacl ((char *) name, STX_NORMAL, &u.a, sizeof u)
: fstatacl (fd, STX_NORMAL, &u.a, sizeof u))
< 0)
return -1; return -1;
return acl_nontrivial (&u.a); return acl_nontrivial (&u.a);
@ -866,6 +942,7 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name,
struct acl entries[NACLENTRIES]; struct acl entries[NACLENTRIES];
int count; int count;
/* Ignore FD, unfortunately. */
count = acl ((char *) name, ACL_GET, NACLENTRIES, entries); count = acl ((char *) name, ACL_GET, NACLENTRIES, entries);
if (count < 0) if (count < 0)

View file

@ -59,18 +59,61 @@
# endif # endif
# endif # endif
/* Disabled NLS. /* Disabled NLS. */
The casts to 'const char *' serve the purpose of producing warnings # if defined __GNUC__ && !defined __clang__ && !defined __cplusplus
for invalid uses of the value returned from these functions. /* Use inline functions, to avoid warnings
On pre-ANSI systems without 'const', the config.h file is supposed to warning: format not a string literal and no format arguments
contain "#define const". */ that don't occur with enabled NLS. */
# undef gettext /* The return type 'const char *' serves the purpose of producing warnings
# define gettext(Msgid) ((const char *) (Msgid)) for invalid uses of the value returned from these functions. */
# undef dgettext # if __GNUC__ >= 9
# define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid)) # pragma GCC diagnostic push
# undef dcgettext # pragma GCC diagnostic ignored "-Wbuiltin-declaration-mismatch"
# define dcgettext(Domainname, Msgid, Category) \ # endif
((void) (Category), dgettext (Domainname, Msgid)) __attribute__ ((__always_inline__, __gnu_inline__)) extern inline
# if !defined(__sun)
const
# endif
char *
gettext (const char *msgid)
{
return msgid;
}
__attribute__ ((__always_inline__, __gnu_inline__)) extern inline
# if !defined(__sun)
const
# endif
char *
dgettext (const char *domain, const char *msgid)
{
(void) domain;
return msgid;
}
__attribute__ ((__always_inline__, __gnu_inline__)) extern inline
# if !defined(__sun)
const
# endif
char *
dcgettext (const char *domain, const char *msgid, int category)
{
(void) domain;
(void) category;
return msgid;
}
# if __GNUC__ >= 9
# pragma GCC diagnostic pop
# endif
# else
/* The casts to 'const char *' serve the purpose of producing warnings
for invalid uses of the value returned from these functions. */
# undef gettext
# define gettext(Msgid) ((const char *) (Msgid))
# undef dgettext
# define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid))
# undef dcgettext
# define dcgettext(Domainname, Msgid, Category) \
((void) (Category), dgettext (Domainname, Msgid))
# endif
# undef ngettext # undef ngettext
# define ngettext(Msgid1, Msgid2, N) \ # define ngettext(Msgid1, Msgid2, N) \
((N) == 1 \ ((N) == 1 \

View file

@ -739,6 +739,9 @@ HAVE_CANONICALIZE_FILE_NAME = @HAVE_CANONICALIZE_FILE_NAME@
HAVE_CHOWN = @HAVE_CHOWN@ HAVE_CHOWN = @HAVE_CHOWN@
HAVE_CLOSEDIR = @HAVE_CLOSEDIR@ HAVE_CLOSEDIR = @HAVE_CLOSEDIR@
HAVE_COPY_FILE_RANGE = @HAVE_COPY_FILE_RANGE@ HAVE_COPY_FILE_RANGE = @HAVE_COPY_FILE_RANGE@
HAVE_CXX_STDCKDINT_H = @HAVE_CXX_STDCKDINT_H@
HAVE_C_STDCKDINT_H = @HAVE_C_STDCKDINT_H@
HAVE_C_UNREACHABLE = @HAVE_C_UNREACHABLE@
HAVE_DECL_DIRFD = @HAVE_DECL_DIRFD@ HAVE_DECL_DIRFD = @HAVE_DECL_DIRFD@
HAVE_DECL_ECVT = @HAVE_DECL_ECVT@ HAVE_DECL_ECVT = @HAVE_DECL_ECVT@
HAVE_DECL_ENVIRON = @HAVE_DECL_ENVIRON@ HAVE_DECL_ENVIRON = @HAVE_DECL_ENVIRON@
@ -911,6 +914,7 @@ HAVE_SIGNED_WINT_T = @HAVE_SIGNED_WINT_T@
HAVE_SIGSET_T = @HAVE_SIGSET_T@ HAVE_SIGSET_T = @HAVE_SIGSET_T@
HAVE_SLEEP = @HAVE_SLEEP@ HAVE_SLEEP = @HAVE_SLEEP@
HAVE_SPAWN_H = @HAVE_SPAWN_H@ HAVE_SPAWN_H = @HAVE_SPAWN_H@
HAVE_STDCKDINT_H = @HAVE_STDCKDINT_H@
HAVE_STDINT_H = @HAVE_STDINT_H@ HAVE_STDINT_H = @HAVE_STDINT_H@
HAVE_STPCPY = @HAVE_STPCPY@ HAVE_STPCPY = @HAVE_STPCPY@
HAVE_STPNCPY = @HAVE_STPNCPY@ HAVE_STPNCPY = @HAVE_STPNCPY@
@ -960,6 +964,8 @@ HAVE_VASPRINTF = @HAVE_VASPRINTF@
HAVE_VDPRINTF = @HAVE_VDPRINTF@ HAVE_VDPRINTF = @HAVE_VDPRINTF@
HAVE_WCHAR_H = @HAVE_WCHAR_H@ HAVE_WCHAR_H = @HAVE_WCHAR_H@
HAVE_WINSOCK2_H = @HAVE_WINSOCK2_H@ HAVE_WINSOCK2_H = @HAVE_WINSOCK2_H@
HAVE_WORKING_CXX_STDCKDINT_H = @HAVE_WORKING_CXX_STDCKDINT_H@
HAVE_WORKING_C_STDCKDINT_H = @HAVE_WORKING_C_STDCKDINT_H@
HAVE_XSERVER = @HAVE_XSERVER@ HAVE_XSERVER = @HAVE_XSERVER@
HAVE__EXIT = @HAVE__EXIT@ HAVE__EXIT = @HAVE__EXIT@
IEEE754_H = @IEEE754_H@ IEEE754_H = @IEEE754_H@
@ -1087,6 +1093,7 @@ NEXT_AS_FIRST_DIRECTIVE_GETOPT_H = @NEXT_AS_FIRST_DIRECTIVE_GETOPT_H@
NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H = @NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H@ NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H = @NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H@
NEXT_AS_FIRST_DIRECTIVE_LIMITS_H = @NEXT_AS_FIRST_DIRECTIVE_LIMITS_H@ NEXT_AS_FIRST_DIRECTIVE_LIMITS_H = @NEXT_AS_FIRST_DIRECTIVE_LIMITS_H@
NEXT_AS_FIRST_DIRECTIVE_SIGNAL_H = @NEXT_AS_FIRST_DIRECTIVE_SIGNAL_H@ NEXT_AS_FIRST_DIRECTIVE_SIGNAL_H = @NEXT_AS_FIRST_DIRECTIVE_SIGNAL_H@
NEXT_AS_FIRST_DIRECTIVE_STDCKDINT_H = @NEXT_AS_FIRST_DIRECTIVE_STDCKDINT_H@
NEXT_AS_FIRST_DIRECTIVE_STDDEF_H = @NEXT_AS_FIRST_DIRECTIVE_STDDEF_H@ NEXT_AS_FIRST_DIRECTIVE_STDDEF_H = @NEXT_AS_FIRST_DIRECTIVE_STDDEF_H@
NEXT_AS_FIRST_DIRECTIVE_STDINT_H = @NEXT_AS_FIRST_DIRECTIVE_STDINT_H@ NEXT_AS_FIRST_DIRECTIVE_STDINT_H = @NEXT_AS_FIRST_DIRECTIVE_STDINT_H@
NEXT_AS_FIRST_DIRECTIVE_STDIO_H = @NEXT_AS_FIRST_DIRECTIVE_STDIO_H@ NEXT_AS_FIRST_DIRECTIVE_STDIO_H = @NEXT_AS_FIRST_DIRECTIVE_STDIO_H@
@ -1107,6 +1114,7 @@ NEXT_GETOPT_H = @NEXT_GETOPT_H@
NEXT_INTTYPES_H = @NEXT_INTTYPES_H@ NEXT_INTTYPES_H = @NEXT_INTTYPES_H@
NEXT_LIMITS_H = @NEXT_LIMITS_H@ NEXT_LIMITS_H = @NEXT_LIMITS_H@
NEXT_SIGNAL_H = @NEXT_SIGNAL_H@ NEXT_SIGNAL_H = @NEXT_SIGNAL_H@
NEXT_STDCKDINT_H = @NEXT_STDCKDINT_H@
NEXT_STDDEF_H = @NEXT_STDDEF_H@ NEXT_STDDEF_H = @NEXT_STDDEF_H@
NEXT_STDINT_H = @NEXT_STDINT_H@ NEXT_STDINT_H = @NEXT_STDINT_H@
NEXT_STDIO_H = @NEXT_STDIO_H@ NEXT_STDIO_H = @NEXT_STDIO_H@
@ -3202,6 +3210,15 @@ BUILT_SOURCES += $(STDCKDINT_H)
ifneq (,$(GL_GENERATE_STDCKDINT_H_CONDITION)) ifneq (,$(GL_GENERATE_STDCKDINT_H_CONDITION))
stdckdint.h: stdckdint.in.h $(top_builddir)/config.status stdckdint.h: stdckdint.in.h $(top_builddir)/config.status
$(gl_V_at)$(SED_HEADER_STDOUT) \ $(gl_V_at)$(SED_HEADER_STDOUT) \
-e 's|@''GUARD_PREFIX''@|GL|g' \
-e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
-e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
-e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
-e 's|@''NEXT_STDCKDINT_H''@|$(NEXT_STDCKDINT_H)|g' \
-e 's|@''HAVE_C_STDCKDINT_H''@|$(HAVE_C_STDCKDINT_H)|g' \
-e 's|@''HAVE_WORKING_C_STDCKDINT_H''@|$(HAVE_WORKING_C_STDCKDINT_H)|g' \
-e 's|@''HAVE_CXX_STDCKDINT_H''@|$(HAVE_CXX_STDCKDINT_H)|g' \
-e 's|@''HAVE_WORKING_CXX_STDCKDINT_H''@|$(HAVE_WORKING_CXX_STDCKDINT_H)|g' \
$(srcdir)/stdckdint.in.h > $@-t $(srcdir)/stdckdint.in.h > $@-t
$(AM_V_at)mv $@-t $@ $(AM_V_at)mv $@-t $@
else else
@ -3234,6 +3251,7 @@ stddef.h: stddef.in.h $(top_builddir)/config.status
-e 's|@''STDDEF_NOT_IDEMPOTENT''@|$(STDDEF_NOT_IDEMPOTENT)|g' \ -e 's|@''STDDEF_NOT_IDEMPOTENT''@|$(STDDEF_NOT_IDEMPOTENT)|g' \
-e 's|@''REPLACE_NULL''@|$(REPLACE_NULL)|g' \ -e 's|@''REPLACE_NULL''@|$(REPLACE_NULL)|g' \
-e 's|@''HAVE_MAX_ALIGN_T''@|$(HAVE_MAX_ALIGN_T)|g' \ -e 's|@''HAVE_MAX_ALIGN_T''@|$(HAVE_MAX_ALIGN_T)|g' \
-e 's|@''HAVE_C_UNREACHABLE''@|$(HAVE_C_UNREACHABLE)|g' \
$(srcdir)/stddef.in.h > $@-t $(srcdir)/stddef.in.h > $@-t
$(AM_V_at)mv $@-t $@ $(AM_V_at)mv $@-t $@
else else

View file

@ -55,24 +55,25 @@ orig_open (const char *filename, int flags, mode_t mode)
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#ifndef REPLACE_OPEN_DIRECTORY #ifndef OPEN_TRAILING_SLASH_BUG
# define REPLACE_OPEN_DIRECTORY 0 # define OPEN_TRAILING_SLASH_BUG false
#endif #endif
#ifndef REPLACE_OPEN_DIRECTORY
# define REPLACE_OPEN_DIRECTORY false
#endif
static int
lstatif (char const *filename, struct stat *st, int flags)
{
return flags & O_NOFOLLOW ? lstat (filename, st) : stat (filename, st);
}
int int
open (const char *filename, int flags, ...) open (const char *filename, int flags, ...)
{ {
/* 0 = unknown, 1 = yes, -1 = no. */ mode_t mode = 0;
#if GNULIB_defined_O_CLOEXEC
int have_cloexec = -1;
#else
static int have_cloexec;
#endif
mode_t mode;
int fd;
mode = 0;
if (flags & O_CREAT) if (flags & O_CREAT)
{ {
va_list arg; va_list arg;
@ -99,7 +100,6 @@ open (const char *filename, int flags, ...)
filename = "NUL"; filename = "NUL";
#endif #endif
#if OPEN_TRAILING_SLASH_BUG
/* Fail if one of O_CREAT, O_WRONLY, O_RDWR is specified and the filename /* Fail if one of O_CREAT, O_WRONLY, O_RDWR is specified and the filename
ends in a slash, as POSIX says such a filename must name a directory ends in a slash, as POSIX says such a filename must name a directory
<https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13>: <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13>:
@ -118,21 +118,55 @@ open (const char *filename, int flags, ...)
directories, directories,
- if O_WRONLY or O_RDWR is specified, open() must fail because the - if O_WRONLY or O_RDWR is specified, open() must fail because the
file does not contain a '.' directory. */ file does not contain a '.' directory. */
if ((flags & O_CREAT) bool check_for_slash_bug;
|| (flags & O_ACCMODE) == O_RDWR if (OPEN_TRAILING_SLASH_BUG)
|| (flags & O_ACCMODE) == O_WRONLY)
{ {
size_t len = strlen (filename); size_t len = strlen (filename);
if (len > 0 && filename[len - 1] == '/') check_for_slash_bug = len && filename[len - 1] == '/';
}
else
check_for_slash_bug = false;
if (check_for_slash_bug
&& (flags & O_CREAT
|| (flags & O_ACCMODE) == O_RDWR
|| (flags & O_ACCMODE) == O_WRONLY))
{
errno = EISDIR;
return -1;
}
/* With the trailing slash bug or without working O_DIRECTORY, check with
stat first lest we hang trying to open a fifo. Although there is
a race between this and opening the file, we can do no better.
After opening the file we will check again with fstat. */
bool check_directory =
(check_for_slash_bug
|| (!HAVE_WORKING_O_DIRECTORY && flags & O_DIRECTORY));
if (check_directory)
{
struct stat statbuf;
if (lstatif (filename, &statbuf, flags) < 0)
{ {
errno = EISDIR; if (! (flags & O_CREAT && errno == ENOENT))
return -1;
}
else if (!S_ISDIR (statbuf.st_mode))
{
errno = ENOTDIR;
return -1; return -1;
} }
} }
/* 0 = unknown, 1 = yes, -1 = no. */
#if GNULIB_defined_O_CLOEXEC
int have_cloexec = -1;
#else
static int have_cloexec;
#endif #endif
fd = orig_open (filename, int fd = orig_open (filename,
flags & ~(have_cloexec < 0 ? O_CLOEXEC : 0), mode); flags & ~(have_cloexec < 0 ? O_CLOEXEC : 0), mode);
if (flags & O_CLOEXEC) if (flags & O_CLOEXEC)
{ {
@ -154,19 +188,21 @@ open (const char *filename, int flags, ...)
#if REPLACE_FCHDIR #if REPLACE_FCHDIR
/* Implementing fchdir and fdopendir requires the ability to open a /* Implementing fchdir and fdopendir requires the ability to open a
directory file descriptor. If open doesn't support that (as on directory file descriptor. If open doesn't support that (as on
mingw), we use a dummy file that behaves the same as directories mingw), use a dummy file that behaves the same as directories
on Linux (ie. always reports EOF on attempts to read()), and on Linux (ie. always reports EOF on attempts to read()), and
override fstat() in fchdir.c to hide the fact that we have a override fstat in fchdir.c to hide the dummy. */
dummy. */
if (REPLACE_OPEN_DIRECTORY && fd < 0 && errno == EACCES if (REPLACE_OPEN_DIRECTORY && fd < 0 && errno == EACCES
&& ((flags & O_ACCMODE) == O_RDONLY && ((flags & (O_ACCMODE | O_CREAT)) == O_RDONLY
|| (O_SEARCH != O_RDONLY && (flags & O_ACCMODE) == O_SEARCH))) || (O_SEARCH != O_RDONLY
&& (flags & (O_ACCMODE | O_CREAT)) == O_SEARCH)))
{ {
struct stat statbuf; struct stat statbuf;
if (stat (filename, &statbuf) == 0 && S_ISDIR (statbuf.st_mode)) if (check_directory
|| (lstatif (filename, &statbuf, flags) == 0
&& S_ISDIR (statbuf.st_mode)))
{ {
/* Maximum recursion depth of 1. */ /* Maximum recursion depth of 1. */
fd = open ("/dev/null", flags, mode); fd = open ("/dev/null", flags & ~O_DIRECTORY, mode);
if (0 <= fd) if (0 <= fd)
fd = _gl_register_fd (fd, filename); fd = _gl_register_fd (fd, filename);
} }
@ -175,10 +211,8 @@ open (const char *filename, int flags, ...)
} }
#endif #endif
#if OPEN_TRAILING_SLASH_BUG /* If checking for directories, fail if fd does not refer to a directory.
/* If the filename ends in a slash and fd does not refer to a directory, Rationale: A filename ending in slash cannot name a non-directory
then fail.
Rationale: POSIX says such a filename must name a directory
<https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13>: <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13>:
"A pathname that contains at least one non-<slash> character and that "A pathname that contains at least one non-<slash> character and that
ends with one or more trailing <slash> characters shall not be resolved ends with one or more trailing <slash> characters shall not be resolved
@ -186,23 +220,18 @@ open (const char *filename, int flags, ...)
<slash> characters names an existing directory" <slash> characters names an existing directory"
If the named file without the slash is not a directory, open() must fail If the named file without the slash is not a directory, open() must fail
with ENOTDIR. */ with ENOTDIR. */
if (fd >= 0) if (check_directory && 0 <= fd)
{ {
/* We know len is positive, since open did not fail with ENOENT. */ struct stat statbuf;
size_t len = strlen (filename); int r = fstat (fd, &statbuf);
if (filename[len - 1] == '/') if (r < 0 || !S_ISDIR (statbuf.st_mode))
{ {
struct stat statbuf; int err = r < 0 ? errno : ENOTDIR;
close (fd);
if (fstat (fd, &statbuf) >= 0 && !S_ISDIR (statbuf.st_mode)) errno = err;
{ return -1;
close (fd);
errno = ENOTDIR;
return -1;
}
} }
} }
#endif
#if REPLACE_FCHDIR #if REPLACE_FCHDIR
if (!REPLACE_OPEN_DIRECTORY && 0 <= fd) if (!REPLACE_OPEN_DIRECTORY && 0 <= fd)

View file

@ -26,6 +26,7 @@
#if USE_XATTR #if USE_XATTR
# include <attr/libattr.h> # include <attr/libattr.h>
# include <dirent.h>
# include <string.h> # include <string.h>
# if HAVE_LINUX_XATTR_H # if HAVE_LINUX_XATTR_H
@ -61,6 +62,7 @@ is_attr_permissions (const char *name, struct error_context *ctx)
a valid file descriptor, use file descriptor operations, else use a valid file descriptor, use file descriptor operations, else use
filename based operations on SRC_NAME. Likewise for DEST_DESC and filename based operations on SRC_NAME. Likewise for DEST_DESC and
DST_NAME. DST_NAME.
MODE should be the source file's st_mode.
If access control lists are not available, fchmod the target file to If access control lists are not available, fchmod the target file to
MODE. Also sets the non-permission bits of the destination file MODE. Also sets the non-permission bits of the destination file
(S_ISUID, S_ISGID, S_ISVTX) to those from MODE if any are set. (S_ISUID, S_ISGID, S_ISVTX) to those from MODE if any are set.
@ -86,10 +88,29 @@ qcopy_acl (const char *src_name, int source_desc, const char *dst_name,
Functions attr_copy_* return 0 in case we copied something OR nothing Functions attr_copy_* return 0 in case we copied something OR nothing
to copy */ to copy */
if (ret == 0) if (ret == 0)
ret = source_desc <= 0 || dest_desc <= 0 {
? attr_copy_file (src_name, dst_name, is_attr_permissions, NULL) ret = source_desc <= 0 || dest_desc <= 0
: attr_copy_fd (src_name, source_desc, dst_name, dest_desc, ? attr_copy_file (src_name, dst_name, is_attr_permissions, NULL)
is_attr_permissions, NULL); : attr_copy_fd (src_name, source_desc, dst_name, dest_desc,
is_attr_permissions, NULL);
/* Copying can fail with EOPNOTSUPP even when the source
permissions are trivial (Bug#78328). Don't report an error
in this case, as the chmod_or_fchmod suffices. */
if (ret < 0 && errno == EOPNOTSUPP)
{
/* fdfile_has_aclinfo cares only about DT_DIR, _GL_DT_NOTDIR,
and DT_LNK (but DT_LNK is not possible here),
so use _GL_DT_NOTDIR | DT_UNKNOWN for other file types. */
int flags = S_ISDIR (mode) ? DT_DIR : _GL_DT_NOTDIR | DT_UNKNOWN;
struct aclinfo ai;
if (!fdfile_has_aclinfo (source_desc, src_name, &ai, flags))
ret = 0;
aclinfo_free (&ai);
errno = EOPNOTSUPP;
}
}
#else #else
/* no XATTR, so we proceed the old dusty way */ /* no XATTR, so we proceed the old dusty way */
struct permission_context ctx; struct permission_context ctx;

View file

@ -1001,21 +1001,25 @@ create_initial_state (re_dfa_t *dfa)
Idx dest_idx = dfa->edests[node_idx].elems[0]; Idx dest_idx = dfa->edests[node_idx].elems[0];
if (!re_node_set_contains (&init_nodes, dest_idx)) if (!re_node_set_contains (&init_nodes, dest_idx))
{ {
reg_errcode_t merge_err err
= re_node_set_merge (&init_nodes, dfa->eclosures + dest_idx); = re_node_set_merge (&init_nodes, dfa->eclosures + dest_idx);
if (merge_err != REG_NOERROR) if (err != REG_NOERROR)
return merge_err; break;
i = 0; i = 0;
} }
} }
} }
/* It must be the first time to invoke acquire_state. */ /* It must be the first time to invoke acquire_state. */
dfa->init_state = re_acquire_state_context (&err, dfa, &init_nodes, 0); dfa->init_state
/* We don't check ERR here, since the initial state must not be NULL. */ = (err == REG_NOERROR
? re_acquire_state_context (&err, dfa, &init_nodes, 0)
: NULL);
if (__glibc_unlikely (dfa->init_state == NULL)) if (__glibc_unlikely (dfa->init_state == NULL))
return err; {
if (dfa->init_state->has_constraint) /* Don't check ERR here, as the initial state must not be null. */
}
else if (dfa->init_state->has_constraint)
{ {
dfa->init_state_word = re_acquire_state_context (&err, dfa, &init_nodes, dfa->init_state_word = re_acquire_state_context (&err, dfa, &init_nodes,
CONTEXT_WORD); CONTEXT_WORD);
@ -1025,17 +1029,13 @@ create_initial_state (re_dfa_t *dfa)
&init_nodes, &init_nodes,
CONTEXT_NEWLINE CONTEXT_NEWLINE
| CONTEXT_BEGBUF); | CONTEXT_BEGBUF);
if (__glibc_unlikely (dfa->init_state_word == NULL
|| dfa->init_state_nl == NULL
|| dfa->init_state_begbuf == NULL))
return err;
} }
else else
dfa->init_state_word = dfa->init_state_nl dfa->init_state_word = dfa->init_state_nl
= dfa->init_state_begbuf = dfa->init_state; = dfa->init_state_begbuf = dfa->init_state;
re_node_set_free (&init_nodes); re_node_set_free (&init_nodes);
return REG_NOERROR; return err;
} }
/* If it is possible to do searching in single byte encoding instead of UTF-8 /* If it is possible to do searching in single byte encoding instead of UTF-8
@ -1677,12 +1677,11 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root)
{ {
err = duplicate_node_closure (dfa, node, node, node, err = duplicate_node_closure (dfa, node, node, node,
dfa->nodes[node].constraint); dfa->nodes[node].constraint);
if (__glibc_unlikely (err != REG_NOERROR))
return err;
} }
/* Expand each epsilon destination nodes. */ /* Expand each epsilon destination nodes. */
if (IS_EPSILON_NODE(dfa->nodes[node].type)) if (__glibc_likely (err == REG_NOERROR)
&& IS_EPSILON_NODE (dfa->nodes[node].type))
for (i = 0; i < dfa->edests[node].nelem; ++i) for (i = 0; i < dfa->edests[node].nelem; ++i)
{ {
re_node_set eclosure_elem; re_node_set eclosure_elem;
@ -1700,14 +1699,14 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root)
{ {
err = calc_eclosure_iter (&eclosure_elem, dfa, edest, false); err = calc_eclosure_iter (&eclosure_elem, dfa, edest, false);
if (__glibc_unlikely (err != REG_NOERROR)) if (__glibc_unlikely (err != REG_NOERROR))
return err; break;
} }
else else
eclosure_elem = dfa->eclosures[edest]; eclosure_elem = dfa->eclosures[edest];
/* Merge the epsilon closure of 'edest'. */ /* Merge the epsilon closure of 'edest'. */
err = re_node_set_merge (&eclosure, &eclosure_elem); err = re_node_set_merge (&eclosure, &eclosure_elem);
if (__glibc_unlikely (err != REG_NOERROR)) if (__glibc_unlikely (err != REG_NOERROR))
return err; break;
/* If the epsilon closure of 'edest' is incomplete, /* If the epsilon closure of 'edest' is incomplete,
the epsilon closure of this node is also incomplete. */ the epsilon closure of this node is also incomplete. */
if (dfa->eclosures[edest].nelem == 0) if (dfa->eclosures[edest].nelem == 0)
@ -1717,12 +1716,18 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root)
} }
} }
if (incomplete && !root) if (err != REG_NOERROR)
dfa->eclosures[node].nelem = 0; re_node_set_free (&eclosure);
else else
dfa->eclosures[node] = eclosure; {
*new_set = eclosure; if (incomplete && !root)
return REG_NOERROR; dfa->eclosures[node].nelem = 0;
else
dfa->eclosures[node] = eclosure;
*new_set = eclosure;
}
return err;
} }
/* Functions for token which are used in the parser. */ /* Functions for token which are used in the parser. */
@ -3275,6 +3280,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
else else
{ {
free_charset (mbcset); free_charset (mbcset);
mbcset = NULL;
/* Build a tree for simple bracket. */ /* Build a tree for simple bracket. */
br_token.type = SIMPLE_BRACKET; br_token.type = SIMPLE_BRACKET;
br_token.opr.sbcset = sbcset; br_token.opr.sbcset = sbcset;
@ -3288,7 +3294,8 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
*err = REG_ESPACE; *err = REG_ESPACE;
parse_bracket_exp_free_return: parse_bracket_exp_free_return:
re_free (sbcset); re_free (sbcset);
free_charset (mbcset); if (__glibc_likely (mbcset != NULL))
free_charset (mbcset);
return NULL; return NULL;
} }

View file

@ -2271,7 +2271,7 @@ merge_state_with_log (reg_errcode_t *err, re_match_context_t *mctx,
these destinations and the results of the transition table. */ these destinations and the results of the transition table. */
pstate = mctx->state_log[cur_idx]; pstate = mctx->state_log[cur_idx];
log_nodes = pstate->entrance_nodes; log_nodes = pstate->entrance_nodes;
if (next_state != NULL) if (next_state != NULL && next_state->entrance_nodes != NULL)
{ {
table_nodes = next_state->entrance_nodes; table_nodes = next_state->entrance_nodes;
*err = re_node_set_init_union (&next_nodes, table_nodes, *err = re_node_set_init_union (&next_nodes, table_nodes,

View file

@ -117,6 +117,31 @@ get_stat_birthtime_ns (_GL_UNUSED struct stat const *st)
# endif # endif
} }
/* Constructs a 'struct timespec' with the given contents.
This macro / function is private to stat-time.h. */
#if !defined __cplusplus
/* Use a C99 compound literal.
This is guaranteed to initialize also the padding bits, for example on
platforms where tv_sec is 64 bits and tv_nsec is 32 bits, thus avoiding
gcc -Wuse-of-uninitialized-value warnings. */
# define _gl_make_timespec(sec,nsec) \
(struct timespec) { .tv_sec = (sec), .tv_nsec = (nsec) }
#else
/* C++ does not have C99 compound literals.
A constructor invocation
timespec { (sec), (nsec) }
would make assumptions about the order of the fields of 'struct timespec',
which are not guaranteed by POSIX. So, use an inline function. */
static inline struct timespec
_gl_make_timespec (time_t sec, long nsec)
{
struct timespec ts;
ts.tv_sec = sec;
ts.tv_nsec = nsec;
return ts;
}
#endif
/* Return *ST's access time. */ /* Return *ST's access time. */
_GL_STAT_TIME_INLINE struct timespec _GL_ATTRIBUTE_PURE _GL_STAT_TIME_INLINE struct timespec _GL_ATTRIBUTE_PURE
get_stat_atime (struct stat const *st) get_stat_atime (struct stat const *st)
@ -124,8 +149,7 @@ get_stat_atime (struct stat const *st)
#ifdef STAT_TIMESPEC #ifdef STAT_TIMESPEC
return STAT_TIMESPEC (st, st_atim); return STAT_TIMESPEC (st, st_atim);
#else #else
return (struct timespec) { .tv_sec = st->st_atime, return _gl_make_timespec (st->st_atime, get_stat_atime_ns (st));
.tv_nsec = get_stat_atime_ns (st) };
#endif #endif
} }
@ -136,8 +160,7 @@ get_stat_ctime (struct stat const *st)
#ifdef STAT_TIMESPEC #ifdef STAT_TIMESPEC
return STAT_TIMESPEC (st, st_ctim); return STAT_TIMESPEC (st, st_ctim);
#else #else
return (struct timespec) { .tv_sec = st->st_ctime, return _gl_make_timespec (st->st_ctime, get_stat_ctime_ns (st));
.tv_nsec = get_stat_ctime_ns (st) };
#endif #endif
} }
@ -148,8 +171,7 @@ get_stat_mtime (struct stat const *st)
#ifdef STAT_TIMESPEC #ifdef STAT_TIMESPEC
return STAT_TIMESPEC (st, st_mtim); return STAT_TIMESPEC (st, st_mtim);
#else #else
return (struct timespec) { .tv_sec = st->st_mtime, return _gl_make_timespec (st->st_mtime, get_stat_mtime_ns (st));
.tv_nsec = get_stat_mtime_ns (st) };
#endif #endif
} }
@ -164,8 +186,7 @@ get_stat_birthtime (_GL_UNUSED struct stat const *st)
|| defined HAVE_STRUCT_STAT_ST_BIRTHTIM_TV_NSEC) || defined HAVE_STRUCT_STAT_ST_BIRTHTIM_TV_NSEC)
t = STAT_TIMESPEC (st, st_birthtim); t = STAT_TIMESPEC (st, st_birthtim);
#elif defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC #elif defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC
t = (struct timespec) { .tv_sec = st->st_birthtime, t = _gl_make_timespec (st->st_birthtime, st->st_birthtimensec);
.tv_nsec = st->st_birthtimensec };
#elif defined _WIN32 && ! defined __CYGWIN__ #elif defined _WIN32 && ! defined __CYGWIN__
/* Native Windows platforms (but not Cygwin) put the "file creation /* Native Windows platforms (but not Cygwin) put the "file creation
time" in st_ctime (!). See time" in st_ctime (!). See
@ -173,11 +194,11 @@ get_stat_birthtime (_GL_UNUSED struct stat const *st)
# if _GL_WINDOWS_STAT_TIMESPEC # if _GL_WINDOWS_STAT_TIMESPEC
t = st->st_ctim; t = st->st_ctim;
# else # else
t = (struct timespec) { .tv_sec = st->st_ctime }; t = _gl_make_timespec (st->st_ctime, 0);
# endif # endif
#else #else
/* Birth time is not supported. */ /* Birth time is not supported. */
t = (struct timespec) { .tv_sec = -1, .tv_nsec = -1 }; t = _gl_make_timespec (-1, -1);
#endif #endif
#if (defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC \ #if (defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC \
@ -189,7 +210,7 @@ get_stat_birthtime (_GL_UNUSED struct stat const *st)
sometimes returns junk in the birth time fields; work around this sometimes returns junk in the birth time fields; work around this
bug if it is detected. */ bug if it is detected. */
if (! (t.tv_sec && 0 <= t.tv_nsec && t.tv_nsec < 1000000000)) if (! (t.tv_sec && 0 <= t.tv_nsec && t.tv_nsec < 1000000000))
t = (struct timespec) { .tv_sec = -1, .tv_nsec = -1 }; t = _gl_make_timespec (-1, -1);
#endif #endif
return t; return t;

View file

@ -15,10 +15,30 @@
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */ along with this program. If not, see <https://www.gnu.org/licenses/>. */
#ifndef _GL_STDCKDINT_H #if __GNUC__ >= 3
#define _GL_STDCKDINT_H @PRAGMA_SYSTEM_HEADER@
#endif
@PRAGMA_COLUMNS@
#include "intprops-internal.h" #ifndef _@GUARD_PREFIX@_STDCKDINT_H
/* The include_next requires a split double-inclusion guard. */
#if defined __cplusplus ? @HAVE_CXX_STDCKDINT_H@ : @HAVE_C_STDCKDINT_H@
# @INCLUDE_NEXT@ @NEXT_STDCKDINT_H@
#endif
#ifndef _@GUARD_PREFIX@_STDCKDINT_H
#define _@GUARD_PREFIX@_STDCKDINT_H
/* Do nothing but include the system header if it works properly. */
# if defined __cplusplus ? !@HAVE_WORKING_CXX_STDCKDINT_H@ : !@HAVE_WORKING_C_STDCKDINT_H@
/* Avoid redefining macros. */
# undef ckd_add
# undef ckd_sub
# undef ckd_mul
# include "intprops-internal.h"
/* Store into *R the low-order bits of A + B, A - B, A * B, respectively. /* Store into *R the low-order bits of A + B, A - B, A * B, respectively.
Return 1 if the result overflows, 0 otherwise. Return 1 if the result overflows, 0 otherwise.
@ -26,10 +46,13 @@
bit-precise integer type, or an enumeration type. bit-precise integer type, or an enumeration type.
These are like the standard macros introduced in C23, except that These are like the standard macros introduced in C23, except that
arguments should not have side effects. */ arguments should not have side effects. The C++26 standard is
expected to add this header and it's macros. */
#define ckd_add(r, a, b) ((bool) _GL_INT_ADD_WRAPV (a, b, r)) # define ckd_add(r, a, b) ((bool) _GL_INT_ADD_WRAPV (a, b, r))
#define ckd_sub(r, a, b) ((bool) _GL_INT_SUBTRACT_WRAPV (a, b, r)) # define ckd_sub(r, a, b) ((bool) _GL_INT_SUBTRACT_WRAPV (a, b, r))
#define ckd_mul(r, a, b) ((bool) _GL_INT_MULTIPLY_WRAPV (a, b, r)) # define ckd_mul(r, a, b) ((bool) _GL_INT_MULTIPLY_WRAPV (a, b, r))
#endif /* _GL_STDCKDINT_H */ # endif /* defined __cplusplus ? @HAVE_WORKING_CXX_STDCKDINT_H@ : @HAVE_WORKING_C_STDCKDINT_H@ */
#endif /* _@GUARD_PREFIX@_STDCKDINT_H */
#endif /* _@GUARD_PREFIX@_STDCKDINT_H */

View file

@ -188,38 +188,57 @@ typedef union
#endif #endif
/* ISO C 23 § 7.21.1 The unreachable macro */ /* ISO C 23 § 7.21.1 The unreachable macro */
#ifndef unreachable /* This macro is only usable in C, not in C++.
There is no way to define it as a macro in C++, because that would break code
that does
#include <utility>
... std::unreachable() ...
Similarly, there is no way to define it as an inline function in C++, because
that would break code that does
#include <utility>
using std::unreachable;
As a workaround, we define a macro gl_unreachable, that is like unreachable,
but is usable in both C and C++. */
/* Code borrowed from verify.h. */ /* Code borrowed from verify.h. */
# ifndef _GL_HAS_BUILTIN_UNREACHABLE #ifndef _GL_HAS_BUILTIN_UNREACHABLE
# if defined __clang_major__ && __clang_major__ < 5 # if defined __clang_major__ && __clang_major__ < 5
# define _GL_HAS_BUILTIN_UNREACHABLE 0 # define _GL_HAS_BUILTIN_UNREACHABLE 0
# elif 4 < __GNUC__ + (5 <= __GNUC_MINOR__) && !defined __clang__ # elif 4 < __GNUC__ + (5 <= __GNUC_MINOR__) && !defined __clang__
# define _GL_HAS_BUILTIN_UNREACHABLE 1 # define _GL_HAS_BUILTIN_UNREACHABLE 1
# elif defined __has_builtin # elif defined __has_builtin
# define _GL_HAS_BUILTIN_UNREACHABLE __has_builtin (__builtin_unreachable) # define _GL_HAS_BUILTIN_UNREACHABLE __has_builtin (__builtin_unreachable)
# else
# define _GL_HAS_BUILTIN_UNREACHABLE 0
# endif
# endif
# if _GL_HAS_BUILTIN_UNREACHABLE
# define unreachable() __builtin_unreachable ()
# elif 1200 <= _MSC_VER
# define unreachable() __assume (0)
# else # else
# define _GL_HAS_BUILTIN_UNREACHABLE 0
# endif
#endif
#if _GL_HAS_BUILTIN_UNREACHABLE
# define gl_unreachable() __builtin_unreachable ()
#elif 1200 <= _MSC_VER
# define gl_unreachable() __assume (0)
#elif !defined __cplusplus && @HAVE_C_UNREACHABLE@
# define gl_unreachable() unreachable ()
#else
/* Declare abort(), without including <stdlib.h>. */ /* Declare abort(), without including <stdlib.h>. */
extern extern
# if defined __cplusplus # if defined __cplusplus
"C" "C"
# endif # endif
_Noreturn _Noreturn
void abort (void) void abort (void)
# if defined __cplusplus && (__GLIBC__ >= 2) # if defined __cplusplus && (__GLIBC__ >= 2)
_GL_ATTRIBUTE_NOTHROW _GL_ATTRIBUTE_NOTHROW
# endif # endif
; ;
# define unreachable() abort () # define gl_unreachable() abort ()
#endif
#if !defined __cplusplus && !@HAVE_C_UNREACHABLE@
/* In C, define unreachable as a macro. */
# ifndef unreachable
# define unreachable() gl_unreachable ()
# endif # endif
#endif #endif

View file

@ -215,25 +215,49 @@ _GL_EXTERN_C void free (void *);
/* Declarations for ISO C N3322. */ /* Declarations for ISO C N3322. */
#if defined __GNUC__ && __GNUC__ >= 15 && !defined __clang__ #if defined __GNUC__ && __GNUC__ >= 15 && !defined __clang__
_GL_EXTERN_C void *memcpy (void *__dest, const void *__src, size_t __n) _GL_EXTERN_C void *memcpy (void *__dest, const void *__src, size_t __n)
# if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2
_GL_ATTRIBUTE_NOTHROW
# endif
_GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3)
_GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3); _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3);
_GL_EXTERN_C void *memccpy (void *__dest, const void *__src, int __c, size_t __n) _GL_EXTERN_C void *memccpy (void *__dest, const void *__src, int __c, size_t __n)
# if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2
_GL_ATTRIBUTE_NOTHROW
# endif
_GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 4) _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 4)
_GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 4); _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 4);
_GL_EXTERN_C void *memmove (void *__dest, const void *__src, size_t __n) _GL_EXTERN_C void *memmove (void *__dest, const void *__src, size_t __n)
# if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2
_GL_ATTRIBUTE_NOTHROW
# endif
_GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3)
_GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3); _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3);
_GL_EXTERN_C char *strncpy (char *__dest, const char *__src, size_t __n) _GL_EXTERN_C char *strncpy (char *__dest, const char *__src, size_t __n)
# if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2
_GL_ATTRIBUTE_NOTHROW
# endif
_GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3)
_GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3); _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3);
_GL_EXTERN_C char *strndup (const char *__s, size_t __n) _GL_EXTERN_C char *strndup (const char *__s, size_t __n)
# if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2
_GL_ATTRIBUTE_NOTHROW
# endif
_GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 2); _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 2);
_GL_EXTERN_C char *strncat (char *__dest, const char *__src, size_t __n) _GL_EXTERN_C char *strncat (char *__dest, const char *__src, size_t __n)
# if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2
_GL_ATTRIBUTE_NOTHROW
# endif
_GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3); _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3);
_GL_EXTERN_C int memcmp (const void *__s1, const void *__s2, size_t __n) _GL_EXTERN_C int memcmp (const void *__s1, const void *__s2, size_t __n)
# if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2
_GL_ATTRIBUTE_NOTHROW
# endif
_GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3)
_GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3); _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3);
_GL_EXTERN_C int strncmp (const char *__s1, const char *__s2, size_t __n) _GL_EXTERN_C int strncmp (const char *__s1, const char *__s2, size_t __n)
# if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2
_GL_ATTRIBUTE_NOTHROW
# endif
_GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3)
_GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3); _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3);
# ifndef __cplusplus # ifndef __cplusplus
@ -243,6 +267,9 @@ _GL_EXTERN_C void *memrchr (const void *__s, int __c, size_t __n)
_GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3); _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3);
# endif # endif
_GL_EXTERN_C void *memset (void *__s, int __c, size_t __n) _GL_EXTERN_C void *memset (void *__s, int __c, size_t __n)
# if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2
_GL_ATTRIBUTE_NOTHROW
# endif
_GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3); _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3);
_GL_EXTERN_C void *memset_explicit (void *__s, int __c, size_t __n) _GL_EXTERN_C void *memset_explicit (void *__s, int __c, size_t __n)
_GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3); _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3);

View file

@ -849,7 +849,11 @@ _GL_WARN_ON_USE (mknodat, "mknodat is not portable - "
# elif @WINDOWS_64_BIT_ST_SIZE@ # elif @WINDOWS_64_BIT_ST_SIZE@
/* Above, we define stat to _stati64. */ /* Above, we define stat to _stati64. */
# if defined __MINGW32__ && defined _stati64 # if defined __MINGW32__ && defined _stati64
# ifndef _USE_32BIT_TIME_T # ifdef _USE_32BIT_TIME_T
/* The system headers possibly define _stati64 to _stat32i64. */
# undef _stat32i64
# define _stat32i64(name, st) rpl_stat (name, st)
# else
/* The system headers define _stati64 to _stat64. */ /* The system headers define _stati64 to _stat64. */
# undef _stat64 # undef _stat64
# define _stat64(name, st) rpl_stat (name, st) # define _stat64(name, st) rpl_stat (name, st)

View file

@ -95,6 +95,15 @@
# include <stdio.h> # include <stdio.h>
#endif #endif
/* Native Windows platforms declare _chdir, _getcwd, _rmdir in
<io.h> and/or <direct.h>, not in <unistd.h>.
They also declare _access(), _chmod(), _close(), _dup(), _dup2(), _isatty(),
_lseek(), _read(), _unlink(), _write() in <io.h>. */
#if defined _WIN32 && !defined __CYGWIN__
# include <io.h>
# include <direct.h>
#endif
/* FreeBSD 14.0, NetBSD 10.0, OpenBSD 7.5, Solaris 11.4, and glibc 2.41 /* FreeBSD 14.0, NetBSD 10.0, OpenBSD 7.5, Solaris 11.4, and glibc 2.41
do not define O_CLOEXEC in <unistd.h>. */ do not define O_CLOEXEC in <unistd.h>. */
/* Cygwin 1.7.1 and Android 4.3 declare unlinkat in <fcntl.h>, not in /* Cygwin 1.7.1 and Android 4.3 declare unlinkat in <fcntl.h>, not in
@ -120,15 +129,6 @@
# undef __need_system_stdlib_h # undef __need_system_stdlib_h
#endif #endif
/* Native Windows platforms declare _chdir, _getcwd, _rmdir in
<io.h> and/or <direct.h>, not in <unistd.h>.
They also declare _access(), _chmod(), _close(), _dup(), _dup2(), _isatty(),
_lseek(), _read(), _unlink(), _write() in <io.h>. */
#if defined _WIN32 && !defined __CYGWIN__
# include <io.h>
# include <direct.h>
#endif
/* Native Windows platforms declare _execl*, _execv* in <process.h>. */ /* Native Windows platforms declare _execl*, _execv* in <process.h>. */
#if defined _WIN32 && !defined __CYGWIN__ #if defined _WIN32 && !defined __CYGWIN__
# include <process.h> # include <process.h>

View file

@ -1,5 +1,5 @@
# acl.m4 # acl.m4
# serial 35 # serial 37
dnl Copyright (C) 2002, 2004-2025 Free Software Foundation, Inc. dnl Copyright (C) 2002, 2004-2025 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it, dnl gives unlimited permission to copy and/or distribute it,
@ -12,7 +12,6 @@ dnl This file is offered as-is, without any warranty.
AC_DEFUN([gl_FUNC_ACL_ARG], AC_DEFUN([gl_FUNC_ACL_ARG],
[ [
gl_need_lib_has_acl=
AC_ARG_ENABLE([acl], AC_ARG_ENABLE([acl],
AS_HELP_STRING([[--disable-acl]], [do not support ACLs]), AS_HELP_STRING([[--disable-acl]], [do not support ACLs]),
, [enable_acl=auto]) , [enable_acl=auto])
@ -22,6 +21,7 @@ AC_DEFUN([gl_FUNC_ACL_ARG],
[], [with_libsmack=maybe]) [], [with_libsmack=maybe])
]) ])
# Prerequisites of module acl-permissions.
AC_DEFUN_ONCE([gl_FUNC_ACL], AC_DEFUN_ONCE([gl_FUNC_ACL],
[ [
AC_REQUIRE([gl_FUNC_ACL_ARG]) AC_REQUIRE([gl_FUNC_ACL_ARG])
@ -145,9 +145,6 @@ int type = ACL_TYPE_EXTENDED;]])],
AC_MSG_WARN([AC_PACKAGE_NAME will be built without ACL support.]) AC_MSG_WARN([AC_PACKAGE_NAME will be built without ACL support.])
fi fi
fi fi
if test -n "$gl_need_lib_has_acl"; then
FILE_HAS_ACL_LIB=$LIB_ACL
fi
AC_SUBST([LIB_ACL]) AC_SUBST([LIB_ACL])
AC_DEFINE_UNQUOTED([USE_ACL], [$use_acl], AC_DEFINE_UNQUOTED([USE_ACL], [$use_acl],
[Define to nonzero if you want access control list support.]) [Define to nonzero if you want access control list support.])
@ -187,6 +184,7 @@ AC_DEFUN([gl_ACL_GET_FILE],
AC_DEFUN([gl_FILE_HAS_ACL], AC_DEFUN([gl_FILE_HAS_ACL],
[ [
AC_REQUIRE([gl_FUNC_ACL_ARG]) AC_REQUIRE([gl_FUNC_ACL_ARG])
AC_REQUIRE([gl_FUNC_ACL])
# On GNU/Linux, testing if a file has an acl can be done with the # On GNU/Linux, testing if a file has an acl can be done with the
# listxattr and getxattr syscalls, which don't require linking # listxattr and getxattr syscalls, which don't require linking
# against additional libraries. Assume this works if linux/attr.h # against additional libraries. Assume this works if linux/attr.h
@ -224,10 +222,7 @@ AC_DEFUN([gl_FILE_HAS_ACL],
AS_CASE([$enable_acl,$gl_file_has_acl_uses_selinux,$gl_file_has_acl_uses_smack], AS_CASE([$enable_acl,$gl_file_has_acl_uses_selinux,$gl_file_has_acl_uses_smack],
[no,* | *,yes,* | *,yes], [], [no,* | *,yes,* | *,yes], [],
[*], [*],
[dnl Set gl_need_lib_has_acl to a nonempty value, so that any [FILE_HAS_ACL_LIB=$LIB_ACL])
dnl later gl_FUNC_ACL call will set FILE_HAS_ACL_LIB=$LIB_ACL.
gl_need_lib_has_acl=1
FILE_HAS_ACL_LIB=$LIB_ACL])
AC_SUBST([FILE_HAS_ACL_LIB]) AC_SUBST([FILE_HAS_ACL_LIB])
]) ])
@ -235,10 +230,11 @@ AC_DEFUN([gl_FILE_HAS_ACL],
AC_DEFUN([gl_QCOPY_ACL], AC_DEFUN([gl_QCOPY_ACL],
[ [
AC_REQUIRE([gl_FUNC_ACL]) AC_REQUIRE([gl_FUNC_ACL])
AC_REQUIRE([gl_FILE_HAS_ACL])
AC_CHECK_HEADERS_ONCE([linux/xattr.h]) AC_CHECK_HEADERS_ONCE([linux/xattr.h])
gl_FUNC_XATTR gl_FUNC_XATTR
if test "$use_xattr" = yes; then if test "$use_xattr" = yes; then
QCOPY_ACL_LIB="$LIB_XATTR" QCOPY_ACL_LIB="$LIB_XATTR $FILE_HAS_ACL_LIB"
else else
QCOPY_ACL_LIB="$LIB_ACL" QCOPY_ACL_LIB="$LIB_ACL"
fi fi

View file

@ -1,5 +1,5 @@
# gnulib-common.m4 # gnulib-common.m4
# serial 110 # serial 112
dnl Copyright (C) 2007-2025 Free Software Foundation, Inc. dnl Copyright (C) 2007-2025 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it, dnl gives unlimited permission to copy and/or distribute it,
@ -57,33 +57,24 @@ AC_DEFUN([gl_COMMON_BODY], [
#endif #endif
]) ])
AH_VERBATIM([_Noreturn], AH_VERBATIM([_Noreturn],
[/* The _Noreturn keyword of C11. */ [/* The _Noreturn keyword of C11.
Do not use [[noreturn]], because with it the syntax
extern _Noreturn void func (...);
would not be valid; such a declaration would be valid only with 'extern'
and '_Noreturn' swapped, or without the 'extern' keyword. However, some
AIX system header files and several gnulib header files use precisely
this syntax with 'extern'. So even though C23 deprecates _Noreturn,
it is currently more portable to prefer it to [[noreturn]].
Also, do not try to work around LLVM bug 59792 (clang 15 or earlier).
This rare bug can be worked around by compiling with 'clang -D_Noreturn=',
though the workaround may generate many false-alarm warnings. */
#ifndef _Noreturn #ifndef _Noreturn
# if (defined __cplusplus \ # if 201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0)
&& ((201103 <= __cplusplus && !(__GNUC__ == 4 && __GNUC_MINOR__ == 7)) \
|| (defined _MSC_VER && 1900 <= _MSC_VER)) \
&& 0)
/* [[noreturn]] is not practically usable, because with it the syntax
extern _Noreturn void func (...);
would not be valid; such a declaration would only be valid with 'extern'
and '_Noreturn' swapped, or without the 'extern' keyword. However, some
AIX system header files and several gnulib header files use precisely
this syntax with 'extern'. */
# define _Noreturn [[noreturn]]
# elif (defined __clang__ && __clang_major__ < 16 \
&& defined _GL_WORK_AROUND_LLVM_BUG_59792)
/* Compile with -D_GL_WORK_AROUND_LLVM_BUG_59792 to work around
that rare LLVM bug, though you may get many false-alarm warnings. */
# define _Noreturn
# elif ((!defined __cplusplus || defined __clang__) \
&& (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \
|| (!defined __STRICT_ANSI__ \
&& (_GL_GNUC_PREREQ (4, 7) \
|| (defined __apple_build_version__ \
? 6000000 <= __apple_build_version__ \
: 3 < __clang_major__ + (5 <= __clang_minor__))))))
/* _Noreturn works as-is. */ /* _Noreturn works as-is. */
# elif _GL_GNUC_PREREQ (2, 8) || defined __clang__ || 0x5110 <= __SUNPRO_C # elif _GL_GNUC_PREREQ (2, 8) || defined __clang__ || 0x5110 <= __SUNPRO_C
/* Prefer __attribute__ ((__noreturn__)) to plain _Noreturn even if the
latter works, as 'gcc -std=gnu99 -Wpedantic' warns about _Noreturn. */
# define _Noreturn __attribute__ ((__noreturn__)) # define _Noreturn __attribute__ ((__noreturn__))
# elif 1200 <= (defined _MSC_VER ? _MSC_VER : 0) # elif 1200 <= (defined _MSC_VER ? _MSC_VER : 0)
# define _Noreturn __declspec (noreturn) # define _Noreturn __declspec (noreturn)
@ -955,8 +946,8 @@ AC_DEFUN([gl_COMMON_BODY], [
-1 if n1 < n2 -1 if n1 < n2
The naïve code (n1 > n2 ? 1 : n1 < n2 ? -1 : 0) produces a conditional The naïve code (n1 > n2 ? 1 : n1 < n2 ? -1 : 0) produces a conditional
jump with nearly all GCC versions up to GCC 10. jump with nearly all GCC versions up to GCC 10.
This variant (n1 < n2 ? -1 : n1 > n2) produces a conditional with many This variant (n1 < n2 ? -1 : n1 > n2) produces a conditional jump with
GCC versions up to GCC 9. many GCC versions up to GCC 9.
The better code (n1 > n2) - (n1 < n2) from Hacker's Delight § 2-9 The better code (n1 > n2) - (n1 < n2) from Hacker's Delight § 2-9
avoids conditional jumps in all GCC versions >= 3.4. */ avoids conditional jumps in all GCC versions >= 3.4. */
#define _GL_CMP(n1, n2) (((n1) > (n2)) - ((n1) < (n2))) #define _GL_CMP(n1, n2) (((n1) > (n2)) - ((n1) < (n2)))
@ -1571,13 +1562,25 @@ AC_DEFUN([gl_CHECK_FUNCS_CASE_FOR_MACOS],
if test $[ac_cv_func_][$1] = yes; then if test $[ac_cv_func_][$1] = yes; then
[gl_cv_onwards_func_][$1]=yes [gl_cv_onwards_func_][$1]=yes
else else
dnl This is a bit complicated, because here we need the behaviour
dnl of AC_CHECK_DECL before the
dnl commit e1bbc9b93cdff61d70719c224b37970e065008bb (2025-05-26).
[ac_cv_have_decl_][$1][_saved]="$[ac_cv_have_decl_][$1]"
unset [ac_cv_have_decl_][$1] unset [ac_cv_have_decl_][$1]
ac_c_future_darwin_options_saved="$ac_c_future_darwin_options"
ac_cxx_future_darwin_options_saved="$ac_cxx_future_darwin_options"
ac_c_future_darwin_options=
ac_cxx_future_darwin_options=
AC_CHECK_DECL([$1], , , [$2]) AC_CHECK_DECL([$1], , , [$2])
ac_c_future_darwin_options="$ac_c_future_darwin_options_saved"
ac_cxx_future_darwin_options="$ac_cxx_future_darwin_options_saved"
if test $[ac_cv_have_decl_][$1] = yes; then if test $[ac_cv_have_decl_][$1] = yes; then
[gl_cv_onwards_func_][$1]='future OS version' [gl_cv_onwards_func_][$1]='future OS version'
else else
[gl_cv_onwards_func_][$1]=no [gl_cv_onwards_func_][$1]=no
fi fi
[ac_cv_have_decl_][$1]="$[ac_cv_have_decl_][$1][_saved]"
unset [ac_cv_have_decl_][$1][_saved]
fi fi
else else
AC_CHECK_FUNC([$1]) AC_CHECK_FUNC([$1])

View file

@ -547,12 +547,7 @@ AC_DEFUN([gl_INIT],
GL_STDC_LEADING_ZEROS=1 GL_STDC_LEADING_ZEROS=1
AC_REQUIRE([gl_STDBIT_H]) AC_REQUIRE([gl_STDBIT_H])
GL_STDC_TRAILING_ZEROS=1 GL_STDC_TRAILING_ZEROS=1
AC_CHECK_HEADERS_ONCE([stdckdint.h]) gl_STDCKDINT_H
if test $ac_cv_header_stdckdint_h = yes; then
GL_GENERATE_STDCKDINT_H=false
else
GL_GENERATE_STDCKDINT_H=true
fi
gl_CONDITIONAL_HEADER([stdckdint.h]) gl_CONDITIONAL_HEADER([stdckdint.h])
AC_PROG_MKDIR_P AC_PROG_MKDIR_P
gl_STDDEF_H gl_STDDEF_H
@ -1558,6 +1553,7 @@ AC_DEFUN([gl_FILE_LIST], [
m4/std-gnu11.m4 m4/std-gnu11.m4
m4/stdalign.m4 m4/stdalign.m4
m4/stdbit_h.m4 m4/stdbit_h.m4
m4/stdckdint_h.m4
m4/stddef_h.m4 m4/stddef_h.m4
m4/stdint.m4 m4/stdint.m4
m4/stdio_h.m4 m4/stdio_h.m4

View file

@ -1,5 +1,5 @@
# libgmp.m4 # libgmp.m4
# serial 8 # serial 9
# Configure the GMP library or a replacement. # Configure the GMP library or a replacement.
dnl Copyright 2020-2025 Free Software Foundation, Inc. dnl Copyright 2020-2025 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation dnl This file is free software; the Free Software Foundation
@ -34,7 +34,11 @@ AC_DEFUN([gl_LIBGMP],
# include <gmp.h> # include <gmp.h>
#else #else
# include <gmp/gmp.h> # include <gmp/gmp.h>
#endif], #endif
#if ! (6 < __GNU_MP_VERSION + (2 <= __GNU_MP_VERSION_MINOR))
# error "GMP < 6.2.0, so mpz_probab_prime_p lacks Baillie-PSW"
#endif
],
[static const mp_limb_t x[2] = { 0x73, 0x55 }; [static const mp_limb_t x[2] = { 0x73, 0x55 };
mpz_t tmp; mpz_t tmp;
mpz_roinit_n (tmp, x, 2); mpz_roinit_n (tmp, x, 2);

View file

@ -1,5 +1,5 @@
# open.m4 # open.m4
# serial 16 # serial 17
dnl Copyright (C) 2007-2025 Free Software Foundation, Inc. dnl Copyright (C) 2007-2025 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it, dnl gives unlimited permission to copy and/or distribute it,
@ -10,6 +10,9 @@ AC_DEFUN([gl_FUNC_OPEN],
[ [
AC_REQUIRE([AC_CANONICAL_HOST]) AC_REQUIRE([AC_CANONICAL_HOST])
AC_REQUIRE([gl_PREPROC_O_CLOEXEC]) AC_REQUIRE([gl_PREPROC_O_CLOEXEC])
AC_REQUIRE([gl_FCNTL_O_FLAGS])
AS_CASE([$gl_cv_header_working_fcntl_h],
[*O_DIRECTORY* | *no], [REPLACE_OPEN=1])
case "$host_os" in case "$host_os" in
mingw* | windows* | pw*) mingw* | windows* | pw*)
REPLACE_OPEN=1 REPLACE_OPEN=1

136
m4/stdckdint_h.m4 Normal file
View file

@ -0,0 +1,136 @@
# stdckdint_h.m4
# serial 1
dnl Copyright 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.
dnl Written by Collin Funk.
AC_DEFUN_ONCE([gl_STDCKDINT_H],
[
gl_CHECK_NEXT_HEADERS([stdckdint.h])
if test $ac_cv_header_stdckdint_h = yes; then
HAVE_STDCKDINT_H=1
else
HAVE_STDCKDINT_H=0
fi
AC_SUBST([HAVE_STDCKDINT_H])
if test $HAVE_STDCKDINT_H = 1; then
AC_CACHE_CHECK([whether stdckdint.h can be included in C],
[gl_cv_header_c_stdckdint_h],
[AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[#include <stdckdint.h>
]])],
[gl_cv_header_c_stdckdint_h=yes],
[gl_cv_header_c_stdckdint_h=no])])
if test $gl_cv_header_c_stdckdint_h = yes; then
HAVE_C_STDCKDINT_H=1
AC_CACHE_CHECK([checking for an ISO C23 compliant stdckdint.h in C],
[gl_cv_header_c_stdckdint_h_works],
[AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[#include <stdckdint.h>
]],
[[int r;
int a = 1;
int b = 1;
return !!(ckd_add (&r, a, b) || ckd_sub (&r, a, b)
|| ckd_mul (&r, a, b));
]])],
[gl_cv_header_c_stdckdint_h_works=yes],
[gl_cv_header_c_stdckdint_h_works=no])])
if test $gl_cv_header_c_stdckdint_h_works = yes; then
HAVE_WORKING_C_STDCKDINT_H=1
else
HAVE_WORKING_C_STDCKDINT_H=0
fi
else
HAVE_C_STDCKDINT_H=0
HAVE_WORKING_C_STDCKDINT_H=0
fi
if test "$CXX" != no; then
AC_CACHE_CHECK([whether stdckdint.h can be included in C++],
[gl_cv_header_cxx_stdckdint_h],
[dnl We can't use AC_LANG_PUSH([C++]) and AC_LANG_POP([C++]) here, due to
dnl an autoconf bug <https://savannah.gnu.org/support/?110294>.
cat > conftest.cpp <<\EOF
#include <stdckdint.h>
EOF
gl_command="$CXX $CXXFLAGS $CPPFLAGS -c conftest.cpp"
if AC_TRY_EVAL([gl_command]); then
gl_cv_header_cxx_stdckdint_h=yes
else
gl_cv_header_cxx_stdckdint_h=no
fi
rm -fr conftest*
])
if test $gl_cv_header_cxx_stdckdint_h = yes; then
HAVE_CXX_STDCKDINT_H=1
AC_CACHE_CHECK([checking for an ISO C++26 compliant stdckdint.h in C++],
[gl_cv_header_cxx_stdckdint_h_works],
[dnl We can't use AC_LANG_PUSH([C++]) and AC_LANG_POP([C++]) here, due to
dnl an autoconf bug <https://savannah.gnu.org/support/?110294>.
cat > conftest.cpp <<\EOF
#include <stdckdint.h>
int
main (void)
{
int r;
int a = 1;
int b = 1;
return !!(ckd_add (&r, a, b) || ckd_sub (&r, a, b) || ckd_mul (&r, a, b));
}
EOF
gl_command="$CXX $CXXFLAGS $CPPFLAGS -c conftest.cpp"
if AC_TRY_EVAL([gl_command]); then
gl_cv_header_cxx_stdckdint_h_works=yes
else
gl_cv_header_cxx_stdckdint_h_works=no
fi
rm -fr conftest*
])
if test $gl_cv_header_cxx_stdckdint_h_works = yes; then
HAVE_WORKING_CXX_STDCKDINT_H=1
else
HAVE_WORKING_CXX_STDCKDINT_H=0
fi
else
HAVE_CXX_STDCKDINT_H=0
HAVE_WORKING_CXX_STDCKDINT_H=0
fi
fi
else
HAVE_C_STDCKDINT_H=0
HAVE_WORKING_C_STDCKDINT_H=0
HAVE_CXX_STDCKDINT_H=0
HAVE_WORKING_CXX_STDCKDINT_H=0
fi
AC_SUBST([HAVE_C_STDCKDINT_H])
AC_SUBST([HAVE_WORKING_C_STDCKDINT_H])
AC_SUBST([HAVE_CXX_STDCKDINT_H])
AC_SUBST([HAVE_WORKING_CXX_STDCKDINT_H])
if test "$CXX" != no; then
dnl We might need the header for C or C++.
if test $HAVE_C_STDCKDINT_H = 1 \
&& test $HAVE_WORKING_C_STDCKDINT_H = 1 \
&& test $HAVE_CXX_STDCKDINT_H = 1 \
&& test $HAVE_WORKING_CXX_STDCKDINT_H = 1; then
GL_GENERATE_STDCKDINT_H=false
else
GL_GENERATE_STDCKDINT_H=true
fi
else
dnl We don't care about C++ here.
if test $HAVE_C_STDCKDINT_H = 1 \
&& test $HAVE_WORKING_C_STDCKDINT_H = 1; then
GL_GENERATE_STDCKDINT_H=false
else
GL_GENERATE_STDCKDINT_H=true
fi
fi
])

View file

@ -1,5 +1,5 @@
# stddef_h.m4 # stddef_h.m4
# serial 21 # serial 23
dnl Copyright (C) 2009-2025 Free Software Foundation, Inc. dnl Copyright (C) 2009-2025 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it, dnl gives unlimited permission to copy and/or distribute it,
@ -64,20 +64,26 @@ AC_DEFUN_ONCE([gl_STDDEF_H],
GL_GENERATE_STDDEF_H=true GL_GENERATE_STDDEF_H=true
fi fi
AC_CACHE_CHECK([for unreachable], AC_CACHE_CHECK([for unreachable in C],
[gl_cv_func_unreachable], [gl_cv_c_func_unreachable],
[AC_LINK_IFELSE( [AC_LINK_IFELSE(
[AC_LANG_PROGRAM( [AC_LANG_PROGRAM(
[[#include <stddef.h> [[#include <stddef.h>
]], ]],
[[unreachable (); [[unreachable ();
]])], ]])],
[gl_cv_func_unreachable=yes], [gl_cv_c_func_unreachable=yes],
[gl_cv_func_unreachable=no]) [gl_cv_c_func_unreachable=no])
]) ])
if test $gl_cv_func_unreachable = no; then if test $gl_cv_c_func_unreachable = no; then
GL_GENERATE_STDDEF_H=true GL_GENERATE_STDDEF_H=true
HAVE_C_UNREACHABLE=0
else
HAVE_C_UNREACHABLE=1
fi fi
AC_SUBST([HAVE_C_UNREACHABLE])
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/bugzilla/show_bug.cgi?id=114869
AC_CACHE_CHECK([whether nullptr_t needs <stddef.h>], AC_CACHE_CHECK([whether nullptr_t needs <stddef.h>],