commit 8cfb387388a90730ab36ac24d9049677db633a11 Author: Jonathan Wakely Date: Thu Mar 11 16:43:51 2021 libstdc++: Handle EPERM for filesystem access errors on MacOS [PR 99537] Contrary to what POSIX says, some directory operations on MacOS can fail with EPERM instead of EACCES, so we need to handle both. libstdc++-v3/ChangeLog: PR libstdc++/99537 * src/c++17/fs_dir.cc (recursive_directory_iterator): Use new helper function to check for permission denied errors. * src/filesystem/dir.cc (recursive_directory_iterator): Likewise. * src/filesystem/dir-common.h (is_permission_denied_error): New helper function. diff --git a/libstdc++-v3/src/c++17/fs_dir.cc b/libstdc++-v3/src/c++17/fs_dir.cc index 994368c25c4..4de0f798d05 100644 --- a/libstdc++-v3/src/c++17/fs_dir.cc +++ b/libstdc++-v3/src/c++17/fs_dir.cc @@ -207,7 +207,7 @@ recursive_directory_iterator(const path& p, directory_options options, else { const int err = errno; - if (err == EACCES + if (fs::is_permission_denied_error(err) && is_set(options, fs::directory_options::skip_permission_denied)) { if (ecptr) diff --git a/libstdc++-v3/src/filesystem/dir-common.h b/libstdc++-v3/src/filesystem/dir-common.h index 56e279230f4..a49b8304a29 100644 --- a/libstdc++-v3/src/filesystem/dir-common.h +++ b/libstdc++-v3/src/filesystem/dir-common.h @@ -141,6 +141,18 @@ struct _Dir_base posix::DIR* dirp; }; +inline bool +is_permission_denied_error(int e) +{ + if (e == EACCES) + return true; +#ifdef __APPLE__ + if (e == EPERM) // See PR 99533 + return true; +#endif + return false; +} + } // namespace filesystem // BEGIN/END macros must be defined before including this file. diff --git a/libstdc++-v3/src/filesystem/dir.cc b/libstdc++-v3/src/filesystem/dir.cc index acc62986c68..215a9533f1b 100644 --- a/libstdc++-v3/src/filesystem/dir.cc +++ b/libstdc++-v3/src/filesystem/dir.cc @@ -202,7 +202,7 @@ recursive_directory_iterator(const path& p, directory_options options, else { const int err = errno; - if (err == EACCES + if (std::filesystem::is_permission_denied_error(err) && is_set(options, fs::directory_options::skip_permission_denied)) { if (ecptr)