aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2015-10-02 17:34:34 +0100
committerJonathan Wakely <redi@gcc.gnu.org>2015-10-02 17:34:34 +0100
commit7b65155f1ccbfd741191f03a01fbc40d3ae39cf0 (patch)
tree5e56fc637df93f9331eb52d4ee89ef587b81bd45 /libstdc++-v3
parent000051e1c5c5d81f3fc8dbd7f9800f2d13a188b5 (diff)
downloadgcc-7b65155f1ccbfd741191f03a01fbc40d3ae39cf0.zip
gcc-7b65155f1ccbfd741191f03a01fbc40d3ae39cf0.tar.gz
gcc-7b65155f1ccbfd741191f03a01fbc40d3ae39cf0.tar.bz2
PR libstdc++/67747 use readdir instead of readdir_r
PR libstdc++/67747 * src/filesystem/dir.cc (native_readdir): Remove. (_Dir::advance): Use readdir instead of native_readdir. (recursive_directory_iterator(const path&, directory_options, error_code*)): Use swap instead of reset. From-SVN: r228404
Diffstat (limited to 'libstdc++-v3')
-rw-r--r--libstdc++-v3/ChangeLog8
-rw-r--r--libstdc++-v3/src/filesystem/dir.cc57
2 files changed, 33 insertions, 32 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 8dcf1bd..239cd44 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,11 @@
+2015-10-02 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/67747
+ * src/filesystem/dir.cc (native_readdir): Remove.
+ (_Dir::advance): Use readdir instead of native_readdir.
+ (recursive_directory_iterator(const path&, directory_options,
+ error_code*)): Use swap instead of reset.
+
2015-10-01 Jonathan Wakely <jwakely@redhat.com>
* doc/html/manual/errno.html: Add new file.
diff --git a/libstdc++-v3/src/filesystem/dir.cc b/libstdc++-v3/src/filesystem/dir.cc
index bce751c..33280ec 100644
--- a/libstdc++-v3/src/filesystem/dir.cc
+++ b/libstdc++-v3/src/filesystem/dir.cc
@@ -69,15 +69,17 @@ struct fs::_Dir
namespace
{
template<typename Bitmask>
- inline bool is_set(Bitmask obj, Bitmask bits)
+ inline bool
+ is_set(Bitmask obj, Bitmask bits)
{
return (obj & bits) != Bitmask::none;
}
// Returns {dirp, p} on success, {nullptr, p} on error.
// If an ignored EACCES error occurs returns {}.
- fs::_Dir
- open_dir(const fs::path& p, fs::directory_options options, std::error_code* ec)
+ inline fs::_Dir
+ open_dir(const fs::path& p, fs::directory_options options,
+ std::error_code* ec)
{
if (ec)
ec->clear();
@@ -100,7 +102,7 @@ namespace
}
inline fs::file_type
- get_file_type(const dirent& d __attribute__((__unused__)))
+ get_file_type(const ::dirent& d __attribute__((__unused__)))
{
#ifdef _GLIBCXX_HAVE_STRUCT_DIRENT_D_TYPE
switch (d.d_type)
@@ -128,20 +130,9 @@ namespace
return fs::file_type::none;
#endif
}
-
- int
- native_readdir(DIR* dirp, ::dirent*& entryp)
- {
-#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
- if ((entryp = ::readdir(dirp)))
- return 0;
- return errno;
-#else
- return ::readdir_r(dirp, entryp, &entryp);
-#endif
- }
}
+
// Returns false when the end of the directory entries is reached.
// Reports errors by setting ec or throwing.
bool
@@ -150,9 +141,20 @@ fs::_Dir::advance(error_code* ec, directory_options options)
if (ec)
ec->clear();
- ::dirent ent;
- ::dirent* result = &ent;
- if (int err = native_readdir(dirp, result))
+ int err = std::exchange(errno, 0);
+ const auto entp = readdir(dirp);
+ std::swap(errno, err);
+
+ if (entp)
+ {
+ // skip past dot and dot-dot
+ if (!strcmp(entp->d_name, ".") || !strcmp(entp->d_name, ".."))
+ return advance(ec, options);
+ entry = fs::directory_entry{path / entp->d_name};
+ type = get_file_type(*entp);
+ return true;
+ }
+ else if (err)
{
if (err == EACCES
&& is_set(options, directory_options::skip_permission_denied))
@@ -165,15 +167,6 @@ fs::_Dir::advance(error_code* ec, directory_options options)
ec->assign(err, std::generic_category());
return true;
}
- else if (result != nullptr)
- {
- // skip past dot and dot-dot
- if (!strcmp(ent.d_name, ".") || !strcmp(ent.d_name, ".."))
- return advance(ec, options);
- entry = fs::directory_entry{path / ent.d_name};
- type = get_file_type(ent);
- return true;
- }
else
{
// reached the end
@@ -251,10 +244,10 @@ recursive_directory_iterator(const path& p, directory_options options,
{
if (DIR* dirp = ::opendir(p.c_str()))
{
- _M_dirs = std::make_shared<_Dir_stack>();
- _M_dirs->push(_Dir{ dirp, p });
- if (!_M_dirs->top().advance(ec))
- _M_dirs.reset();
+ auto sp = std::make_shared<_Dir_stack>();
+ sp->push(_Dir{ dirp, p });
+ if (sp->top().advance(ec))
+ _M_dirs.swap(sp);
}
else
{