public inbox for libstdc++-cvs@sourceware.org help / color / mirror / Atom feed
From: Alexandre Oliva <aoliva@gcc.gnu.org> To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc(refs/users/aoliva/heads/testme)] libstdc++: introduce _At_path Date: Mon, 27 Jun 2022 15:45:38 +0000 (GMT) [thread overview] Message-ID: <20220627154538.D74543830884@sourceware.org> (raw) https://gcc.gnu.org/g:962030fb97b8862972e86cc62e1844481f6a121e commit 962030fb97b8862972e86cc62e1844481f6a121e Author: Jonathan Wakely <jwakely@redhat.com> Date: Mon Jun 27 12:07:21 2022 -0300 libstdc++: introduce _At_path Diff: --- libstdc++-v3/src/c++17/fs_dir.cc | 13 ++++----- libstdc++-v3/src/filesystem/dir-common.h | 50 +++++++++++++++++++++----------- libstdc++-v3/src/filesystem/dir.cc | 13 ++++----- 3 files changed, 45 insertions(+), 31 deletions(-) diff --git a/libstdc++-v3/src/c++17/fs_dir.cc b/libstdc++-v3/src/c++17/fs_dir.cc index 25b33baa875..87f947e9e37 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 if (filename_only) @@ -120,15 +120,15 @@ struct fs::_Dir : _Dir_base // 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*> + _At_path dir_and_pathname() 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()}; + return {::dirfd(this->dirp), std::prev(p.end())->c_str(), p.c_str()}; #endif - return {this->fdcwd(), p.c_str()}; + return p.c_str(); } // Create a new _Dir for the directory this->entry.path(). @@ -136,8 +136,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(dir_and_pathname(), 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,7 +146,7 @@ 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(); + auto [dirfd, pathname, _] = dir_and_pathname(); if (::unlinkat(dirfd, pathname, is_directory ? AT_REMOVEDIR : 0) == -1) { ec.assign(errno, std::generic_category()); diff --git a/libstdc++-v3/src/filesystem/dir-common.h b/libstdc++-v3/src/filesystem/dir-common.h index 669780ea23f..e003aee4ff3 100644 --- a/libstdc++-v3/src/filesystem/dir-common.h +++ b/libstdc++-v3/src/filesystem/dir-common.h @@ -91,12 +91,37 @@ is_permission_denied_error(int e) struct _Dir_base { + struct _At_path + { + _At_path(const char* p) noexcept + : dir_fd(fdcwd()), path_from_dir(p), pathname(p) + { } + + _At_path(int fd, const char* p1, const char* p2) + : dir_fd(fd), path_from_dir(p1), pathname(p2) + { } + + int dir_fd; // A directory descriptor (either the parent dir, or AT_FDCWD). + const posix::char_type* path_from_dir; // Path relative to dir_fd. + const posix::char_type* pathname; // Full path relative to CWD. + + static constexpr int + fdcwd() noexcept + { +#ifdef AT_FDCWD + return AT_FDCWD; +#else + return -1; // Use invalid fd if AT_FDCWD isn't supported. +#endif + } + }; + // If no error occurs then dirp is non-null, // otherwise null (even if a permission denied error is ignored). - _Dir_base(int fd, const posix::char_type* pathname, + _Dir_base(const _At_path& atp, bool skip_permission_denied, bool nofollow, error_code& ec) noexcept - : dirp(_Dir_base::openat(fd, pathname, nofollow)) + : dirp(_Dir_base::openat(atp, nofollow)) { if (dirp) ec.clear(); @@ -143,16 +168,6 @@ struct _Dir_base } } - static constexpr int - fdcwd() noexcept - { -#ifdef AT_FDCWD - return AT_FDCWD; -#else - return -1; // Use invalid fd if AT_FDCWD isn't supported. -#endif - } - static bool is_dot_or_dotdot(const char* s) noexcept { return !strcmp(s, ".") || !strcmp(s, ".."); } @@ -174,7 +189,7 @@ struct _Dir_base } static posix::DIR* - openat(int fd, const posix::char_type* pathname, bool nofollow) + openat(const _At_path& atp, bool nofollow) { #if _GLIBCXX_HAVE_FDOPENDIR && defined O_RDONLY && defined O_DIRECTORY \ && ! _GLIBCXX_FILESYSTEM_IS_WINDOWS @@ -198,16 +213,17 @@ struct _Dir_base nofollow = false; #endif + int fd; #if _GLIBCXX_HAVE_OPENAT && defined AT_FDCWD - fd = ::openat(fd, pathname, flags); + fd = ::openat(atp.dir_fd, atp.path_from_dir, flags); #else // If we cannot use openat, there's no benefit to using posix::open unless // we will use O_NOFOLLOW, so just use the simpler posix::opendir. if (!nofollow) - return posix::opendir(pathname); + return posix::opendir(atp.pathname); - fd = ::open(pathname, flags); + fd = ::open(atp.pathname, flags); #endif if (fd == -1) @@ -220,7 +236,7 @@ struct _Dir_base errno = err; return nullptr; #else - return posix::opendir(pathname); + return posix::opendir(atp.pathname); #endif } diff --git a/libstdc++-v3/src/filesystem/dir.cc b/libstdc++-v3/src/filesystem/dir.cc index e64489162e5..c0202849bc4 100644 --- a/libstdc++-v3/src/filesystem/dir.cc +++ b/libstdc++-v3/src/filesystem/dir.cc @@ -53,7 +53,7 @@ struct fs::_Dir : std::filesystem::_Dir_base { _Dir(const fs::path& p, bool skip_permission_denied, bool nofollow, error_code& ec) - : _Dir_base(this->fdcwd(), p.c_str(), skip_permission_denied, nofollow, ec) + : _Dir_base(p.c_str(), skip_permission_denied, nofollow, ec) { if (!ec) path = p; @@ -116,14 +116,14 @@ struct fs::_Dir : std::filesystem::_Dir_base // 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*> + _At_path dir_and_pathname() const noexcept { const fs::path& p = entry.path(); -#if _GLIBCXX_HAVE_DIRFD && _GLIBCXX_HAVE_OPENAT - return {::dirfd(this->dirp), std::prev(p.end())->c_str()}; +#if _GLIBCXX_HAVE_DIRFD + return {::dirfd(this->dirp), std::prev(p.end())->c_str(), p.c_str()}; #endif - return {this->fdcwd(), p.c_str()}; + return p.c_str(); } // Create a new _Dir for the directory this->entry.path(). @@ -131,8 +131,7 @@ struct fs::_Dir : std::filesystem::_Dir_base open_subdir(bool skip_permission_denied, bool nofollow, error_code& ec) noexcept { - auto [dirfd, pathname] = dir_and_pathname(); - _Dir_base d(dirfd, pathname, skip_permission_denied, nofollow, ec); + _Dir_base d(dir_and_pathname(), skip_permission_denied, nofollow, ec); return _Dir(std::move(d), entry.path()); }
next reply other threads:[~2022-06-27 15:45 UTC|newest] Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top 2022-06-27 15:45 Alexandre Oliva [this message] -- strict thread matches above, loose matches on Subject: below -- 2022-06-27 13:35 Alexandre Oliva 2022-06-27 10:50 Alexandre Oliva 2022-06-27 9:33 Alexandre Oliva
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20220627154538.D74543830884@sourceware.org \ --to=aoliva@gcc.gnu.org \ --cc=gcc-cvs@gcc.gnu.org \ --cc=libstdc++-cvs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).