diff options
| -rw-r--r-- | llvm/include/llvm/Support/FileSystem.h | 7 | ||||
| -rw-r--r-- | llvm/lib/Support/Unix/Path.inc | 10 | ||||
| -rw-r--r-- | llvm/lib/Support/Windows/Path.inc | 12 | ||||
| -rw-r--r-- | llvm/unittests/Support/Path.cpp | 19 |
4 files changed, 48 insertions, 0 deletions
diff --git a/llvm/include/llvm/Support/FileSystem.h b/llvm/include/llvm/Support/FileSystem.h index ad21d8af66e..a0ddcf3dddb 100644 --- a/llvm/include/llvm/Support/FileSystem.h +++ b/llvm/include/llvm/Support/FileSystem.h @@ -357,6 +357,13 @@ std::error_code create_hard_link(const Twine &to, const Twine &from); /// otherwise a platform-specific error_code. std::error_code current_path(SmallVectorImpl<char> &result); +/// @brief Set the current path. +/// +/// @param path The path to set. +/// @returns errc::success if the current path was successfully set, +/// otherwise a platform-specific error_code. +std::error_code set_current_path(const Twine &path); + /// @brief Remove path. Equivalent to POSIX remove(). /// /// @param path Input path. diff --git a/llvm/lib/Support/Unix/Path.inc b/llvm/lib/Support/Unix/Path.inc index 0bf9dbae220..f7334245a00 100644 --- a/llvm/lib/Support/Unix/Path.inc +++ b/llvm/lib/Support/Unix/Path.inc @@ -257,6 +257,16 @@ std::error_code current_path(SmallVectorImpl<char> &result) { return std::error_code(); } +std::error_code set_current_path(const Twine &path) { + SmallString<128> path_storage; + StringRef p = path.toNullTerminatedStringRef(path_storage); + + if (::chdir(p.begin()) == -1) + return std::error_code(errno, std::generic_category()); + + return std::error_code(); +} + std::error_code create_directory(const Twine &path, bool IgnoreExisting, perms Perms) { SmallString<128> path_storage; diff --git a/llvm/lib/Support/Windows/Path.inc b/llvm/lib/Support/Windows/Path.inc index 27b250b428a..3597b551098 100644 --- a/llvm/lib/Support/Windows/Path.inc +++ b/llvm/lib/Support/Windows/Path.inc @@ -200,6 +200,18 @@ std::error_code current_path(SmallVectorImpl<char> &result) { return UTF16ToUTF8(cur_path.begin(), cur_path.size(), result); } +std::error_code set_current_path(const Twine &path) { + // Convert to utf-16. + SmallVector<wchar_t, 128> wide_path; + if (std::error_code ec = widenPath(path, wide_path)) + return ec; + + if (!::SetCurrentDirectoryW(wide_path.begin())) + return mapWindowsError(::GetLastError()); + + return std::error_code(); +} + std::error_code create_directory(const Twine &path, bool IgnoreExisting, perms Perms) { SmallVector<wchar_t, 128> path_utf16; diff --git a/llvm/unittests/Support/Path.cpp b/llvm/unittests/Support/Path.cpp index 30eaa8b278a..fb61cc7c26e 100644 --- a/llvm/unittests/Support/Path.cpp +++ b/llvm/unittests/Support/Path.cpp @@ -1135,4 +1135,23 @@ TEST_F(FileSystemTest, OpenFileForRead) { ::close(FileDescriptor); } + +TEST_F(FileSystemTest, set_current_path) { + SmallString<128> path; + + ASSERT_NO_ERROR(fs::current_path(path)); + ASSERT_NE(TestDirectory, path); + + struct RestorePath { + SmallString<128> path; + RestorePath(const SmallString<128> &path) : path(path) {} + ~RestorePath() { fs::set_current_path(path); } + } restore_path(path); + + ASSERT_NO_ERROR(fs::set_current_path(TestDirectory)); + + ASSERT_NO_ERROR(fs::current_path(path)); + ASSERT_EQ(TestDirectory, path); +} + } // anonymous namespace |

