Index: llvm/include/llvm/Support/FileSystem.h =================================================================== --- llvm/include/llvm/Support/FileSystem.h +++ llvm/include/llvm/Support/FileSystem.h @@ -411,6 +411,21 @@ /// platform-specific error_code. std::error_code resize_file(int FD, uint64_t Size); +/// Resize \p FD to \p Size before mapping \a mapped_file_region::readwrite. On +/// non-Windows, this calls \a resize_file(). On Windows, this is a no-op, +/// since the subsequent mapping (via \c CreateFileMapping) automatically +/// extends the file. +inline std::error_code resize_file_before_mapping_readwrite(int FD, + uint64_t Size) { +#ifdef _WIN32 + (void)FD; + (void)Size; + return std::error_code(); +#else + return resize_file(FD, Size); +#endif +} + /// Compute an MD5 hash of a file's contents. /// /// @param FD Input file descriptor. Index: llvm/unittests/Support/Path.cpp =================================================================== --- llvm/unittests/Support/Path.cpp +++ llvm/unittests/Support/Path.cpp @@ -1284,6 +1284,31 @@ ASSERT_NO_ERROR(fs::remove(TempPath)); } +TEST_F(FileSystemTest, ResizeBeforeMapping) { + // Create a temp file. + int FD; + SmallString<64> TempPath; + ASSERT_NO_ERROR(fs::createTemporaryFile("prefix", "temp", FD, TempPath)); + ASSERT_NO_ERROR(fs::resize_file_before_mapping_readwrite(FD, 123)); + + // Map in temp file. On Windows, fs::resize_file_before_mapping_readwrite is + // a no-op and the mapping itself will resize the file. + std::error_code EC; + { + fs::mapped_file_region mfr(fs::convertFDToNativeFile(FD), + fs::mapped_file_region::readwrite, 4096, 0, EC); + ASSERT_NO_ERROR(EC); + // Unmap temp file + } + + // Check the size. + fs::file_status Status; + ASSERT_NO_ERROR(fs::status(FD, Status)); + ASSERT_EQ(Status.getSize(), 123U); + ::close(FD); + ASSERT_NO_ERROR(fs::remove(TempPath)); +} + TEST_F(FileSystemTest, MD5) { int FD; SmallString<64> TempPath; @@ -1305,7 +1330,8 @@ ASSERT_NO_ERROR( fs::createTemporaryFile("prefix", "temp", FileDescriptor, TempPath)); unsigned Size = 4096; - ASSERT_NO_ERROR(fs::resize_file(FileDescriptor, Size)); + ASSERT_NO_ERROR( + fs::resize_file_before_mapping_readwrite(FileDescriptor, Size)); // Map in temp file and add some content std::error_code EC;