TTY.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/CircularDeque.h>
  8. #include <AK/WeakPtr.h>
  9. #include <Kernel/Devices/CharacterDevice.h>
  10. #include <Kernel/DoubleBuffer.h>
  11. #include <Kernel/ProcessGroup.h>
  12. #include <Kernel/UnixTypes.h>
  13. #define TTY_BUFFER_SIZE 1024
  14. namespace Kernel {
  15. class TTY : public CharacterDevice {
  16. public:
  17. virtual ~TTY() override;
  18. virtual KResultOr<size_t> read(FileDescription&, u64, UserOrKernelBuffer&, size_t) override;
  19. virtual KResultOr<size_t> write(FileDescription&, u64, const UserOrKernelBuffer&, size_t) override;
  20. virtual bool can_read(const FileDescription&, size_t) const override;
  21. virtual bool can_write(const FileDescription&, size_t) const override;
  22. virtual KResult ioctl(FileDescription&, unsigned request, Userspace<void*> arg) override final;
  23. virtual String absolute_path(const FileDescription&) const override { return tty_name(); }
  24. virtual String const& tty_name() const = 0;
  25. unsigned short rows() const { return m_rows; }
  26. unsigned short columns() const { return m_columns; }
  27. ProcessGroupID pgid() const
  28. {
  29. if (auto pg = m_pg.strong_ref())
  30. return pg->pgid();
  31. return 0;
  32. }
  33. KResult set_termios(const termios&);
  34. bool should_generate_signals() const { return m_termios.c_lflag & ISIG; }
  35. bool should_flush_on_signal() const { return !(m_termios.c_lflag & NOFLSH); }
  36. bool should_echo_input() const { return m_termios.c_lflag & ECHO; }
  37. bool in_canonical_mode() const { return m_termios.c_lflag & ICANON; }
  38. void set_default_termios();
  39. void hang_up();
  40. // ^Device
  41. virtual mode_t required_mode() const override { return 0620; }
  42. protected:
  43. virtual KResultOr<size_t> on_tty_write(const UserOrKernelBuffer&, size_t) = 0;
  44. void set_size(unsigned short columns, unsigned short rows);
  45. TTY(unsigned major, unsigned minor);
  46. void emit(u8, bool do_evaluate_block_conditions = false);
  47. void echo_with_processing(u8);
  48. bool can_do_backspace() const;
  49. void do_backspace();
  50. void erase_word();
  51. void erase_character();
  52. void kill_line();
  53. void flush_input();
  54. bool is_eol(u8) const;
  55. bool is_eof(u8) const;
  56. bool is_kill(u8) const;
  57. bool is_erase(u8) const;
  58. bool is_werase(u8) const;
  59. void generate_signal(int signal);
  60. int m_available_lines { 0 };
  61. private:
  62. // ^CharacterDevice
  63. virtual bool is_tty() const final override { return true; }
  64. virtual void echo(u8) = 0;
  65. template<typename Functor>
  66. void process_output(u8, Functor put_char);
  67. CircularDeque<u8, TTY_BUFFER_SIZE> m_input_buffer;
  68. // FIXME: use something like AK::Bitmap but which takes a size template parameter
  69. u8 m_special_character_bitmask[TTY_BUFFER_SIZE / 8];
  70. WeakPtr<Process> m_original_process_parent;
  71. WeakPtr<ProcessGroup> m_pg;
  72. termios m_termios;
  73. unsigned short m_rows { 0 };
  74. unsigned short m_columns { 0 };
  75. };
  76. }