summaryrefslogtreecommitdiff
path: root/libstdc++-v3/src/c++17/fs_dir.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libstdc++-v3/src/c++17/fs_dir.cc')
-rw-r--r--libstdc++-v3/src/c++17/fs_dir.cc29
1 files changed, 15 insertions, 14 deletions
diff --git a/libstdc++-v3/src/c++17/fs_dir.cc b/libstdc++-v3/src/c++17/fs_dir.cc
index 025317b0a08..2258399da25 100644
--- a/libstdc++-v3/src/c++17/fs_dir.cc
+++ b/libstdc++-v3/src/c++17/fs_dir.cc
@@ -46,7 +46,7 @@ struct fs::_Dir : _Dir_base
{
_Dir(const fs::path& p, bool skip_permission_denied, bool nofollow,
[[maybe_unused]] bool filename_only, error_code& ec)
- : _Dir_base(fdcwd(), p.c_str(), skip_permission_denied, nofollow, ec)
+ : _Dir_base(p.c_str(), skip_permission_denied, nofollow, ec)
{
#if _GLIBCXX_HAVE_DIRFD && _GLIBCXX_HAVE_OPENAT && _GLIBCXX_HAVE_UNLINKAT
if (filename_only)
@@ -117,18 +117,19 @@ struct fs::_Dir : _Dir_base
return false;
}
- // Return a file descriptor for the directory and current entry's path.
- // If dirfd is available, use it and return only the filename.
- // Otherwise, return AT_FDCWD and return the full path.
- pair<int, const posix::char_type*>
- dir_and_pathname() const noexcept
+ // Return a pathname for the current directory entry, as an _At_path.
+ _Dir_base::_At_path
+ current() const noexcept
{
const fs::path& p = entry.path();
-#if _GLIBCXX_HAVE_DIRFD && _GLIBCXX_HAVE_OPENAT
- if (!p.empty())
- return {::dirfd(this->dirp), std::prev(p.end())->c_str()};
+#if _GLIBCXX_HAVE_DIRFD
+ if (!p.empty()) [[__likely__]]
+ {
+ auto len = std::prev(p.end())->native().size();
+ return {::dirfd(this->dirp), p.c_str(), p.native().size() - len};
+ }
#endif
- return {this->fdcwd(), p.c_str()};
+ return p.c_str();
}
// Create a new _Dir for the directory this->entry.path().
@@ -136,8 +137,7 @@ struct fs::_Dir : _Dir_base
open_subdir(bool skip_permission_denied, bool nofollow,
error_code& ec) const noexcept
{
- auto [dirfd, pathname] = dir_and_pathname();
- _Dir_base d(dirfd, pathname, skip_permission_denied, nofollow, ec);
+ _Dir_base d(current(), skip_permission_denied, nofollow, ec);
// If this->path is empty, the new _Dir should have an empty path too.
const fs::path& p = this->path.empty() ? this->path : this->entry.path();
return _Dir(std::move(d), p);
@@ -147,8 +147,9 @@ struct fs::_Dir : _Dir_base
do_unlink(bool is_directory, error_code& ec) const noexcept
{
#if _GLIBCXX_HAVE_UNLINKAT
- auto [dirfd, pathname] = dir_and_pathname();
- if (::unlinkat(dirfd, pathname, is_directory ? AT_REMOVEDIR : 0) == -1)
+ const auto atp = current();
+ if (::unlinkat(atp.dir(), atp.path_at_dir(),
+ is_directory ? AT_REMOVEDIR : 0) == -1)
{
ec.assign(errno, std::generic_category());
return false;