mirror of git://gcc.gnu.org/git/gcc.git
PR libstdc++/79283 fix filesystem::read_symlink for /proc
PR libstdc++/79283 * src/filesystem/ops.cc (read_symlink): Handle st_size being zero. * src/filesystem/std-ops.cc (read_symlink): Likewise. (do_copy_file) [!NEED_DO_COPY_FILE]: Avoid multiple definitions. From-SVN: r254076
This commit is contained in:
parent
eeb517d3e7
commit
220645d019
|
|
@ -1,5 +1,10 @@
|
||||||
2017-10-25 Jonathan Wakely <jwakely@redhat.com>
|
2017-10-25 Jonathan Wakely <jwakely@redhat.com>
|
||||||
|
|
||||||
|
PR libstdc++/79283
|
||||||
|
* src/filesystem/ops.cc (read_symlink): Handle st_size being zero.
|
||||||
|
* src/filesystem/std-ops.cc (read_symlink): Likewise.
|
||||||
|
(do_copy_file) [!NEED_DO_COPY_FILE]: Avoid multiple definitions.
|
||||||
|
|
||||||
* src/filesystem/std-path.cc (path::lexically_normal): Add missing
|
* src/filesystem/std-path.cc (path::lexically_normal): Add missing
|
||||||
step to algorithm, for removing dot-dot elements after root-directory.
|
step to algorithm, for removing dot-dot elements after root-directory.
|
||||||
* testsuite/27_io/filesystem/operations/canonical.cc: Use
|
* testsuite/27_io/filesystem/operations/canonical.cc: Use
|
||||||
|
|
|
||||||
|
|
@ -962,26 +962,45 @@ fs::read_symlink(const path& p)
|
||||||
|
|
||||||
fs::path fs::read_symlink(const path& p, error_code& ec)
|
fs::path fs::read_symlink(const path& p, error_code& ec)
|
||||||
{
|
{
|
||||||
|
path result;
|
||||||
#ifdef _GLIBCXX_HAVE_SYS_STAT_H
|
#ifdef _GLIBCXX_HAVE_SYS_STAT_H
|
||||||
stat_type st;
|
stat_type st;
|
||||||
if (::lstat(p.c_str(), &st))
|
if (::lstat(p.c_str(), &st))
|
||||||
{
|
{
|
||||||
ec.assign(errno, std::generic_category());
|
ec.assign(errno, std::generic_category());
|
||||||
return {};
|
return result;
|
||||||
}
|
}
|
||||||
std::string buf(st.st_size, '\0');
|
std::string buf(st.st_size ? st.st_size + 1 : 128, '\0');
|
||||||
ssize_t len = ::readlink(p.c_str(), &buf.front(), buf.size());
|
do
|
||||||
if (len == -1)
|
|
||||||
{
|
{
|
||||||
ec.assign(errno, std::generic_category());
|
ssize_t len = ::readlink(p.c_str(), buf.data(), buf.size());
|
||||||
return {};
|
if (len == -1)
|
||||||
|
{
|
||||||
|
ec.assign(errno, std::generic_category());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else if (len == (ssize_t)buf.size())
|
||||||
|
{
|
||||||
|
if (buf.size() > 4096)
|
||||||
|
{
|
||||||
|
ec.assign(ENAMETOOLONG, std::generic_category());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
buf.resize(buf.size() * 2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buf.resize(len);
|
||||||
|
result.assign(buf);
|
||||||
|
ec.clear();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ec.clear();
|
while (true);
|
||||||
return path{buf.data(), buf.data()+len};
|
|
||||||
#else
|
#else
|
||||||
ec = std::make_error_code(std::errc::not_supported);
|
ec = std::make_error_code(std::errc::not_supported);
|
||||||
return {};
|
|
||||||
#endif
|
#endif
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#ifndef _GLIBCXX_USE_CXX11_ABI
|
#ifndef _GLIBCXX_USE_CXX11_ABI
|
||||||
# define _GLIBCXX_USE_CXX11_ABI 1
|
# define _GLIBCXX_USE_CXX11_ABI 1
|
||||||
|
# define NEED_DO_COPY_FILE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
@ -251,6 +252,7 @@ namespace std::filesystem
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _GLIBCXX_HAVE_SYS_STAT_H
|
#ifdef _GLIBCXX_HAVE_SYS_STAT_H
|
||||||
|
#ifdef NEED_DO_COPY_FILE
|
||||||
bool
|
bool
|
||||||
fs::do_copy_file(const char* from, const char* to,
|
fs::do_copy_file(const char* from, const char* to,
|
||||||
copy_options_existing_file options,
|
copy_options_existing_file options,
|
||||||
|
|
@ -423,6 +425,7 @@ fs::do_copy_file(const char* from, const char* to,
|
||||||
return true;
|
return true;
|
||||||
#endif // _GLIBCXX_USE_SENDFILE
|
#endif // _GLIBCXX_USE_SENDFILE
|
||||||
}
|
}
|
||||||
|
#endif // NEED_DO_COPY_FILE
|
||||||
#endif // _GLIBCXX_HAVE_SYS_STAT_H
|
#endif // _GLIBCXX_HAVE_SYS_STAT_H
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -1166,26 +1169,45 @@ fs::read_symlink(const path& p)
|
||||||
|
|
||||||
fs::path fs::read_symlink(const path& p, error_code& ec)
|
fs::path fs::read_symlink(const path& p, error_code& ec)
|
||||||
{
|
{
|
||||||
|
path result;
|
||||||
#ifdef _GLIBCXX_HAVE_SYS_STAT_H
|
#ifdef _GLIBCXX_HAVE_SYS_STAT_H
|
||||||
stat_type st;
|
stat_type st;
|
||||||
if (::lstat(p.c_str(), &st))
|
if (::lstat(p.c_str(), &st))
|
||||||
{
|
{
|
||||||
ec.assign(errno, std::generic_category());
|
ec.assign(errno, std::generic_category());
|
||||||
return {};
|
return result;
|
||||||
}
|
}
|
||||||
std::string buf(st.st_size, '\0');
|
std::string buf(st.st_size ? st.st_size + 1 : 128, '\0');
|
||||||
ssize_t len = ::readlink(p.c_str(), &buf.front(), buf.size());
|
do
|
||||||
if (len == -1)
|
|
||||||
{
|
{
|
||||||
ec.assign(errno, std::generic_category());
|
ssize_t len = ::readlink(p.c_str(), buf.data(), buf.size());
|
||||||
return {};
|
if (len == -1)
|
||||||
|
{
|
||||||
|
ec.assign(errno, std::generic_category());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else if (len == (ssize_t)buf.size())
|
||||||
|
{
|
||||||
|
if (buf.size() > 4096)
|
||||||
|
{
|
||||||
|
ec.assign(ENAMETOOLONG, std::generic_category());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
buf.resize(buf.size() * 2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buf.resize(len);
|
||||||
|
result.assign(buf);
|
||||||
|
ec.clear();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ec.clear();
|
while (true);
|
||||||
return path{buf.data(), buf.data()+len};
|
|
||||||
#else
|
#else
|
||||||
ec = std::make_error_code(std::errc::not_supported);
|
ec = std::make_error_code(std::errc::not_supported);
|
||||||
return {};
|
|
||||||
#endif
|
#endif
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
fs::path
|
fs::path
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue