aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2019-01-17 15:32:05 +0000
committerJonathan Wakely <redi@gcc.gnu.org>2019-01-17 15:32:05 +0000
commitfc6f857bd30bd678323783a595fc132769cdc659 (patch)
tree50fde227b2b65d8e1c2a5b2a8eb129b9360858c6
parentdd0f7ba27314978e77aab5d8da1eb6070805ee4c (diff)
downloadgcc-fc6f857bd30bd678323783a595fc132769cdc659.zip
gcc-fc6f857bd30bd678323783a595fc132769cdc659.tar.gz
gcc-fc6f857bd30bd678323783a595fc132769cdc659.tar.bz2
PR libstdc++/88884 fix filesystem::absolute("//") for mingw
PR libstdc++/88884 * src/c++17/fs_ops.cc (absolute(const path&, error_code&)): Do nothing if the path is already absolute. [_GLIBCXX_FILESYSTEM_IS_WINDOWS]: Normalize root-directory. [!_GLIBCXX_FILESYSTEM_IS_WINDOWS]: Pass error_code to current_path. From-SVN: r268035
-rw-r--r--libstdc++-v3/ChangeLog6
-rw-r--r--libstdc++-v3/src/c++17/fs_ops.cc29
2 files changed, 30 insertions, 5 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 62d5db8..1be8354 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,11 @@
2019-01-17 Jonathan Wakely <jwakely@redhat.com>
+ PR libstdc++/88884
+ * src/c++17/fs_ops.cc (absolute(const path&, error_code&)): Do nothing
+ if the path is already absolute.
+ [_GLIBCXX_FILESYSTEM_IS_WINDOWS]: Normalize root-directory.
+ [!_GLIBCXX_FILESYSTEM_IS_WINDOWS]: Pass error_code to current_path.
+
PR libstdc++/88881
* src/c++17/fs_ops.cc (canonical(const path&, error_code&))
[_GLIBCXX_FILESYSTEM_IS_WINDOWS]: Normalize path, to match behaviour
diff --git a/libstdc++-v3/src/c++17/fs_ops.cc b/libstdc++-v3/src/c++17/fs_ops.cc
index 5f8be5b..c4b99fb 100644
--- a/libstdc++-v3/src/c++17/fs_ops.cc
+++ b/libstdc++-v3/src/c++17/fs_ops.cc
@@ -85,14 +85,35 @@ fs::absolute(const path& p, error_code& ec)
ec = make_error_code(std::errc::no_such_file_or_directory);
return ret;
}
+ ec.clear();
+ if (p.is_absolute())
+ {
+ ret = p;
+ return ret;
+ }
+
#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
- const wstring& s = p.native();
+ wstring_view s = p.native();
+
+ if (p.has_root_directory()) // implies !p.has_root_name()
+ {
+ // GetFullPathNameW("//") gives unwanted result (PR 88884).
+ // If there are multiple directory separators at the start,
+ // skip all but the last of them.
+ const auto pos = s.find_first_not_of(L"/\\");
+ __glibcxx_assert(pos != 0);
+ s.remove_prefix(std::min(s.length(), pos) - 1);
+ }
+
+ // s must be null-terminated
+ __glibcxx_assert(!s.empty() && s.back() == 0);
+
uint32_t len = 1024;
wstring buf;
do
{
buf.resize(len);
- len = GetFullPathNameW(s.c_str(), len, buf.data(), nullptr);
+ len = GetFullPathNameW(s.data(), len, buf.data(), nullptr);
}
while (len > buf.size());
@@ -100,13 +121,11 @@ fs::absolute(const path& p, error_code& ec)
ec.assign((int)GetLastError(), std::system_category());
else
{
- ec.clear();
buf.resize(len);
ret = std::move(buf);
}
#else
- ec.clear();
- ret = current_path();
+ ret = current_path(ec);
ret /= p;
#endif
return ret;