DevPtsFS.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. #include <AK/StringBuilder.h>
  2. #include <Kernel/FileSystem/DevPtsFS.h>
  3. #include <Kernel/FileSystem/VirtualFileSystem.h>
  4. #include <Kernel/TTY/SlavePTY.h>
  5. NonnullRefPtr<DevPtsFS> DevPtsFS::create()
  6. {
  7. return adopt(*new DevPtsFS);
  8. }
  9. DevPtsFS::DevPtsFS()
  10. {
  11. }
  12. DevPtsFS::~DevPtsFS()
  13. {
  14. }
  15. static HashTable<unsigned>* ptys;
  16. bool DevPtsFS::initialize()
  17. {
  18. if (ptys == nullptr) {
  19. ptys = new HashTable<unsigned>();
  20. }
  21. m_root_inode = adopt(*new DevPtsFSInode(*this, 1));
  22. m_root_inode->m_metadata.inode = { fsid(), 1 };
  23. m_root_inode->m_metadata.mode = 0040555;
  24. m_root_inode->m_metadata.uid = 0;
  25. m_root_inode->m_metadata.gid = 0;
  26. m_root_inode->m_metadata.size = 0;
  27. m_root_inode->m_metadata.mtime = mepoch;
  28. return true;
  29. }
  30. static unsigned inode_index_to_pty_index(unsigned inode_index)
  31. {
  32. ASSERT(inode_index > 1);
  33. return inode_index - 2;
  34. }
  35. static unsigned pty_index_to_inode_index(unsigned pty_index)
  36. {
  37. return pty_index + 2;
  38. }
  39. InodeIdentifier DevPtsFS::root_inode() const
  40. {
  41. return { fsid(), 1 };
  42. }
  43. RefPtr<Inode> DevPtsFS::create_inode(InodeIdentifier, const String&, mode_t, off_t, dev_t, int& error)
  44. {
  45. error = -EROFS;
  46. return nullptr;
  47. }
  48. RefPtr<Inode> DevPtsFS::create_directory(InodeIdentifier, const String&, mode_t, int& error)
  49. {
  50. error = -EROFS;
  51. return nullptr;
  52. }
  53. RefPtr<Inode> DevPtsFS::get_inode(InodeIdentifier inode_id) const
  54. {
  55. if (inode_id.index() == 1)
  56. return m_root_inode;
  57. unsigned pty_index = inode_index_to_pty_index(inode_id.index());
  58. auto* device = Device::get_device(11, pty_index);
  59. ASSERT(device);
  60. auto inode = adopt(*new DevPtsFSInode(const_cast<DevPtsFS&>(*this), inode_id.index()));
  61. inode->m_metadata.inode = inode_id;
  62. inode->m_metadata.size = 0;
  63. inode->m_metadata.uid = device->uid();
  64. inode->m_metadata.gid = device->gid();
  65. inode->m_metadata.mode = 0020644;
  66. inode->m_metadata.major_device = device->major();
  67. inode->m_metadata.minor_device = device->minor();
  68. inode->m_metadata.mtime = mepoch;
  69. return inode;
  70. }
  71. void DevPtsFS::register_slave_pty(SlavePTY& slave_pty)
  72. {
  73. ptys->set(slave_pty.index());
  74. }
  75. void DevPtsFS::unregister_slave_pty(SlavePTY& slave_pty)
  76. {
  77. ptys->remove(slave_pty.index());
  78. }
  79. DevPtsFSInode::DevPtsFSInode(DevPtsFS& fs, unsigned index)
  80. : Inode(fs, index)
  81. {
  82. }
  83. DevPtsFSInode::~DevPtsFSInode()
  84. {
  85. }
  86. ssize_t DevPtsFSInode::read_bytes(off_t, ssize_t, u8*, FileDescription*) const
  87. {
  88. ASSERT_NOT_REACHED();
  89. }
  90. ssize_t DevPtsFSInode::write_bytes(off_t, ssize_t, const u8*, FileDescription*)
  91. {
  92. ASSERT_NOT_REACHED();
  93. }
  94. InodeMetadata DevPtsFSInode::metadata() const
  95. {
  96. return m_metadata;
  97. }
  98. bool DevPtsFSInode::traverse_as_directory(Function<bool(const FS::DirectoryEntry&)> callback) const
  99. {
  100. if (identifier().index() > 1)
  101. return false;
  102. callback({ ".", 1, identifier(), 0 });
  103. callback({ "..", 2, identifier(), 0 });
  104. for (unsigned pty_index : *ptys) {
  105. String name = String::number(pty_index);
  106. InodeIdentifier identifier = { fsid(), pty_index_to_inode_index(pty_index) };
  107. callback({ name.characters(), name.length(), identifier, 0 });
  108. }
  109. return true;
  110. }
  111. size_t DevPtsFSInode::directory_entry_count() const
  112. {
  113. ASSERT(identifier().index() == 1);
  114. return 2 + ptys->size();
  115. }
  116. InodeIdentifier DevPtsFSInode::lookup(StringView name)
  117. {
  118. ASSERT(identifier().index() == 1);
  119. if (name == "." || name == "..")
  120. return identifier();
  121. bool ok;
  122. unsigned pty_index = name.to_uint(ok);
  123. if (ok && ptys->contains(pty_index)) {
  124. return { fsid(), pty_index_to_inode_index(pty_index) };
  125. }
  126. return {};
  127. }
  128. void DevPtsFSInode::flush_metadata()
  129. {
  130. }
  131. KResult DevPtsFSInode::add_child(InodeIdentifier, const StringView&, mode_t)
  132. {
  133. return KResult(-EROFS);
  134. }
  135. KResult DevPtsFSInode::remove_child(const StringView&)
  136. {
  137. return KResult(-EROFS);
  138. }
  139. KResult DevPtsFSInode::chmod(mode_t)
  140. {
  141. return KResult(-EPERM);
  142. }
  143. KResult DevPtsFSInode::chown(uid_t, gid_t)
  144. {
  145. return KResult(-EPERM);
  146. }