mirror of git://gcc.gnu.org/git/gcc.git
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>
|
2015-10-01 Jonathan Wakely <jwakely@redhat.com>
|
||||||
|
|
||||||
* doc/html/manual/errno.html: Add new file.
|
* doc/html/manual/errno.html: Add new file.
|
||||||
|
|
|
||||||
|
|
@ -69,15 +69,17 @@ struct fs::_Dir
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
template<typename Bitmask>
|
template<typename Bitmask>
|
||||||
inline bool is_set(Bitmask obj, Bitmask bits)
|
inline bool
|
||||||
|
is_set(Bitmask obj, Bitmask bits)
|
||||||
{
|
{
|
||||||
return (obj & bits) != Bitmask::none;
|
return (obj & bits) != Bitmask::none;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns {dirp, p} on success, {nullptr, p} on error.
|
// Returns {dirp, p} on success, {nullptr, p} on error.
|
||||||
// If an ignored EACCES error occurs returns {}.
|
// If an ignored EACCES error occurs returns {}.
|
||||||
fs::_Dir
|
inline fs::_Dir
|
||||||
open_dir(const fs::path& p, fs::directory_options options, std::error_code* ec)
|
open_dir(const fs::path& p, fs::directory_options options,
|
||||||
|
std::error_code* ec)
|
||||||
{
|
{
|
||||||
if (ec)
|
if (ec)
|
||||||
ec->clear();
|
ec->clear();
|
||||||
|
|
@ -100,7 +102,7 @@ namespace
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fs::file_type
|
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
|
#ifdef _GLIBCXX_HAVE_STRUCT_DIRENT_D_TYPE
|
||||||
switch (d.d_type)
|
switch (d.d_type)
|
||||||
|
|
@ -126,22 +128,11 @@ namespace
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
return fs::file_type::none;
|
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
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Returns false when the end of the directory entries is reached.
|
// Returns false when the end of the directory entries is reached.
|
||||||
// Reports errors by setting ec or throwing.
|
// Reports errors by setting ec or throwing.
|
||||||
bool
|
bool
|
||||||
|
|
@ -150,9 +141,20 @@ fs::_Dir::advance(error_code* ec, directory_options options)
|
||||||
if (ec)
|
if (ec)
|
||||||
ec->clear();
|
ec->clear();
|
||||||
|
|
||||||
::dirent ent;
|
int err = std::exchange(errno, 0);
|
||||||
::dirent* result = &ent;
|
const auto entp = readdir(dirp);
|
||||||
if (int err = native_readdir(dirp, result))
|
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
|
if (err == EACCES
|
||||||
&& is_set(options, directory_options::skip_permission_denied))
|
&& 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());
|
ec->assign(err, std::generic_category());
|
||||||
return true;
|
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
|
else
|
||||||
{
|
{
|
||||||
// reached the end
|
// reached the end
|
||||||
|
|
@ -251,10 +244,10 @@ recursive_directory_iterator(const path& p, directory_options options,
|
||||||
{
|
{
|
||||||
if (DIR* dirp = ::opendir(p.c_str()))
|
if (DIR* dirp = ::opendir(p.c_str()))
|
||||||
{
|
{
|
||||||
_M_dirs = std::make_shared<_Dir_stack>();
|
auto sp = std::make_shared<_Dir_stack>();
|
||||||
_M_dirs->push(_Dir{ dirp, p });
|
sp->push(_Dir{ dirp, p });
|
||||||
if (!_M_dirs->top().advance(ec))
|
if (sp->top().advance(ec))
|
||||||
_M_dirs.reset();
|
_M_dirs.swap(sp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue