diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2017-12-18 20:11:37 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2017-12-18 20:11:37 +0000 | 
| commit | 461a67fa15370a9ec88f8f8a240bf7c123bb2029 (patch) | |
| tree | 6942083d7d56bba40ec790a453ca58ad3baf6832 /lib/Basic/VirtualFileSystem.cpp | |
| parent | 75c3240472ba6ac2669ee72ca67eb72d4e2851fc (diff) | |
Notes
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 *> | 
