SyntheticFileSystem.h 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. #pragma once
  2. #include <AK/HashMap.h>
  3. #include <Kernel/FileSystem/FileSystem.h>
  4. #include <Kernel/FileSystem/Inode.h>
  5. #include <Kernel/UnixTypes.h>
  6. class SynthFSInode;
  7. class SynthFS : public FS {
  8. public:
  9. virtual ~SynthFS() override;
  10. static NonnullRefPtr<SynthFS> create();
  11. virtual bool initialize() override;
  12. virtual const char* class_name() const override;
  13. virtual InodeIdentifier root_inode() const override;
  14. virtual RefPtr<Inode> create_inode(InodeIdentifier parentInode, const String& name, mode_t, off_t size, dev_t, int& error) override;
  15. virtual RefPtr<Inode> create_directory(InodeIdentifier parentInode, const String& name, mode_t, int& error) override;
  16. virtual RefPtr<Inode> get_inode(InodeIdentifier) const override;
  17. protected:
  18. typedef unsigned InodeIndex;
  19. InodeIndex generate_inode_index();
  20. static constexpr InodeIndex RootInodeIndex = 1;
  21. SynthFS();
  22. NonnullRefPtr<SynthFSInode> create_directory(String&& name);
  23. NonnullRefPtr<SynthFSInode> create_text_file(String&& name, ByteBuffer&&, mode_t = 0010644);
  24. NonnullRefPtr<SynthFSInode> create_generated_file(String&& name, Function<ByteBuffer(SynthFSInode&)>&&, mode_t = 0100644);
  25. NonnullRefPtr<SynthFSInode> create_generated_file(String&& name, Function<ByteBuffer(SynthFSInode&)>&&, Function<ssize_t(SynthFSInode&, const ByteBuffer&)>&&, mode_t = 0100644);
  26. InodeIdentifier add_file(RefPtr<SynthFSInode>&&, InodeIndex parent = RootInodeIndex);
  27. bool remove_file(InodeIndex);
  28. private:
  29. InodeIndex m_next_inode_index { 2 };
  30. HashMap<InodeIndex, RefPtr<SynthFSInode>> m_inodes;
  31. };
  32. struct SynthFSInodeCustomData {
  33. virtual ~SynthFSInodeCustomData();
  34. };
  35. class SynthFSInode final : public Inode {
  36. friend class SynthFS;
  37. friend class DevPtsFS;
  38. public:
  39. virtual ~SynthFSInode() override;
  40. void set_custom_data(OwnPtr<SynthFSInodeCustomData>&& custom_data) { m_custom_data = move(custom_data); }
  41. SynthFSInodeCustomData* custom_data() { return m_custom_data.ptr(); }
  42. const SynthFSInodeCustomData* custom_data() const { return m_custom_data.ptr(); }
  43. private:
  44. // ^Inode
  45. virtual ssize_t read_bytes(off_t, ssize_t, u8* buffer, FileDescription*) const override;
  46. virtual InodeMetadata metadata() const override;
  47. virtual bool traverse_as_directory(Function<bool(const FS::DirectoryEntry&)>) const override;
  48. virtual InodeIdentifier lookup(StringView name) override;
  49. virtual void flush_metadata() override;
  50. virtual ssize_t write_bytes(off_t, ssize_t, const u8* buffer, FileDescription*) override;
  51. virtual KResult add_child(InodeIdentifier child_id, const StringView& name, mode_t) override;
  52. virtual KResult remove_child(const StringView& name) override;
  53. virtual size_t directory_entry_count() const override;
  54. virtual KResult chmod(mode_t) override;
  55. virtual KResult chown(uid_t, gid_t) override;
  56. SynthFS& fs();
  57. const SynthFS& fs() const;
  58. SynthFSInode(SynthFS&, unsigned index);
  59. String m_name;
  60. InodeIdentifier m_parent;
  61. ByteBuffer m_data;
  62. Function<ByteBuffer(SynthFSInode&)> m_generator;
  63. Function<ssize_t(SynthFSInode&, const ByteBuffer&)> m_write_callback;
  64. Vector<SynthFSInode*> m_children;
  65. InodeMetadata m_metadata;
  66. OwnPtr<SynthFSInodeCustomData> m_custom_data;
  67. };
  68. inline SynthFS& SynthFSInode::fs()
  69. {
  70. return static_cast<SynthFS&>(Inode::fs());
  71. }
  72. inline const SynthFS& SynthFSInode::fs() const
  73. {
  74. return static_cast<const SynthFS&>(Inode::fs());
  75. }