mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-06 16:40:47 +00:00
Merge commit 4a39d0890894 from llvm-project (by Mark Johnston):
[libc++] Fix filesystem::remove_all() on FreeBSD (#79540) remove_all_impl() opens the target path with O_NOFOLLOW, which fails if the target is a symbolic link. On FreeBSD, rather than returning ELOOP, openat() returns EMLINK. This is unlikely to change for compatibility reasons, see https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=214633 . Thus, check for EMLINK as well. Reported by: markj PR: 276632 MFC after: 3 days
This commit is contained in:
parent
8d5353de74
commit
ee14a9725d
|
@ -823,8 +823,9 @@ uintmax_t remove_all_impl(int parent_directory, const path& p, error_code& ec) {
|
||||||
|
|
||||||
// If opening `p` failed because it wasn't a directory, remove it as
|
// If opening `p` failed because it wasn't a directory, remove it as
|
||||||
// a normal file instead. Note that `openat()` can return either ENOTDIR
|
// a normal file instead. Note that `openat()` can return either ENOTDIR
|
||||||
// or ELOOP depending on the exact reason of the failure.
|
// or ELOOP depending on the exact reason of the failure. On FreeBSD it
|
||||||
if (ec == errc::not_a_directory || ec == errc::too_many_symbolic_link_levels) {
|
// may return EMLINK instead of ELOOP, contradicting POSIX.
|
||||||
|
if (ec == errc::not_a_directory || ec == errc::too_many_symbolic_link_levels || ec == errc::too_many_links) {
|
||||||
ec.clear();
|
ec.clear();
|
||||||
if (::unlinkat(parent_directory, p.c_str(), /* flags = */0) == -1) {
|
if (::unlinkat(parent_directory, p.c_str(), /* flags = */0) == -1) {
|
||||||
ec = detail::capture_errno();
|
ec = detail::capture_errno();
|
||||||
|
|
Loading…
Reference in a new issue