diff options
Diffstat (limited to 'lib/Basic/VirtualFileSystem.cpp')
-rw-r--r-- | lib/Basic/VirtualFileSystem.cpp | 57 |
1 files changed, 39 insertions, 18 deletions
diff --git a/lib/Basic/VirtualFileSystem.cpp b/lib/Basic/VirtualFileSystem.cpp index f5db717866a9..9d44597dc3fb 100644 --- a/lib/Basic/VirtualFileSystem.cpp +++ b/lib/Basic/VirtualFileSystem.cpp @@ -59,6 +59,7 @@ Status Status::copyWithNewName(const file_status &In, StringRef NewName) { } bool Status::equivalent(const Status &Other) const { + assert(isStatusKnown() && Other.isStatusKnown()); return getUniqueID() == Other.getUniqueID(); } bool Status::isDirectory() const { @@ -243,7 +244,7 @@ public: RealFSDirIter(const Twine &Path, std::error_code &EC) : Iter(Path, EC) { if (!EC && Iter != llvm::sys::fs::directory_iterator()) { llvm::sys::fs::file_status S; - EC = Iter->status(S); + EC = llvm::sys::fs::status(Iter->path(), S, true); CurrentEntry = Status::copyWithNewName(S, Iter->path()); } } @@ -257,7 +258,7 @@ public: CurrentEntry = Status(); } else { llvm::sys::fs::file_status S; - EC = Iter->status(S); + EC = llvm::sys::fs::status(Iter->path(), S, true); CurrentEntry = Status::copyWithNewName(S, Iter->path()); } return EC; @@ -492,7 +493,11 @@ std::string InMemoryFileSystem::toString() const { } bool InMemoryFileSystem::addFile(const Twine &P, time_t ModificationTime, - std::unique_ptr<llvm::MemoryBuffer> Buffer) { + std::unique_ptr<llvm::MemoryBuffer> Buffer, + Optional<uint32_t> User, + Optional<uint32_t> Group, + Optional<llvm::sys::fs::file_type> Type, + Optional<llvm::sys::fs::perms> Perms) { SmallString<128> Path; P.toVector(Path); @@ -508,32 +513,42 @@ bool InMemoryFileSystem::addFile(const Twine &P, time_t ModificationTime, return false; detail::InMemoryDirectory *Dir = Root.get(); - auto I = llvm::sys::path::begin(Path), E = llvm::sys::path::end(Path); + auto I = llvm::sys::path::begin(Path), E = sys::path::end(Path); + const auto ResolvedUser = User.getValueOr(0); + const auto ResolvedGroup = Group.getValueOr(0); + const auto ResolvedType = Type.getValueOr(sys::fs::file_type::regular_file); + const auto ResolvedPerms = Perms.getValueOr(sys::fs::all_all); + // Any intermediate directories we create should be accessible by + // the owner, even if Perms says otherwise for the final path. + const auto NewDirectoryPerms = ResolvedPerms | sys::fs::owner_all; while (true) { StringRef Name = *I; detail::InMemoryNode *Node = Dir->getChild(Name); ++I; if (!Node) { if (I == E) { - // End of the path, create a new file. - // FIXME: expose the status details in the interface. + // End of the path, create a new file or directory. Status Stat(P.str(), getNextVirtualUniqueID(), - llvm::sys::toTimePoint(ModificationTime), 0, 0, - Buffer->getBufferSize(), - llvm::sys::fs::file_type::regular_file, - llvm::sys::fs::all_all); - Dir->addChild(Name, llvm::make_unique<detail::InMemoryFile>( - std::move(Stat), std::move(Buffer))); + llvm::sys::toTimePoint(ModificationTime), ResolvedUser, + ResolvedGroup, Buffer->getBufferSize(), ResolvedType, + ResolvedPerms); + std::unique_ptr<detail::InMemoryNode> Child; + if (ResolvedType == sys::fs::file_type::directory_file) { + Child.reset(new detail::InMemoryDirectory(std::move(Stat))); + } else { + Child.reset(new detail::InMemoryFile(std::move(Stat), + std::move(Buffer))); + } + Dir->addChild(Name, std::move(Child)); return true; } // Create a new directory. Use the path up to here. - // FIXME: expose the status details in the interface. Status Stat( StringRef(Path.str().begin(), Name.end() - Path.str().begin()), - getNextVirtualUniqueID(), llvm::sys::toTimePoint(ModificationTime), 0, - 0, Buffer->getBufferSize(), llvm::sys::fs::file_type::directory_file, - llvm::sys::fs::all_all); + getNextVirtualUniqueID(), llvm::sys::toTimePoint(ModificationTime), + ResolvedUser, ResolvedGroup, Buffer->getBufferSize(), + sys::fs::file_type::directory_file, NewDirectoryPerms); Dir = cast<detail::InMemoryDirectory>(Dir->addChild( Name, llvm::make_unique<detail::InMemoryDirectory>(std::move(Stat)))); continue; @@ -557,10 +572,16 @@ bool InMemoryFileSystem::addFile(const Twine &P, time_t ModificationTime, } bool InMemoryFileSystem::addFileNoOwn(const Twine &P, time_t ModificationTime, - llvm::MemoryBuffer *Buffer) { + llvm::MemoryBuffer *Buffer, + Optional<uint32_t> User, + Optional<uint32_t> Group, + Optional<llvm::sys::fs::file_type> Type, + Optional<llvm::sys::fs::perms> Perms) { return addFile(P, ModificationTime, llvm::MemoryBuffer::getMemBuffer( - Buffer->getBuffer(), Buffer->getBufferIdentifier())); + Buffer->getBuffer(), Buffer->getBufferIdentifier()), + std::move(User), std::move(Group), std::move(Type), + std::move(Perms)); } static ErrorOr<detail::InMemoryNode *> |