mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-16 13:01:21 +08:00
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
This commit is contained in:
parent
000051e1c5
commit
7b65155f1c
@ -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.
|
||||
|
@ -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)
|
||||
@ -126,22 +128,11 @@ namespace
|
||||
}
|
||||
#else
|
||||
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
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user