This is an archive of the discontinued LLVM Phabricator instance.

Windows: fix bug in getcwd() and add chdir().
ClosedPublic

Authored by ted on Apr 27 2015, 10:28 AM.

Details

Summary

GetCurrentDirectory() returns the number of characters copied; 0 is a failure, not a success.

Add implementation for chdir().

Diff Detail

Event Timeline

ted updated this revision to Diff 24488.Apr 27 2015, 10:28 AM
ted retitled this revision from to Windows: fix bug in getcwd() and add chdir()..
ted updated this object.
ted edited the test plan for this revision. (Show Details)
ted added a reviewer: zturner.
ted added a subscriber: Unknown Object (MLST).
zturner added inline comments.Apr 27 2015, 11:08 AM
source/Host/windows/Windows.cpp
168–177

I think a better fix would be to just delete this and change all the callsites to llvm::sys::fs::current_path(). The current implementation is currently already broken in the case of a path being longer than MAX_PATH (which is possible on Windows).

Admittedly, the fix here is certainly better than what we were doing before, but it would be better still to have a proper fix that re-uses the implementation in LLVM.

179–184

Can you also find all the places that call chdir() in LLDB, and remove the #ifdefs that disabled those codepaths on Windows? A quick search shows there's a few, so now that Windows has a chdir implementation I wouldn't want fixing the callsites to fall off of the radar.

181

You can probably just have this function return _chdir(). This guarantees that errno will be set appropriately.

ted updated this revision to Diff 24509.Apr 27 2015, 4:01 PM

Changed getcwd() and chdir() to use _getcwd() and _chdir().

Removed #ifdef _WIN32 disabling calls to chdir() in Platform.cpp and GDBRemoteCommunicationServerPlatform.cpp.

zturner added inline comments.Apr 27 2015, 4:06 PM
source/Host/windows/Windows.cpp
167–171

This is fine for now, but it's worth pointing out this is still broken for paths longer than MAX_PATH. So if you ever run LLDB from a directory longer than 256 characters, things will get messed up. If you don't want to change this to use llvm::sys::fs::current_path(), can you add a TODO mentioning the problem?

ted updated this revision to Diff 24511.Apr 27 2015, 4:06 PM

Replace erroneously removed comment

ted added a comment.Apr 29 2015, 10:16 AM

llvm::sys::fs::current_path() doesn't handle paths > MAX_PATH-1:

std::error_code current_path(SmallVectorImpl<char> &result) {
  SmallVector<wchar_t, MAX_PATH> cur_path;
  DWORD len = MAX_PATH;

  do {
    cur_path.reserve(len);
    len = ::GetCurrentDirectoryW(cur_path.capacity(), cur_path.data());

    // A zero return value indicates a failure other than insufficient space.
    if (len == 0)
      return windows_error(::GetLastError());

    // If there's insufficient space, the len returned is larger than the len
    // given.
  } while (len > cur_path.capacity());

  // On success, GetCurrentDirectoryW returns the number of characters not
  // including the null-terminator.
  cur_path.set_size(len);
  return UTF16ToUTF8(cur_path.begin(), cur_path.size(), result);
}

The MSDN page for _getcwd() says that it supports paths > MAX_PATH if you pass NULL for the buffer. I'm not sure what happens if you pass a size > MAX_PATH.

What should getcwd() do if the path is > MAX_PATH? I could change it so if the first call returns an error, errno is ERANGE and max > MAX_PATH, call _getcwd() again with a NULL, then check that strlen(new buffer) < max, strcpy the new buffer into path and free it.

ted added a comment.Apr 29 2015, 10:25 AM

Whoops - missed the do loop upping the size of the buffer to the return value. But I can't find any documentation saying that GetCurrentDirectory() supports paths > MAX_PATH. Are we sure it does?

zturner accepted this revision.Apr 29 2015, 10:47 AM
zturner edited edge metadata.
In D9300#163393, @ted wrote:

Whoops - missed the do loop upping the size of the buffer to the return value. But I can't find any documentation saying that GetCurrentDirectory() supports paths > MAX_PATH. Are we sure it does?

The documentation for SetCurrentDirectory actually says it can't be longer than MAX_PATH. So maybe we can assume GetCurrentDirectory has the same issue. In any case, I guess it's not so important to change this. It still seems like a nice cleanup, but not very high priority, so feel free to commit as is.

This revision is now accepted and ready to land.Apr 29 2015, 10:47 AM
ted closed this revision.Apr 30 2015, 9:42 AM