<div>Setting current directory is common in a debugger, it determines where your processes launch from by default.  It's usually even configurable in the debugger.</div><div><br></div><div>It's less clear for non-debuggers, but I don't think having this harms anyone, and having API symmetry is nice</div><div><br><div class="gmail_quote"><div>On Mon, Jan 23, 2017 at 11:09 AM Rafael Avila de Espindola <<a href="mailto:rafael.espindola@gmail.com">rafael.espindola@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Unix version is fine with me.<br class="gmail_msg"><br><br class="gmail_msg"><br>Why do you need to change the current directory btw?<br class="gmail_msg"><br><br class="gmail_msg"><br>Pavel Labath via Phabricator <<a href="mailto:reviews@reviews.llvm.org" class="gmail_msg" target="_blank">reviews@reviews.llvm.org</a>> writes:<br class="gmail_msg"><br><br class="gmail_msg"><br>> labath created this revision.<br class="gmail_msg"><br>><br class="gmail_msg"><br>> This adds a cross-platform way of setting the current working directory<br class="gmail_msg"><br>> analogous to the existing current_path() function used for retrieving<br class="gmail_msg"><br>> it. The function will be used in lldb.<br class="gmail_msg"><br>><br class="gmail_msg"><br>><br class="gmail_msg"><br>> <a href="https://reviews.llvm.org/D29035" rel="noreferrer" class="gmail_msg" target="_blank">https://reviews.llvm.org/D29035</a><br class="gmail_msg"><br>><br class="gmail_msg"><br>> Files:<br class="gmail_msg"><br>>   include/llvm/Support/FileSystem.h<br class="gmail_msg"><br>>   lib/Support/Unix/Path.inc<br class="gmail_msg"><br>>   lib/Support/Windows/Path.inc<br class="gmail_msg"><br>>   unittests/Support/Path.cpp<br class="gmail_msg"><br>><br class="gmail_msg"><br>><br class="gmail_msg"><br>> Index: unittests/Support/Path.cpp<br class="gmail_msg"><br>> ===================================================================<br class="gmail_msg"><br>> --- unittests/Support/Path.cpp<br class="gmail_msg"><br>> +++ unittests/Support/Path.cpp<br class="gmail_msg"><br>> @@ -1135,4 +1135,23 @@<br class="gmail_msg"><br>><br class="gmail_msg"><br>>    ::close(FileDescriptor);<br class="gmail_msg"><br>>  }<br class="gmail_msg"><br>> +<br class="gmail_msg"><br>> +TEST_F(FileSystemTest, set_current_path) {<br class="gmail_msg"><br>> +  SmallString<128> path;<br class="gmail_msg"><br>> +<br class="gmail_msg"><br>> +  ASSERT_NO_ERROR(fs::current_path(path));<br class="gmail_msg"><br>> +  ASSERT_NE(TestDirectory, path);<br class="gmail_msg"><br>> +<br class="gmail_msg"><br>> +  struct RestorePath {<br class="gmail_msg"><br>> +    SmallString<128> path;<br class="gmail_msg"><br>> +    RestorePath(const SmallString<128> &path) : path(path) {}<br class="gmail_msg"><br>> +    ~RestorePath() { fs::set_current_path(path); }<br class="gmail_msg"><br>> +  } restore_path(path);<br class="gmail_msg"><br>> +<br class="gmail_msg"><br>> +  ASSERT_NO_ERROR(fs::set_current_path(TestDirectory));<br class="gmail_msg"><br>> +<br class="gmail_msg"><br>> +  ASSERT_NO_ERROR(fs::current_path(path));<br class="gmail_msg"><br>> +  ASSERT_EQ(TestDirectory, path);<br class="gmail_msg"><br>> +}<br class="gmail_msg"><br>> +<br class="gmail_msg"><br>>  } // anonymous namespace<br class="gmail_msg"><br>> Index: lib/Support/Windows/Path.inc<br class="gmail_msg"><br>> ===================================================================<br class="gmail_msg"><br>> --- lib/Support/Windows/Path.inc<br class="gmail_msg"><br>> +++ lib/Support/Windows/Path.inc<br class="gmail_msg"><br>> @@ -200,6 +200,18 @@<br class="gmail_msg"><br>>    return UTF16ToUTF8(cur_path.begin(), cur_path.size(), result);<br class="gmail_msg"><br>>  }<br class="gmail_msg"><br>><br class="gmail_msg"><br>> +std::error_code set_current_path(const Twine &path) {<br class="gmail_msg"><br>> +  // Convert to utf-16.<br class="gmail_msg"><br>> +  SmallVector<wchar_t, 128> wide_path;<br class="gmail_msg"><br>> +  if (std::error_code ec = widenPath(path, wide_path))<br class="gmail_msg"><br>> +    return ec;<br class="gmail_msg"><br>> +<br class="gmail_msg"><br>> +  if (!::SetCurrentDirectoryW(wide_path.begin()))<br class="gmail_msg"><br>> +    return mapWindowsError(::GetLastError());<br class="gmail_msg"><br>> +<br class="gmail_msg"><br>> +  return std::error_code();<br class="gmail_msg"><br>> +}<br class="gmail_msg"><br>> +<br class="gmail_msg"><br>>  std::error_code create_directory(const Twine &path, bool IgnoreExisting,<br class="gmail_msg"><br>>                                   perms Perms) {<br class="gmail_msg"><br>>    SmallVector<wchar_t, 128> path_utf16;<br class="gmail_msg"><br>> Index: lib/Support/Unix/Path.inc<br class="gmail_msg"><br>> ===================================================================<br class="gmail_msg"><br>> --- lib/Support/Unix/Path.inc<br class="gmail_msg"><br>> +++ lib/Support/Unix/Path.inc<br class="gmail_msg"><br>> @@ -257,6 +257,16 @@<br class="gmail_msg"><br>>    return std::error_code();<br class="gmail_msg"><br>>  }<br class="gmail_msg"><br>><br class="gmail_msg"><br>> +std::error_code set_current_path(const Twine &path) {<br class="gmail_msg"><br>> +  SmallString<128> path_storage;<br class="gmail_msg"><br>> +  StringRef p = path.toNullTerminatedStringRef(path_storage);<br class="gmail_msg"><br>> +<br class="gmail_msg"><br>> +  if (::chdir(p.begin()) == -1)<br class="gmail_msg"><br>> +    return std::error_code(errno, std::generic_category());<br class="gmail_msg"><br>> +<br class="gmail_msg"><br>> +  return std::error_code();<br class="gmail_msg"><br>> +}<br class="gmail_msg"><br>> +<br class="gmail_msg"><br>>  std::error_code create_directory(const Twine &path, bool IgnoreExisting,<br class="gmail_msg"><br>>                                   perms Perms) {<br class="gmail_msg"><br>>    SmallString<128> path_storage;<br class="gmail_msg"><br>> Index: include/llvm/Support/FileSystem.h<br class="gmail_msg"><br>> ===================================================================<br class="gmail_msg"><br>> --- include/llvm/Support/FileSystem.h<br class="gmail_msg"><br>> +++ include/llvm/Support/FileSystem.h<br class="gmail_msg"><br>> @@ -357,6 +357,13 @@<br class="gmail_msg"><br>>  ///          otherwise a platform-specific error_code.<br class="gmail_msg"><br>>  std::error_code current_path(SmallVectorImpl<char> &result);<br class="gmail_msg"><br>><br class="gmail_msg"><br>> +/// @brief Set the current path.<br class="gmail_msg"><br>> +///<br class="gmail_msg"><br>> +/// @param path The path to set.<br class="gmail_msg"><br>> +/// @returns errc::success if the current path was successfully set,<br class="gmail_msg"><br>> +///          otherwise a platform-specific error_code.<br class="gmail_msg"><br>> +std::error_code set_current_path(const Twine &path);<br class="gmail_msg"><br>> +<br class="gmail_msg"><br>>  /// @brief Remove path. Equivalent to POSIX remove().<br class="gmail_msg"><br>>  ///<br class="gmail_msg"><br>>  /// @param path Input path.<br class="gmail_msg"><br>><br class="gmail_msg"><br>><br class="gmail_msg"><br>> Index: unittests/Support/Path.cpp<br class="gmail_msg"><br>> ===================================================================<br class="gmail_msg"><br>> --- unittests/Support/Path.cpp<br class="gmail_msg"><br>> +++ unittests/Support/Path.cpp<br class="gmail_msg"><br>> @@ -1135,4 +1135,23 @@<br class="gmail_msg"><br>><br class="gmail_msg"><br>>    ::close(FileDescriptor);<br class="gmail_msg"><br>>  }<br class="gmail_msg"><br>> +<br class="gmail_msg"><br>> +TEST_F(FileSystemTest, set_current_path) {<br class="gmail_msg"><br>> +  SmallString<128> path;<br class="gmail_msg"><br>> +<br class="gmail_msg"><br>> +  ASSERT_NO_ERROR(fs::current_path(path));<br class="gmail_msg"><br>> +  ASSERT_NE(TestDirectory, path);<br class="gmail_msg"><br>> +<br class="gmail_msg"><br>> +  struct RestorePath {<br class="gmail_msg"><br>> +    SmallString<128> path;<br class="gmail_msg"><br>> +    RestorePath(const SmallString<128> &path) : path(path) {}<br class="gmail_msg"><br>> +    ~RestorePath() { fs::set_current_path(path); }<br class="gmail_msg"><br>> +  } restore_path(path);<br class="gmail_msg"><br>> +<br class="gmail_msg"><br>> +  ASSERT_NO_ERROR(fs::set_current_path(TestDirectory));<br class="gmail_msg"><br>> +<br class="gmail_msg"><br>> +  ASSERT_NO_ERROR(fs::current_path(path));<br class="gmail_msg"><br>> +  ASSERT_EQ(TestDirectory, path);<br class="gmail_msg"><br>> +}<br class="gmail_msg"><br>> +<br class="gmail_msg"><br>>  } // anonymous namespace<br class="gmail_msg"><br>> Index: lib/Support/Windows/Path.inc<br class="gmail_msg"><br>> ===================================================================<br class="gmail_msg"><br>> --- lib/Support/Windows/Path.inc<br class="gmail_msg"><br>> +++ lib/Support/Windows/Path.inc<br class="gmail_msg"><br>> @@ -200,6 +200,18 @@<br class="gmail_msg"><br>>    return UTF16ToUTF8(cur_path.begin(), cur_path.size(), result);<br class="gmail_msg"><br>>  }<br class="gmail_msg"><br>><br class="gmail_msg"><br>> +std::error_code set_current_path(const Twine &path) {<br class="gmail_msg"><br>> +  // Convert to utf-16.<br class="gmail_msg"><br>> +  SmallVector<wchar_t, 128> wide_path;<br class="gmail_msg"><br>> +  if (std::error_code ec = widenPath(path, wide_path))<br class="gmail_msg"><br>> +    return ec;<br class="gmail_msg"><br>> +<br class="gmail_msg"><br>> +  if (!::SetCurrentDirectoryW(wide_path.begin()))<br class="gmail_msg"><br>> +    return mapWindowsError(::GetLastError());<br class="gmail_msg"><br>> +<br class="gmail_msg"><br>> +  return std::error_code();<br class="gmail_msg"><br>> +}<br class="gmail_msg"><br>> +<br class="gmail_msg"><br>>  std::error_code create_directory(const Twine &path, bool IgnoreExisting,<br class="gmail_msg"><br>>                                   perms Perms) {<br class="gmail_msg"><br>>    SmallVector<wchar_t, 128> path_utf16;<br class="gmail_msg"><br>> Index: lib/Support/Unix/Path.inc<br class="gmail_msg"><br>> ===================================================================<br class="gmail_msg"><br>> --- lib/Support/Unix/Path.inc<br class="gmail_msg"><br>> +++ lib/Support/Unix/Path.inc<br class="gmail_msg"><br>> @@ -257,6 +257,16 @@<br class="gmail_msg"><br>>    return std::error_code();<br class="gmail_msg"><br>>  }<br class="gmail_msg"><br>><br class="gmail_msg"><br>> +std::error_code set_current_path(const Twine &path) {<br class="gmail_msg"><br>> +  SmallString<128> path_storage;<br class="gmail_msg"><br>> +  StringRef p = path.toNullTerminatedStringRef(path_storage);<br class="gmail_msg"><br>> +<br class="gmail_msg"><br>> +  if (::chdir(p.begin()) == -1)<br class="gmail_msg"><br>> +    return std::error_code(errno, std::generic_category());<br class="gmail_msg"><br>> +<br class="gmail_msg"><br>> +  return std::error_code();<br class="gmail_msg"><br>> +}<br class="gmail_msg"><br>> +<br class="gmail_msg"><br>>  std::error_code create_directory(const Twine &path, bool IgnoreExisting,<br class="gmail_msg"><br>>                                   perms Perms) {<br class="gmail_msg"><br>>    SmallString<128> path_storage;<br class="gmail_msg"><br>> Index: include/llvm/Support/FileSystem.h<br class="gmail_msg"><br>> ===================================================================<br class="gmail_msg"><br>> --- include/llvm/Support/FileSystem.h<br class="gmail_msg"><br>> +++ include/llvm/Support/FileSystem.h<br class="gmail_msg"><br>> @@ -357,6 +357,13 @@<br class="gmail_msg"><br>>  ///          otherwise a platform-specific error_code.<br class="gmail_msg"><br>>  std::error_code current_path(SmallVectorImpl<char> &result);<br class="gmail_msg"><br>><br class="gmail_msg"><br>> +/// @brief Set the current path.<br class="gmail_msg"><br>> +///<br class="gmail_msg"><br>> +/// @param path The path to set.<br class="gmail_msg"><br>> +/// @returns errc::success if the current path was successfully set,<br class="gmail_msg"><br>> +///          otherwise a platform-specific error_code.<br class="gmail_msg"><br>> +std::error_code set_current_path(const Twine &path);<br class="gmail_msg"><br>> +<br class="gmail_msg"><br>>  /// @brief Remove path. Equivalent to POSIX remove().<br class="gmail_msg"><br>>  ///<br class="gmail_msg"><br>>  /// @param path Input path.<br class="gmail_msg"><br></blockquote></div></div>