aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2022-07-05 23:57:32 -0500
committerPaul Eggert2022-07-06 00:00:18 -0500
commit27436451ecbf250db4d1704c586763cb40e6dfeb (patch)
treea0713c338993726cc8bf4a8d1cef7d0336fa5065
parent2be06b13dd9582d7216c479e9874f0df6d32746b (diff)
downloademacs-27436451ecbf250db4d1704c586763cb40e6dfeb.tar.gz
emacs-27436451ecbf250db4d1704c586763cb40e6dfeb.zip
Update from Gnulib by running admin/merge-gnulib
* admin/merge-gnulib (AVOIDED_MODULES): Add chmod.
-rwxr-xr-xadmin/merge-gnulib2
-rwxr-xr-xbuild-aux/config.guess9
-rwxr-xr-xbuild-aux/config.sub6
-rw-r--r--doc/misc/texinfo.tex2
-rw-r--r--lib/fchmodat.c59
-rw-r--r--lib/filevercmp.c18
-rw-r--r--lib/filevercmp.h4
-rw-r--r--lib/gnulib.mk.in6
-rw-r--r--lib/lchmod.c84
-rw-r--r--lib/mini-gmp.h2
-rw-r--r--lib/str-two-way.h4
-rw-r--r--lib/string.in.h16
-rw-r--r--lib/sys_stat.in.h28
-rw-r--r--m4/fchmodat.m44
-rw-r--r--m4/lchmod.m46
-rw-r--r--m4/sys_stat_h.m46
16 files changed, 135 insertions, 121 deletions
diff --git a/admin/merge-gnulib b/admin/merge-gnulib
index ea3d23686f4..4dd6a4d222f 100755
--- a/admin/merge-gnulib
+++ b/admin/merge-gnulib
@@ -51,7 +51,7 @@ GNULIB_MODULES='
51' 51'
52 52
53AVOIDED_MODULES=' 53AVOIDED_MODULES='
54 btowc close crypto/af_alg dup fchdir fstat langinfo lock 54 btowc chmod close crypto/af_alg dup fchdir fstat langinfo lock
55 mbrtowc mbsinit memchr mkdir msvc-inval msvc-nothrow nl_langinfo 55 mbrtowc mbsinit memchr mkdir msvc-inval msvc-nothrow nl_langinfo
56 openat-die opendir pthread-h raise 56 openat-die opendir pthread-h raise
57 save-cwd select setenv sigprocmask stat stdarg stdbool 57 save-cwd select setenv sigprocmask stat stdarg stdbool
diff --git a/build-aux/config.guess b/build-aux/config.guess
index 160ecf0951b..1817bdce90d 100755
--- a/build-aux/config.guess
+++ b/build-aux/config.guess
@@ -4,7 +4,7 @@
4 4
5# shellcheck disable=SC2006,SC2268 # see below for rationale 5# shellcheck disable=SC2006,SC2268 # see below for rationale
6 6
7timestamp='2022-05-08' 7timestamp='2022-05-25'
8 8
9# This file is free software; you can redistribute it and/or modify it 9# This file is free software; you can redistribute it and/or modify it
10# under the terms of the GNU General Public License as published by 10# under the terms of the GNU General Public License as published by
@@ -1378,8 +1378,11 @@ EOF
1378 BePC:Haiku:*:*) # Haiku running on Intel PC compatible. 1378 BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
1379 GUESS=i586-pc-haiku 1379 GUESS=i586-pc-haiku
1380 ;; 1380 ;;
1381 x86_64:Haiku:*:*) 1381 ppc:Haiku:*:*) # Haiku running on Apple PowerPC
1382 GUESS=x86_64-unknown-haiku 1382 GUESS=powerpc-apple-haiku
1383 ;;
1384 *:Haiku:*:*) # Haiku modern gcc (not bound by BeOS compat)
1385 GUESS=$UNAME_MACHINE-unknown-haiku
1383 ;; 1386 ;;
1384 SX-4:SUPER-UX:*:*) 1387 SX-4:SUPER-UX:*:*)
1385 GUESS=sx4-nec-superux$UNAME_RELEASE 1388 GUESS=sx4-nec-superux$UNAME_RELEASE
diff --git a/build-aux/config.sub b/build-aux/config.sub
index 9b62e37c43c..dba16e84c77 100755
--- a/build-aux/config.sub
+++ b/build-aux/config.sub
@@ -1,10 +1,10 @@
1#! /bin/sh 1#! /bin/sh
2# Configuration validation subroutine script. 2# Configuration validation subroutine script.
3# Copyright 1992-2021 Free Software Foundation, Inc. 3# Copyright 1992-2022 Free Software Foundation, Inc.
4 4
5# shellcheck disable=SC2006,SC2268 # see below for rationale 5# shellcheck disable=SC2006,SC2268 # see below for rationale
6 6
7timestamp='2021-12-25' 7timestamp='2022-01-03'
8 8
9# This file is free software; you can redistribute it and/or modify it 9# This file is free software; you can redistribute it and/or modify it
10# under the terms of the GNU General Public License as published by 10# under the terms of the GNU General Public License as published by
@@ -76,7 +76,7 @@ Report bugs and patches to <config-patches@gnu.org>."
76version="\ 76version="\
77GNU config.sub ($timestamp) 77GNU config.sub ($timestamp)
78 78
79Copyright 1992-2021 Free Software Foundation, Inc. 79Copyright 1992-2022 Free Software Foundation, Inc.
80 80
81This is free software; see the source for copying conditions. There is NO 81This is free software; see the source for copying conditions. There is NO
82warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." 82warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
diff --git a/doc/misc/texinfo.tex b/doc/misc/texinfo.tex
index aa16f51aa4e..8872e5e055f 100644
--- a/doc/misc/texinfo.tex
+++ b/doc/misc/texinfo.tex
@@ -7651,7 +7651,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
7651% If SUBTOPIC is present, precede it with a space, and call \doind. 7651% If SUBTOPIC is present, precede it with a space, and call \doind.
7652% (At some time during the 20th century, this made a two-level entry in an 7652% (At some time during the 20th century, this made a two-level entry in an
7653% index such as the operation index. Nobody seemed to notice the change in 7653% index such as the operation index. Nobody seemed to notice the change in
7654% behavior though.) 7654% behaviour though.)
7655\def\dosubind#1#2#3{% 7655\def\dosubind#1#2#3{%
7656 \def\thirdarg{#3}% 7656 \def\thirdarg{#3}%
7657 \ifx\thirdarg\empty 7657 \ifx\thirdarg\empty
diff --git a/lib/fchmodat.c b/lib/fchmodat.c
index dc535833660..164e2c4a95f 100644
--- a/lib/fchmodat.c
+++ b/lib/fchmodat.c
@@ -83,9 +83,10 @@ fchmodat (int dir, char const *file, mode_t mode, int flags)
83# if NEED_FCHMODAT_NONSYMLINK_FIX 83# if NEED_FCHMODAT_NONSYMLINK_FIX
84 if (flags == AT_SYMLINK_NOFOLLOW) 84 if (flags == AT_SYMLINK_NOFOLLOW)
85 { 85 {
86 struct stat st; 86# if HAVE_READLINKAT
87 char readlink_buf[1];
87 88
88# if defined O_PATH && defined AT_EMPTY_PATH 89# ifdef O_PATH
89 /* Open a file descriptor with O_NOFOLLOW, to make sure we don't 90 /* Open a file descriptor with O_NOFOLLOW, to make sure we don't
90 follow symbolic links, if /proc is mounted. O_PATH is used to 91 follow symbolic links, if /proc is mounted. O_PATH is used to
91 avoid a failure if the file is not readable. 92 avoid a failure if the file is not readable.
@@ -94,49 +95,29 @@ fchmodat (int dir, char const *file, mode_t mode, int flags)
94 if (fd < 0) 95 if (fd < 0)
95 return fd; 96 return fd;
96 97
97 /* Up to Linux 5.3 at least, when FILE refers to a symbolic link, the 98 int err;
98 chmod call below will change the permissions of the symbolic link 99 if (0 <= readlinkat (fd, "", readlink_buf, sizeof readlink_buf))
99 - which is undesired - and on many file systems (ext4, btrfs, jfs, 100 err = EOPNOTSUPP;
100 xfs, ..., but not reiserfs) fail with error EOPNOTSUPP - which is 101 else if (errno == EINVAL)
101 misleading. Therefore test for a symbolic link explicitly.
102 Use fstatat because fstat does not work on O_PATH descriptors
103 before Linux 3.6. */
104 if (fstatat (fd, "", &st, AT_EMPTY_PATH) != 0)
105 { 102 {
106 int stat_errno = errno; 103 static char const fmt[] = "/proc/self/fd/%d";
107 close (fd); 104 char buf[sizeof fmt - sizeof "%d" + INT_BUFSIZE_BOUND (int)];
108 errno = stat_errno; 105 sprintf (buf, fmt, fd);
109 return -1; 106 err = chmod (buf, mode) == 0 ? 0 : errno == ENOENT ? -1 : errno;
110 }
111 if (S_ISLNK (st.st_mode))
112 {
113 close (fd);
114 errno = EOPNOTSUPP;
115 return -1;
116 } 107 }
108 else
109 err = errno == ENOENT ? -1 : errno;
117 110
118# if defined __linux__ || defined __ANDROID__ || defined __CYGWIN__
119 static char const fmt[] = "/proc/self/fd/%d";
120 char buf[sizeof fmt - sizeof "%d" + INT_BUFSIZE_BOUND (int)];
121 sprintf (buf, fmt, fd);
122 int chmod_result = chmod (buf, mode);
123 int chmod_errno = errno;
124 close (fd); 111 close (fd);
125 if (chmod_result == 0) 112
126 return chmod_result; 113 errno = err;
127 if (chmod_errno != ENOENT) 114 if (0 <= err)
128 { 115 return err == 0 ? 0 : -1;
129 errno = chmod_errno;
130 return chmod_result;
131 }
132# endif 116# endif
133 /* /proc is not mounted or would not work as in GNU/Linux. */
134 117
135# else 118 /* O_PATH + /proc is not supported. */
136 int fstatat_result = fstatat (dir, file, &st, AT_SYMLINK_NOFOLLOW); 119
137 if (fstatat_result != 0) 120 if (0 <= readlinkat (dir, file, readlink_buf, sizeof readlink_buf))
138 return fstatat_result;
139 if (S_ISLNK (st.st_mode))
140 { 121 {
141 errno = EOPNOTSUPP; 122 errno = EOPNOTSUPP;
142 return -1; 123 return -1;
diff --git a/lib/filevercmp.c b/lib/filevercmp.c
index d546e790548..7e54793e613 100644
--- a/lib/filevercmp.c
+++ b/lib/filevercmp.c
@@ -29,6 +29,8 @@
29/* Return the length of a prefix of S that corresponds to the suffix 29/* Return the length of a prefix of S that corresponds to the suffix
30 defined by this extended regular expression in the C locale: 30 defined by this extended regular expression in the C locale:
31 (\.[A-Za-z~][A-Za-z0-9~]*)*$ 31 (\.[A-Za-z~][A-Za-z0-9~]*)*$
32 Use the longest suffix matching this regular expression,
33 except do not use all of S as a suffix if S is nonempty.
32 If *LEN is -1, S is a string; set *LEN to S's length. 34 If *LEN is -1, S is a string; set *LEN to S's length.
33 Otherwise, *LEN should be nonnegative, S is a char array, 35 Otherwise, *LEN should be nonnegative, S is a char array,
34 and *LEN does not change. */ 36 and *LEN does not change. */
@@ -36,20 +38,22 @@ static idx_t
36file_prefixlen (char const *s, ptrdiff_t *len) 38file_prefixlen (char const *s, ptrdiff_t *len)
37{ 39{
38 size_t n = *len; /* SIZE_MAX if N == -1. */ 40 size_t n = *len; /* SIZE_MAX if N == -1. */
41 idx_t prefixlen = 0;
39 42
40 for (idx_t i = 0; ; i++) 43 for (idx_t i = 0; ; )
41 { 44 {
42 idx_t prefixlen = i;
43 while (i + 1 < n && s[i] == '.' && (c_isalpha (s[i + 1])
44 || s[i + 1] == '~'))
45 for (i += 2; i < n && (c_isalnum (s[i]) || s[i] == '~'); i++)
46 continue;
47
48 if (*len < 0 ? !s[i] : i == n) 45 if (*len < 0 ? !s[i] : i == n)
49 { 46 {
50 *len = i; 47 *len = i;
51 return prefixlen; 48 return prefixlen;
52 } 49 }
50
51 i++;
52 prefixlen = i;
53 while (i + 1 < n && s[i] == '.' && (c_isalpha (s[i + 1])
54 || s[i + 1] == '~'))
55 for (i += 2; i < n && (c_isalnum (s[i]) || s[i] == '~'); i++)
56 continue;
53 } 57 }
54} 58}
55 59
diff --git a/lib/filevercmp.h b/lib/filevercmp.h
index 5a336776719..57949760b25 100644
--- a/lib/filevercmp.h
+++ b/lib/filevercmp.h
@@ -61,7 +61,9 @@
61 without them, using version sort without special priority; 61 without them, using version sort without special priority;
62 if they do not compare equal, this comparison result is used and 62 if they do not compare equal, this comparison result is used and
63 the suffixes are effectively ignored. Otherwise, the entire 63 the suffixes are effectively ignored. Otherwise, the entire
64 strings are compared using version sort. 64 strings are compared using version sort. When removing a suffix
65 from a nonempty string, remove the maximal-length suffix such that
66 the remaining string is nonempty.
65 67
66 This function is intended to be a replacement for strverscmp. */ 68 This function is intended to be a replacement for strverscmp. */
67int filevercmp (char const *a, char const *b) _GL_ATTRIBUTE_PURE; 69int filevercmp (char const *a, char const *b) _GL_ATTRIBUTE_PURE;
diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in
index bf0df878a5b..2ffe89d4239 100644
--- a/lib/gnulib.mk.in
+++ b/lib/gnulib.mk.in
@@ -35,6 +35,7 @@
35# --macro-prefix=gl \ 35# --macro-prefix=gl \
36# --no-vc-files \ 36# --no-vc-files \
37# --avoid=btowc \ 37# --avoid=btowc \
38# --avoid=chmod \
38# --avoid=close \ 39# --avoid=close \
39# --avoid=crypto/af_alg \ 40# --avoid=crypto/af_alg \
40# --avoid=dup \ 41# --avoid=dup \
@@ -327,6 +328,7 @@ GL_GNULIB_CALLOC_GNU = @GL_GNULIB_CALLOC_GNU@
327GL_GNULIB_CALLOC_POSIX = @GL_GNULIB_CALLOC_POSIX@ 328GL_GNULIB_CALLOC_POSIX = @GL_GNULIB_CALLOC_POSIX@
328GL_GNULIB_CANONICALIZE_FILE_NAME = @GL_GNULIB_CANONICALIZE_FILE_NAME@ 329GL_GNULIB_CANONICALIZE_FILE_NAME = @GL_GNULIB_CANONICALIZE_FILE_NAME@
329GL_GNULIB_CHDIR = @GL_GNULIB_CHDIR@ 330GL_GNULIB_CHDIR = @GL_GNULIB_CHDIR@
331GL_GNULIB_CHMOD = @GL_GNULIB_CHMOD@
330GL_GNULIB_CHOWN = @GL_GNULIB_CHOWN@ 332GL_GNULIB_CHOWN = @GL_GNULIB_CHOWN@
331GL_GNULIB_CLOSE = @GL_GNULIB_CLOSE@ 333GL_GNULIB_CLOSE = @GL_GNULIB_CLOSE@
332GL_GNULIB_CLOSEDIR = @GL_GNULIB_CLOSEDIR@ 334GL_GNULIB_CLOSEDIR = @GL_GNULIB_CLOSEDIR@
@@ -1029,6 +1031,7 @@ REPLACE_ALIGNED_ALLOC = @REPLACE_ALIGNED_ALLOC@
1029REPLACE_CALLOC_FOR_CALLOC_GNU = @REPLACE_CALLOC_FOR_CALLOC_GNU@ 1031REPLACE_CALLOC_FOR_CALLOC_GNU = @REPLACE_CALLOC_FOR_CALLOC_GNU@
1030REPLACE_CALLOC_FOR_CALLOC_POSIX = @REPLACE_CALLOC_FOR_CALLOC_POSIX@ 1032REPLACE_CALLOC_FOR_CALLOC_POSIX = @REPLACE_CALLOC_FOR_CALLOC_POSIX@
1031REPLACE_CANONICALIZE_FILE_NAME = @REPLACE_CANONICALIZE_FILE_NAME@ 1033REPLACE_CANONICALIZE_FILE_NAME = @REPLACE_CANONICALIZE_FILE_NAME@
1034REPLACE_CHMOD = @REPLACE_CHMOD@
1032REPLACE_CHOWN = @REPLACE_CHOWN@ 1035REPLACE_CHOWN = @REPLACE_CHOWN@
1033REPLACE_CLOSE = @REPLACE_CLOSE@ 1036REPLACE_CLOSE = @REPLACE_CLOSE@
1034REPLACE_CLOSEDIR = @REPLACE_CLOSEDIR@ 1037REPLACE_CLOSEDIR = @REPLACE_CLOSEDIR@
@@ -1196,6 +1199,7 @@ SETTINGS_LIBS = @SETTINGS_LIBS@
1196SHELL = @SHELL@ 1199SHELL = @SHELL@
1197SIG_ATOMIC_T_SUFFIX = @SIG_ATOMIC_T_SUFFIX@ 1200SIG_ATOMIC_T_SUFFIX = @SIG_ATOMIC_T_SUFFIX@
1198SIZE_T_SUFFIX = @SIZE_T_SUFFIX@ 1201SIZE_T_SUFFIX = @SIZE_T_SUFFIX@
1202SMALL_JA_DIC = @SMALL_JA_DIC@
1199SQLITE3_LIBS = @SQLITE3_LIBS@ 1203SQLITE3_LIBS = @SQLITE3_LIBS@
1200STDALIGN_H = @STDALIGN_H@ 1204STDALIGN_H = @STDALIGN_H@
1201STDDEF_H = @STDDEF_H@ 1205STDDEF_H = @STDDEF_H@
@@ -3497,6 +3501,7 @@ sys/stat.h: sys_stat.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNU
3497 -e 's|@''NEXT_SYS_STAT_H''@|$(NEXT_SYS_STAT_H)|g' \ 3501 -e 's|@''NEXT_SYS_STAT_H''@|$(NEXT_SYS_STAT_H)|g' \
3498 -e 's|@''WINDOWS_64_BIT_ST_SIZE''@|$(WINDOWS_64_BIT_ST_SIZE)|g' \ 3502 -e 's|@''WINDOWS_64_BIT_ST_SIZE''@|$(WINDOWS_64_BIT_ST_SIZE)|g' \
3499 -e 's|@''WINDOWS_STAT_TIMESPEC''@|$(WINDOWS_STAT_TIMESPEC)|g' \ 3503 -e 's|@''WINDOWS_STAT_TIMESPEC''@|$(WINDOWS_STAT_TIMESPEC)|g' \
3504 -e 's/@''GNULIB_CHMOD''@/$(GL_GNULIB_CHMOD)/g' \
3500 -e 's/@''GNULIB_FCHMODAT''@/$(GL_GNULIB_FCHMODAT)/g' \ 3505 -e 's/@''GNULIB_FCHMODAT''@/$(GL_GNULIB_FCHMODAT)/g' \
3501 -e 's/@''GNULIB_FSTAT''@/$(GL_GNULIB_FSTAT)/g' \ 3506 -e 's/@''GNULIB_FSTAT''@/$(GL_GNULIB_FSTAT)/g' \
3502 -e 's/@''GNULIB_FSTATAT''@/$(GL_GNULIB_FSTATAT)/g' \ 3507 -e 's/@''GNULIB_FSTATAT''@/$(GL_GNULIB_FSTATAT)/g' \
@@ -3528,6 +3533,7 @@ sys/stat.h: sys_stat.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNU
3528 -e 's|@''HAVE_MKNOD''@|$(HAVE_MKNOD)|g' \ 3533 -e 's|@''HAVE_MKNOD''@|$(HAVE_MKNOD)|g' \
3529 -e 's|@''HAVE_MKNODAT''@|$(HAVE_MKNODAT)|g' \ 3534 -e 's|@''HAVE_MKNODAT''@|$(HAVE_MKNODAT)|g' \
3530 -e 's|@''HAVE_UTIMENSAT''@|$(HAVE_UTIMENSAT)|g' \ 3535 -e 's|@''HAVE_UTIMENSAT''@|$(HAVE_UTIMENSAT)|g' \
3536 -e 's|@''REPLACE_CHMOD''@|$(REPLACE_CHMOD)|g' \
3531 -e 's|@''REPLACE_FCHMODAT''@|$(REPLACE_FCHMODAT)|g' \ 3537 -e 's|@''REPLACE_FCHMODAT''@|$(REPLACE_FCHMODAT)|g' \
3532 -e 's|@''REPLACE_FSTAT''@|$(REPLACE_FSTAT)|g' \ 3538 -e 's|@''REPLACE_FSTAT''@|$(REPLACE_FSTAT)|g' \
3533 -e 's|@''REPLACE_FSTATAT''@|$(REPLACE_FSTATAT)|g' \ 3539 -e 's|@''REPLACE_FSTATAT''@|$(REPLACE_FSTATAT)|g' \
diff --git a/lib/lchmod.c b/lib/lchmod.c
index 706dddff7bb..8410a2d835f 100644
--- a/lib/lchmod.c
+++ b/lib/lchmod.c
@@ -25,17 +25,9 @@
25#include <errno.h> 25#include <errno.h>
26#include <fcntl.h> 26#include <fcntl.h>
27#include <stdio.h> 27#include <stdio.h>
28#include <string.h>
28#include <unistd.h> 29#include <unistd.h>
29 30
30#ifdef __osf__
31/* Write "sys/stat.h" here, not <sys/stat.h>, otherwise OSF/1 5.1 DTK cc
32 eliminates this include because of the preliminary #include <sys/stat.h>
33 above. */
34# include "sys/stat.h"
35#else
36# include <sys/stat.h>
37#endif
38
39#include <intprops.h> 31#include <intprops.h>
40 32
41/* Work like chmod, except when FILE is a symbolic link. 33/* Work like chmod, except when FILE is a symbolic link.
@@ -45,7 +37,9 @@
45int 37int
46lchmod (char const *file, mode_t mode) 38lchmod (char const *file, mode_t mode)
47{ 39{
48#if defined O_PATH && defined AT_EMPTY_PATH 40 char readlink_buf[1];
41
42#ifdef O_PATH
49 /* Open a file descriptor with O_NOFOLLOW, to make sure we don't 43 /* Open a file descriptor with O_NOFOLLOW, to make sure we don't
50 follow symbolic links, if /proc is mounted. O_PATH is used to 44 follow symbolic links, if /proc is mounted. O_PATH is used to
51 avoid a failure if the file is not readable. 45 avoid a failure if the file is not readable.
@@ -54,56 +48,46 @@ lchmod (char const *file, mode_t mode)
54 if (fd < 0) 48 if (fd < 0)
55 return fd; 49 return fd;
56 50
57 /* Up to Linux 5.3 at least, when FILE refers to a symbolic link, the 51 int err;
58 chmod call below will change the permissions of the symbolic link 52 if (0 <= readlinkat (fd, "", readlink_buf, sizeof readlink_buf))
59 - which is undesired - and on many file systems (ext4, btrfs, jfs, 53 err = EOPNOTSUPP;
60 xfs, ..., but not reiserfs) fail with error EOPNOTSUPP - which is 54 else if (errno == EINVAL)
61 misleading. Therefore test for a symbolic link explicitly.
62 Use fstatat because fstat does not work on O_PATH descriptors
63 before Linux 3.6. */
64 struct stat st;
65 if (fstatat (fd, "", &st, AT_EMPTY_PATH) != 0)
66 { 55 {
67 int stat_errno = errno; 56 static char const fmt[] = "/proc/self/fd/%d";
68 close (fd); 57 char buf[sizeof fmt - sizeof "%d" + INT_BUFSIZE_BOUND (int)];
69 errno = stat_errno; 58 sprintf (buf, fmt, fd);
70 return -1; 59 err = chmod (buf, mode) == 0 ? 0 : errno == ENOENT ? -1 : errno;
71 }
72 if (S_ISLNK (st.st_mode))
73 {
74 close (fd);
75 errno = EOPNOTSUPP;
76 return -1;
77 } 60 }
61 else
62 err = errno == ENOENT ? -1 : errno;
78 63
79# if defined __linux__ || defined __ANDROID__ || defined __CYGWIN__
80 static char const fmt[] = "/proc/self/fd/%d";
81 char buf[sizeof fmt - sizeof "%d" + INT_BUFSIZE_BOUND (int)];
82 sprintf (buf, fmt, fd);
83 int chmod_result = chmod (buf, mode);
84 int chmod_errno = errno;
85 close (fd); 64 close (fd);
86 if (chmod_result == 0) 65
87 return chmod_result; 66 errno = err;
88 if (chmod_errno != ENOENT) 67 if (0 <= err)
68 return err == 0 ? 0 : -1;
69#endif
70
71 size_t len = strlen (file);
72 if (len && file[len - 1] == '/')
89 { 73 {
90 errno = chmod_errno; 74 struct stat st;
91 return chmod_result; 75 if (lstat (file, &st) < 0)
76 return -1;
77 if (!S_ISDIR (st.st_mode))
78 {
79 errno = ENOTDIR;
80 return -1;
81 }
92 } 82 }
93# endif 83
94 /* /proc is not mounted or would not work as in GNU/Linux. */ 84 /* O_PATH + /proc is not supported. */
95 85
96#elif HAVE_LSTAT 86 if (0 <= readlink (file, readlink_buf, sizeof readlink_buf))
97 struct stat st;
98 int lstat_result = lstat (file, &st);
99 if (lstat_result != 0)
100 return lstat_result;
101 if (S_ISLNK (st.st_mode))
102 { 87 {
103 errno = EOPNOTSUPP; 88 errno = EOPNOTSUPP;
104 return -1; 89 return -1;
105 } 90 }
106#endif
107 91
108 /* Fall back on chmod, despite a possible race. */ 92 /* Fall back on chmod, despite a possible race. */
109 return chmod (file, mode); 93 return chmod (file, mode);
diff --git a/lib/mini-gmp.h b/lib/mini-gmp.h
index 508712d235b..59c24cf5111 100644
--- a/lib/mini-gmp.h
+++ b/lib/mini-gmp.h
@@ -8,7 +8,7 @@ The GNU MP Library is free software; you can redistribute it and/or modify
8it under the terms of either: 8it under the terms of either:
9 9
10 * the GNU Lesser General Public License as published by the Free 10 * the GNU Lesser General Public License as published by the Free
11 Software Foundation, either version 3 of the License, or (at your 11 Software Foundation; either version 3 of the License, or (at your
12 option) any later version. 12 option) any later version.
13 13
14or 14or
diff --git a/lib/str-two-way.h b/lib/str-two-way.h
index 7ee344aea14..b00017c0b4b 100644
--- a/lib/str-two-way.h
+++ b/lib/str-two-way.h
@@ -231,7 +231,7 @@ critical_factorization (const unsigned char *needle, size_t needle_len,
231 most 2 * HAYSTACK_LEN - NEEDLE_LEN comparisons occur in searching. 231 most 2 * HAYSTACK_LEN - NEEDLE_LEN comparisons occur in searching.
232 If AVAILABLE modifies HAYSTACK_LEN (as in strstr), then at most 3 * 232 If AVAILABLE modifies HAYSTACK_LEN (as in strstr), then at most 3 *
233 HAYSTACK_LEN - NEEDLE_LEN comparisons occur in searching. */ 233 HAYSTACK_LEN - NEEDLE_LEN comparisons occur in searching. */
234static RETURN_TYPE 234static RETURN_TYPE _GL_ATTRIBUTE_PURE
235two_way_short_needle (const unsigned char *haystack, size_t haystack_len, 235two_way_short_needle (const unsigned char *haystack, size_t haystack_len,
236 const unsigned char *needle, size_t needle_len) 236 const unsigned char *needle, size_t needle_len)
237{ 237{
@@ -325,7 +325,7 @@ two_way_short_needle (const unsigned char *haystack, size_t haystack_len,
325 If AVAILABLE modifies HAYSTACK_LEN (as in strstr), then at most 3 * 325 If AVAILABLE modifies HAYSTACK_LEN (as in strstr), then at most 3 *
326 HAYSTACK_LEN - NEEDLE_LEN comparisons occur in searching, and 326 HAYSTACK_LEN - NEEDLE_LEN comparisons occur in searching, and
327 sublinear performance is not possible. */ 327 sublinear performance is not possible. */
328static RETURN_TYPE 328static RETURN_TYPE _GL_ATTRIBUTE_PURE
329two_way_long_needle (const unsigned char *haystack, size_t haystack_len, 329two_way_long_needle (const unsigned char *haystack, size_t haystack_len,
330 const unsigned char *needle, size_t needle_len) 330 const unsigned char *needle, size_t needle_len)
331{ 331{
diff --git a/lib/string.in.h b/lib/string.in.h
index 33160b25254..3996da9fcb5 100644
--- a/lib/string.in.h
+++ b/lib/string.in.h
@@ -122,8 +122,12 @@ _GL_EXTERN_C void rpl_free (void *);
122# undef _GL_ATTRIBUTE_DEALLOC_FREE 122# undef _GL_ATTRIBUTE_DEALLOC_FREE
123# define _GL_ATTRIBUTE_DEALLOC_FREE _GL_ATTRIBUTE_DEALLOC (rpl_free, 1) 123# define _GL_ATTRIBUTE_DEALLOC_FREE _GL_ATTRIBUTE_DEALLOC (rpl_free, 1)
124# else 124# else
125# if defined _MSC_VER 125# if defined _MSC_VER && !defined free
126_GL_EXTERN_C void __cdecl free (void *); 126_GL_EXTERN_C
127# if defined _DLL
128 __declspec (dllimport)
129# endif
130 void __cdecl free (void *);
127# else 131# else
128# if defined __cplusplus && (__GLIBC__ + (__GLIBC_MINOR__ >= 14) > 2) 132# if defined __cplusplus && (__GLIBC__ + (__GLIBC_MINOR__ >= 14) > 2)
129_GL_EXTERN_C void free (void *) throw (); 133_GL_EXTERN_C void free (void *) throw ();
@@ -133,8 +137,12 @@ _GL_EXTERN_C void free (void *);
133# endif 137# endif
134# endif 138# endif
135#else 139#else
136# if defined _MSC_VER 140# if defined _MSC_VER && !defined free
137_GL_EXTERN_C void __cdecl free (void *); 141_GL_EXTERN_C
142# if defined _DLL
143 __declspec (dllimport)
144# endif
145 void __cdecl free (void *);
138# else 146# else
139# if defined __cplusplus && (__GLIBC__ + (__GLIBC_MINOR__ >= 14) > 2) 147# if defined __cplusplus && (__GLIBC__ + (__GLIBC_MINOR__ >= 14) > 2)
140_GL_EXTERN_C void free (void *) throw (); 148_GL_EXTERN_C void free (void *) throw ();
diff --git a/lib/sys_stat.in.h b/lib/sys_stat.in.h
index 28ddd42f818..714c3cb189e 100644
--- a/lib/sys_stat.in.h
+++ b/lib/sys_stat.in.h
@@ -391,7 +391,33 @@ struct stat
391#endif 391#endif
392 392
393 393
394#if @GNULIB_MDA_CHMOD@ 394#if @GNULIB_CHMOD@
395# if @REPLACE_CHMOD@
396# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
397# undef chmod
398# define chmod rpl_chmod
399# endif
400_GL_FUNCDECL_RPL (chmod, int, (const char *filename, mode_t mode)
401 _GL_ARG_NONNULL ((1)));
402_GL_CXXALIAS_RPL (chmod, int, (const char *filename, mode_t mode));
403# elif defined _WIN32 && !defined __CYGWIN__
404# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
405# undef chmod
406# define chmod _chmod
407# endif
408/* Need to cast, because in mingw the last argument is 'int mode'. */
409_GL_CXXALIAS_MDA_CAST (chmod, int, (const char *filename, mode_t mode));
410# else
411_GL_CXXALIAS_SYS (chmod, int, (const char *filename, mode_t mode));
412# endif
413_GL_CXXALIASWARN (chmod);
414#elif defined GNULIB_POSIXCHECK
415# undef chmod
416# if HAVE_RAW_DECL_CHMOD
417_GL_WARN_ON_USE (chmod, "chmod has portability problems - "
418 "use gnulib module chmod for portability");
419# endif
420#elif @GNULIB_MDA_CHMOD@
395/* On native Windows, map 'chmod' to '_chmod', so that -loldnames is not 421/* On native Windows, map 'chmod' to '_chmod', so that -loldnames is not
396 required. In C++ with GNULIB_NAMESPACE, avoid differences between 422 required. In C++ with GNULIB_NAMESPACE, avoid differences between
397 platforms by defining GNULIB_NAMESPACE::chmod always. */ 423 platforms by defining GNULIB_NAMESPACE::chmod always. */
diff --git a/m4/fchmodat.m4 b/m4/fchmodat.m4
index a5cf95a88be..f743ce1b025 100644
--- a/m4/fchmodat.m4
+++ b/m4/fchmodat.m4
@@ -1,4 +1,4 @@
1# fchmodat.m4 serial 6 1# fchmodat.m4 serial 7
2dnl Copyright (C) 2004-2022 Free Software Foundation, Inc. 2dnl Copyright (C) 2004-2022 Free Software Foundation, Inc.
3dnl This file is free software; the Free Software Foundation 3dnl This file is free software; the Free Software Foundation
4dnl gives unlimited permission to copy and/or distribute it, 4dnl gives unlimited permission to copy and/or distribute it,
@@ -97,6 +97,6 @@ AC_DEFUN([gl_FUNC_FCHMODAT],
97# Prerequisites of lib/fchmodat.c. 97# Prerequisites of lib/fchmodat.c.
98AC_DEFUN([gl_PREREQ_FCHMODAT], 98AC_DEFUN([gl_PREREQ_FCHMODAT],
99[ 99[
100 AC_CHECK_FUNCS_ONCE([lchmod]) 100 AC_CHECK_FUNCS_ONCE([readlinkat])
101 : 101 :
102]) 102])
diff --git a/m4/lchmod.m4 b/m4/lchmod.m4
index 5baee738efd..cd43beed851 100644
--- a/m4/lchmod.m4
+++ b/m4/lchmod.m4
@@ -1,4 +1,4 @@
1#serial 8 1#serial 10
2 2
3dnl Copyright (C) 2005-2006, 2008-2022 Free Software Foundation, Inc. 3dnl Copyright (C) 2005-2006, 2008-2022 Free Software Foundation, Inc.
4dnl This file is free software; the Free Software Foundation 4dnl This file is free software; the Free Software Foundation
@@ -15,9 +15,7 @@ AC_DEFUN([gl_FUNC_LCHMOD],
15 dnl Persuade glibc <sys/stat.h> to declare lchmod(). 15 dnl Persuade glibc <sys/stat.h> to declare lchmod().
16 AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) 16 AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
17 17
18 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles 18 AC_CHECK_FUNCS_ONCE([lchmod])
19
20 AC_CHECK_FUNCS_ONCE([lchmod lstat])
21 if test "$ac_cv_func_lchmod" = no; then 19 if test "$ac_cv_func_lchmod" = no; then
22 HAVE_LCHMOD=0 20 HAVE_LCHMOD=0
23 fi 21 fi
diff --git a/m4/sys_stat_h.m4 b/m4/sys_stat_h.m4
index b5a9789b818..2adbfdeef4e 100644
--- a/m4/sys_stat_h.m4
+++ b/m4/sys_stat_h.m4
@@ -1,4 +1,4 @@
1# sys_stat_h.m4 serial 41 -*- Autoconf -*- 1# sys_stat_h.m4 serial 42 -*- Autoconf -*-
2dnl Copyright (C) 2006-2022 Free Software Foundation, Inc. 2dnl Copyright (C) 2006-2022 Free Software Foundation, Inc.
3dnl This file is free software; the Free Software Foundation 3dnl This file is free software; the Free Software Foundation
4dnl gives unlimited permission to copy and/or distribute it, 4dnl gives unlimited permission to copy and/or distribute it,
@@ -46,7 +46,7 @@ AC_DEFUN_ONCE([gl_SYS_STAT_H],
46 dnl Check for declarations of anything we want to poison if the 46 dnl Check for declarations of anything we want to poison if the
47 dnl corresponding gnulib module is not in use. 47 dnl corresponding gnulib module is not in use.
48 gl_WARN_ON_USE_PREPARE([[#include <sys/stat.h> 48 gl_WARN_ON_USE_PREPARE([[#include <sys/stat.h>
49 ]], [fchmodat fstat fstatat futimens getumask lchmod lstat 49 ]], [chmod fchmodat fstat fstatat futimens getumask lchmod lstat
50 mkdirat mkfifo mkfifoat mknod mknodat stat utimensat]) 50 mkdirat mkfifo mkfifoat mknod mknodat stat utimensat])
51 51
52 AC_REQUIRE([AC_C_RESTRICT]) 52 AC_REQUIRE([AC_C_RESTRICT])
@@ -72,6 +72,7 @@ AC_DEFUN([gl_SYS_STAT_H_REQUIRE_DEFAULTS],
72[ 72[
73 m4_defun(GL_MODULE_INDICATOR_PREFIX[_SYS_STAT_H_MODULE_INDICATOR_DEFAULTS], [ 73 m4_defun(GL_MODULE_INDICATOR_PREFIX[_SYS_STAT_H_MODULE_INDICATOR_DEFAULTS], [
74 gl_UNISTD_H_REQUIRE_DEFAULTS dnl for REPLACE_FCHDIR 74 gl_UNISTD_H_REQUIRE_DEFAULTS dnl for REPLACE_FCHDIR
75 gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CHMOD])
75 gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FCHMODAT]) 76 gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FCHMODAT])
76 gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FSTAT]) 77 gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FSTAT])
77 gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FSTATAT]) 78 gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FSTATAT])
@@ -112,6 +113,7 @@ AC_DEFUN([gl_SYS_STAT_H_DEFAULTS],
112 HAVE_MKNOD=1; AC_SUBST([HAVE_MKNOD]) 113 HAVE_MKNOD=1; AC_SUBST([HAVE_MKNOD])
113 HAVE_MKNODAT=1; AC_SUBST([HAVE_MKNODAT]) 114 HAVE_MKNODAT=1; AC_SUBST([HAVE_MKNODAT])
114 HAVE_UTIMENSAT=1; AC_SUBST([HAVE_UTIMENSAT]) 115 HAVE_UTIMENSAT=1; AC_SUBST([HAVE_UTIMENSAT])
116 REPLACE_CHMOD=0; AC_SUBST([REPLACE_CHMOD])
115 REPLACE_FCHMODAT=0; AC_SUBST([REPLACE_FCHMODAT]) 117 REPLACE_FCHMODAT=0; AC_SUBST([REPLACE_FCHMODAT])
116 REPLACE_FSTAT=0; AC_SUBST([REPLACE_FSTAT]) 118 REPLACE_FSTAT=0; AC_SUBST([REPLACE_FSTAT])
117 REPLACE_FSTATAT=0; AC_SUBST([REPLACE_FSTATAT]) 119 REPLACE_FSTATAT=0; AC_SUBST([REPLACE_FSTATAT])