libstdc++: Handle EMLINK and EFTYPE in std::filesystem::remove_all
commit9586d6248e89c6bc138f65ea1992de3a2f54a522
authorJonathan Wakely <jwakely@redhat.com>
Mon, 8 Apr 2024 16:41:00 +0000 (8 17:41 +0100)
committerJonathan Wakely <jwakely@redhat.com>
Wed, 10 Apr 2024 11:58:28 +0000 (10 12:58 +0100)
tree5dc0d4b3148355fcc4d157b18fabcce859a0263d
parent4be1cc5f50578fafcdcbd09160235066d76a3f86
libstdc++: Handle EMLINK and EFTYPE in std::filesystem::remove_all

Although POSIX requires ELOOP, FreeBSD documents that openat with
O_NOFOLLOW returns EMLINK if the last component of a filename is a
symbolic link.  Check for EMLINK as well as ELOOP, so that the TOCTTOU
mitigation in remove_all works correctly.

See https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=214633 or the
FreeBSD man page for reference.

According to its man page, DragonFlyBSD also uses EMLINK for this error,
and NetBSD uses its own EFTYPE. OpenBSD follows POSIX and uses EMLINK.

This fixes these failures on FreeBSD:
FAIL: 27_io/filesystem/operations/remove_all.cc  -std=gnu++17 execution test
FAIL: experimental/filesystem/operations/remove_all.cc  -std=gnu++17 execution test

libstdc++-v3/ChangeLog:

* src/c++17/fs_ops.cc (remove_all) [__FreeBSD__ || __DragonFly__]:
Check for EMLINK as well as ELOOP.
[__NetBSD__]: Check for EFTYPE as well as ELOOP.
libstdc++-v3/src/c++17/fs_ops.cc