aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorPaul Eggert2024-12-17 14:02:41 -0800
committerPaul Eggert2024-12-17 14:13:54 -0800
commitb1e5f6d6ef8432a9cce0664238de72d387730bd1 (patch)
tree7eb50047793367bf8f2483e28fb716cfc4334c13 /lib
parent22806c65f4f8d68547d33997d017039763b4bf6a (diff)
downloademacs-b1e5f6d6ef8432a9cce0664238de72d387730bd1.tar.gz
emacs-b1e5f6d6ef8432a9cce0664238de72d387730bd1.zip
Update from Gnulib by running admin/merge-gnulib
* admin/merge-gnulib (AVOIDED_MODULES): Avoid gnulib-i18n. * lib/stdlib.c, m4/selinux-selinux-h.m4: New files, taken from Gnulib.
Diffstat (limited to 'lib')
-rw-r--r--lib/acl-internal.c6
-rw-r--r--lib/acl.h59
-rw-r--r--lib/dirent.in.h95
-rw-r--r--lib/file-has-acl.c583
-rw-r--r--lib/getopt-cdefs.in.h10
-rw-r--r--lib/getopt-pfx-core.h7
-rw-r--r--lib/getopt.c4
-rw-r--r--lib/gettext.h32
-rw-r--r--lib/gnulib.mk.in50
-rw-r--r--lib/malloc.c11
-rw-r--r--lib/md5-stream.c3
-rw-r--r--lib/md5.h8
-rw-r--r--lib/memset_explicit.c5
-rw-r--r--lib/mini-gmp.c95
-rw-r--r--lib/mini-gmp.h1
-rw-r--r--lib/mktime-internal.h9
-rw-r--r--lib/mktime.c113
-rw-r--r--lib/nproc.c41
-rw-r--r--lib/pipe2.c2
-rw-r--r--lib/realloc.c71
-rw-r--r--lib/regex.h18
-rw-r--r--lib/regex_internal.c3
-rw-r--r--lib/regex_internal.h10
-rw-r--r--lib/stdio-impl.h2
-rw-r--r--lib/stdlib.c21
-rw-r--r--lib/stdlib.in.h43
-rw-r--r--lib/timegm.c3
-rw-r--r--lib/unistd.in.h5
-rw-r--r--lib/utimens.c68
-rw-r--r--lib/utimens.h10
30 files changed, 949 insertions, 439 deletions
diff --git a/lib/acl-internal.c b/lib/acl-internal.c
index ae5398306af..b729126118a 100644
--- a/lib/acl-internal.c
+++ b/lib/acl-internal.c
@@ -19,10 +19,12 @@
19 19
20#include <config.h> 20#include <config.h>
21 21
22#include "acl.h" 22/* Specification. */
23 23#define ACL_INTERNAL_INLINE _GL_EXTERN_INLINE
24#include "acl-internal.h" 24#include "acl-internal.h"
25 25
26#include "acl.h"
27
26#if defined __CYGWIN__ 28#if defined __CYGWIN__
27# include <sys/types.h> 29# include <sys/types.h>
28# include <grp.h> 30# include <grp.h>
diff --git a/lib/acl.h b/lib/acl.h
index 475231c2db7..1d52345c668 100644
--- a/lib/acl.h
+++ b/lib/acl.h
@@ -32,9 +32,68 @@
32extern "C" { 32extern "C" {
33#endif 33#endif
34 34
35/* file_has_acl flags guaranteed to not collide with any <dirent.h>
36 DT_* or _GL_DT_* value. */
37enum
38 {
39 /* Get scontext information as well. */
40 ACL_GET_SCONTEXT = 0x10000,
41
42 /* Follow symlinks. */
43 ACL_SYMLINK_FOLLOW = 0x20000,
44 };
45
46/* Information about an ACL. */
47struct aclinfo
48{
49 /* If 'size' is nonnegative, a buffer holding the concatenation
50 of extended attribute names, each terminated by NUL
51 (either u.__gl_acl_ch, or heap-allocated). */
52 char *buf;
53
54 /* The number of useful bytes at the start of buf, counting trailing NULs.
55 If negative, there was an error in getting the ACL info,
56 and u.err is the corresponding errno. */
57 ssize_t size;
58
59 /* Security context string. Do not modify its contents. */
60 char *scontext;
61 /* Security context errno value. It is zero if there was no
62 error getting the security context. When nonzero, scontext is "?". */
63 int scontext_err;
64
65 union
66 {
67 /* An errno value, when there was an error getting the ACL info. */
68 int err;
69
70 /* A small array of char, big enough for most listxattr results.
71 The size is somewhat arbitrary; it equals the max length of a
72 trivial NFSv4 ACL (a size used by file-has-acl.c in 2023-2024
73 but no longer relevant now), and a different value might be
74 better once experience is gained. For internal use only. */
75 char __gl_acl_ch[152];
76 } u;
77};
35 78
36bool acl_errno_valid (int) _GL_ATTRIBUTE_CONST; 79bool acl_errno_valid (int) _GL_ATTRIBUTE_CONST;
37int file_has_acl (char const *, struct stat const *); 80int file_has_acl (char const *, struct stat const *);
81int file_has_aclinfo (char const *restrict, struct aclinfo *restrict, int);
82
83#if HAVE_LINUX_XATTR_H && HAVE_LISTXATTR
84bool aclinfo_has_xattr (struct aclinfo const *, char const *)
85 _GL_ATTRIBUTE_PURE;
86void aclinfo_free (struct aclinfo *);
87#else
88# define aclinfo_has_xattr(ai, xattr) false
89# define aclinfo_free(ai) ((void) 0)
90#endif
91#if (HAVE_LINUX_XATTR_H && HAVE_LISTXATTR \
92 && (HAVE_SMACK || USE_SELINUX_SELINUX_H))
93void aclinfo_scontext_free (char *);
94#else
95# define aclinfo_scontext_free(s) ((void) 0)
96#endif
38 97
39int qset_acl (char const *, int, mode_t); 98int qset_acl (char const *, int, mode_t);
40int xset_acl (char const *, int, mode_t); 99int xset_acl (char const *, int, mode_t);
diff --git a/lib/dirent.in.h b/lib/dirent.in.h
index 7ba8fc64d89..a0ac39b4968 100644
--- a/lib/dirent.in.h
+++ b/lib/dirent.in.h
@@ -46,20 +46,95 @@ struct dirent
46 char d_type; 46 char d_type;
47 char d_name[1]; 47 char d_name[1];
48}; 48};
49/* Possible values for 'd_type'. */
50# define DT_UNKNOWN 0
51# define DT_FIFO 1 /* FIFO */
52# define DT_CHR 2 /* character device */
53# define DT_DIR 4 /* directory */
54# define DT_BLK 6 /* block device */
55# define DT_REG 8 /* regular file */
56# define DT_LNK 10 /* symbolic link */
57# define DT_SOCK 12 /* socket */
58# define DT_WHT 14 /* whiteout */
59# define GNULIB_defined_struct_dirent 1 49# define GNULIB_defined_struct_dirent 1
60# endif 50# endif
61#endif 51#endif
62 52
53/* 'd_type' macros specified in GNU, i.e., POSIX.1-2024 plus DT_WHT,
54 but not (yet) DT_MQ, DT_SEM, DT_SHM, DT_TMO.
55 These macros can be useful even on platforms that do not support
56 d_type or the corresponding file types.
57 The values of these macros are all in the 'unsigned char' range.
58 Default to the Linux values which are also popular elsewhere,
59 and check that all macros have distinct values. */
60#ifndef DT_UNKNOWN
61# define DT_UNKNOWN 0
62#endif
63#ifndef DT_FIFO
64# define DT_FIFO 1 /* FIFO */
65#endif
66#ifndef DT_CHR
67# define DT_CHR 2 /* character device */
68#endif
69#ifndef DT_DIR
70# define DT_DIR 4 /* directory */
71#endif
72#ifndef DT_BLK
73# define DT_BLK 6 /* block device */
74#endif
75#ifndef DT_REG
76# define DT_REG 8 /* regular file */
77#endif
78#ifndef DT_LNK
79# define DT_LNK 10 /* symbolic link */
80#endif
81#ifndef DT_SOCK
82# define DT_SOCK 12 /* socket */
83#endif
84#ifndef DT_WHT
85# define DT_WHT 14 /* whiteout */
86#endif
87static_assert (DT_UNKNOWN != DT_FIFO && DT_UNKNOWN != DT_CHR
88 && DT_UNKNOWN != DT_BLK && DT_UNKNOWN != DT_REG
89 && DT_UNKNOWN != DT_LNK && DT_UNKNOWN != DT_SOCK
90 && DT_UNKNOWN != DT_WHT
91 && DT_FIFO != DT_CHR && DT_FIFO != DT_BLK && DT_FIFO != DT_REG
92 && DT_FIFO != DT_LNK && DT_FIFO != DT_SOCK && DT_FIFO != DT_WHT
93 && DT_CHR != DT_BLK && DT_CHR != DT_REG && DT_CHR != DT_LNK
94 && DT_CHR != DT_SOCK && DT_CHR != DT_WHT
95 && DT_BLK != DT_REG && DT_BLK != DT_LNK && DT_BLK != DT_SOCK
96 && DT_BLK != DT_WHT
97 && DT_REG != DT_LNK && DT_REG != DT_SOCK && DT_REG != DT_WHT
98 && DT_LNK != DT_SOCK && DT_LNK != DT_WHT
99 && DT_SOCK != DT_WHT);
100
101/* Other optional information about a directory entry. */
102#define _GL_DT_NOTDIR 0x100 /* Not a directory */
103
104/* Conversion between S_IF* and DT_* file types. */
105#if ! (defined IFTODT && defined DTTOIF)
106# include <sys/stat.h>
107# ifdef S_ISWHT
108# define _GL_DIRENT_S_ISWHT(mode) S_ISWHT(mode)
109# else
110# define _GL_DIRENT_S_ISWHT(mode) 0
111# endif
112# ifdef S_IFWHT
113# define _GL_DIRENT_S_IFWHT S_IFWHT
114# else
115# define _GL_DIRENT_S_IFWHT (DT_WHT << 12) /* just a guess */
116# endif
117#endif
118/* Conversion from a 'stat' mode to a DT_* value. */
119#ifndef IFTODT
120# define IFTODT(mode) \
121 (S_ISREG (mode) ? DT_REG : S_ISDIR (mode) ? DT_DIR \
122 : S_ISLNK (mode) ? DT_LNK : S_ISBLK (mode) ? DT_BLK \
123 : S_ISCHR (mode) ? DT_CHR : S_ISFIFO (mode) ? DT_FIFO \
124 : S_ISSOCK (mode) ? DT_SOCK \
125 : _GL_DIRENT_S_ISWHT (mode) ? DT_WHT : DT_UNKNOWN)
126#endif
127/* Conversion from a DT_* value to a 'stat' mode. */
128#ifndef DTTOIF
129# define DTTOIF(dirtype) \
130 ((dirtype) == DT_REG ? S_IFREG : (dirtype) == DT_DIR ? S_IFDIR \
131 : (dirtype) == DT_LNK ? S_IFLNK : (dirtype) == DT_BLK ? S_IFBLK \
132 : (dirtype) == DT_CHR ? S_IFCHR : dirtype == DT_FIFO ? S_IFIFO \
133 : (dirtype) == DT_SOCK ? S_IFSOCK \
134 : (dirtype) == DT_WHT ? _GL_DIRENT_S_IFWHT \
135 : (dirtype) << 12 /* just a guess */)
136#endif
137
63#if !@DIR_HAS_FD_MEMBER@ 138#if !@DIR_HAS_FD_MEMBER@
64# if !GNULIB_defined_DIR 139# if !GNULIB_defined_DIR
65/* struct gl_directory is a type with a field 'int fd_to_close'. 140/* struct gl_directory is a type with a field 'int fd_to_close'.
diff --git a/lib/file-has-acl.c b/lib/file-has-acl.c
index 06759a4948c..7c29f201589 100644
--- a/lib/file-has-acl.c
+++ b/lib/file-has-acl.c
@@ -27,12 +27,30 @@
27 27
28#include "acl.h" 28#include "acl.h"
29 29
30#include <dirent.h>
31#include <limits.h>
32
30#include "acl-internal.h" 33#include "acl-internal.h"
31#include "attribute.h" 34#include "attribute.h"
32#include "minmax.h" 35#include "minmax.h"
33 36
34#if USE_ACL && HAVE_LINUX_XATTR_H && HAVE_LISTXATTR 37/* Check the assumption that UCHAR_MAX < INT_MAX. */
38static_assert (ACL_SYMLINK_FOLLOW & ~ (unsigned char) -1);
39
40static char const UNKNOWN_SECURITY_CONTEXT[] = "?";
41
42#if HAVE_LINUX_XATTR_H && HAVE_LISTXATTR
43# define USE_LINUX_XATTR true
44#else
45# define USE_LINUX_XATTR false
46#endif
47
48#if USE_LINUX_XATTR
49# if USE_SELINUX_SELINUX_H
50# include <selinux/selinux.h>
51# endif
35# include <stdckdint.h> 52# include <stdckdint.h>
53# include <stdint.h>
36# include <string.h> 54# include <string.h>
37# include <arpa/inet.h> 55# include <arpa/inet.h>
38# include <sys/xattr.h> 56# include <sys/xattr.h>
@@ -47,26 +65,186 @@
47# define XATTR_NAME_POSIX_ACL_DEFAULT "system.posix_acl_default" 65# define XATTR_NAME_POSIX_ACL_DEFAULT "system.posix_acl_default"
48# endif 66# endif
49 67
68# ifdef HAVE_SMACK
69# include <sys/smack.h>
70# else
71static char const *
72smack_smackfs_path (void)
73{
74 return NULL;
75}
76static ssize_t
77smack_new_label_from_path (MAYBE_UNUSED const char *path,
78 MAYBE_UNUSED const char *xattr,
79 MAYBE_UNUSED int follow, MAYBE_UNUSED char **label)
80{
81 return -1;
82}
83# endif
84static bool
85is_smack_enabled (void)
86{
87 return !!smack_smackfs_path ();
88}
89
50enum { 90enum {
51 /* ACE4_ACCESS_ALLOWED_ACE_TYPE = 0x00000000, */ 91 /* ACE4_ACCESS_ALLOWED_ACE_TYPE = 0x00000000, */
52 ACE4_ACCESS_DENIED_ACE_TYPE = 0x00000001, 92 ACE4_ACCESS_DENIED_ACE_TYPE = 0x00000001,
53 ACE4_IDENTIFIER_GROUP = 0x00000040 93 ACE4_IDENTIFIER_GROUP = 0x00000040
54}; 94};
55 95
56/* Return true if ATTR is in the set represented by the NUL-terminated 96/* Does AI's xattr set contain XATTR? */
57 strings in LISTBUF, which is of size LISTSIZE. */
58 97
59ATTRIBUTE_PURE static bool 98bool
60have_xattr (char const *attr, char const *listbuf, ssize_t listsize) 99aclinfo_has_xattr (struct aclinfo const *ai, char const *xattr)
61{ 100{
62 char const *blim = listbuf + listsize; 101 if (0 < ai->size)
63 for (char const *b = listbuf; b < blim; b += strlen (b) + 1) 102 {
64 for (char const *a = attr; *a == *b; a++, b++) 103 char const *blim = ai->buf + ai->size;
65 if (!*a) 104 for (char const *b = ai->buf; b < blim; b += strlen (b) + 1)
66 return true; 105 for (char const *a = xattr; *a == *b; a++, b++)
106 if (!*a)
107 return true;
108 }
67 return false; 109 return false;
68} 110}
69 111
112/* Get attributes of the file NAME into AI, if USE_ACL.
113 If FLAGS & ACL_GET_SCONTEXT, also get security context.
114 If FLAGS & ACL_SYMLINK_FOLLOW, follow symbolic links. */
115static void
116get_aclinfo (char const *name, struct aclinfo *ai, int flags)
117{
118 int scontext_err = ENOTSUP;
119 ai->buf = ai->u.__gl_acl_ch;
120 ssize_t acl_alloc = sizeof ai->u.__gl_acl_ch;
121
122 if (! (USE_ACL || flags & ACL_GET_SCONTEXT))
123 ai->size = 0;
124 else
125 {
126 ssize_t (*lsxattr) (char const *, char *, size_t)
127 = (flags & ACL_SYMLINK_FOLLOW ? listxattr : llistxattr);
128 while (true)
129 {
130 ai->size = lsxattr (name, ai->buf, acl_alloc);
131 if (0 < ai->size)
132 break;
133 ai->u.err = ai->size < 0 ? errno : 0;
134 if (! (ai->size < 0 && ai->u.err == ERANGE && acl_alloc < SSIZE_MAX))
135 break;
136
137 /* The buffer was too small. Find how large it should have been. */
138 ssize_t size = lsxattr (name, NULL, 0);
139 if (size <= 0)
140 {
141 ai->size = size;
142 ai->u.err = size < 0 ? errno : 0;
143 break;
144 }
145
146 /* Grow allocation to at least 'size'. Grow it by a nontrivial
147 amount, to defend against denial of service by an adversary
148 that fiddles with ACLs. */
149 if (ai->buf != ai->u.__gl_acl_ch)
150 {
151 free (ai->buf);
152 ai->buf = ai->u.__gl_acl_ch;
153 }
154 if (ckd_add (&acl_alloc, acl_alloc, acl_alloc >> 1))
155 acl_alloc = SSIZE_MAX;
156 if (acl_alloc < size)
157 acl_alloc = size;
158 if (SIZE_MAX < acl_alloc)
159 {
160 ai->u.err = ENOMEM;
161 break;
162 }
163 char *newbuf = malloc (acl_alloc);
164 if (!newbuf)
165 {
166 ai->u.err = errno;
167 break;
168 }
169 ai->buf = newbuf;
170 }
171 }
172
173 if (0 < ai->size && flags & ACL_GET_SCONTEXT)
174 {
175 if (is_smack_enabled ())
176 {
177 if (aclinfo_has_xattr (ai, XATTR_NAME_SMACK))
178 {
179 ssize_t r = smack_new_label_from_path (name, "security.SMACK64",
180 flags & ACL_SYMLINK_FOLLOW,
181 &ai->scontext);
182 scontext_err = r < 0 ? errno : 0;
183 }
184 }
185 else
186 {
187# if USE_SELINUX_SELINUX_H
188 if (aclinfo_has_xattr (ai, XATTR_NAME_SELINUX))
189 {
190 ssize_t r =
191 ((flags & ACL_SYMLINK_FOLLOW ? getfilecon : lgetfilecon)
192 (name, &ai->scontext));
193 scontext_err = r < 0 ? errno : 0;
194# ifndef SE_SELINUX_INLINE
195 /* Gnulib's selinux-h module is not in use, so getfilecon and
196 lgetfilecon can misbehave, be it via an old version of
197 libselinux where these would return 0 and set the result
198 context to NULL, or via a modern kernel+lib operating on a
199 file from a disk whose attributes were set by a kernel from
200 around 2006. In that latter case, the functions return a
201 length of 10 for the "unlabeled" context. Map both failures
202 to a return value of -1, and set errno to ENOTSUP in the
203 first case, and ENODATA in the latter. */
204 if (r == 0)
205 scontext_err = ENOTSUP;
206 if (r == 10 && memcmp (ai->scontext, "unlabeled", 10) == 0)
207 {
208 freecon (ai->scontext);
209 scontext_err = ENODATA;
210 }
211# endif
212 }
213# endif
214 }
215 }
216 ai->scontext_err = scontext_err;
217 if (scontext_err)
218 ai->scontext = (char *) UNKNOWN_SECURITY_CONTEXT;
219}
220
221# ifndef aclinfo_scontext_free
222/* Free the pointer that file_has_aclinfo put into scontext.
223 However, do nothing if the argument is a null pointer;
224 This lets the caller replace the scontext member with a null pointer if it
225 is willing to own the member and call this function later. */
226void
227aclinfo_scontext_free (char *scontext)
228{
229 if (scontext != UNKNOWN_SECURITY_CONTEXT)
230 {
231 if (is_smack_enabled ())
232 free (scontext);
233 else if (scontext)
234 freecon (scontext);
235 }
236}
237# endif
238
239/* Free AI's heap storage. */
240void
241aclinfo_free (struct aclinfo *ai)
242{
243 if (ai->buf != ai->u.__gl_acl_ch)
244 free (ai->buf);
245 aclinfo_scontext_free (ai->scontext);
246}
247
70/* Return 1 if given ACL in XDR format is non-trivial, 0 if it is trivial. 248/* Return 1 if given ACL in XDR format is non-trivial, 0 if it is trivial.
71 -1 upon failure to determine it. Possibly change errno. Assume that 249 -1 upon failure to determine it. Possibly change errno. Assume that
72 the ACL is valid, except avoid undefined behavior even if invalid. 250 the ACL is valid, except avoid undefined behavior even if invalid.
@@ -150,196 +328,183 @@ acl_nfs4_nontrivial (uint32_t *xattr, ssize_t nbytes)
150 0 if ACLs are not supported, or if NAME has no or only a base ACL, 328 0 if ACLs are not supported, or if NAME has no or only a base ACL,
151 and -1 (setting errno) on error. Note callers can determine 329 and -1 (setting errno) on error. Note callers can determine
152 if ACLs are not supported as errno is set in that case also. 330 if ACLs are not supported as errno is set in that case also.
153 SB must be set to the stat buffer of NAME, 331 Set *AI to ACL info regardless of return value.
154 obtained through stat() or lstat(). */ 332 FLAGS should be a <dirent.h> d_type value, optionally ORed with
155 333 - _GL_DT_NOTDIR if it is known that NAME is not a directory,
334 - ACL_GET_SCONTEXT to retrieve security context and return 1 if present,
335 - ACL_SYMLINK_FOLLOW to follow the link if NAME is a symbolic link;
336 otherwise do not follow them if possible.
337 If the d_type value is not known, use DT_UNKNOWN though this may be less
338 efficient. */
156int 339int
157file_has_acl (char const *name, struct stat const *sb) 340file_has_aclinfo (MAYBE_UNUSED char const *restrict name,
341 struct aclinfo *restrict ai, int flags)
158{ 342{
159#if USE_ACL 343 MAYBE_UNUSED unsigned char d_type = flags & UCHAR_MAX;
160 if (! S_ISLNK (sb->st_mode)) 344
345#if USE_LINUX_XATTR
346 int initial_errno = errno;
347 get_aclinfo (name, ai, flags);
348
349 if (ai->size <= 0)
161 { 350 {
351 errno = ai->size < 0 ? ai->u.err : initial_errno;
352 return ai->size;
353 }
162 354
163# if HAVE_LINUX_XATTR_H && HAVE_LISTXATTR 355 /* In Fedora 39, a file can have both NFSv4 and POSIX ACLs,
164 int initial_errno = errno; 356 but if it has an NFSv4 ACL that's the one that matters.
165 357 In earlier Fedora the two types of ACLs were mutually exclusive.
166 /* The max length of a trivial NFSv4 ACL is 6 words for owner, 358 Attempt to work correctly on both kinds of systems. */
167 6 for group, 7 for everyone, all times 2 because there are 359
168 both allow and deny ACEs. There are 6 words for owner 360 if (!aclinfo_has_xattr (ai, XATTR_NAME_NFSV4_ACL))
169 because of type, flag, mask, wholen, "OWNER@"+pad and 361 return
170 similarly for group; everyone is another word to hold 362 (aclinfo_has_xattr (ai, XATTR_NAME_POSIX_ACL_ACCESS)
171 "EVERYONE@". */ 363 || ((d_type == DT_DIR || d_type == DT_UNKNOWN)
172 typedef uint32_t trivial_NFSv4_xattr_buf[2 * (6 + 6 + 7)]; 364 && aclinfo_has_xattr (ai, XATTR_NAME_POSIX_ACL_DEFAULT)));
173 365
174 /* A buffer large enough to hold any trivial NFSv4 ACL, 366 /* A buffer large enough to hold any trivial NFSv4 ACL.
175 and also useful as a small array of char. */ 367 The max length of a trivial NFSv4 ACL is 6 words for owner,
176 union { 368 6 for group, 7 for everyone, all times 2 because there are both
177 trivial_NFSv4_xattr_buf xattr; 369 allow and deny ACEs. There are 6 words for owner because of
178 char ch[sizeof (trivial_NFSv4_xattr_buf)]; 370 type, flag, mask, wholen, "OWNER@"+pad and similarly for group;
179 } stackbuf; 371 everyone is another word to hold "EVERYONE@". */
180 372 uint32_t buf[2 * (6 + 6 + 7)];
181 char *listbuf = stackbuf.ch; 373
182 ssize_t listbufsize = sizeof stackbuf.ch; 374 int ret = ((flags & ACL_SYMLINK_FOLLOW ? getxattr : lgetxattr)
183 char *heapbuf = NULL; 375 (name, XATTR_NAME_NFSV4_ACL, buf, sizeof buf));
184 ssize_t listsize; 376 if (ret < 0)
185 377 switch (errno)
186 /* Use listxattr first, as this means just one syscall in the 378 {
187 typical case where the file lacks an ACL. Try stackbuf 379 case ENODATA: return 0;
188 first, falling back on malloc if stackbuf is too small. */ 380 case ERANGE : return 1; /* ACL must be nontrivial. */
189 while ((listsize = listxattr (name, listbuf, listbufsize)) < 0 381 default: return - acl_errno_valid (errno);
190 && errno == ERANGE) 382 }
191 {
192 free (heapbuf);
193 ssize_t newsize = listxattr (name, NULL, 0);
194 if (newsize <= 0)
195 return newsize;
196
197 /* Grow LISTBUFSIZE to at least NEWSIZE. Grow it by a
198 nontrivial amount too, to defend against denial of
199 service by an adversary that fiddles with ACLs. */
200 bool overflow = ckd_add (&listbufsize, listbufsize, listbufsize >> 1);
201 listbufsize = MAX (listbufsize, newsize);
202 if (overflow || SIZE_MAX < listbufsize)
203 {
204 errno = ENOMEM;
205 return -1;
206 }
207 383
208 listbuf = heapbuf = malloc (listbufsize); 384 /* It looks like a trivial ACL, but investigate further. */
209 if (!listbuf) 385 ret = acl_nfs4_nontrivial (buf, ret);
210 return -1; 386 errno = ret < 0 ? EINVAL : initial_errno;
211 } 387 return ret;
388
389#else /* !USE_LINUX_XATTR */
390
391 ai->buf = ai->u.__gl_acl_ch;
392 ai->size = -1;
393 ai->u.err = ENOTSUP;
394 ai->scontext = (char *) UNKNOWN_SECURITY_CONTEXT;
395 ai->scontext_err = ENOTSUP;
396
397# if USE_ACL
398# if HAVE_ACL_GET_FILE
399
400 {
401 /* POSIX 1003.1e (draft 17 -- abandoned) specific version. */
402 /* Linux, FreeBSD, NetBSD >= 10, Mac OS X, IRIX, Tru64, Cygwin >= 2.5 */
403 int ret;
404
405# if HAVE_ACL_EXTENDED_FILE /* Linux */
406 /* On Linux, acl_extended_file is an optimized function: It only
407 makes two calls to getxattr(), one for ACL_TYPE_ACCESS, one for
408 ACL_TYPE_DEFAULT. */
409 ret = ((flags & ACL_SYMLINK_FOLLOW
410 ? acl_extended_file
411 : acl_extended_file_nofollow)
412 (name));
413# elif HAVE_ACL_TYPE_EXTENDED /* Mac OS X */
414 /* On Mac OS X, acl_get_file (name, ACL_TYPE_ACCESS)
415 and acl_get_file (name, ACL_TYPE_DEFAULT)
416 always return NULL / EINVAL. There is no point in making
417 these two useless calls. The real ACL is retrieved through
418 acl_get_file (name, ACL_TYPE_EXTENDED). */
419 acl_t acl = ((flags & ACL_SYMLINK_FOLLOW
420 ? acl_get_file
421 : acl_get_link_np)
422 (name, ACL_TYPE_EXTENDED));
423 if (acl)
424 {
425 ret = acl_extended_nontrivial (acl);
426 acl_free (acl);
427 }
428 else
429 ret = -1;
430# else /* FreeBSD, NetBSD >= 10, IRIX, Tru64, Cygwin >= 2.5 */
431 acl_t (*acl_get_file_or_link) (char const *, acl_type_t) = acl_get_file;
432# if HAVE_ACL_GET_LINK_NP /* FreeBSD, NetBSD >= 10 */
433 if (! (flags & ACL_SYMLINK_FOLLOW))
434 acl_get_file_or_link = acl_get_link_np;
435# endif
212 436
213 /* In Fedora 39, a file can have both NFSv4 and POSIX ACLs, 437 acl_t acl = acl_get_file_or_link (name, ACL_TYPE_ACCESS);
214 but if it has an NFSv4 ACL that's the one that matters. 438 if (acl)
215 In earlier Fedora the two types of ACLs were mutually exclusive. 439 {
216 Attempt to work correctly on both kinds of systems. */ 440 ret = acl_access_nontrivial (acl);
217 bool nfsv4_acl 441 int saved_errno = errno;
218 = 0 < listsize && have_xattr (XATTR_NAME_NFSV4_ACL, listbuf, listsize); 442 acl_free (acl);
219 int ret 443 errno = saved_errno;
220 = (listsize <= 0 ? listsize 444# if HAVE_ACL_FREE_TEXT /* Tru64 */
221 : (nfsv4_acl 445 /* On OSF/1, acl_get_file (name, ACL_TYPE_DEFAULT) always
222 || have_xattr (XATTR_NAME_POSIX_ACL_ACCESS, listbuf, listsize) 446 returns NULL with errno not set. There is no point in
223 || (S_ISDIR (sb->st_mode) 447 making this call. */
224 && have_xattr (XATTR_NAME_POSIX_ACL_DEFAULT, 448# else /* FreeBSD, NetBSD >= 10, IRIX, Cygwin >= 2.5 */
225 listbuf, listsize)))); 449 /* On Linux, FreeBSD, NetBSD, IRIX,
226 free (heapbuf); 450 acl_get_file (name, ACL_TYPE_ACCESS)
227 451 and acl_get_file (name, ACL_TYPE_DEFAULT) on a directory
228 /* If there is an NFSv4 ACL, follow up with a getxattr syscall 452 either both succeed or both fail; it depends on the
229 to see whether the NFSv4 ACL is nontrivial. */ 453 file system. Therefore there is no point in making the second
230 if (nfsv4_acl) 454 call if the first one already failed. */
231 { 455 if (ret == 0
232 ret = getxattr (name, XATTR_NAME_NFSV4_ACL, 456 && (d_type == DT_DIR
233 stackbuf.xattr, sizeof stackbuf.xattr); 457 || (d_type == DT_UNKNOWN && !(flags & _GL_DT_NOTDIR))))
234 if (ret < 0) 458 {
235 switch (errno) 459 acl = acl_get_file_or_link (name, ACL_TYPE_DEFAULT);
460 if (acl)
236 { 461 {
237 case ENODATA: return 0; 462# ifdef __CYGWIN__ /* Cygwin >= 2.5 */
238 case ERANGE : return 1; /* ACL must be nontrivial. */ 463 ret = acl_access_nontrivial (acl);
464 saved_errno = errno;
465 acl_free (acl);
466 errno = saved_errno;
467# else
468 ret = (0 < acl_entries (acl));
469 acl_free (acl);
470# endif
239 } 471 }
240 else 472 else
241 { 473 {
242 /* It looks like a trivial ACL, but investigate further. */ 474 ret = -1;
243 ret = acl_nfs4_nontrivial (stackbuf.xattr, ret); 475# ifdef __CYGWIN__ /* Cygwin >= 2.5 */
244 if (ret < 0) 476 if (d_type == DT_UNKNOWN)
245 { 477 ret = 0;
246 errno = EINVAL; 478# endif
247 return ret; 479 }
248 } 480 }
249 errno = initial_errno; 481# endif
250 } 482 }
251 } 483 else
252 if (ret < 0) 484 ret = -1;
253 return - acl_errno_valid (errno); 485# endif
254 return ret;
255 486
256# elif HAVE_ACL_GET_FILE 487 return ret < 0 ? - acl_errno_valid (errno) : ret;
488 }
257 489
258 /* POSIX 1003.1e (draft 17 -- abandoned) specific version. */ 490# else /* !HAVE_ACL_GET_FILE */
259 /* Linux, FreeBSD, Mac OS X, IRIX, Tru64, Cygwin >= 2.5 */
260 int ret;
261 491
262 if (HAVE_ACL_EXTENDED_FILE) /* Linux */ 492 /* The remaining APIs always follow symlinks and operate on
263 { 493 platforms where symlinks do not have ACLs, so skip the APIs if
264 /* On Linux, acl_extended_file is an optimized function: It only 494 NAME is known to be a symlink. */
265 makes two calls to getxattr(), one for ACL_TYPE_ACCESS, one for 495 if (d_type != DT_LNK)
266 ACL_TYPE_DEFAULT. */ 496 {
267 ret = acl_extended_file (name);
268 }
269 else /* FreeBSD, Mac OS X, IRIX, Tru64, Cygwin >= 2.5 */
270 {
271# if HAVE_ACL_TYPE_EXTENDED /* Mac OS X */
272 /* On Mac OS X, acl_get_file (name, ACL_TYPE_ACCESS)
273 and acl_get_file (name, ACL_TYPE_DEFAULT)
274 always return NULL / EINVAL. There is no point in making
275 these two useless calls. The real ACL is retrieved through
276 acl_get_file (name, ACL_TYPE_EXTENDED). */
277 acl_t acl = acl_get_file (name, ACL_TYPE_EXTENDED);
278 if (acl)
279 {
280 ret = acl_extended_nontrivial (acl);
281 acl_free (acl);
282 }
283 else
284 ret = -1;
285# else /* FreeBSD, IRIX, Tru64, Cygwin >= 2.5 */
286 acl_t acl = acl_get_file (name, ACL_TYPE_ACCESS);
287 if (acl)
288 {
289 int saved_errno;
290
291 ret = acl_access_nontrivial (acl);
292 saved_errno = errno;
293 acl_free (acl);
294 errno = saved_errno;
295# if HAVE_ACL_FREE_TEXT /* Tru64 */
296 /* On OSF/1, acl_get_file (name, ACL_TYPE_DEFAULT) always
297 returns NULL with errno not set. There is no point in
298 making this call. */
299# else /* FreeBSD, IRIX, Cygwin >= 2.5 */
300 /* On Linux, FreeBSD, IRIX, acl_get_file (name, ACL_TYPE_ACCESS)
301 and acl_get_file (name, ACL_TYPE_DEFAULT) on a directory
302 either both succeed or both fail; it depends on the
303 file system. Therefore there is no point in making the second
304 call if the first one already failed. */
305 if (ret == 0 && S_ISDIR (sb->st_mode))
306 {
307 acl = acl_get_file (name, ACL_TYPE_DEFAULT);
308 if (acl)
309 {
310# ifdef __CYGWIN__ /* Cygwin >= 2.5 */
311 ret = acl_access_nontrivial (acl);
312 saved_errno = errno;
313 acl_free (acl);
314 errno = saved_errno;
315# else
316 ret = (0 < acl_entries (acl));
317 acl_free (acl);
318# endif
319 }
320 else
321 ret = -1;
322 }
323# endif
324 }
325 else
326 ret = -1;
327# endif
328 }
329 if (ret < 0)
330 return - acl_errno_valid (errno);
331 return ret;
332 497
333# elif HAVE_FACL && defined GETACL /* Solaris, Cygwin < 2.5, not HP-UX */ 498# if HAVE_FACL && defined GETACL /* Solaris, Cygwin < 2.5, not HP-UX */
334 499
335# if defined ACL_NO_TRIVIAL 500# ifdef ACL_NO_TRIVIAL
336 501
337 /* Solaris 10 (newer version), which has additional API declared in 502 /* Solaris 10 (newer version), which has additional API declared in
338 <sys/acl.h> (acl_t) and implemented in libsec (acl_set, acl_trivial, 503 <sys/acl.h> (acl_t) and implemented in libsec (acl_set, acl_trivial,
339 acl_fromtext, ...). */ 504 acl_fromtext, ...). */
340 return acl_trivial (name); 505 return acl_trivial (name);
341 506
342# else /* Solaris, Cygwin, general case */ 507# else /* Solaris, Cygwin, general case */
343 508
344 /* Solaris 2.5 through Solaris 10, Cygwin, and contemporaneous versions 509 /* Solaris 2.5 through Solaris 10, Cygwin, and contemporaneous versions
345 of Unixware. The acl() call returns the access and default ACL both 510 of Unixware. The acl() call returns the access and default ACL both
@@ -374,10 +539,7 @@ file_has_acl (char const *name, struct stat const *sb)
374 entries = malloced = 539 entries = malloced =
375 (aclent_t *) malloc (alloc * sizeof (aclent_t)); 540 (aclent_t *) malloc (alloc * sizeof (aclent_t));
376 if (entries == NULL) 541 if (entries == NULL)
377 { 542 return -1;
378 errno = ENOMEM;
379 return -1;
380 }
381 continue; 543 continue;
382 } 544 }
383 break; 545 break;
@@ -415,7 +577,7 @@ file_has_acl (char const *name, struct stat const *sb)
415 free (malloced); 577 free (malloced);
416 } 578 }
417 579
418# ifdef ACE_GETACL 580# ifdef ACE_GETACL
419 /* Solaris also has a different variant of ACLs, used in ZFS and NFSv4 581 /* Solaris also has a different variant of ACLs, used in ZFS and NFSv4
420 file systems (whereas the other ones are used in UFS file systems). */ 582 file systems (whereas the other ones are used in UFS file systems). */
421 { 583 {
@@ -447,10 +609,7 @@ file_has_acl (char const *name, struct stat const *sb)
447 alloc = 2 * alloc; /* <= alloc_max */ 609 alloc = 2 * alloc; /* <= alloc_max */
448 entries = malloced = (ace_t *) malloc (alloc * sizeof (ace_t)); 610 entries = malloced = (ace_t *) malloc (alloc * sizeof (ace_t));
449 if (entries == NULL) 611 if (entries == NULL)
450 { 612 return -1;
451 errno = ENOMEM;
452 return -1;
453 }
454 continue; 613 continue;
455 } 614 }
456 break; 615 break;
@@ -491,12 +650,12 @@ file_has_acl (char const *name, struct stat const *sb)
491 } 650 }
492 free (malloced); 651 free (malloced);
493 } 652 }
494# endif 653# endif
495 654
496 return 0; 655 return 0;
497# endif 656# endif
498 657
499# elif HAVE_GETACL /* HP-UX */ 658# elif HAVE_GETACL /* HP-UX */
500 659
501 { 660 {
502 struct acl_entry entries[NACLENTRIES]; 661 struct acl_entry entries[NACLENTRIES];
@@ -539,7 +698,7 @@ file_has_acl (char const *name, struct stat const *sb)
539 } 698 }
540 } 699 }
541 700
542# if HAVE_ACLV_H /* HP-UX >= 11.11 */ 701# if HAVE_ACLV_H /* HP-UX >= 11.11 */
543 702
544 { 703 {
545 struct acl entries[NACLVENTRIES]; 704 struct acl entries[NACLVENTRIES];
@@ -574,9 +733,9 @@ file_has_acl (char const *name, struct stat const *sb)
574 } 733 }
575 } 734 }
576 735
577# endif 736# endif
578 737
579# elif HAVE_ACLX_GET && defined ACL_AIX_WIP /* AIX */ 738# elif HAVE_ACLX_GET && defined ACL_AIX_WIP /* AIX */
580 739
581 acl_type_t type; 740 acl_type_t type;
582 char aclbuf[1024]; 741 char aclbuf[1024];
@@ -604,10 +763,7 @@ file_has_acl (char const *name, struct stat const *sb)
604 free (acl); 763 free (acl);
605 acl = malloc (aclsize); 764 acl = malloc (aclsize);
606 if (acl == NULL) 765 if (acl == NULL)
607 { 766 return -1;
608 errno = ENOMEM;
609 return -1;
610 }
611 } 767 }
612 768
613 if (type.u64 == ACL_AIXC) 769 if (type.u64 == ACL_AIXC)
@@ -634,7 +790,7 @@ file_has_acl (char const *name, struct stat const *sb)
634 return -1; 790 return -1;
635 } 791 }
636 792
637# elif HAVE_STATACL /* older AIX */ 793# elif HAVE_STATACL /* older AIX */
638 794
639 union { struct acl a; char room[4096]; } u; 795 union { struct acl a; char room[4096]; } u;
640 796
@@ -643,7 +799,7 @@ file_has_acl (char const *name, struct stat const *sb)
643 799
644 return acl_nontrivial (&u.a); 800 return acl_nontrivial (&u.a);
645 801
646# elif HAVE_ACLSORT /* NonStop Kernel */ 802# elif HAVE_ACLSORT /* NonStop Kernel */
647 803
648 { 804 {
649 struct acl entries[NACLENTRIES]; 805 struct acl entries[NACLENTRIES];
@@ -675,10 +831,29 @@ file_has_acl (char const *name, struct stat const *sb)
675 return acl_nontrivial (count, entries); 831 return acl_nontrivial (count, entries);
676 } 832 }
677 } 833 }
678 834# endif
679# endif
680 } 835 }
836# endif
837# endif
681#endif 838#endif
682 839
683 return 0; 840 return 0;
684} 841}
842
843/* Return 1 if NAME has a nontrivial access control list,
844 0 if ACLs are not supported, or if NAME has no or only a base ACL,
845 and -1 (setting errno) on error. Note callers can determine
846 if ACLs are not supported as errno is set in that case also.
847 SB must be set to the stat buffer of NAME,
848 obtained through stat() or lstat(). */
849int
850file_has_acl (char const *name, struct stat const *sb)
851{
852 int flags = IFTODT (sb->st_mode);
853 if (!S_ISDIR (sb->st_mode))
854 flags |= _GL_DT_NOTDIR;
855 struct aclinfo ai;
856 int r = file_has_aclinfo (name, &ai, flags);
857 aclinfo_free (&ai);
858 return r;
859}
diff --git a/lib/getopt-cdefs.in.h b/lib/getopt-cdefs.in.h
index a1d304d49e8..9d704a9f6e5 100644
--- a/lib/getopt-cdefs.in.h
+++ b/lib/getopt-cdefs.in.h
@@ -46,10 +46,14 @@
46# endif 46# endif
47#endif 47#endif
48 48
49#if defined __clang__
50 /* clang really only groks GNU C 4.2, regardless of its value of __GNUC__. */
51# undef __GNUC_PREREQ
52# define __GNUC_PREREQ(maj, min) ((maj) < 4 + ((min) <= 2))
53#endif
49#ifndef __GNUC_PREREQ 54#ifndef __GNUC_PREREQ
50# if defined __GNUC__ && defined __GNUC_VERSION__ 55# if defined __GNUC__ && defined __GNUC_MINOR__
51# define __GNUC_PREREQ(maj, min) \ 56# define __GNUC_PREREQ(maj, min) ((maj) < __GNUC__ + ((min) <= __GNUC_MINOR__))
52 ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
53# else 57# else
54# define __GNUC_PREREQ(maj, min) 0 58# define __GNUC_PREREQ(maj, min) 0
55# endif 59# endif
diff --git a/lib/getopt-pfx-core.h b/lib/getopt-pfx-core.h
index 78b7816aa42..df2cb183a52 100644
--- a/lib/getopt-pfx-core.h
+++ b/lib/getopt-pfx-core.h
@@ -31,6 +31,13 @@
31 functions and variables. Renaming avoids problems with some 31 functions and variables. Renaming avoids problems with some
32 compilers and linkers. */ 32 compilers and linkers. */
33#ifdef __GETOPT_PREFIX 33#ifdef __GETOPT_PREFIX
34
35/* Include platform-dependent header files that may declare getopt() and
36 friends. */
37# if defined _AIX || defined __hpux || defined __sun || defined __QNX__
38# include <stdio.h>
39# endif
40
34# ifndef __GETOPT_ID 41# ifndef __GETOPT_ID
35# define __GETOPT_CONCAT(x, y) x ## y 42# define __GETOPT_CONCAT(x, y) x ## y
36# define __GETOPT_XCONCAT(x, y) __GETOPT_CONCAT (x, y) 43# define __GETOPT_XCONCAT(x, y) __GETOPT_CONCAT (x, y)
diff --git a/lib/getopt.c b/lib/getopt.c
index ea2d1a529c4..47800c1b35b 100644
--- a/lib/getopt.c
+++ b/lib/getopt.c
@@ -42,7 +42,7 @@
42# define funlockfile(fp) _IO_funlockfile (fp) 42# define funlockfile(fp) _IO_funlockfile (fp)
43#else 43#else
44# include "gettext.h" 44# include "gettext.h"
45# define _(msgid) gettext (msgid) 45# define _(msgid) dgettext ("gnulib", msgid)
46/* When used standalone, flockfile and funlockfile might not be 46/* When used standalone, flockfile and funlockfile might not be
47 available. */ 47 available. */
48# if (!defined _POSIX_THREAD_SAFE_FUNCTIONS \ 48# if (!defined _POSIX_THREAD_SAFE_FUNCTIONS \
@@ -732,7 +732,7 @@ _getopt_internal (int argc, char **argv, const char *optstring,
732 NAME (int argc, char *const *argv, const char *optstring) \ 732 NAME (int argc, char *const *argv, const char *optstring) \
733 { \ 733 { \
734 return _getopt_internal (argc, (char **)argv, optstring, \ 734 return _getopt_internal (argc, (char **)argv, optstring, \
735 0, 0, 0, POSIXLY_CORRECT); \ 735 NULL, NULL, 0, POSIXLY_CORRECT); \
736 } 736 }
737 737
738#ifdef _LIBC 738#ifdef _LIBC
diff --git a/lib/gettext.h b/lib/gettext.h
index 39d5ae4daa5..bf0aa41e230 100644
--- a/lib/gettext.h
+++ b/lib/gettext.h
@@ -1,6 +1,5 @@
1/* Convenience header for conditional use of GNU <libintl.h>. 1/* Convenience header for conditional use of GNU <libintl.h>.
2 Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009-2024 Free Software 2 Copyright (C) 1995-2024 Free Software Foundation, Inc.
3 Foundation, Inc.
4 3
5 This file is free software: you can redistribute it and/or modify 4 This file is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as 5 it under the terms of the GNU Lesser General Public License as
@@ -18,6 +17,7 @@
18#ifndef _LIBGETTEXT_H 17#ifndef _LIBGETTEXT_H
19#define _LIBGETTEXT_H 1 18#define _LIBGETTEXT_H 1
20 19
20
21/* NLS can be disabled through the configure --disable-nls option 21/* NLS can be disabled through the configure --disable-nls option
22 or through "#define ENABLE NLS 0" before including this file. */ 22 or through "#define ENABLE NLS 0" before including this file. */
23#if defined ENABLE_NLS && ENABLE_NLS 23#if defined ENABLE_NLS && ENABLE_NLS
@@ -45,19 +45,19 @@
45 as well because people using "gettext.h" will not include <libintl.h>, 45 as well because people using "gettext.h" will not include <libintl.h>,
46 and also including <libintl.h> would fail on SunOS 4, whereas <locale.h> 46 and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
47 is OK. */ 47 is OK. */
48#if defined(__sun) 48# if defined(__sun)
49# include <locale.h> 49# include <locale.h>
50#endif 50# endif
51 51
52/* Many header files from the libstdc++ coming with g++ 3.3 or newer include 52/* Many header files from the libstdc++ coming with g++ 3.3 or newer include
53 <libintl.h>, which chokes if dcgettext is defined as a macro. So include 53 <libintl.h>, which chokes if dcgettext is defined as a macro. So include
54 it now, to make later inclusions of <libintl.h> a NOP. */ 54 it now, to make later inclusions of <libintl.h> a NOP. */
55#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3) 55# if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3)
56# include <cstdlib> 56# include <cstdlib>
57# if (__GLIBC__ >= 2 && !defined __UCLIBC__) || _GLIBCXX_HAVE_LIBINTL_H 57# if (__GLIBC__ >= 2 && !defined __UCLIBC__) || _GLIBCXX_HAVE_LIBINTL_H
58# include <libintl.h> 58# include <libintl.h>
59# endif
59# endif 60# endif
60#endif
61 61
62/* Disabled NLS. 62/* Disabled NLS.
63 The casts to 'const char *' serve the purpose of producing warnings 63 The casts to 'const char *' serve the purpose of producing warnings
@@ -93,12 +93,14 @@
93 93
94#endif 94#endif
95 95
96
96/* Prefer gnulib's setlocale override over libintl's setlocale override. */ 97/* Prefer gnulib's setlocale override over libintl's setlocale override. */
97#ifdef GNULIB_defined_setlocale 98#ifdef GNULIB_defined_setlocale
98# undef setlocale 99# undef setlocale
99# define setlocale rpl_setlocale 100# define setlocale rpl_setlocale
100#endif 101#endif
101 102
103
102/* A pseudo function call that serves as a marker for the automated 104/* A pseudo function call that serves as a marker for the automated
103 extraction of messages, but does not call gettext(). The run-time 105 extraction of messages, but does not call gettext(). The run-time
104 translation is done at a different place in the code. 106 translation is done at a different place in the code.
@@ -108,6 +110,7 @@
108 initializer for static 'char[]' or 'const char[]' variables. */ 110 initializer for static 'char[]' or 'const char[]' variables. */
109#define gettext_noop(String) String 111#define gettext_noop(String) String
110 112
113
111/* The separator between msgctxt and msgid in a .mo file. */ 114/* The separator between msgctxt and msgid in a .mo file. */
112#define GETTEXT_CONTEXT_GLUE "\004" 115#define GETTEXT_CONTEXT_GLUE "\004"
113 116
@@ -115,6 +118,9 @@
115 MSGID. MSGCTXT and MSGID must be string literals. MSGCTXT should be 118 MSGID. MSGCTXT and MSGID must be string literals. MSGCTXT should be
116 short and rarely need to change. 119 short and rarely need to change.
117 The letter 'p' stands for 'particular' or 'special'. */ 120 The letter 'p' stands for 'particular' or 'special'. */
121
122#include <locale.h> /* for LC_MESSAGES */
123
118#ifdef DEFAULT_TEXT_DOMAIN 124#ifdef DEFAULT_TEXT_DOMAIN
119# define pgettext(Msgctxt, Msgid) \ 125# define pgettext(Msgctxt, Msgid) \
120 pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) 126 pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
@@ -178,11 +184,12 @@ npgettext_aux (const char *domain,
178 return translation; 184 return translation;
179} 185}
180 186
187
181/* The same thing extended for non-constant arguments. Here MSGCTXT and MSGID 188/* The same thing extended for non-constant arguments. Here MSGCTXT and MSGID
182 can be arbitrary expressions. But for string literals these macros are 189 can be arbitrary expressions. But for string literals these macros are
183 less efficient than those above. */ 190 less efficient than those above. */
184 191
185#include <string.h> 192#include <string.h> /* for memcpy */
186 193
187/* GNULIB_NO_VLA can be defined to disable use of VLAs even if supported. 194/* GNULIB_NO_VLA can be defined to disable use of VLAs even if supported.
188 This relates to the -Wvla and -Wvla-larger-than warnings, enabled in 195 This relates to the -Wvla and -Wvla-larger-than warnings, enabled in
@@ -199,7 +206,7 @@ npgettext_aux (const char *domain,
199#endif 206#endif
200 207
201#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 208#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
202#include <stdlib.h> 209# include <stdlib.h> /* for malloc, free */
203#endif 210#endif
204 211
205#define pgettext_expr(Msgctxt, Msgid) \ 212#define pgettext_expr(Msgctxt, Msgid) \
@@ -297,4 +304,5 @@ dcnpgettext_expr (const char *domain,
297 return (n == 1 ? msgid : msgid_plural); 304 return (n == 1 ? msgid : msgid_plural);
298} 305}
299 306
307
300#endif /* _LIBGETTEXT_H */ 308#endif /* _LIBGETTEXT_H */
diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in
index 5e541d9af1f..53275a4e62f 100644
--- a/lib/gnulib.mk.in
+++ b/lib/gnulib.mk.in
@@ -42,6 +42,7 @@
42# --avoid=dup \ 42# --avoid=dup \
43# --avoid=fchdir \ 43# --avoid=fchdir \
44# --avoid=fstat \ 44# --avoid=fstat \
45# --avoid=gnulib-i18n \
45# --avoid=iswblank \ 46# --avoid=iswblank \
46# --avoid=iswctype \ 47# --avoid=iswctype \
47# --avoid=iswdigit \ 48# --avoid=iswdigit \
@@ -80,6 +81,7 @@
80# alloca-opt \ 81# alloca-opt \
81# binary-io \ 82# binary-io \
82# boot-time \ 83# boot-time \
84# builtin-expect \
83# byteswap \ 85# byteswap \
84# c-ctype \ 86# c-ctype \
85# c-strcase \ 87# c-strcase \
@@ -261,7 +263,6 @@ DYNLIB_OBJ = @DYNLIB_OBJ@
261ECHO_C = @ECHO_C@ 263ECHO_C = @ECHO_C@
262ECHO_N = @ECHO_N@ 264ECHO_N = @ECHO_N@
263ECHO_T = @ECHO_T@ 265ECHO_T = @ECHO_T@
264EGREP = @EGREP@
265EMACSRES = @EMACSRES@ 266EMACSRES = @EMACSRES@
266EMACS_MANIFEST = @EMACS_MANIFEST@ 267EMACS_MANIFEST = @EMACS_MANIFEST@
267EMULTIHOP_HIDDEN = @EMULTIHOP_HIDDEN@ 268EMULTIHOP_HIDDEN = @EMULTIHOP_HIDDEN@
@@ -336,6 +337,7 @@ GL_COND_OBJ_PTHREAD_SIGMASK_CONDITION = @GL_COND_OBJ_PTHREAD_SIGMASK_CONDITION@
336GL_COND_OBJ_RAWMEMCHR_CONDITION = @GL_COND_OBJ_RAWMEMCHR_CONDITION@ 337GL_COND_OBJ_RAWMEMCHR_CONDITION = @GL_COND_OBJ_RAWMEMCHR_CONDITION@
337GL_COND_OBJ_READLINKAT_CONDITION = @GL_COND_OBJ_READLINKAT_CONDITION@ 338GL_COND_OBJ_READLINKAT_CONDITION = @GL_COND_OBJ_READLINKAT_CONDITION@
338GL_COND_OBJ_READLINK_CONDITION = @GL_COND_OBJ_READLINK_CONDITION@ 339GL_COND_OBJ_READLINK_CONDITION = @GL_COND_OBJ_READLINK_CONDITION@
340GL_COND_OBJ_REALLOC_POSIX_CONDITION = @GL_COND_OBJ_REALLOC_POSIX_CONDITION@
339GL_COND_OBJ_REGEX_CONDITION = @GL_COND_OBJ_REGEX_CONDITION@ 341GL_COND_OBJ_REGEX_CONDITION = @GL_COND_OBJ_REGEX_CONDITION@
340GL_COND_OBJ_SIG2STR_CONDITION = @GL_COND_OBJ_SIG2STR_CONDITION@ 342GL_COND_OBJ_SIG2STR_CONDITION = @GL_COND_OBJ_SIG2STR_CONDITION@
341GL_COND_OBJ_SIGDESCR_NP_CONDITION = @GL_COND_OBJ_SIGDESCR_NP_CONDITION@ 343GL_COND_OBJ_SIGDESCR_NP_CONDITION = @GL_COND_OBJ_SIGDESCR_NP_CONDITION@
@@ -584,7 +586,6 @@ GL_GNULIB_READDIR = @GL_GNULIB_READDIR@
584GL_GNULIB_READLINK = @GL_GNULIB_READLINK@ 586GL_GNULIB_READLINK = @GL_GNULIB_READLINK@
585GL_GNULIB_READLINKAT = @GL_GNULIB_READLINKAT@ 587GL_GNULIB_READLINKAT = @GL_GNULIB_READLINKAT@
586GL_GNULIB_REALLOCARRAY = @GL_GNULIB_REALLOCARRAY@ 588GL_GNULIB_REALLOCARRAY = @GL_GNULIB_REALLOCARRAY@
587GL_GNULIB_REALLOC_GNU = @GL_GNULIB_REALLOC_GNU@
588GL_GNULIB_REALLOC_POSIX = @GL_GNULIB_REALLOC_POSIX@ 589GL_GNULIB_REALLOC_POSIX = @GL_GNULIB_REALLOC_POSIX@
589GL_GNULIB_REALPATH = @GL_GNULIB_REALPATH@ 590GL_GNULIB_REALPATH = @GL_GNULIB_REALPATH@
590GL_GNULIB_REMOVE = @GL_GNULIB_REMOVE@ 591GL_GNULIB_REMOVE = @GL_GNULIB_REMOVE@
@@ -707,7 +708,6 @@ GNUSTEP_CFLAGS = @GNUSTEP_CFLAGS@
707GNU_OBJC_CFLAGS = @GNU_OBJC_CFLAGS@ 708GNU_OBJC_CFLAGS = @GNU_OBJC_CFLAGS@
708GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ 709GOBJECT_CFLAGS = @GOBJECT_CFLAGS@
709GOBJECT_LIBS = @GOBJECT_LIBS@ 710GOBJECT_LIBS = @GOBJECT_LIBS@
710GREP = @GREP@
711GSETTINGS_CFLAGS = @GSETTINGS_CFLAGS@ 711GSETTINGS_CFLAGS = @GSETTINGS_CFLAGS@
712GSETTINGS_LIBS = @GSETTINGS_LIBS@ 712GSETTINGS_LIBS = @GSETTINGS_LIBS@
713GTK_CFLAGS = @GTK_CFLAGS@ 713GTK_CFLAGS = @GTK_CFLAGS@
@@ -1031,6 +1031,7 @@ LIB_MATH = @LIB_MATH@
1031LIB_NANOSLEEP = @LIB_NANOSLEEP@ 1031LIB_NANOSLEEP = @LIB_NANOSLEEP@
1032LIB_PTHREAD = @LIB_PTHREAD@ 1032LIB_PTHREAD = @LIB_PTHREAD@
1033LIB_PTHREAD_SIGMASK = @LIB_PTHREAD_SIGMASK@ 1033LIB_PTHREAD_SIGMASK = @LIB_PTHREAD_SIGMASK@
1034LIB_SELINUX = @LIB_SELINUX@
1034LIB_TIMER_TIME = @LIB_TIMER_TIME@ 1035LIB_TIMER_TIME = @LIB_TIMER_TIME@
1035LIB_WSOCK32 = @LIB_WSOCK32@ 1036LIB_WSOCK32 = @LIB_WSOCK32@
1036LIB_XATTR = @LIB_XATTR@ 1037LIB_XATTR = @LIB_XATTR@
@@ -1277,7 +1278,6 @@ REPLACE_READDIR = @REPLACE_READDIR@
1277REPLACE_READLINK = @REPLACE_READLINK@ 1278REPLACE_READLINK = @REPLACE_READLINK@
1278REPLACE_READLINKAT = @REPLACE_READLINKAT@ 1279REPLACE_READLINKAT = @REPLACE_READLINKAT@
1279REPLACE_REALLOCARRAY = @REPLACE_REALLOCARRAY@ 1280REPLACE_REALLOCARRAY = @REPLACE_REALLOCARRAY@
1280REPLACE_REALLOC_FOR_REALLOC_GNU = @REPLACE_REALLOC_FOR_REALLOC_GNU@
1281REPLACE_REALLOC_FOR_REALLOC_POSIX = @REPLACE_REALLOC_FOR_REALLOC_POSIX@ 1281REPLACE_REALLOC_FOR_REALLOC_POSIX = @REPLACE_REALLOC_FOR_REALLOC_POSIX@
1282REPLACE_REALPATH = @REPLACE_REALPATH@ 1282REPLACE_REALPATH = @REPLACE_REALPATH@
1283REPLACE_REMOVE = @REPLACE_REMOVE@ 1283REPLACE_REMOVE = @REPLACE_REMOVE@
@@ -1384,6 +1384,7 @@ UNISTD_H_HAVE_SYS_RANDOM_H = @UNISTD_H_HAVE_SYS_RANDOM_H@
1384UNISTD_H_HAVE_WINSOCK2_H = @UNISTD_H_HAVE_WINSOCK2_H@ 1384UNISTD_H_HAVE_WINSOCK2_H = @UNISTD_H_HAVE_WINSOCK2_H@
1385UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS = @UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS@ 1385UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS = @UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS@
1386USE_ACL = @USE_ACL@ 1386USE_ACL = @USE_ACL@
1387USE_SELINUX_SELINUX_H = @USE_SELINUX_SELINUX_H@
1387USE_STARTUP_NOTIFICATION = @USE_STARTUP_NOTIFICATION@ 1388USE_STARTUP_NOTIFICATION = @USE_STARTUP_NOTIFICATION@
1388VMLIMIT_OBJ = @VMLIMIT_OBJ@ 1389VMLIMIT_OBJ = @VMLIMIT_OBJ@
1389W32_LIBS = @W32_LIBS@ 1390W32_LIBS = @W32_LIBS@
@@ -1470,16 +1471,13 @@ gl_GNULIB_ENABLED_260941c0e5dc67ec9e87d1fb321c300b_CONDITION = @gl_GNULIB_ENABLE
1470gl_GNULIB_ENABLED_5264294aa0a5557541b53c8c741f7f31_CONDITION = @gl_GNULIB_ENABLED_5264294aa0a5557541b53c8c741f7f31_CONDITION@ 1471gl_GNULIB_ENABLED_5264294aa0a5557541b53c8c741f7f31_CONDITION = @gl_GNULIB_ENABLED_5264294aa0a5557541b53c8c741f7f31_CONDITION@
1471gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c_CONDITION = @gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c_CONDITION@ 1472gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c_CONDITION = @gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c_CONDITION@
1472gl_GNULIB_ENABLED_61bcaca76b3e6f9ae55d57a1c3193bc4_CONDITION = @gl_GNULIB_ENABLED_61bcaca76b3e6f9ae55d57a1c3193bc4_CONDITION@ 1473gl_GNULIB_ENABLED_61bcaca76b3e6f9ae55d57a1c3193bc4_CONDITION = @gl_GNULIB_ENABLED_61bcaca76b3e6f9ae55d57a1c3193bc4_CONDITION@
1473gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec_CONDITION = @gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec_CONDITION@
1474gl_GNULIB_ENABLED_8444034ea779b88768865bb60b4fb8c9_CONDITION = @gl_GNULIB_ENABLED_8444034ea779b88768865bb60b4fb8c9_CONDITION@ 1474gl_GNULIB_ENABLED_8444034ea779b88768865bb60b4fb8c9_CONDITION = @gl_GNULIB_ENABLED_8444034ea779b88768865bb60b4fb8c9_CONDITION@
1475gl_GNULIB_ENABLED_925677f0343de64b89a9f0c790b4104c_CONDITION = @gl_GNULIB_ENABLED_925677f0343de64b89a9f0c790b4104c_CONDITION@ 1475gl_GNULIB_ENABLED_925677f0343de64b89a9f0c790b4104c_CONDITION = @gl_GNULIB_ENABLED_925677f0343de64b89a9f0c790b4104c_CONDITION@
1476gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1_CONDITION = @gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1_CONDITION@ 1476gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1_CONDITION = @gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1_CONDITION@
1477gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36_CONDITION = @gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36_CONDITION@ 1477gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36_CONDITION = @gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36_CONDITION@
1478gl_GNULIB_ENABLED_cloexec_CONDITION = @gl_GNULIB_ENABLED_cloexec_CONDITION@ 1478gl_GNULIB_ENABLED_cloexec_CONDITION = @gl_GNULIB_ENABLED_cloexec_CONDITION@
1479gl_GNULIB_ENABLED_d3b2383720ee0e541357aa2aac598e2b_CONDITION = @gl_GNULIB_ENABLED_d3b2383720ee0e541357aa2aac598e2b_CONDITION@
1480gl_GNULIB_ENABLED_dirfd_CONDITION = @gl_GNULIB_ENABLED_dirfd_CONDITION@ 1479gl_GNULIB_ENABLED_dirfd_CONDITION = @gl_GNULIB_ENABLED_dirfd_CONDITION@
1481gl_GNULIB_ENABLED_e80bf6f757095d2e5fc94dafb8f8fc8b_CONDITION = @gl_GNULIB_ENABLED_e80bf6f757095d2e5fc94dafb8f8fc8b_CONDITION@ 1480gl_GNULIB_ENABLED_e80bf6f757095d2e5fc94dafb8f8fc8b_CONDITION = @gl_GNULIB_ENABLED_e80bf6f757095d2e5fc94dafb8f8fc8b_CONDITION@
1482gl_GNULIB_ENABLED_ef455225c00f5049c808c2eda3e76866_CONDITION = @gl_GNULIB_ENABLED_ef455225c00f5049c808c2eda3e76866_CONDITION@
1483gl_GNULIB_ENABLED_endian_CONDITION = @gl_GNULIB_ENABLED_endian_CONDITION@ 1481gl_GNULIB_ENABLED_endian_CONDITION = @gl_GNULIB_ENABLED_endian_CONDITION@
1484gl_GNULIB_ENABLED_euidaccess_CONDITION = @gl_GNULIB_ENABLED_euidaccess_CONDITION@ 1482gl_GNULIB_ENABLED_euidaccess_CONDITION = @gl_GNULIB_ENABLED_euidaccess_CONDITION@
1485gl_GNULIB_ENABLED_fd38c7e463b54744b77b98aeafb4fa7c_CONDITION = @gl_GNULIB_ENABLED_fd38c7e463b54744b77b98aeafb4fa7c_CONDITION@ 1483gl_GNULIB_ENABLED_fd38c7e463b54744b77b98aeafb4fa7c_CONDITION = @gl_GNULIB_ENABLED_fd38c7e463b54744b77b98aeafb4fa7c_CONDITION@
@@ -2694,9 +2692,7 @@ endif
2694## begin gnulib module malloc-posix 2692## begin gnulib module malloc-posix
2695ifeq (,$(OMIT_GNULIB_MODULE_malloc-posix)) 2693ifeq (,$(OMIT_GNULIB_MODULE_malloc-posix))
2696 2694
2697ifneq (,$(gl_GNULIB_ENABLED_ef455225c00f5049c808c2eda3e76866_CONDITION))
2698 2695
2699endif
2700EXTRA_DIST += malloc.c 2696EXTRA_DIST += malloc.c
2701 2697
2702EXTRA_libgnu_a_SOURCES += malloc.c 2698EXTRA_libgnu_a_SOURCES += malloc.c
@@ -2925,30 +2921,16 @@ EXTRA_libgnu_a_SOURCES += at-func.c
2925endif 2921endif
2926## end gnulib module readlinkat 2922## end gnulib module readlinkat
2927 2923
2928## begin gnulib module realloc-gnu
2929ifeq (,$(OMIT_GNULIB_MODULE_realloc-gnu))
2930
2931ifneq (,$(gl_GNULIB_ENABLED_d3b2383720ee0e541357aa2aac598e2b_CONDITION))
2932
2933endif
2934EXTRA_DIST += realloc.c
2935
2936EXTRA_libgnu_a_SOURCES += realloc.c
2937
2938endif
2939## end gnulib module realloc-gnu
2940
2941## begin gnulib module realloc-posix 2924## begin gnulib module realloc-posix
2942ifeq (,$(OMIT_GNULIB_MODULE_realloc-posix)) 2925ifeq (,$(OMIT_GNULIB_MODULE_realloc-posix))
2943 2926
2944ifneq (,$(gl_GNULIB_ENABLED_61bcaca76b3e6f9ae55d57a1c3193bc4_CONDITION)) 2927ifneq (,$(gl_GNULIB_ENABLED_61bcaca76b3e6f9ae55d57a1c3193bc4_CONDITION))
2945 2928ifneq (,$(GL_COND_OBJ_REALLOC_POSIX_CONDITION))
2929libgnu_a_SOURCES += realloc.c
2946endif 2930endif
2947EXTRA_DIST += realloc.c
2948
2949EXTRA_libgnu_a_SOURCES += realloc.c
2950 2931
2951endif 2932endif
2933endif
2952## end gnulib module realloc-posix 2934## end gnulib module realloc-posix
2953 2935
2954## begin gnulib module regex 2936## begin gnulib module regex
@@ -3459,9 +3441,8 @@ endif
3459ifeq (,$(OMIT_GNULIB_MODULE_stdlib)) 3441ifeq (,$(OMIT_GNULIB_MODULE_stdlib))
3460 3442
3461BUILT_SOURCES += stdlib.h 3443BUILT_SOURCES += stdlib.h
3444libgnu_a_SOURCES += stdlib.c
3462 3445
3463# We need the following in order to create <stdlib.h> when the system
3464# doesn't have one that works with the given compiler.
3465stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \ 3446stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \
3466 $(_NORETURN_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) 3447 $(_NORETURN_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
3467 $(gl_V_at)$(SED_HEADER_STDOUT) \ 3448 $(gl_V_at)$(SED_HEADER_STDOUT) \
@@ -3500,7 +3481,6 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \
3500 -e 's/@''GNULIB_RAND''@/$(GL_GNULIB_RAND)/g' \ 3481 -e 's/@''GNULIB_RAND''@/$(GL_GNULIB_RAND)/g' \
3501 -e 's/@''GNULIB_RANDOM''@/$(GL_GNULIB_RANDOM)/g' \ 3482 -e 's/@''GNULIB_RANDOM''@/$(GL_GNULIB_RANDOM)/g' \
3502 -e 's/@''GNULIB_RANDOM_R''@/$(GL_GNULIB_RANDOM_R)/g' \ 3483 -e 's/@''GNULIB_RANDOM_R''@/$(GL_GNULIB_RANDOM_R)/g' \
3503 -e 's/@''GNULIB_REALLOC_GNU''@/$(GL_GNULIB_REALLOC_GNU)/g' \
3504 -e 's/@''GNULIB_REALLOC_POSIX''@/$(GL_GNULIB_REALLOC_POSIX)/g' \ 3484 -e 's/@''GNULIB_REALLOC_POSIX''@/$(GL_GNULIB_REALLOC_POSIX)/g' \
3505 -e 's/@''GNULIB_REALLOCARRAY''@/$(GL_GNULIB_REALLOCARRAY)/g' \ 3485 -e 's/@''GNULIB_REALLOCARRAY''@/$(GL_GNULIB_REALLOCARRAY)/g' \
3506 -e 's/@''GNULIB_REALPATH''@/$(GL_GNULIB_REALPATH)/g' \ 3486 -e 's/@''GNULIB_REALPATH''@/$(GL_GNULIB_REALPATH)/g' \
@@ -3602,7 +3582,6 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \
3602 -e 's|@''REPLACE_RAND''@|$(REPLACE_RAND)|g' \ 3582 -e 's|@''REPLACE_RAND''@|$(REPLACE_RAND)|g' \
3603 -e 's|@''REPLACE_RANDOM''@|$(REPLACE_RANDOM)|g' \ 3583 -e 's|@''REPLACE_RANDOM''@|$(REPLACE_RANDOM)|g' \
3604 -e 's|@''REPLACE_RANDOM_R''@|$(REPLACE_RANDOM_R)|g' \ 3584 -e 's|@''REPLACE_RANDOM_R''@|$(REPLACE_RANDOM_R)|g' \
3605 -e 's|@''REPLACE_REALLOC_FOR_REALLOC_GNU''@|$(REPLACE_REALLOC_FOR_REALLOC_GNU)|g' \
3606 -e 's|@''REPLACE_REALLOC_FOR_REALLOC_POSIX''@|$(REPLACE_REALLOC_FOR_REALLOC_POSIX)|g' \ 3585 -e 's|@''REPLACE_REALLOC_FOR_REALLOC_POSIX''@|$(REPLACE_REALLOC_FOR_REALLOC_POSIX)|g' \
3607 -e 's|@''REPLACE_REALLOCARRAY''@|$(REPLACE_REALLOCARRAY)|g' \ 3586 -e 's|@''REPLACE_REALLOCARRAY''@|$(REPLACE_REALLOCARRAY)|g' \
3608 -e 's|@''REPLACE_REALPATH''@|$(REPLACE_REALPATH)|g' \ 3587 -e 's|@''REPLACE_REALPATH''@|$(REPLACE_REALPATH)|g' \
@@ -4446,17 +4425,6 @@ EXTRA_DIST += vla.h
4446endif 4425endif
4447## end gnulib module vla 4426## end gnulib module vla
4448 4427
4449## begin gnulib module xalloc-oversized
4450ifeq (,$(OMIT_GNULIB_MODULE_xalloc-oversized))
4451
4452ifneq (,$(gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec_CONDITION))
4453
4454endif
4455EXTRA_DIST += xalloc-oversized.h
4456
4457endif
4458## end gnulib module xalloc-oversized
4459
4460 4428
4461mostlyclean-local: mostlyclean-generic 4429mostlyclean-local: mostlyclean-generic
4462 @for dir in '' $(MOSTLYCLEANDIRS); do \ 4430 @for dir in '' $(MOSTLYCLEANDIRS); do \
diff --git a/lib/malloc.c b/lib/malloc.c
index 2a7867a1d1f..045ff82c1a7 100644
--- a/lib/malloc.c
+++ b/lib/malloc.c
@@ -17,28 +17,33 @@
17 17
18/* written by Jim Meyering and Bruno Haible */ 18/* written by Jim Meyering and Bruno Haible */
19 19
20/* Ensure that we call the system's malloc() below. */
20#define _GL_USE_STDLIB_ALLOC 1 21#define _GL_USE_STDLIB_ALLOC 1
21#include <config.h> 22#include <config.h>
22 23
23#include <stdlib.h> 24#include <stdlib.h>
24 25
25#include <errno.h> 26#include <errno.h>
26 27#include <stdckdint.h>
27#include "xalloc-oversized.h"
28 28
29/* Allocate an N-byte block of memory from the heap, even if N is 0. */ 29/* Allocate an N-byte block of memory from the heap, even if N is 0. */
30 30
31void * 31void *
32rpl_malloc (size_t n) 32rpl_malloc (size_t n)
33{ 33{
34#if !HAVE_MALLOC_0_NONNULL
34 if (n == 0) 35 if (n == 0)
35 n = 1; 36 n = 1;
37#endif
36 38
37 if (xalloc_oversized (n, 1)) 39#if !HAVE_MALLOC_PTRDIFF
40 ptrdiff_t signed_n;
41 if (ckd_add (&signed_n, n, 0))
38 { 42 {
39 errno = ENOMEM; 43 errno = ENOMEM;
40 return NULL; 44 return NULL;
41 } 45 }
46#endif
42 47
43 void *result = malloc (n); 48 void *result = malloc (n);
44 49
diff --git a/lib/md5-stream.c b/lib/md5-stream.c
index fdd2bd8b4bf..2cbdda6b0fa 100644
--- a/lib/md5-stream.c
+++ b/lib/md5-stream.c
@@ -22,9 +22,6 @@
22#include <config.h> 22#include <config.h>
23 23
24/* Specification. */ 24/* Specification. */
25#if HAVE_OPENSSL_MD5
26# define GL_OPENSSL_INLINE _GL_EXTERN_INLINE
27#endif
28#include "md5.h" 25#include "md5.h"
29 26
30#include <stdlib.h> 27#include <stdlib.h>
diff --git a/lib/md5.h b/lib/md5.h
index 2f470703f5c..94cc6994cc1 100644
--- a/lib/md5.h
+++ b/lib/md5.h
@@ -52,10 +52,14 @@
52#define MD5_DIGEST_SIZE 16 52#define MD5_DIGEST_SIZE 16
53#define MD5_BLOCK_SIZE 64 53#define MD5_BLOCK_SIZE 64
54 54
55#if defined __clang__
56 /* clang really only groks GNU C 4.2, regardless of its value of __GNUC__. */
57# undef __GNUC_PREREQ
58# define __GNUC_PREREQ(maj, min) ((maj) < 4 + ((min) <= 2))
59#endif
55#ifndef __GNUC_PREREQ 60#ifndef __GNUC_PREREQ
56# if defined __GNUC__ && defined __GNUC_MINOR__ 61# if defined __GNUC__ && defined __GNUC_MINOR__
57# define __GNUC_PREREQ(maj, min) \ 62# define __GNUC_PREREQ(maj, min) ((maj) < __GNUC__ + ((min) <= __GNUC_MINOR__))
58 ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
59# else 63# else
60# define __GNUC_PREREQ(maj, min) 0 64# define __GNUC_PREREQ(maj, min) 0
61# endif 65# endif
diff --git a/lib/memset_explicit.c b/lib/memset_explicit.c
index 33c09873482..a5d2b00b7ea 100644
--- a/lib/memset_explicit.c
+++ b/lib/memset_explicit.c
@@ -27,7 +27,10 @@ memset_explicit (void *s, int c, size_t len)
27#if HAVE_EXPLICIT_MEMSET 27#if HAVE_EXPLICIT_MEMSET
28 return explicit_memset (s, c, len); 28 return explicit_memset (s, c, len);
29#elif HAVE_MEMSET_S 29#elif HAVE_MEMSET_S
30 (void) memset_s (s, len, c, len); 30# if !HAVE_MEMSET_S_SUPPORTS_ZERO
31 if (len > 0)
32# endif
33 (void) memset_s (s, len, c, len);
31 return s; 34 return s;
32#elif defined __GNUC__ && !defined __clang__ 35#elif defined __GNUC__ && !defined __clang__
33 memset (s, c, len); 36 memset (s, c, len);
diff --git a/lib/mini-gmp.c b/lib/mini-gmp.c
index c580a8fc025..c97dc7e6cfa 100644
--- a/lib/mini-gmp.c
+++ b/lib/mini-gmp.c
@@ -2706,6 +2706,66 @@ mpn_gcd_11 (mp_limb_t u, mp_limb_t v)
2706 return u << shift; 2706 return u << shift;
2707} 2707}
2708 2708
2709mp_size_t
2710mpn_gcd (mp_ptr rp, mp_ptr up, mp_size_t un, mp_ptr vp, mp_size_t vn)
2711{
2712 assert (un >= vn);
2713 assert (vn > 0);
2714 assert (!GMP_MPN_OVERLAP_P (up, un, vp, vn));
2715 assert (vp[vn-1] > 0);
2716 assert ((up[0] | vp[0]) & 1);
2717
2718 if (un > vn)
2719 mpn_div_qr (NULL, up, un, vp, vn);
2720
2721 un = mpn_normalized_size (up, vn);
2722 if (un == 0)
2723 {
2724 mpn_copyi (rp, vp, vn);
2725 return vn;
2726 }
2727
2728 if (!(vp[0] & 1))
2729 MPN_PTR_SWAP (up, un, vp, vn);
2730
2731 while (un > 1 || vn > 1)
2732 {
2733 int shift;
2734 assert (vp[0] & 1);
2735
2736 while (up[0] == 0)
2737 {
2738 up++;
2739 un--;
2740 }
2741 gmp_ctz (shift, up[0]);
2742 if (shift > 0)
2743 {
2744 gmp_assert_nocarry (mpn_rshift(up, up, un, shift));
2745 un -= (up[un-1] == 0);
2746 }
2747
2748 if (un < vn)
2749 MPN_PTR_SWAP (up, un, vp, vn);
2750 else if (un == vn)
2751 {
2752 int c = mpn_cmp (up, vp, un);
2753 if (c == 0)
2754 {
2755 mpn_copyi (rp, up, un);
2756 return un;
2757 }
2758 else if (c < 0)
2759 MP_PTR_SWAP (up, vp);
2760 }
2761
2762 gmp_assert_nocarry (mpn_sub (up, up, un, vp, vn));
2763 un = mpn_normalized_size (up, un);
2764 }
2765 rp[0] = mpn_gcd_11 (up[0], vp[0]);
2766 return 1;
2767}
2768
2709unsigned long 2769unsigned long
2710mpz_gcd_ui (mpz_t g, const mpz_t u, unsigned long v) 2770mpz_gcd_ui (mpz_t g, const mpz_t u, unsigned long v)
2711{ 2771{
@@ -2765,42 +2825,11 @@ mpz_gcd (mpz_t g, const mpz_t u, const mpz_t v)
2765 if (tu->_mp_size < tv->_mp_size) 2825 if (tu->_mp_size < tv->_mp_size)
2766 mpz_swap (tu, tv); 2826 mpz_swap (tu, tv);
2767 2827
2768 mpz_tdiv_r (tu, tu, tv); 2828 tu->_mp_size = mpn_gcd (tu->_mp_d, tu->_mp_d, tu->_mp_size, tv->_mp_d, tv->_mp_size);
2769 if (tu->_mp_size == 0) 2829 mpz_mul_2exp (g, tu, gz);
2770 {
2771 mpz_swap (g, tv);
2772 }
2773 else
2774 for (;;)
2775 {
2776 int c;
2777
2778 mpz_make_odd (tu);
2779 c = mpz_cmp (tu, tv);
2780 if (c == 0)
2781 {
2782 mpz_swap (g, tu);
2783 break;
2784 }
2785 if (c < 0)
2786 mpz_swap (tu, tv);
2787 2830
2788 if (tv->_mp_size == 1)
2789 {
2790 mp_limb_t *gp;
2791
2792 mpz_tdiv_r (tu, tu, tv);
2793 gp = MPZ_REALLOC (g, 1); /* gp = mpz_limbs_modify (g, 1); */
2794 *gp = mpn_gcd_11 (tu->_mp_d[0], tv->_mp_d[0]);
2795
2796 g->_mp_size = *gp != 0; /* mpz_limbs_finish (g, 1); */
2797 break;
2798 }
2799 mpz_sub (tu, tu, tv);
2800 }
2801 mpz_clear (tu); 2831 mpz_clear (tu);
2802 mpz_clear (tv); 2832 mpz_clear (tv);
2803 mpz_mul_2exp (g, g, gz);
2804} 2833}
2805 2834
2806void 2835void
diff --git a/lib/mini-gmp.h b/lib/mini-gmp.h
index 59c24cf5111..f28cb360ce1 100644
--- a/lib/mini-gmp.h
+++ b/lib/mini-gmp.h
@@ -105,6 +105,7 @@ void mpn_mul_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
105void mpn_sqr (mp_ptr, mp_srcptr, mp_size_t); 105void mpn_sqr (mp_ptr, mp_srcptr, mp_size_t);
106int mpn_perfect_square_p (mp_srcptr, mp_size_t); 106int mpn_perfect_square_p (mp_srcptr, mp_size_t);
107mp_size_t mpn_sqrtrem (mp_ptr, mp_ptr, mp_srcptr, mp_size_t); 107mp_size_t mpn_sqrtrem (mp_ptr, mp_ptr, mp_srcptr, mp_size_t);
108mp_size_t mpn_gcd (mp_ptr, mp_ptr, mp_size_t, mp_ptr, mp_size_t);
108 109
109mp_limb_t mpn_lshift (mp_ptr, mp_srcptr, mp_size_t, unsigned int); 110mp_limb_t mpn_lshift (mp_ptr, mp_srcptr, mp_size_t, unsigned int);
110mp_limb_t mpn_rshift (mp_ptr, mp_srcptr, mp_size_t, unsigned int); 111mp_limb_t mpn_rshift (mp_ptr, mp_srcptr, mp_size_t, unsigned int);
diff --git a/lib/mktime-internal.h b/lib/mktime-internal.h
index 0693aaf1402..3e2848c1210 100644
--- a/lib/mktime-internal.h
+++ b/lib/mktime-internal.h
@@ -71,9 +71,8 @@ typedef int mktime_offset_t;
71#endif 71#endif
72 72
73/* Subroutine of mktime. Return the time_t representation of TP and 73/* Subroutine of mktime. Return the time_t representation of TP and
74 normalize TP, given that a struct tm * maps to a time_t as performed 74 normalize TP, given that a struct tm * maps to a time_t. If
75 by FUNC. Record next guess for localtime-gmtime offset in *OFFSET. */ 75 LOCAL, the mapping is performed by localtime_r, otherwise by gmtime_r.
76extern __time64_t __mktime_internal (struct tm *tp, 76 Record next guess for localtime-gmtime offset in *OFFSET. */
77 struct tm *(*func) (__time64_t const *, 77extern __time64_t __mktime_internal (struct tm *tp, bool local,
78 struct tm *),
79 mktime_offset_t *offset) attribute_hidden; 78 mktime_offset_t *offset) attribute_hidden;
diff --git a/lib/mktime.c b/lib/mktime.c
index c704f415740..81d58fd01a3 100644
--- a/lib/mktime.c
+++ b/lib/mktime.c
@@ -51,7 +51,6 @@
51#include <string.h> 51#include <string.h>
52 52
53#include <intprops.h> 53#include <intprops.h>
54#include <verify.h>
55 54
56#ifndef NEED_MKTIME_INTERNAL 55#ifndef NEED_MKTIME_INTERNAL
57# define NEED_MKTIME_INTERNAL 0 56# define NEED_MKTIME_INTERNAL 0
@@ -119,12 +118,12 @@ my_tzset (void)
119 __time64_t values that mktime can generate even on platforms where 118 __time64_t values that mktime can generate even on platforms where
120 __time64_t is wider than the int components of struct tm. */ 119 __time64_t is wider than the int components of struct tm. */
121 120
122#if INT_MAX <= LONG_MAX / 4 / 366 / 24 / 60 / 60 121# if INT_MAX <= LONG_MAX / 4 / 366 / 24 / 60 / 60
123typedef long int long_int; 122typedef long int long_int;
124#else 123# else
125typedef long long int long_int; 124typedef long long int long_int;
126#endif 125# endif
127verify (INT_MAX <= TYPE_MAXIMUM (long_int) / 4 / 366 / 24 / 60 / 60); 126static_assert (INT_MAX <= TYPE_MAXIMUM (long_int) / 4 / 366 / 24 / 60 / 60);
128 127
129/* Shift A right by B bits portably, by dividing A by 2**B and 128/* Shift A right by B bits portably, by dividing A by 2**B and
130 truncating towards minus infinity. B should be in the range 0 <= B 129 truncating towards minus infinity. B should be in the range 0 <= B
@@ -155,9 +154,9 @@ static long_int const mktime_max
155 = (TYPE_MAXIMUM (long_int) < TYPE_MAXIMUM (__time64_t) 154 = (TYPE_MAXIMUM (long_int) < TYPE_MAXIMUM (__time64_t)
156 ? TYPE_MAXIMUM (long_int) : TYPE_MAXIMUM (__time64_t)); 155 ? TYPE_MAXIMUM (long_int) : TYPE_MAXIMUM (__time64_t));
157 156
158#define EPOCH_YEAR 1970 157# define EPOCH_YEAR 1970
159#define TM_YEAR_BASE 1900 158# define TM_YEAR_BASE 1900
160verify (TM_YEAR_BASE % 100 == 0); 159static_assert (TM_YEAR_BASE % 100 == 0);
161 160
162/* Is YEAR + TM_YEAR_BASE a leap year? */ 161/* Is YEAR + TM_YEAR_BASE a leap year? */
163static bool 162static bool
@@ -172,9 +171,9 @@ leapyear (long_int year)
172} 171}
173 172
174/* How many days come before each month (0-12). */ 173/* How many days come before each month (0-12). */
175#ifndef _LIBC 174# ifndef _LIBC
176static 175static
177#endif 176# endif
178const unsigned short int __mon_yday[2][13] = 177const unsigned short int __mon_yday[2][13] =
179 { 178 {
180 /* Normal years. */ 179 /* Normal years. */
@@ -206,7 +205,7 @@ static long_int
206ydhms_diff (long_int year1, long_int yday1, int hour1, int min1, int sec1, 205ydhms_diff (long_int year1, long_int yday1, int hour1, int min1, int sec1,
207 int year0, int yday0, int hour0, int min0, int sec0) 206 int year0, int yday0, int hour0, int min0, int sec0)
208{ 207{
209 verify (-1 / 2 == 0); 208 static_assert (-1 / 2 == 0);
210 209
211 /* Compute intervening leap days correctly even if year is negative. 210 /* Compute intervening leap days correctly even if year is negative.
212 Take care to avoid integer overflow here. */ 211 Take care to avoid integer overflow here. */
@@ -251,29 +250,33 @@ tm_diff (long_int year, long_int yday, int hour, int min, int sec,
251 tp->tm_hour, tp->tm_min, tp->tm_sec); 250 tp->tm_hour, tp->tm_min, tp->tm_sec);
252} 251}
253 252
254/* Use CONVERT to convert T to a struct tm value in *TM. T must be in 253/* Convert T to a struct tm value in *TM. Use localtime64_r if LOCAL,
255 range for __time64_t. Return TM if successful, NULL (setting errno) on 254 otherwise gmtime64_r. T must be in range for __time64_t. Return
256 failure. */ 255 TM if successful, NULL (setting errno) on failure. */
257static struct tm * 256static struct tm *
258convert_time (struct tm *(*convert) (const __time64_t *, struct tm *), 257convert_time (long_int t, bool local, struct tm *tm)
259 long_int t, struct tm *tm)
260{ 258{
261 __time64_t x = t; 259 __time64_t x = t;
262 return convert (&x, tm); 260 if (local)
261 return __localtime64_r (&x, tm);
262 else
263 return __gmtime64_r (&x, tm);
263} 264}
264 265/* Call it __tzconvert to sync with other parts of glibc. */
265/* Use CONVERT to convert *T to a broken down time in *TP. 266#define __tz_convert convert_time
266 If *T is out of range for conversion, adjust it so that 267
267 it is the nearest in-range value and then convert that. 268/* Convert *T to a broken down time in *TP (as if by localtime if
268 A value is in range if it fits in both __time64_t and long_int. 269 LOCAL, otherwise as if by gmtime). If *T is out of range for
269 Return TP on success, NULL (setting errno) on failure. */ 270 conversion, adjust it so that it is the nearest in-range value and
271 then convert that. A value is in range if it fits in both
272 __time64_t and long_int. Return TP on success, NULL (setting
273 errno) on failure. */
270static struct tm * 274static struct tm *
271ranged_convert (struct tm *(*convert) (const __time64_t *, struct tm *), 275ranged_convert (bool local, long_int *t, struct tm *tp)
272 long_int *t, struct tm *tp)
273{ 276{
274 long_int t1 = (*t < mktime_min ? mktime_min 277 long_int t1 = (*t < mktime_min ? mktime_min
275 : *t <= mktime_max ? *t : mktime_max); 278 : *t <= mktime_max ? *t : mktime_max);
276 struct tm *r = convert_time (convert, t1, tp); 279 struct tm *r = __tz_convert (t1, local, tp);
277 if (r) 280 if (r)
278 { 281 {
279 *t = t1; 282 *t = t1;
@@ -294,7 +297,7 @@ ranged_convert (struct tm *(*convert) (const __time64_t *, struct tm *),
294 long_int mid = long_int_avg (ok, bad); 297 long_int mid = long_int_avg (ok, bad);
295 if (mid == ok || mid == bad) 298 if (mid == ok || mid == bad)
296 break; 299 break;
297 if (convert_time (convert, mid, tp)) 300 if (__tz_convert (mid, local, tp))
298 ok = mid, oktm = *tp; 301 ok = mid, oktm = *tp;
299 else if (errno != EOVERFLOW) 302 else if (errno != EOVERFLOW)
300 return NULL; 303 return NULL;
@@ -310,36 +313,45 @@ ranged_convert (struct tm *(*convert) (const __time64_t *, struct tm *),
310} 313}
311 314
312 315
313/* Convert *TP to a __time64_t value, inverting 316/* Convert *TP to a __time64_t value. If LOCAL, the reverse mapping
314 the monotonic and mostly-unit-linear conversion function CONVERT. 317 is performed as if localtime, otherwise as if by gmtime. Use
315 Use *OFFSET to keep track of a guess at the offset of the result, 318 *OFFSET to keep track of a guess at the offset of the result,
316 compared to what the result would be for UTC without leap seconds. 319 compared to what the result would be for UTC without leap seconds.
317 If *OFFSET's guess is correct, only one CONVERT call is needed. 320 If *OFFSET's guess is correct, only one reverse mapping call is
318 If successful, set *TP to the canonicalized struct tm; 321 needed. If successful, set *TP to the canonicalized struct tm;
319 otherwise leave *TP alone, return ((time_t) -1) and set errno. 322 otherwise leave *TP alone, return ((time_t) -1) and set errno.
320 This function is external because it is used also by timegm.c. */ 323 This function is external because it is used also by timegm.c. */
321__time64_t 324__time64_t
322__mktime_internal (struct tm *tp, 325__mktime_internal (struct tm *tp, bool local, mktime_offset_t *offset)
323 struct tm *(*convert) (const __time64_t *, struct tm *),
324 mktime_offset_t *offset)
325{ 326{
326 struct tm tm; 327 struct tm tm;
327 328
328 /* The maximum number of probes (calls to CONVERT) should be enough 329 /* The maximum number of probes should be enough to handle any
329 to handle any combinations of time zone rule changes, solar time, 330 combinations of time zone rule changes, solar time, leap seconds,
330 leap seconds, and oscillations around a spring-forward gap. 331 and oscillations around a spring-forward gap. POSIX.1 prohibits
331 POSIX.1 prohibits leap seconds, but some hosts have them anyway. */ 332 leap seconds, but some hosts have them anyway. */
332 int remaining_probes = 6; 333 int remaining_probes = 6;
333 334
334 /* Time requested. Copy it in case CONVERT modifies *TP; this can 335#ifndef _LIBC
335 occur if TP is localtime's returned value and CONVERT is localtime. */ 336 /* Gnulib mktime doesn't lock the tz state, so it may need to probe
337 more often if some other thread changes local time while
338 __mktime_internal is probing. Double the number of probes; this
339 should suffice for practical cases that are at all likely. */
340 remaining_probes *= 2;
341#endif
342
343 /* Time requested. Copy it in case gmtime/localtime modify *TP;
344 this can occur if TP is localtime's returned value and CONVERT is
345 localtime. */
336 int sec = tp->tm_sec; 346 int sec = tp->tm_sec;
337 int min = tp->tm_min; 347 int min = tp->tm_min;
338 int hour = tp->tm_hour; 348 int hour = tp->tm_hour;
339 int mday = tp->tm_mday; 349 int mday = tp->tm_mday;
340 int mon = tp->tm_mon; 350 int mon = tp->tm_mon;
341 int year_requested = tp->tm_year; 351 int year_requested = tp->tm_year;
342 int isdst = tp->tm_isdst; 352
353 /* Ignore any tm_isdst request for timegm. */
354 int isdst = local ? tp->tm_isdst : 0;
343 355
344 /* 1 if the previous probe was DST. */ 356 /* 1 if the previous probe was DST. */
345 int dst2 = 0; 357 int dst2 = 0;
@@ -390,7 +402,7 @@ __mktime_internal (struct tm *tp,
390 402
391 while (true) 403 while (true)
392 { 404 {
393 if (! ranged_convert (convert, &t, &tm)) 405 if (! ranged_convert (local, &t, &tm))
394 return -1; 406 return -1;
395 long_int dt = tm_diff (year, yday, hour, min, sec, &tm); 407 long_int dt = tm_diff (year, yday, hour, min, sec, &tm);
396 if (dt == 0) 408 if (dt == 0)
@@ -469,7 +481,7 @@ __mktime_internal (struct tm *tp,
469 if (! ckd_add (&ot, t, delta * direction)) 481 if (! ckd_add (&ot, t, delta * direction))
470 { 482 {
471 struct tm otm; 483 struct tm otm;
472 if (! ranged_convert (convert, &ot, &otm)) 484 if (! ranged_convert (local, &ot, &otm))
473 return -1; 485 return -1;
474 if (! isdst_differ (isdst, otm.tm_isdst)) 486 if (! isdst_differ (isdst, otm.tm_isdst))
475 { 487 {
@@ -479,7 +491,7 @@ __mktime_internal (struct tm *tp,
479 &otm); 491 &otm);
480 if (mktime_min <= gt && gt <= mktime_max) 492 if (mktime_min <= gt && gt <= mktime_max)
481 { 493 {
482 if (convert_time (convert, gt, &tm)) 494 if (__tz_convert (gt, local, &tm))
483 { 495 {
484 t = gt; 496 t = gt;
485 goto offset_found; 497 goto offset_found;
@@ -493,7 +505,7 @@ __mktime_internal (struct tm *tp,
493 505
494 /* No unusual DST offset was found nearby. Assume one-hour DST. */ 506 /* No unusual DST offset was found nearby. Assume one-hour DST. */
495 t += 60 * 60 * dst_difference; 507 t += 60 * 60 * dst_difference;
496 if (mktime_min <= t && t <= mktime_max && convert_time (convert, t, &tm)) 508 if (mktime_min <= t && t <= mktime_max && __tz_convert (t, local, &tm))
497 goto offset_found; 509 goto offset_found;
498 510
499 __set_errno (EOVERFLOW); 511 __set_errno (EOVERFLOW);
@@ -520,7 +532,7 @@ __mktime_internal (struct tm *tp,
520 __set_errno (EOVERFLOW); 532 __set_errno (EOVERFLOW);
521 return -1; 533 return -1;
522 } 534 }
523 if (! convert_time (convert, t, &tm)) 535 if (! __tz_convert (t, local, &tm))
524 return -1; 536 return -1;
525 } 537 }
526 538
@@ -536,14 +548,13 @@ __mktime_internal (struct tm *tp,
536__time64_t 548__time64_t
537__mktime64 (struct tm *tp) 549__mktime64 (struct tm *tp)
538{ 550{
539 /* POSIX.1 8.1.1 requires that whenever mktime() is called, the 551 /* POSIX.1 requires mktime to set external variables like 'tzname'
540 time zone names contained in the external variable 'tzname' shall 552 as though tzset had been called. */
541 be set as if the tzset() function had been called. */
542 __tzset (); 553 __tzset ();
543 554
544# if defined _LIBC || NEED_MKTIME_WORKING 555# if defined _LIBC || NEED_MKTIME_WORKING
545 static mktime_offset_t localtime_offset; 556 static mktime_offset_t localtime_offset;
546 return __mktime_internal (tp, __localtime64_r, &localtime_offset); 557 return __mktime_internal (tp, true, &localtime_offset);
547# else 558# else
548# undef mktime 559# undef mktime
549 return mktime (tp); 560 return mktime (tp);
diff --git a/lib/nproc.c b/lib/nproc.c
index 92a07e82890..0b5898d88ff 100644
--- a/lib/nproc.c
+++ b/lib/nproc.c
@@ -20,6 +20,7 @@
20#include <config.h> 20#include <config.h>
21#include "nproc.h" 21#include "nproc.h"
22 22
23#include <errno.h>
23#include <limits.h> 24#include <limits.h>
24#include <stdlib.h> 25#include <stdlib.h>
25#include <unistd.h> 26#include <unistd.h>
@@ -125,6 +126,46 @@ num_processors_via_affinity_mask (void)
125 } 126 }
126 } 127 }
127#elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC /* glibc >= 2.3.4 */ 128#elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC /* glibc >= 2.3.4 */
129 /* There are two ways to use the sched_getaffinity() function:
130 - With a statically-sized cpu_set_t.
131 - With a dynamically-sized cpu_set_t.
132 Documentation:
133 <https://www.kernel.org/doc/man-pages/online/pages/man2/sched_getaffinity.2.html>
134 <https://www.kernel.org/doc/man-pages/online/pages/man3/CPU_SET.3.html>
135 The second way has the advantage that it works on systems with more than
136 1024 CPUs. The first way has the advantage that it works also when memory
137 is tight. */
138# if defined CPU_ALLOC_SIZE /* glibc >= 2.6 */
139 {
140 unsigned int alloc_count = 1024;
141 for (;;)
142 {
143 cpu_set_t *set = CPU_ALLOC (alloc_count);
144 if (set == NULL)
145 /* Out of memory. */
146 break;
147 unsigned int size = CPU_ALLOC_SIZE (alloc_count);
148 if (sched_getaffinity (0, size, set) == 0)
149 {
150 unsigned int count = CPU_COUNT_S (size, set);
151 CPU_FREE (set);
152 return count;
153 }
154 if (errno != EINVAL)
155 {
156 /* Some other error. */
157 CPU_FREE (set);
158 return 0;
159 }
160 CPU_FREE (set);
161 /* Retry with some larger cpu_set_t. */
162 alloc_count *= 2;
163 if (alloc_count == 0)
164 /* Integer overflow. Avoid an endless loop. */
165 return 0;
166 }
167 }
168# endif
128 { 169 {
129 cpu_set_t set; 170 cpu_set_t set;
130 171
diff --git a/lib/pipe2.c b/lib/pipe2.c
index 7b476df3457..e290f94a94a 100644
--- a/lib/pipe2.c
+++ b/lib/pipe2.c
@@ -40,7 +40,7 @@ pipe2 (int fd[2], int flags)
40{ 40{
41 /* Mingw _pipe() corrupts fd on failure; also, if we succeed at 41 /* Mingw _pipe() corrupts fd on failure; also, if we succeed at
42 creating the pipe but later fail at changing fcntl, we want 42 creating the pipe but later fail at changing fcntl, we want
43 to leave fd unchanged: http://austingroupbugs.net/view.php?id=467 */ 43 to leave fd unchanged: https://austingroupbugs.net/view.php?id=467 */
44 int tmp[2]; 44 int tmp[2];
45 tmp[0] = fd[0]; 45 tmp[0] = fd[0];
46 tmp[1] = fd[1]; 46 tmp[1] = fd[1];
diff --git a/lib/realloc.c b/lib/realloc.c
index 0573139625e..58044745f45 100644
--- a/lib/realloc.c
+++ b/lib/realloc.c
@@ -18,17 +18,21 @@
18 18
19/* written by Jim Meyering and Bruno Haible */ 19/* written by Jim Meyering and Bruno Haible */
20 20
21/* Ensure that we call the system's realloc() below. */
22#define _GL_USE_STDLIB_ALLOC 1
21#include <config.h> 23#include <config.h>
22 24
25#define _GL_REALLOC_INLINE _GL_EXTERN_INLINE
23#include <stdlib.h> 26#include <stdlib.h>
24 27
25#include <errno.h> 28#include <errno.h>
29#include <stdckdint.h>
26 30
27#include "xalloc-oversized.h" 31#ifdef __CHERI_PURE_CAPABILITY__
32# include <cheri.h>
33#endif
28 34
29/* Call the system's realloc below. This file does not define 35#ifndef _GL_INLINE_RPL_REALLOC
30 _GL_USE_STDLIB_ALLOC because it needs Gnulib's malloc if present. */
31#undef realloc
32 36
33/* Change the size of an allocated block of memory P to N bytes, 37/* Change the size of an allocated block of memory P to N bytes,
34 with error checking. If P is NULL, use malloc. Otherwise if N is zero, 38 with error checking. If P is NULL, use malloc. Otherwise if N is zero,
@@ -37,27 +41,70 @@
37void * 41void *
38rpl_realloc (void *p, size_t n) 42rpl_realloc (void *p, size_t n)
39{ 43{
40 if (p == NULL) 44 size_t n1 = n;
41 return malloc (n);
42 45
43 if (n == 0) 46 if (n == 0)
44 { 47 {
45 free (p); 48# if NEED_SANITIZED_REALLOC
46 return NULL; 49 /* When P is non-null, ISO C23 §7.24.3.7.(3) says realloc (P, 0) has
50 undefined behavior even though C17 and earlier partially defined
51 the behavior. Let the programmer know.
52 When the undefined-behaviour sanitizers report this case, i.e. when
53 <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117233> and
54 <https://github.com/llvm/llvm-project/issues/113065>
55 have been closed and new releases of GCC and clang have been made,
56 we can revisit this code. */
57 if (p != NULL)
58 abort ();
59# endif
60
61 /* realloc (NULL, 0) acts like glibc malloc (0), i.e., like malloc (1)
62 except the caller cannot dereference any non-null return.
63
64 realloc (P, 0) with non-null P is a messier situation.
65 As mentioned above, C23 says behavior is undefined.
66 POSIX.1-2024 extends C17 to say realloc (P, 0)
67 either fails by setting errno and returning a null pointer,
68 or succeeds by freeing P and then either:
69 (a) setting errno=EINVAL and returning a null pointer; or
70 (b) acting like a successful malloc (0).
71 glibc 1 through 2.1 realloc acted like (b),
72 which conforms to C17, to C23 and to POSIX.1-2024.
73 glibc 2.1.1+ realloc acts like (a) except it does not set errno;
74 this conforms to C17 and to C23 but not to POSIX.1-2024.
75 Quite possibly future versions of POSIX will change,
76 due either to C23 or to (a)'s semantics being messy.
77 Act like (b), as that's easy, matches GNU, BSD and V7 malloc,
78 matches BSD and V7 realloc, and requires no extra code at
79 caller sites. */
80
81# if !HAVE_REALLOC_0_NONNULL
82 n1 = 1;
83# endif
47 } 84 }
48 85
49 if (xalloc_oversized (n, 1)) 86# if !HAVE_MALLOC_PTRDIFF
87 ptrdiff_t signed_n;
88 if (ckd_add (&signed_n, n, 0))
50 { 89 {
51 errno = ENOMEM; 90 errno = ENOMEM;
52 return NULL; 91 return NULL;
53 } 92 }
93# endif
54 94
55 void *result = realloc (p, n); 95 void *result = realloc (p, n1);
56 96
57#if !HAVE_MALLOC_POSIX 97# if !HAVE_MALLOC_POSIX
58 if (result == NULL) 98 if (result == NULL)
59 errno = ENOMEM; 99 errno = ENOMEM;
60#endif 100# endif
101
102# ifdef __CHERI_PURE_CAPABILITY__
103 if (result != NULL)
104 result = cheri_bounds_set (result, n);
105# endif
61 106
62 return result; 107 return result;
63} 108}
109
110#endif
diff --git a/lib/regex.h b/lib/regex.h
index ccf40cebc0e..004dc624050 100644
--- a/lib/regex.h
+++ b/lib/regex.h
@@ -647,10 +647,12 @@ extern int re_exec (const char *);
647 || 2 < __GNUC__ + (95 <= __GNUC_MINOR__) \ 647 || 2 < __GNUC__ + (95 <= __GNUC_MINOR__) \
648 || __clang_major__ >= 3 648 || __clang_major__ >= 3
649# define _Restrict_ __restrict 649# define _Restrict_ __restrict
650# elif 199901L <= __STDC_VERSION__ || defined restrict
651# define _Restrict_ restrict
652# else 650# else
653# define _Restrict_ 651# if 199901L <= __STDC_VERSION__ || defined restrict
652# define _Restrict_ restrict
653# else
654# define _Restrict_
655# endif
654# endif 656# endif
655#endif 657#endif
656/* For the ISO C99 syntax 658/* For the ISO C99 syntax
@@ -661,13 +663,15 @@ extern int re_exec (const char *);
661#ifndef _Restrict_arr_ 663#ifndef _Restrict_arr_
662# ifdef __restrict_arr 664# ifdef __restrict_arr
663# define _Restrict_arr_ __restrict_arr 665# define _Restrict_arr_ __restrict_arr
664# elif ((199901L <= __STDC_VERSION__ \ 666# else
667# if ((199901L <= __STDC_VERSION__ \
665 || 3 < __GNUC__ + (1 <= __GNUC_MINOR__) \ 668 || 3 < __GNUC__ + (1 <= __GNUC_MINOR__) \
666 || __clang_major__ >= 3) \ 669 || __clang_major__ >= 3) \
667 && !defined __cplusplus) 670 && !defined __cplusplus)
668# define _Restrict_arr_ _Restrict_ 671# define _Restrict_arr_ _Restrict_
669# else 672# else
670# define _Restrict_arr_ 673# define _Restrict_arr_
674# endif
671# endif 675# endif
672#endif 676#endif
673 677
diff --git a/lib/regex_internal.c b/lib/regex_internal.c
index 8cd096ebcfb..6ccf701f266 100644
--- a/lib/regex_internal.c
+++ b/lib/regex_internal.c
@@ -937,8 +937,7 @@ re_node_set_alloc (re_node_set *set, Idx size)
937 set->alloc = size; 937 set->alloc = size;
938 set->nelem = 0; 938 set->nelem = 0;
939 set->elems = re_malloc (Idx, size); 939 set->elems = re_malloc (Idx, size);
940 if (__glibc_unlikely (set->elems == NULL) 940 if (__glibc_unlikely (set->elems == NULL))
941 && (MALLOC_0_IS_NONNULL || size != 0))
942 return REG_ESPACE; 941 return REG_ESPACE;
943 return REG_NOERROR; 942 return REG_NOERROR;
944} 943}
diff --git a/lib/regex_internal.h b/lib/regex_internal.h
index 6165cb17c70..02c2ca68960 100644
--- a/lib/regex_internal.h
+++ b/lib/regex_internal.h
@@ -100,10 +100,12 @@
100/* This is for other GNU distributions with internationalized messages. */ 100/* This is for other GNU distributions with internationalized messages. */
101#if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC 101#if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
102# include <libintl.h> 102# include <libintl.h>
103# undef gettext
103# ifdef _LIBC 104# ifdef _LIBC
104# undef gettext
105# define gettext(msgid) \ 105# define gettext(msgid) \
106 __dcgettext (_libc_intl_domainname, msgid, LC_MESSAGES) 106 __dcgettext (_libc_intl_domainname, msgid, LC_MESSAGES)
107# else
108# define gettext(msgid) dgettext ("gnulib", msgid)
107# endif 109# endif
108#else 110#else
109# undef gettext 111# undef gettext
@@ -436,12 +438,6 @@ typedef struct re_dfa_t re_dfa_t;
436#define re_string_skip_bytes(pstr,idx) ((pstr)->cur_idx += (idx)) 438#define re_string_skip_bytes(pstr,idx) ((pstr)->cur_idx += (idx))
437#define re_string_set_index(pstr,idx) ((pstr)->cur_idx = (idx)) 439#define re_string_set_index(pstr,idx) ((pstr)->cur_idx = (idx))
438 440
439#ifdef _LIBC
440# define MALLOC_0_IS_NONNULL 1
441#elif !defined MALLOC_0_IS_NONNULL
442# define MALLOC_0_IS_NONNULL 0
443#endif
444
445#ifndef MAX 441#ifndef MAX
446# define MAX(a,b) ((a) < (b) ? (b) : (a)) 442# define MAX(a,b) ((a) < (b) ? (b) : (a))
447#endif 443#endif
diff --git a/lib/stdio-impl.h b/lib/stdio-impl.h
index 63ebf7c64b7..dfb5166171a 100644
--- a/lib/stdio-impl.h
+++ b/lib/stdio-impl.h
@@ -110,7 +110,7 @@
110# endif 110# endif
111 111
112# if (defined __NetBSD__ && __NetBSD_Version__ >= 105270000) || defined __OpenBSD__ || defined __minix /* NetBSD >= 1.5ZA, OpenBSD, Minix 3 */ 112# if (defined __NetBSD__ && __NetBSD_Version__ >= 105270000) || defined __OpenBSD__ || defined __minix /* NetBSD >= 1.5ZA, OpenBSD, Minix 3 */
113 /* See <http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/stdio/fileext.h?rev=HEAD&content-type=text/x-cvsweb-markup> 113 /* See <https://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/stdio/fileext.h?rev=HEAD&content-type=text/x-cvsweb-markup>
114 and <https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libc/stdio/fileext.h?rev=HEAD&content-type=text/x-cvsweb-markup> 114 and <https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libc/stdio/fileext.h?rev=HEAD&content-type=text/x-cvsweb-markup>
115 and <https://github.com/Stichting-MINIX-Research-Foundation/minix/blob/master/lib/libc/stdio/fileext.h> */ 115 and <https://github.com/Stichting-MINIX-Research-Foundation/minix/blob/master/lib/libc/stdio/fileext.h> */
116 struct __sfileext 116 struct __sfileext
diff --git a/lib/stdlib.c b/lib/stdlib.c
new file mode 100644
index 00000000000..521d64627dc
--- /dev/null
+++ b/lib/stdlib.c
@@ -0,0 +1,21 @@
1/* Inline functions for <stdlib.h>.
2
3 Copyright (C) 2024 Free Software Foundation, Inc.
4
5 This file is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as
7 published by the Free Software Foundation; either version 2.1 of the
8 License, or (at your option) any later version.
9
10 This file is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */
17
18#include <config.h>
19
20#define _GL_STDLIB_INLINE _GL_EXTERN_INLINE
21#include <stdlib.h>
diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h
index 6667f426ad9..adbef69131b 100644
--- a/lib/stdlib.in.h
+++ b/lib/stdlib.in.h
@@ -54,7 +54,7 @@
54 54
55/* This file uses _Noreturn, _GL_ATTRIBUTE_DEALLOC, _GL_ATTRIBUTE_MALLOC, 55/* This file uses _Noreturn, _GL_ATTRIBUTE_DEALLOC, _GL_ATTRIBUTE_MALLOC,
56 _GL_ATTRIBUTE_NODISCARD, _GL_ATTRIBUTE_NOTHROW, _GL_ATTRIBUTE_PURE, 56 _GL_ATTRIBUTE_NODISCARD, _GL_ATTRIBUTE_NOTHROW, _GL_ATTRIBUTE_PURE,
57 GNULIB_POSIXCHECK, HAVE_RAW_DECL_*. */ 57 _GL_INLINE_HEADER_BEGIN, GNULIB_POSIXCHECK, HAVE_RAW_DECL_*. */
58#if !_GL_CONFIG_H_INCLUDED 58#if !_GL_CONFIG_H_INCLUDED
59 #error "Please include config.h first." 59 #error "Please include config.h first."
60#endif 60#endif
@@ -130,6 +130,14 @@ struct random_data
130# include <string> 130# include <string>
131#endif 131#endif
132 132
133_GL_INLINE_HEADER_BEGIN
134#ifndef _GL_STDLIB_INLINE
135# define _GL_STDLIB_INLINE _GL_INLINE
136#endif
137#ifndef _GL_REALLOC_INLINE
138# define _GL_REALLOC_INLINE _GL_INLINE
139#endif
140
133/* _GL_ATTRIBUTE_DEALLOC (F, I) declares that the function returns pointers 141/* _GL_ATTRIBUTE_DEALLOC (F, I) declares that the function returns pointers
134 that can be freed by passing them as the Ith argument to the 142 that can be freed by passing them as the Ith argument to the
135 function F. */ 143 function F. */
@@ -283,8 +291,8 @@ _GL_CXXALIASWARN (free);
283#elif defined GNULIB_POSIXCHECK 291#elif defined GNULIB_POSIXCHECK
284# undef free 292# undef free
285/* Assume free is always declared. */ 293/* Assume free is always declared. */
286_GL_WARN_ON_USE (free, "free is not future POSIX compliant everywhere - " 294_GL_WARN_ON_USE (free, "free is not POSIX:2024 compliant everywhere - "
287 "use gnulib module free for portability"); 295 "use gnulib module free-posix for portability");
288#endif 296#endif
289 297
290 298
@@ -367,9 +375,10 @@ _GL_WARN_ON_USE (atoll, "atoll is unportable - "
367#endif 375#endif
368 376
369#if @GNULIB_CALLOC_POSIX@ 377#if @GNULIB_CALLOC_POSIX@
370# if (@GNULIB_CALLOC_POSIX@ && @REPLACE_CALLOC_FOR_CALLOC_POSIX@) \ 378# if @REPLACE_CALLOC_FOR_CALLOC_POSIX@ \
371 || (@GNULIB_CALLOC_GNU@ && @REPLACE_CALLOC_FOR_CALLOC_GNU@) 379 || (@GNULIB_CALLOC_GNU@ && @REPLACE_CALLOC_FOR_CALLOC_GNU@)
372# if !(defined __cplusplus && defined GNULIB_NAMESPACE) 380# if !((defined __cplusplus && defined GNULIB_NAMESPACE) \
381 || _GL_USE_STDLIB_ALLOC)
373# undef calloc 382# undef calloc
374# define calloc rpl_calloc 383# define calloc rpl_calloc
375# endif 384# endif
@@ -681,7 +690,7 @@ _GL_WARN_ON_USE (grantpt, "grantpt is not portable - "
681 by never specifying a zero size), so it does not need malloc or 690 by never specifying a zero size), so it does not need malloc or
682 realloc to be redefined. */ 691 realloc to be redefined. */
683#if @GNULIB_MALLOC_POSIX@ 692#if @GNULIB_MALLOC_POSIX@
684# if (@GNULIB_MALLOC_POSIX@ && @REPLACE_MALLOC_FOR_MALLOC_POSIX@) \ 693# if @REPLACE_MALLOC_FOR_MALLOC_POSIX@ \
685 || (@GNULIB_MALLOC_GNU@ && @REPLACE_MALLOC_FOR_MALLOC_GNU@) 694 || (@GNULIB_MALLOC_GNU@ && @REPLACE_MALLOC_FOR_MALLOC_GNU@)
686# if !((defined __cplusplus && defined GNULIB_NAMESPACE) \ 695# if !((defined __cplusplus && defined GNULIB_NAMESPACE) \
687 || _GL_USE_STDLIB_ALLOC) 696 || _GL_USE_STDLIB_ALLOC)
@@ -740,11 +749,12 @@ _GL_WARN_ON_USE (malloc, "malloc is not POSIX compliant everywhere - "
740/* Return maximum number of bytes of a multibyte character. */ 749/* Return maximum number of bytes of a multibyte character. */
741#if @REPLACE_MB_CUR_MAX@ 750#if @REPLACE_MB_CUR_MAX@
742# if !GNULIB_defined_MB_CUR_MAX 751# if !GNULIB_defined_MB_CUR_MAX
743static inline 752_GL_STDLIB_INLINE int
744int gl_MB_CUR_MAX (void) 753gl_MB_CUR_MAX (void)
745{ 754{
746 /* Turn the value 3 to the value 4, as needed for the UTF-8 encoding. */ 755 /* Turn the value 3 to the value 4, as needed for the UTF-8 encoding. */
747 return MB_CUR_MAX + (MB_CUR_MAX == 3); 756 int gl_mb_cur_max = MB_CUR_MAX;
757 return gl_mb_cur_max == 3 ? 4 : gl_mb_cur_max;
748} 758}
749# undef MB_CUR_MAX 759# undef MB_CUR_MAX
750# define MB_CUR_MAX gl_MB_CUR_MAX () 760# define MB_CUR_MAX gl_MB_CUR_MAX ()
@@ -1454,16 +1464,25 @@ _GL_WARN_ON_USE (setstate_r, "setstate_r is unportable - "
1454 1464
1455 1465
1456#if @GNULIB_REALLOC_POSIX@ 1466#if @GNULIB_REALLOC_POSIX@
1457# if (@GNULIB_REALLOC_POSIX@ && @REPLACE_REALLOC_FOR_REALLOC_POSIX@) \ 1467# if @REPLACE_REALLOC_FOR_REALLOC_POSIX@
1458 || (@GNULIB_REALLOC_GNU@ && @REPLACE_REALLOC_FOR_REALLOC_GNU@) 1468# if @REPLACE_REALLOC_FOR_REALLOC_POSIX@ == 2
1469# define _GL_INLINE_RPL_REALLOC 1
1470_GL_REALLOC_INLINE void *
1471rpl_realloc (void *ptr, size_t size)
1472{
1473 return realloc (ptr, size ? size : 1);
1474}
1475# endif
1459# if !((defined __cplusplus && defined GNULIB_NAMESPACE) \ 1476# if !((defined __cplusplus && defined GNULIB_NAMESPACE) \
1460 || _GL_USE_STDLIB_ALLOC) 1477 || _GL_USE_STDLIB_ALLOC)
1461# undef realloc 1478# undef realloc
1462# define realloc rpl_realloc 1479# define realloc rpl_realloc
1463# endif 1480# endif
1481# if !defined _GL_INLINE_RPL_REALLOC
1464_GL_FUNCDECL_RPL (realloc, void *, 1482_GL_FUNCDECL_RPL (realloc, void *,
1465 (void *ptr, size_t size), 1483 (void *ptr, size_t size),
1466 _GL_ATTRIBUTE_DEALLOC_FREE _GL_ATTRIBUTE_NODISCARD); 1484 _GL_ATTRIBUTE_DEALLOC_FREE _GL_ATTRIBUTE_NODISCARD);
1485# endif
1467_GL_CXXALIAS_RPL (realloc, void *, (void *ptr, size_t size)); 1486_GL_CXXALIAS_RPL (realloc, void *, (void *ptr, size_t size));
1468# else 1487# else
1469# if __GNUC__ >= 11 && !defined __clang__ 1488# if __GNUC__ >= 11 && !defined __clang__
@@ -1968,6 +1987,8 @@ _GL_CXXALIASWARN (wctomb);
1968#endif 1987#endif
1969 1988
1970 1989
1990_GL_INLINE_HEADER_END
1991
1971#endif /* _@GUARD_PREFIX@_STDLIB_H */ 1992#endif /* _@GUARD_PREFIX@_STDLIB_H */
1972#endif /* _@GUARD_PREFIX@_STDLIB_H */ 1993#endif /* _@GUARD_PREFIX@_STDLIB_H */
1973#endif 1994#endif
diff --git a/lib/timegm.c b/lib/timegm.c
index e5cf30c0198..ba28b3ecd96 100644
--- a/lib/timegm.c
+++ b/lib/timegm.c
@@ -30,8 +30,7 @@ __time64_t
30__timegm64 (struct tm *tmp) 30__timegm64 (struct tm *tmp)
31{ 31{
32 static mktime_offset_t gmtime_offset; 32 static mktime_offset_t gmtime_offset;
33 tmp->tm_isdst = 0; 33 return __mktime_internal (tmp, false, &gmtime_offset);
34 return __mktime_internal (tmp, __gmtime64_r, &gmtime_offset);
35} 34}
36 35
37#if defined _LIBC && __TIMESIZE != 64 36#if defined _LIBC && __TIMESIZE != 64
diff --git a/lib/unistd.in.h b/lib/unistd.in.h
index 20b1356fd38..ceb3cb48f15 100644
--- a/lib/unistd.in.h
+++ b/lib/unistd.in.h
@@ -181,6 +181,9 @@ _GL_INLINE_HEADER_BEGIN
181#ifndef _GL_UNISTD_INLINE 181#ifndef _GL_UNISTD_INLINE
182# define _GL_UNISTD_INLINE _GL_INLINE 182# define _GL_UNISTD_INLINE _GL_INLINE
183#endif 183#endif
184#ifndef _GL_GETPAGESIZE_INLINE
185# define _GL_GETPAGESIZE_INLINE _GL_INLINE
186#endif
184 187
185/* Hide some function declarations from <winsock2.h>. */ 188/* Hide some function declarations from <winsock2.h>. */
186 189
@@ -1478,7 +1481,7 @@ _GL_FUNCDECL_SYS (getpagesize, int, (void), );
1478# define getpagesize() _gl_getpagesize () 1481# define getpagesize() _gl_getpagesize ()
1479# else 1482# else
1480# if !GNULIB_defined_getpagesize_function 1483# if !GNULIB_defined_getpagesize_function
1481_GL_UNISTD_INLINE int 1484_GL_GETPAGESIZE_INLINE int
1482getpagesize () 1485getpagesize ()
1483{ 1486{
1484 return _gl_getpagesize (); 1487 return _gl_getpagesize ();
diff --git a/lib/utimens.c b/lib/utimens.c
index cd86a44ea76..3c81b5c3492 100644
--- a/lib/utimens.c
+++ b/lib/utimens.c
@@ -78,6 +78,21 @@ static int utimensat_works_really;
78static int lutimensat_works_really; 78static int lutimensat_works_really;
79#endif /* HAVE_UTIMENSAT || HAVE_FUTIMENS */ 79#endif /* HAVE_UTIMENSAT || HAVE_FUTIMENS */
80 80
81static bool
82is_valid_timespec (struct timespec const *timespec)
83{
84 return (timespec->tv_nsec == UTIME_NOW
85 || timespec->tv_nsec == UTIME_OMIT
86 || (0 <= timespec->tv_nsec && timespec->tv_nsec < TIMESPEC_HZ));
87}
88
89static bool
90is_valid_timespecs (struct timespec const timespec[2])
91{
92 return (is_valid_timespec (&timespec[0])
93 && is_valid_timespec (&timespec[1]));
94}
95
81/* Validate the requested timestamps. Return 0 if the resulting 96/* Validate the requested timestamps. Return 0 if the resulting
82 timespec can be used for utimensat (after possibly modifying it to 97 timespec can be used for utimensat (after possibly modifying it to
83 work around bugs in utimensat). Return a positive value if the 98 work around bugs in utimensat). Return a positive value if the
@@ -90,14 +105,7 @@ validate_timespec (struct timespec timespec[2])
90{ 105{
91 int result = 0; 106 int result = 0;
92 int utime_omit_count = 0; 107 int utime_omit_count = 0;
93 if ((timespec[0].tv_nsec != UTIME_NOW 108 if (!is_valid_timespecs (timespec))
94 && timespec[0].tv_nsec != UTIME_OMIT
95 && ! (0 <= timespec[0].tv_nsec
96 && timespec[0].tv_nsec < TIMESPEC_HZ))
97 || (timespec[1].tv_nsec != UTIME_NOW
98 && timespec[1].tv_nsec != UTIME_OMIT
99 && ! (0 <= timespec[1].tv_nsec
100 && timespec[1].tv_nsec < TIMESPEC_HZ)))
101 { 109 {
102 errno = EINVAL; 110 errno = EINVAL;
103 return -1; 111 return -1;
@@ -516,24 +524,44 @@ fdutimens (int fd, char const *file, struct timespec const timespec[2])
516 } 524 }
517} 525}
518 526
519#if !HAVE_UTIMENS
520/* Set the access and modification timestamps of FILE to be 527/* Set the access and modification timestamps of FILE to be
521 TIMESPEC[0] and TIMESPEC[1], respectively. */ 528 TIMESPEC[0] and TIMESPEC[1], respectively. */
522int 529int
523utimens (char const *file, struct timespec const timespec[2]) 530utimens (char const *file, struct timespec const timespec[2])
531#undef utimens
524{ 532{
533#if HAVE_UTIMENS
534 /* NetBSD's native utimens() does not fulfil the Gnulib expectations:
535 At least in NetBSD 10.0, it does not validate the timespec argument. */
536 if (timespec != NULL && !is_valid_timespecs (timespec))
537 {
538 errno = EINVAL;
539 return -1;
540 }
541 return utimens (file, timespec);
542#else
525 return fdutimens (-1, file, timespec); 543 return fdutimens (-1, file, timespec);
526}
527#endif 544#endif
545}
528 546
529#if !HAVE_LUTIMENS
530/* Set the access and modification timestamps of FILE to be 547/* Set the access and modification timestamps of FILE to be
531 TIMESPEC[0] and TIMESPEC[1], respectively, without dereferencing 548 TIMESPEC[0] and TIMESPEC[1], respectively, without dereferencing
532 symlinks. Fail with ENOSYS if the platform does not support 549 symlinks. Fail with ENOSYS if the platform does not support
533 changing symlink timestamps, but FILE was a symlink. */ 550 changing symlink timestamps, but FILE was a symlink. */
534int 551int
535lutimens (char const *file, struct timespec const timespec[2]) 552lutimens (char const *file, struct timespec const timespec[2])
553#undef lutimens
536{ 554{
555#if HAVE_LUTIMENS
556 /* NetBSD's native lutimens() does not fulfil the Gnulib expectations:
557 At least in NetBSD 10.0, it does not validate the timespec argument. */
558 if (timespec != NULL && !is_valid_timespecs (timespec))
559 {
560 errno = EINVAL;
561 return -1;
562 }
563 return lutimens (file, timespec);
564#else
537 struct timespec adjusted_timespec[2]; 565 struct timespec adjusted_timespec[2];
538 struct timespec *ts = timespec ? adjusted_timespec : NULL; 566 struct timespec *ts = timespec ? adjusted_timespec : NULL;
539 int adjustment_needed = 0; 567 int adjustment_needed = 0;
@@ -553,11 +581,11 @@ lutimens (char const *file, struct timespec const timespec[2])
553 fdutimens' worry about buggy NFS clients. But we do have to 581 fdutimens' worry about buggy NFS clients. But we do have to
554 worry about bogus return values. */ 582 worry about bogus return values. */
555 583
556#if HAVE_UTIMENSAT 584# if HAVE_UTIMENSAT
557 if (0 <= lutimensat_works_really) 585 if (0 <= lutimensat_works_really)
558 { 586 {
559 int result; 587 int result;
560# if defined __linux__ || defined __sun || defined __NetBSD__ 588# if defined __linux__ || defined __sun || defined __NetBSD__
561 /* As recently as Linux kernel 2.6.32 (Dec 2009), several file 589 /* As recently as Linux kernel 2.6.32 (Dec 2009), several file
562 systems (xfs, ntfs-3g) have bugs with a single UTIME_OMIT, 590 systems (xfs, ntfs-3g) have bugs with a single UTIME_OMIT,
563 but work if both times are either explicitly specified or 591 but work if both times are either explicitly specified or
@@ -582,9 +610,9 @@ lutimens (char const *file, struct timespec const timespec[2])
582 /* Note that st is good, in case utimensat gives ENOSYS. */ 610 /* Note that st is good, in case utimensat gives ENOSYS. */
583 adjustment_needed++; 611 adjustment_needed++;
584 } 612 }
585# endif 613# endif
586 result = utimensat (AT_FDCWD, file, ts, AT_SYMLINK_NOFOLLOW); 614 result = utimensat (AT_FDCWD, file, ts, AT_SYMLINK_NOFOLLOW);
587# ifdef __linux__ 615# ifdef __linux__
588 /* Work around a kernel bug: 616 /* Work around a kernel bug:
589 https://bugzilla.redhat.com/show_bug.cgi?id=442352 617 https://bugzilla.redhat.com/show_bug.cgi?id=442352
590 https://bugzilla.redhat.com/show_bug.cgi?id=449910 618 https://bugzilla.redhat.com/show_bug.cgi?id=449910
@@ -594,7 +622,7 @@ lutimens (char const *file, struct timespec const timespec[2])
594 are no longer in common use. */ 622 are no longer in common use. */
595 if (0 < result) 623 if (0 < result)
596 errno = ENOSYS; 624 errno = ENOSYS;
597# endif 625# endif
598 if (result == 0 || errno != ENOSYS) 626 if (result == 0 || errno != ENOSYS)
599 { 627 {
600 utimensat_works_really = 1; 628 utimensat_works_really = 1;
@@ -603,7 +631,7 @@ lutimens (char const *file, struct timespec const timespec[2])
603 } 631 }
604 } 632 }
605 lutimensat_works_really = -1; 633 lutimensat_works_really = -1;
606#endif /* HAVE_UTIMENSAT */ 634# endif /* HAVE_UTIMENSAT */
607 635
608 /* The platform lacks an interface to set file timestamps with 636 /* The platform lacks an interface to set file timestamps with
609 nanosecond resolution, so do the best we can, discarding any 637 nanosecond resolution, so do the best we can, discarding any
@@ -619,7 +647,7 @@ lutimens (char const *file, struct timespec const timespec[2])
619 647
620 /* On Linux, lutimes is a thin wrapper around utimensat, so there is 648 /* On Linux, lutimes is a thin wrapper around utimensat, so there is
621 no point trying lutimes if utimensat failed with ENOSYS. */ 649 no point trying lutimes if utimensat failed with ENOSYS. */
622#if HAVE_LUTIMES && !HAVE_UTIMENSAT 650# if HAVE_LUTIMES && !HAVE_UTIMENSAT
623 { 651 {
624 struct timeval timeval[2]; 652 struct timeval timeval[2];
625 struct timeval *t; 653 struct timeval *t;
@@ -639,7 +667,7 @@ lutimens (char const *file, struct timespec const timespec[2])
639 if (result == 0 || errno != ENOSYS) 667 if (result == 0 || errno != ENOSYS)
640 return result; 668 return result;
641 } 669 }
642#endif /* HAVE_LUTIMES && !HAVE_UTIMENSAT */ 670# endif /* HAVE_LUTIMES && !HAVE_UTIMENSAT */
643 671
644 /* Out of luck for symlinks, but we still handle regular files. */ 672 /* Out of luck for symlinks, but we still handle regular files. */
645 if (!(adjustment_needed || REPLACE_FUNC_STAT_FILE) && lstat (file, &st)) 673 if (!(adjustment_needed || REPLACE_FUNC_STAT_FILE) && lstat (file, &st))
@@ -648,5 +676,5 @@ lutimens (char const *file, struct timespec const timespec[2])
648 return fdutimens (-1, file, ts); 676 return fdutimens (-1, file, ts);
649 errno = ENOSYS; 677 errno = ENOSYS;
650 return -1; 678 return -1;
651}
652#endif 679#endif
680}
diff --git a/lib/utimens.h b/lib/utimens.h
index e85477b8493..762c3f9a858 100644
--- a/lib/utimens.h
+++ b/lib/utimens.h
@@ -33,12 +33,16 @@ extern "C" {
33#endif 33#endif
34 34
35int fdutimens (int, char const *, struct timespec const [2]); 35int fdutimens (int, char const *, struct timespec const [2]);
36#if !HAVE_UTIMENS 36
37#if HAVE_UTIMENS
38# define utimens rpl_utimens
39#endif
37int utimens (char const *, struct timespec const [2]); 40int utimens (char const *, struct timespec const [2]);
41
42#if HAVE_LUTIMENS
43# define lutimens rpl_lutimens
38#endif 44#endif
39#if !HAVE_LUTIMENS
40int lutimens (char const *, struct timespec const [2]); 45int lutimens (char const *, struct timespec const [2]);
41#endif
42 46
43#ifdef __cplusplus 47#ifdef __cplusplus
44} 48}