MasterPTY.cpp 2.2 KB

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