Skip to content

Commit

Permalink
Merge commit 4a39d0890894 from llvm-project (by Mark Johnston):
Browse files Browse the repository at this point in the history
  [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
  • Loading branch information
DimitryAndric committed Jan 29, 2024
1 parent 8d5353d commit ee14a97
Showing 1 changed file with 3 additions and 2 deletions.
5 changes: 3 additions & 2 deletions contrib/llvm-project/libcxx/src/filesystem/operations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
// a normal file instead. Note that `openat()` can return either ENOTDIR
// or ELOOP depending on the exact reason of the failure.
if (ec == errc::not_a_directory || ec == errc::too_many_symbolic_link_levels) {
// or ELOOP depending on the exact reason of the failure. On FreeBSD it
// 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();
if (::unlinkat(parent_directory, p.c_str(), /* flags = */0) == -1) {
ec = detail::capture_errno();
Expand Down

0 comments on commit ee14a97

Please sign in to comment.