2024-11-19 Paul Eggert <eggert@cs.ucla.edu>
+ savewd: remove O_SEARCH optimization
+ * lib/savewd.c (savewd_save): Remove recently-added optimization
+ for platforms with O_SEARCH, as it does not work on macOS 12.6
+ due to what seems to be a bug there.
+
strerror, vasnprintf: pacify clang 14 on macOS
* lib/strerror.c, lib/vasnprintf.c: Pacify clang 14 on macOS 12.6.
The Gnulib replacement for @code{O_CLOEXEC} is not atomic, and so is
not safe in the presence of multiple threads or signal handlers.
@item
+The Gnulib replacement for @code{O_SEARCH} may require read access
+instead of search/execute access.
+@item
+On some platforms, @code{O_SEARCH} may reject directories
+where you have search access even though @code{O_SEARCH} is not replaced:
+macOS 12.6.
+@item
@code{open ("symlink", O_CREAT ...)} fails when the argument points to a
nonexistent file in an existing directory on some platforms:
@c https://dev.haiku-os.org/ticket/18355
The Gnulib replacement for @code{O_CLOEXEC} is not atomic, and so is
not safe in the presence of multiple threads or signal handlers.
@item
+The Gnulib replacement for @code{O_SEARCH} may require read access
+instead of search/execute access.
+@item
+On some platforms, @code{O_SEARCH} may reject directories
+where you have search access even though @code{O_SEARCH} is not replaced:
+macOS 12.6.
+@item
@code{openat (fd, "symlink", O_NOFOLLOW ...)} fails with @code{errno}
set to @code{EMLINK} instead of the POSIX-required @code{ELOOP} on
some platforms:
wd->val.fd = fd;
break;
}
-# if O_SEARCH != O_RDONLY || (defined _WIN32 && !defined __CYGWIN__)
- /* There is no point to forking if O_SEARCH conforms to POSIX,
- or on native MS-Windows which lacks 'fork'. */
+
+ /* There is no point to forking on native MS-Windows which lacks 'fork'.
+ Although there is also no point on systems that support O_SEARCH,
+ macOS 12.6 APFS open (".", O_SEARCH) incorrectly fails if "." is
+ mode 311, so do not attempt to optimize for O_SEARCH != O_RDONLY. */
+# if defined _WIN32 && !defined __CYGWIN__
bool try_fork = false;
# else
bool try_fork = errno == EACCES || errno == ESTALE;