public inbox for libstdc++-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/aoliva/heads/testme)] libstdc++: introduce _At_path
@ 2022-06-27 9:33 Alexandre Oliva
0 siblings, 0 replies; 4+ messages in thread
From: Alexandre Oliva @ 2022-06-27 9:33 UTC (permalink / raw)
To: gcc-cvs, libstdc++-cvs
https://gcc.gnu.org/g:59f62962e1394734a4baef3d55599ff21dd5d4e2
commit 59f62962e1394734a4baef3d55599ff21dd5d4e2
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Mon Jun 27 05:31:00 2022 -0300
libstdc++: introduce _At_path
Diff:
---
libstdc++-v3/src/c++17/fs_dir.cc | 15 +++++-----
libstdc++-v3/src/filesystem/dir-common.h | 50 +++++++++++++++++++++-----------
libstdc++-v3/src/filesystem/dir.cc | 13 ++++-----
3 files changed, 46 insertions(+), 32 deletions(-)
diff --git a/libstdc++-v3/src/c++17/fs_dir.cc b/libstdc++-v3/src/c++17/fs_dir.cc
index 25b33baa875..fb752239e1f 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 _GLIBCXX_HAVE_DIRFD
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());
}
^ permalink raw reply [flat|nested] 4+ messages in thread
* [gcc(refs/users/aoliva/heads/testme)] libstdc++: introduce _At_path
@ 2022-06-27 10:50 Alexandre Oliva
0 siblings, 0 replies; 4+ messages in thread
From: Alexandre Oliva @ 2022-06-27 10:50 UTC (permalink / raw)
To: gcc-cvs, libstdc++-cvs
https://gcc.gnu.org/g:2f7f8a6e365fe98d0644208232a1ac6ca54299e0
commit 2f7f8a6e365fe98d0644208232a1ac6ca54299e0
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Mon Jun 27 05:31:00 2022 -0300
libstdc++: introduce _At_path
Diff:
---
libstdc++-v3/src/c++17/fs_dir.cc | 15 +++++-----
libstdc++-v3/src/filesystem/dir-common.h | 50 +++++++++++++++++++++-----------
libstdc++-v3/src/filesystem/dir.cc | 13 ++++-----
3 files changed, 46 insertions(+), 32 deletions(-)
diff --git a/libstdc++-v3/src/c++17/fs_dir.cc b/libstdc++-v3/src/c++17/fs_dir.cc
index 25b33baa875..fb752239e1f 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 _GLIBCXX_HAVE_DIRFD
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());
}
^ permalink raw reply [flat|nested] 4+ messages in thread
* [gcc(refs/users/aoliva/heads/testme)] libstdc++: introduce _At_path
@ 2022-06-27 13:35 Alexandre Oliva
0 siblings, 0 replies; 4+ messages in thread
From: Alexandre Oliva @ 2022-06-27 13:35 UTC (permalink / raw)
To: gcc-cvs, libstdc++-cvs
https://gcc.gnu.org/g:5bde8cf8d7378a991aa2d8683312b60d092b69f9
commit 5bde8cf8d7378a991aa2d8683312b60d092b69f9
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Mon Jun 27 05:31:00 2022 -0300
libstdc++: introduce _At_path
Diff:
---
libstdc++-v3/src/c++17/fs_dir.cc | 15 +++++-----
libstdc++-v3/src/filesystem/dir-common.h | 50 +++++++++++++++++++++-----------
libstdc++-v3/src/filesystem/dir.cc | 13 ++++-----
3 files changed, 46 insertions(+), 32 deletions(-)
diff --git a/libstdc++-v3/src/c++17/fs_dir.cc b/libstdc++-v3/src/c++17/fs_dir.cc
index 25b33baa875..fb752239e1f 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 _GLIBCXX_HAVE_DIRFD
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());
}
^ permalink raw reply [flat|nested] 4+ messages in thread
* [gcc(refs/users/aoliva/heads/testme)] libstdc++: introduce _At_path
@ 2022-06-27 15:45 Alexandre Oliva
0 siblings, 0 replies; 4+ messages in thread
From: Alexandre Oliva @ 2022-06-27 15:45 UTC (permalink / raw)
To: gcc-cvs, libstdc++-cvs
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());
}
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2022-06-27 15:45 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-27 9:33 [gcc(refs/users/aoliva/heads/testme)] libstdc++: introduce _At_path Alexandre Oliva
2022-06-27 10:50 Alexandre Oliva
2022-06-27 13:35 Alexandre Oliva
2022-06-27 15:45 Alexandre Oliva
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).