diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2015-10-02 17:34:34 +0100 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2015-10-02 17:34:34 +0100 |
commit | 7b65155f1ccbfd741191f03a01fbc40d3ae39cf0 (patch) | |
tree | 5e56fc637df93f9331eb52d4ee89ef587b81bd45 /libstdc++-v3 | |
parent | 000051e1c5c5d81f3fc8dbd7f9800f2d13a188b5 (diff) | |
download | gcc-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/ChangeLog | 8 | ||||
-rw-r--r-- | libstdc++-v3/src/filesystem/dir.cc | 57 |
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 { |