[libcxx-commits] [PATCH] D91169: [14/N] [libcxx] Implement the current_path function for windows

Martin Storsjö via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Fri Jan 29 04:32:58 PST 2021


mstorsjo updated this revision to Diff 320102.
mstorsjo set the repository for this revision to rG LLVM Github Monorepo.
mstorsjo added a comment.

Reworked this patch to allow two use patterns of the POSIX getcwd() function - in strict POSIX getcwd(), it has to be given a preallocated buffer of a fixed size - but at least glibc and Darwin libc's (and windows) allow passing nullptr, to let the function allocate a suitably large buffer. For now I only use that codepath for windows (to reduce the risk of anything breaking due to this patch), but we could enable it on POSIX systems where we know it's supported as a later feature.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D91169/new/

https://reviews.llvm.org/D91169

Files:
  libcxx/src/filesystem/operations.cpp
  libcxx/src/filesystem/posix_compat.h


Index: libcxx/src/filesystem/posix_compat.h
===================================================================
--- libcxx/src/filesystem/posix_compat.h
+++ libcxx/src/filesystem/posix_compat.h
@@ -277,6 +277,8 @@
 }
 int close(int fd) { return _close(fd); }
 int chdir(const wchar_t *path) { return _wchdir(path); }
+
+wchar_t *getcwd(wchar_t *buff, size_t size) { return _wgetcwd(buff, size); }
 #else
 int symlink_file(const char *oldname, const char *newname) {
   return ::symlink(oldname, newname);
@@ -288,6 +290,7 @@
 using ::close;
 using ::fstat;
 using ::ftruncate;
+using ::getcwd;
 using ::link;
 using ::lstat;
 using ::mkdir;
Index: libcxx/src/filesystem/operations.cpp
===================================================================
--- libcxx/src/filesystem/operations.cpp
+++ libcxx/src/filesystem/operations.cpp
@@ -1022,15 +1022,31 @@
 path __current_path(error_code* ec) {
   ErrorHandler<path> err("current_path", ec);
 
+#if defined(_LIBCPP_WIN32API)
+  // Common extension outside of POSIX getcwd() spec, without needing to
+  // preallocate a buffer. Also supported by a number of other POSIX libcs.
+  int size = 0;
+  path::value_type* ptr = nullptr;
+  typedef decltype(&::free) Deleter;
+  Deleter deleter = &::free;
+#else
   auto size = ::pathconf(".", _PC_PATH_MAX);
   _LIBCPP_ASSERT(size >= 0, "pathconf returned a 0 as max size");
 
-  auto buff = unique_ptr<char[]>(new char[size + 1]);
-  char* ret;
-  if ((ret = ::getcwd(buff.get(), static_cast<size_t>(size))) == nullptr)
+  auto buff = unique_ptr<path::value_type[]>(new path::value_type[size + 1]);
+  path::value_type* ptr = buff.get();
+
+  // Preallocated buffer, don't free the buffer in the second unique_ptr
+  // below.
+  struct Deleter { void operator()(void*) const {} };
+  Deleter deleter;
+#endif
+
+  unique_ptr<path::value_type, Deleter> hold(detail::getcwd(ptr, size), deleter);
+  if (hold.get() == nullptr)
     return err.report(capture_errno(), "call to getcwd failed");
 
-  return {buff.get()};
+  return {hold.get()};
 }
 
 void __current_path(const path& p, error_code* ec) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D91169.320102.patch
Type: text/x-patch
Size: 2096 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20210129/59572693/attachment.bin>


More information about the libcxx-commits mailing list