MasterPTY.cpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. #include "MasterPTY.h"
  2. #include "PTYMultiplexer.h"
  3. #include "SlavePTY.h"
  4. #include <Kernel/Process.h>
  5. #include <LibC/errno_numbers.h>
  6. #include <LibC/signal_numbers.h>
  7. #include <LibC/sys/ioctl_numbers.h>
  8. //#define MASTERPTY_DEBUG
  9. MasterPTY::MasterPTY(unsigned index)
  10. : CharacterDevice(10, index)
  11. , m_slave(adopt(*new SlavePTY(*this, index)))
  12. , m_index(index)
  13. {
  14. m_pts_name = String::format("/dev/pts/%u", m_index);
  15. set_uid(current->process().uid());
  16. set_gid(current->process().gid());
  17. }
  18. MasterPTY::~MasterPTY()
  19. {
  20. #ifdef MASTERPTY_DEBUG
  21. dbgprintf("~MasterPTY(%u)\n", m_index);
  22. #endif
  23. PTYMultiplexer::the().notify_master_destroyed({}, m_index);
  24. }
  25. String MasterPTY::pts_name() const
  26. {
  27. return m_pts_name;
  28. }
  29. ssize_t MasterPTY::read(FileDescription&, u8* buffer, ssize_t size)
  30. {
  31. if (!m_slave && m_buffer.is_empty())
  32. return 0;
  33. return m_buffer.read(buffer, size);
  34. }
  35. ssize_t MasterPTY::write(FileDescription&, const u8* buffer, ssize_t size)
  36. {
  37. if (!m_slave)
  38. return -EIO;
  39. m_slave->on_master_write(buffer, size);
  40. return size;
  41. }
  42. bool MasterPTY::can_read(FileDescription&) const
  43. {
  44. if (!m_slave)
  45. return true;
  46. return !m_buffer.is_empty();
  47. }
  48. bool MasterPTY::can_write(FileDescription&) const
  49. {
  50. return true;
  51. }
  52. void MasterPTY::notify_slave_closed(Badge<SlavePTY>)
  53. {
  54. #ifdef MASTERPTY_DEBUG
  55. dbgprintf("MasterPTY(%u): slave closed, my retains: %u, slave retains: %u\n", m_index, ref_count(), m_slave->ref_count());
  56. #endif
  57. // +1 ref for my MasterPTY::m_slave
  58. // +1 ref for FileDescription::m_device
  59. if (m_slave->ref_count() == 2)
  60. m_slave = nullptr;
  61. }
  62. ssize_t MasterPTY::on_slave_write(const u8* data, ssize_t size)
  63. {
  64. if (m_closed)
  65. return -EIO;
  66. m_buffer.write(data, size);
  67. return size;
  68. }
  69. bool MasterPTY::can_write_from_slave() const
  70. {
  71. if (m_closed)
  72. return true;
  73. return m_buffer.bytes_in_write_buffer() < 4096;
  74. }
  75. void MasterPTY::close()
  76. {
  77. if (ref_count() == 2) {
  78. InterruptDisabler disabler;
  79. // After the closing FileDescription dies, slave is the only thing keeping me alive.
  80. // From this point, let's consider ourselves closed.
  81. m_closed = true;
  82. m_slave->hang_up();
  83. }
  84. }
  85. int MasterPTY::ioctl(FileDescription& description, unsigned request, unsigned arg)
  86. {
  87. if (request == TIOCSWINSZ)
  88. return m_slave->ioctl(description, request, arg);
  89. return -EINVAL;
  90. }
  91. String MasterPTY::absolute_path(const FileDescription&) const
  92. {
  93. return String::format("ptm:%s", m_pts_name.characters());
  94. }