diff options
| author | Paul Eggert | 2024-12-17 14:02:41 -0800 |
|---|---|---|
| committer | Paul Eggert | 2024-12-17 14:13:54 -0800 |
| commit | b1e5f6d6ef8432a9cce0664238de72d387730bd1 (patch) | |
| tree | 7eb50047793367bf8f2483e28fb716cfc4334c13 /lib | |
| parent | 22806c65f4f8d68547d33997d017039763b4bf6a (diff) | |
| download | emacs-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.c | 6 | ||||
| -rw-r--r-- | lib/acl.h | 59 | ||||
| -rw-r--r-- | lib/dirent.in.h | 95 | ||||
| -rw-r--r-- | lib/file-has-acl.c | 583 | ||||
| -rw-r--r-- | lib/getopt-cdefs.in.h | 10 | ||||
| -rw-r--r-- | lib/getopt-pfx-core.h | 7 | ||||
| -rw-r--r-- | lib/getopt.c | 4 | ||||
| -rw-r--r-- | lib/gettext.h | 32 | ||||
| -rw-r--r-- | lib/gnulib.mk.in | 50 | ||||
| -rw-r--r-- | lib/malloc.c | 11 | ||||
| -rw-r--r-- | lib/md5-stream.c | 3 | ||||
| -rw-r--r-- | lib/md5.h | 8 | ||||
| -rw-r--r-- | lib/memset_explicit.c | 5 | ||||
| -rw-r--r-- | lib/mini-gmp.c | 95 | ||||
| -rw-r--r-- | lib/mini-gmp.h | 1 | ||||
| -rw-r--r-- | lib/mktime-internal.h | 9 | ||||
| -rw-r--r-- | lib/mktime.c | 113 | ||||
| -rw-r--r-- | lib/nproc.c | 41 | ||||
| -rw-r--r-- | lib/pipe2.c | 2 | ||||
| -rw-r--r-- | lib/realloc.c | 71 | ||||
| -rw-r--r-- | lib/regex.h | 18 | ||||
| -rw-r--r-- | lib/regex_internal.c | 3 | ||||
| -rw-r--r-- | lib/regex_internal.h | 10 | ||||
| -rw-r--r-- | lib/stdio-impl.h | 2 | ||||
| -rw-r--r-- | lib/stdlib.c | 21 | ||||
| -rw-r--r-- | lib/stdlib.in.h | 43 | ||||
| -rw-r--r-- | lib/timegm.c | 3 | ||||
| -rw-r--r-- | lib/unistd.in.h | 5 | ||||
| -rw-r--r-- | lib/utimens.c | 68 | ||||
| -rw-r--r-- | lib/utimens.h | 10 |
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> |
| @@ -32,9 +32,68 @@ | |||
| 32 | extern "C" { | 32 | extern "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. */ | ||
| 37 | enum | ||
| 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. */ | ||
| 47 | struct 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 | ||
| 36 | bool acl_errno_valid (int) _GL_ATTRIBUTE_CONST; | 79 | bool acl_errno_valid (int) _GL_ATTRIBUTE_CONST; |
| 37 | int file_has_acl (char const *, struct stat const *); | 80 | int file_has_acl (char const *, struct stat const *); |
| 81 | int file_has_aclinfo (char const *restrict, struct aclinfo *restrict, int); | ||
| 82 | |||
| 83 | #if HAVE_LINUX_XATTR_H && HAVE_LISTXATTR | ||
| 84 | bool aclinfo_has_xattr (struct aclinfo const *, char const *) | ||
| 85 | _GL_ATTRIBUTE_PURE; | ||
| 86 | void 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)) | ||
| 93 | void aclinfo_scontext_free (char *); | ||
| 94 | #else | ||
| 95 | # define aclinfo_scontext_free(s) ((void) 0) | ||
| 96 | #endif | ||
| 38 | 97 | ||
| 39 | int qset_acl (char const *, int, mode_t); | 98 | int qset_acl (char const *, int, mode_t); |
| 40 | int xset_acl (char const *, int, mode_t); | 99 | int 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 | ||
| 87 | static_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. */ |
| 38 | static_assert (ACL_SYMLINK_FOLLOW & ~ (unsigned char) -1); | ||
| 39 | |||
| 40 | static 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 | ||
| 71 | static char const * | ||
| 72 | smack_smackfs_path (void) | ||
| 73 | { | ||
| 74 | return NULL; | ||
| 75 | } | ||
| 76 | static ssize_t | ||
| 77 | smack_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 | ||
| 84 | static bool | ||
| 85 | is_smack_enabled (void) | ||
| 86 | { | ||
| 87 | return !!smack_smackfs_path (); | ||
| 88 | } | ||
| 89 | |||
| 50 | enum { | 90 | enum { |
| 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 | ||
| 59 | ATTRIBUTE_PURE static bool | 98 | bool |
| 60 | have_xattr (char const *attr, char const *listbuf, ssize_t listsize) | 99 | aclinfo_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. */ | ||
| 115 | static void | ||
| 116 | get_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. */ | ||
| 226 | void | ||
| 227 | aclinfo_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. */ | ||
| 240 | void | ||
| 241 | aclinfo_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. */ | ||
| 156 | int | 339 | int |
| 157 | file_has_acl (char const *name, struct stat const *sb) | 340 | file_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(). */ | ||
| 849 | int | ||
| 850 | file_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@ | |||
| 261 | ECHO_C = @ECHO_C@ | 263 | ECHO_C = @ECHO_C@ |
| 262 | ECHO_N = @ECHO_N@ | 264 | ECHO_N = @ECHO_N@ |
| 263 | ECHO_T = @ECHO_T@ | 265 | ECHO_T = @ECHO_T@ |
| 264 | EGREP = @EGREP@ | ||
| 265 | EMACSRES = @EMACSRES@ | 266 | EMACSRES = @EMACSRES@ |
| 266 | EMACS_MANIFEST = @EMACS_MANIFEST@ | 267 | EMACS_MANIFEST = @EMACS_MANIFEST@ |
| 267 | EMULTIHOP_HIDDEN = @EMULTIHOP_HIDDEN@ | 268 | EMULTIHOP_HIDDEN = @EMULTIHOP_HIDDEN@ |
| @@ -336,6 +337,7 @@ GL_COND_OBJ_PTHREAD_SIGMASK_CONDITION = @GL_COND_OBJ_PTHREAD_SIGMASK_CONDITION@ | |||
| 336 | GL_COND_OBJ_RAWMEMCHR_CONDITION = @GL_COND_OBJ_RAWMEMCHR_CONDITION@ | 337 | GL_COND_OBJ_RAWMEMCHR_CONDITION = @GL_COND_OBJ_RAWMEMCHR_CONDITION@ |
| 337 | GL_COND_OBJ_READLINKAT_CONDITION = @GL_COND_OBJ_READLINKAT_CONDITION@ | 338 | GL_COND_OBJ_READLINKAT_CONDITION = @GL_COND_OBJ_READLINKAT_CONDITION@ |
| 338 | GL_COND_OBJ_READLINK_CONDITION = @GL_COND_OBJ_READLINK_CONDITION@ | 339 | GL_COND_OBJ_READLINK_CONDITION = @GL_COND_OBJ_READLINK_CONDITION@ |
| 340 | GL_COND_OBJ_REALLOC_POSIX_CONDITION = @GL_COND_OBJ_REALLOC_POSIX_CONDITION@ | ||
| 339 | GL_COND_OBJ_REGEX_CONDITION = @GL_COND_OBJ_REGEX_CONDITION@ | 341 | GL_COND_OBJ_REGEX_CONDITION = @GL_COND_OBJ_REGEX_CONDITION@ |
| 340 | GL_COND_OBJ_SIG2STR_CONDITION = @GL_COND_OBJ_SIG2STR_CONDITION@ | 342 | GL_COND_OBJ_SIG2STR_CONDITION = @GL_COND_OBJ_SIG2STR_CONDITION@ |
| 341 | GL_COND_OBJ_SIGDESCR_NP_CONDITION = @GL_COND_OBJ_SIGDESCR_NP_CONDITION@ | 343 | GL_COND_OBJ_SIGDESCR_NP_CONDITION = @GL_COND_OBJ_SIGDESCR_NP_CONDITION@ |
| @@ -584,7 +586,6 @@ GL_GNULIB_READDIR = @GL_GNULIB_READDIR@ | |||
| 584 | GL_GNULIB_READLINK = @GL_GNULIB_READLINK@ | 586 | GL_GNULIB_READLINK = @GL_GNULIB_READLINK@ |
| 585 | GL_GNULIB_READLINKAT = @GL_GNULIB_READLINKAT@ | 587 | GL_GNULIB_READLINKAT = @GL_GNULIB_READLINKAT@ |
| 586 | GL_GNULIB_REALLOCARRAY = @GL_GNULIB_REALLOCARRAY@ | 588 | GL_GNULIB_REALLOCARRAY = @GL_GNULIB_REALLOCARRAY@ |
| 587 | GL_GNULIB_REALLOC_GNU = @GL_GNULIB_REALLOC_GNU@ | ||
| 588 | GL_GNULIB_REALLOC_POSIX = @GL_GNULIB_REALLOC_POSIX@ | 589 | GL_GNULIB_REALLOC_POSIX = @GL_GNULIB_REALLOC_POSIX@ |
| 589 | GL_GNULIB_REALPATH = @GL_GNULIB_REALPATH@ | 590 | GL_GNULIB_REALPATH = @GL_GNULIB_REALPATH@ |
| 590 | GL_GNULIB_REMOVE = @GL_GNULIB_REMOVE@ | 591 | GL_GNULIB_REMOVE = @GL_GNULIB_REMOVE@ |
| @@ -707,7 +708,6 @@ GNUSTEP_CFLAGS = @GNUSTEP_CFLAGS@ | |||
| 707 | GNU_OBJC_CFLAGS = @GNU_OBJC_CFLAGS@ | 708 | GNU_OBJC_CFLAGS = @GNU_OBJC_CFLAGS@ |
| 708 | GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ | 709 | GOBJECT_CFLAGS = @GOBJECT_CFLAGS@ |
| 709 | GOBJECT_LIBS = @GOBJECT_LIBS@ | 710 | GOBJECT_LIBS = @GOBJECT_LIBS@ |
| 710 | GREP = @GREP@ | ||
| 711 | GSETTINGS_CFLAGS = @GSETTINGS_CFLAGS@ | 711 | GSETTINGS_CFLAGS = @GSETTINGS_CFLAGS@ |
| 712 | GSETTINGS_LIBS = @GSETTINGS_LIBS@ | 712 | GSETTINGS_LIBS = @GSETTINGS_LIBS@ |
| 713 | GTK_CFLAGS = @GTK_CFLAGS@ | 713 | GTK_CFLAGS = @GTK_CFLAGS@ |
| @@ -1031,6 +1031,7 @@ LIB_MATH = @LIB_MATH@ | |||
| 1031 | LIB_NANOSLEEP = @LIB_NANOSLEEP@ | 1031 | LIB_NANOSLEEP = @LIB_NANOSLEEP@ |
| 1032 | LIB_PTHREAD = @LIB_PTHREAD@ | 1032 | LIB_PTHREAD = @LIB_PTHREAD@ |
| 1033 | LIB_PTHREAD_SIGMASK = @LIB_PTHREAD_SIGMASK@ | 1033 | LIB_PTHREAD_SIGMASK = @LIB_PTHREAD_SIGMASK@ |
| 1034 | LIB_SELINUX = @LIB_SELINUX@ | ||
| 1034 | LIB_TIMER_TIME = @LIB_TIMER_TIME@ | 1035 | LIB_TIMER_TIME = @LIB_TIMER_TIME@ |
| 1035 | LIB_WSOCK32 = @LIB_WSOCK32@ | 1036 | LIB_WSOCK32 = @LIB_WSOCK32@ |
| 1036 | LIB_XATTR = @LIB_XATTR@ | 1037 | LIB_XATTR = @LIB_XATTR@ |
| @@ -1277,7 +1278,6 @@ REPLACE_READDIR = @REPLACE_READDIR@ | |||
| 1277 | REPLACE_READLINK = @REPLACE_READLINK@ | 1278 | REPLACE_READLINK = @REPLACE_READLINK@ |
| 1278 | REPLACE_READLINKAT = @REPLACE_READLINKAT@ | 1279 | REPLACE_READLINKAT = @REPLACE_READLINKAT@ |
| 1279 | REPLACE_REALLOCARRAY = @REPLACE_REALLOCARRAY@ | 1280 | REPLACE_REALLOCARRAY = @REPLACE_REALLOCARRAY@ |
| 1280 | REPLACE_REALLOC_FOR_REALLOC_GNU = @REPLACE_REALLOC_FOR_REALLOC_GNU@ | ||
| 1281 | REPLACE_REALLOC_FOR_REALLOC_POSIX = @REPLACE_REALLOC_FOR_REALLOC_POSIX@ | 1281 | REPLACE_REALLOC_FOR_REALLOC_POSIX = @REPLACE_REALLOC_FOR_REALLOC_POSIX@ |
| 1282 | REPLACE_REALPATH = @REPLACE_REALPATH@ | 1282 | REPLACE_REALPATH = @REPLACE_REALPATH@ |
| 1283 | REPLACE_REMOVE = @REPLACE_REMOVE@ | 1283 | REPLACE_REMOVE = @REPLACE_REMOVE@ |
| @@ -1384,6 +1384,7 @@ UNISTD_H_HAVE_SYS_RANDOM_H = @UNISTD_H_HAVE_SYS_RANDOM_H@ | |||
| 1384 | UNISTD_H_HAVE_WINSOCK2_H = @UNISTD_H_HAVE_WINSOCK2_H@ | 1384 | UNISTD_H_HAVE_WINSOCK2_H = @UNISTD_H_HAVE_WINSOCK2_H@ |
| 1385 | UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS = @UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS@ | 1385 | UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS = @UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS@ |
| 1386 | USE_ACL = @USE_ACL@ | 1386 | USE_ACL = @USE_ACL@ |
| 1387 | USE_SELINUX_SELINUX_H = @USE_SELINUX_SELINUX_H@ | ||
| 1387 | USE_STARTUP_NOTIFICATION = @USE_STARTUP_NOTIFICATION@ | 1388 | USE_STARTUP_NOTIFICATION = @USE_STARTUP_NOTIFICATION@ |
| 1388 | VMLIMIT_OBJ = @VMLIMIT_OBJ@ | 1389 | VMLIMIT_OBJ = @VMLIMIT_OBJ@ |
| 1389 | W32_LIBS = @W32_LIBS@ | 1390 | W32_LIBS = @W32_LIBS@ |
| @@ -1470,16 +1471,13 @@ gl_GNULIB_ENABLED_260941c0e5dc67ec9e87d1fb321c300b_CONDITION = @gl_GNULIB_ENABLE | |||
| 1470 | gl_GNULIB_ENABLED_5264294aa0a5557541b53c8c741f7f31_CONDITION = @gl_GNULIB_ENABLED_5264294aa0a5557541b53c8c741f7f31_CONDITION@ | 1471 | gl_GNULIB_ENABLED_5264294aa0a5557541b53c8c741f7f31_CONDITION = @gl_GNULIB_ENABLED_5264294aa0a5557541b53c8c741f7f31_CONDITION@ |
| 1471 | gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c_CONDITION = @gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c_CONDITION@ | 1472 | gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c_CONDITION = @gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c_CONDITION@ |
| 1472 | gl_GNULIB_ENABLED_61bcaca76b3e6f9ae55d57a1c3193bc4_CONDITION = @gl_GNULIB_ENABLED_61bcaca76b3e6f9ae55d57a1c3193bc4_CONDITION@ | 1473 | gl_GNULIB_ENABLED_61bcaca76b3e6f9ae55d57a1c3193bc4_CONDITION = @gl_GNULIB_ENABLED_61bcaca76b3e6f9ae55d57a1c3193bc4_CONDITION@ |
| 1473 | gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec_CONDITION = @gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec_CONDITION@ | ||
| 1474 | gl_GNULIB_ENABLED_8444034ea779b88768865bb60b4fb8c9_CONDITION = @gl_GNULIB_ENABLED_8444034ea779b88768865bb60b4fb8c9_CONDITION@ | 1474 | gl_GNULIB_ENABLED_8444034ea779b88768865bb60b4fb8c9_CONDITION = @gl_GNULIB_ENABLED_8444034ea779b88768865bb60b4fb8c9_CONDITION@ |
| 1475 | gl_GNULIB_ENABLED_925677f0343de64b89a9f0c790b4104c_CONDITION = @gl_GNULIB_ENABLED_925677f0343de64b89a9f0c790b4104c_CONDITION@ | 1475 | gl_GNULIB_ENABLED_925677f0343de64b89a9f0c790b4104c_CONDITION = @gl_GNULIB_ENABLED_925677f0343de64b89a9f0c790b4104c_CONDITION@ |
| 1476 | gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1_CONDITION = @gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1_CONDITION@ | 1476 | gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1_CONDITION = @gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1_CONDITION@ |
| 1477 | gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36_CONDITION = @gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36_CONDITION@ | 1477 | gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36_CONDITION = @gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36_CONDITION@ |
| 1478 | gl_GNULIB_ENABLED_cloexec_CONDITION = @gl_GNULIB_ENABLED_cloexec_CONDITION@ | 1478 | gl_GNULIB_ENABLED_cloexec_CONDITION = @gl_GNULIB_ENABLED_cloexec_CONDITION@ |
| 1479 | gl_GNULIB_ENABLED_d3b2383720ee0e541357aa2aac598e2b_CONDITION = @gl_GNULIB_ENABLED_d3b2383720ee0e541357aa2aac598e2b_CONDITION@ | ||
| 1480 | gl_GNULIB_ENABLED_dirfd_CONDITION = @gl_GNULIB_ENABLED_dirfd_CONDITION@ | 1479 | gl_GNULIB_ENABLED_dirfd_CONDITION = @gl_GNULIB_ENABLED_dirfd_CONDITION@ |
| 1481 | gl_GNULIB_ENABLED_e80bf6f757095d2e5fc94dafb8f8fc8b_CONDITION = @gl_GNULIB_ENABLED_e80bf6f757095d2e5fc94dafb8f8fc8b_CONDITION@ | 1480 | gl_GNULIB_ENABLED_e80bf6f757095d2e5fc94dafb8f8fc8b_CONDITION = @gl_GNULIB_ENABLED_e80bf6f757095d2e5fc94dafb8f8fc8b_CONDITION@ |
| 1482 | gl_GNULIB_ENABLED_ef455225c00f5049c808c2eda3e76866_CONDITION = @gl_GNULIB_ENABLED_ef455225c00f5049c808c2eda3e76866_CONDITION@ | ||
| 1483 | gl_GNULIB_ENABLED_endian_CONDITION = @gl_GNULIB_ENABLED_endian_CONDITION@ | 1481 | gl_GNULIB_ENABLED_endian_CONDITION = @gl_GNULIB_ENABLED_endian_CONDITION@ |
| 1484 | gl_GNULIB_ENABLED_euidaccess_CONDITION = @gl_GNULIB_ENABLED_euidaccess_CONDITION@ | 1482 | gl_GNULIB_ENABLED_euidaccess_CONDITION = @gl_GNULIB_ENABLED_euidaccess_CONDITION@ |
| 1485 | gl_GNULIB_ENABLED_fd38c7e463b54744b77b98aeafb4fa7c_CONDITION = @gl_GNULIB_ENABLED_fd38c7e463b54744b77b98aeafb4fa7c_CONDITION@ | 1483 | gl_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 |
| 2695 | ifeq (,$(OMIT_GNULIB_MODULE_malloc-posix)) | 2693 | ifeq (,$(OMIT_GNULIB_MODULE_malloc-posix)) |
| 2696 | 2694 | ||
| 2697 | ifneq (,$(gl_GNULIB_ENABLED_ef455225c00f5049c808c2eda3e76866_CONDITION)) | ||
| 2698 | 2695 | ||
| 2699 | endif | ||
| 2700 | EXTRA_DIST += malloc.c | 2696 | EXTRA_DIST += malloc.c |
| 2701 | 2697 | ||
| 2702 | EXTRA_libgnu_a_SOURCES += malloc.c | 2698 | EXTRA_libgnu_a_SOURCES += malloc.c |
| @@ -2925,30 +2921,16 @@ EXTRA_libgnu_a_SOURCES += at-func.c | |||
| 2925 | endif | 2921 | endif |
| 2926 | ## end gnulib module readlinkat | 2922 | ## end gnulib module readlinkat |
| 2927 | 2923 | ||
| 2928 | ## begin gnulib module realloc-gnu | ||
| 2929 | ifeq (,$(OMIT_GNULIB_MODULE_realloc-gnu)) | ||
| 2930 | |||
| 2931 | ifneq (,$(gl_GNULIB_ENABLED_d3b2383720ee0e541357aa2aac598e2b_CONDITION)) | ||
| 2932 | |||
| 2933 | endif | ||
| 2934 | EXTRA_DIST += realloc.c | ||
| 2935 | |||
| 2936 | EXTRA_libgnu_a_SOURCES += realloc.c | ||
| 2937 | |||
| 2938 | endif | ||
| 2939 | ## end gnulib module realloc-gnu | ||
| 2940 | |||
| 2941 | ## begin gnulib module realloc-posix | 2924 | ## begin gnulib module realloc-posix |
| 2942 | ifeq (,$(OMIT_GNULIB_MODULE_realloc-posix)) | 2925 | ifeq (,$(OMIT_GNULIB_MODULE_realloc-posix)) |
| 2943 | 2926 | ||
| 2944 | ifneq (,$(gl_GNULIB_ENABLED_61bcaca76b3e6f9ae55d57a1c3193bc4_CONDITION)) | 2927 | ifneq (,$(gl_GNULIB_ENABLED_61bcaca76b3e6f9ae55d57a1c3193bc4_CONDITION)) |
| 2945 | 2928 | ifneq (,$(GL_COND_OBJ_REALLOC_POSIX_CONDITION)) | |
| 2929 | libgnu_a_SOURCES += realloc.c | ||
| 2946 | endif | 2930 | endif |
| 2947 | EXTRA_DIST += realloc.c | ||
| 2948 | |||
| 2949 | EXTRA_libgnu_a_SOURCES += realloc.c | ||
| 2950 | 2931 | ||
| 2951 | endif | 2932 | endif |
| 2933 | endif | ||
| 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 | |||
| 3459 | ifeq (,$(OMIT_GNULIB_MODULE_stdlib)) | 3441 | ifeq (,$(OMIT_GNULIB_MODULE_stdlib)) |
| 3460 | 3442 | ||
| 3461 | BUILT_SOURCES += stdlib.h | 3443 | BUILT_SOURCES += stdlib.h |
| 3444 | libgnu_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. | ||
| 3465 | stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \ | 3446 | stdlib.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 | |||
| 4446 | endif | 4425 | endif |
| 4447 | ## end gnulib module vla | 4426 | ## end gnulib module vla |
| 4448 | 4427 | ||
| 4449 | ## begin gnulib module xalloc-oversized | ||
| 4450 | ifeq (,$(OMIT_GNULIB_MODULE_xalloc-oversized)) | ||
| 4451 | |||
| 4452 | ifneq (,$(gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec_CONDITION)) | ||
| 4453 | |||
| 4454 | endif | ||
| 4455 | EXTRA_DIST += xalloc-oversized.h | ||
| 4456 | |||
| 4457 | endif | ||
| 4458 | ## end gnulib module xalloc-oversized | ||
| 4459 | |||
| 4460 | 4428 | ||
| 4461 | mostlyclean-local: mostlyclean-generic | 4429 | mostlyclean-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 | ||
| 31 | void * | 31 | void * |
| 32 | rpl_malloc (size_t n) | 32 | rpl_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> |
| @@ -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 | ||
| 2709 | mp_size_t | ||
| 2710 | mpn_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 | |||
| 2709 | unsigned long | 2769 | unsigned long |
| 2710 | mpz_gcd_ui (mpz_t g, const mpz_t u, unsigned long v) | 2770 | mpz_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 | ||
| 2806 | void | 2835 | void |
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); | |||
| 105 | void mpn_sqr (mp_ptr, mp_srcptr, mp_size_t); | 105 | void mpn_sqr (mp_ptr, mp_srcptr, mp_size_t); |
| 106 | int mpn_perfect_square_p (mp_srcptr, mp_size_t); | 106 | int mpn_perfect_square_p (mp_srcptr, mp_size_t); |
| 107 | mp_size_t mpn_sqrtrem (mp_ptr, mp_ptr, mp_srcptr, mp_size_t); | 107 | mp_size_t mpn_sqrtrem (mp_ptr, mp_ptr, mp_srcptr, mp_size_t); |
| 108 | mp_size_t mpn_gcd (mp_ptr, mp_ptr, mp_size_t, mp_ptr, mp_size_t); | ||
| 108 | 109 | ||
| 109 | mp_limb_t mpn_lshift (mp_ptr, mp_srcptr, mp_size_t, unsigned int); | 110 | mp_limb_t mpn_lshift (mp_ptr, mp_srcptr, mp_size_t, unsigned int); |
| 110 | mp_limb_t mpn_rshift (mp_ptr, mp_srcptr, mp_size_t, unsigned int); | 111 | mp_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. |
| 76 | extern __time64_t __mktime_internal (struct tm *tp, | 76 | Record next guess for localtime-gmtime offset in *OFFSET. */ |
| 77 | struct tm *(*func) (__time64_t const *, | 77 | extern __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 |
| 123 | typedef long int long_int; | 122 | typedef long int long_int; |
| 124 | #else | 123 | # else |
| 125 | typedef long long int long_int; | 124 | typedef long long int long_int; |
| 126 | #endif | 125 | # endif |
| 127 | verify (INT_MAX <= TYPE_MAXIMUM (long_int) / 4 / 366 / 24 / 60 / 60); | 126 | static_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 |
| 160 | verify (TM_YEAR_BASE % 100 == 0); | 159 | static_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? */ |
| 163 | static bool | 162 | static 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 |
| 176 | static | 175 | static |
| 177 | #endif | 176 | # endif |
| 178 | const unsigned short int __mon_yday[2][13] = | 177 | const unsigned short int __mon_yday[2][13] = |
| 179 | { | 178 | { |
| 180 | /* Normal years. */ | 179 | /* Normal years. */ |
| @@ -206,7 +205,7 @@ static long_int | |||
| 206 | ydhms_diff (long_int year1, long_int yday1, int hour1, int min1, int sec1, | 205 | ydhms_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. */ |
| 257 | static struct tm * | 256 | static struct tm * |
| 258 | convert_time (struct tm *(*convert) (const __time64_t *, struct tm *), | 257 | convert_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. */ | ||
| 270 | static struct tm * | 274 | static struct tm * |
| 271 | ranged_convert (struct tm *(*convert) (const __time64_t *, struct tm *), | 275 | ranged_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 @@ | |||
| 37 | void * | 41 | void * |
| 38 | rpl_realloc (void *p, size_t n) | 42 | rpl_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 |
| 743 | static inline | 752 | _GL_STDLIB_INLINE int |
| 744 | int gl_MB_CUR_MAX (void) | 753 | gl_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 * | ||
| 1471 | rpl_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 |
| 1482 | getpagesize () | 1485 | getpagesize () |
| 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; | |||
| 78 | static int lutimensat_works_really; | 78 | static int lutimensat_works_really; |
| 79 | #endif /* HAVE_UTIMENSAT || HAVE_FUTIMENS */ | 79 | #endif /* HAVE_UTIMENSAT || HAVE_FUTIMENS */ |
| 80 | 80 | ||
| 81 | static bool | ||
| 82 | is_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 | |||
| 89 | static bool | ||
| 90 | is_valid_timespecs (struct timespec const timespec[2]) | ||
| 91 | { | ||
| 92 | return (is_valid_timespec (×pec[0]) | ||
| 93 | && is_valid_timespec (×pec[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. */ |
| 522 | int | 529 | int |
| 523 | utimens (char const *file, struct timespec const timespec[2]) | 530 | utimens (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. */ |
| 534 | int | 551 | int |
| 535 | lutimens (char const *file, struct timespec const timespec[2]) | 552 | lutimens (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 | ||
| 35 | int fdutimens (int, char const *, struct timespec const [2]); | 35 | int fdutimens (int, char const *, struct timespec const [2]); |
| 36 | #if !HAVE_UTIMENS | 36 | |
| 37 | #if HAVE_UTIMENS | ||
| 38 | # define utimens rpl_utimens | ||
| 39 | #endif | ||
| 37 | int utimens (char const *, struct timespec const [2]); | 40 | int 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 | ||
| 40 | int lutimens (char const *, struct timespec const [2]); | 45 | int lutimens (char const *, struct timespec const [2]); |
| 41 | #endif | ||
| 42 | 46 | ||
| 43 | #ifdef __cplusplus | 47 | #ifdef __cplusplus |
| 44 | } | 48 | } |