Преглед изворни кода

Refactor TTY signal generation a bit.

We now respect the VINTR and VQUIT control characters in the termios.
Andreas Kling пре 6 година
родитељ
комит
a788e85c09
7 измењених фајлова са 50 додато и 29 уклоњено
  1. 1 1
      Kernel/Keyboard.cpp
  2. 5 0
      Kernel/Process.cpp
  3. 23 12
      Kernel/TTY.cpp
  4. 5 4
      Kernel/TTY.h
  5. 11 11
      Kernel/VirtualConsole.cpp
  6. 1 1
      Kernel/VirtualConsole.h
  7. 4 0
      VirtualFileSystem/UnixTypes.h

+ 1 - 1
Kernel/Keyboard.cpp

@@ -82,7 +82,7 @@ void Keyboard::handleIRQ()
             else if (m_modifiers & Mod_Shift)
             else if (m_modifiers & Mod_Shift)
                 emit(shift_map[ch]);
                 emit(shift_map[ch]);
             else if (m_modifiers & Mod_Ctrl)
             else if (m_modifiers & Mod_Ctrl)
-                emit(shift_map[ch]);
+                emit(map[ch]);
             }
             }
         //break;
         //break;
     }
     }

+ 5 - 0
Kernel/Process.cpp

@@ -777,6 +777,11 @@ void Process::dispatch_signal(byte signal)
         return terminate_due_to_signal(signal);
         return terminate_due_to_signal(signal);
     }
     }
 
 
+    if (handler_laddr.asPtr() == SIG_IGN) {
+        dbgprintf("%s(%u) ignored signal %u\n", name().characters(), pid(), signal);
+        return;
+    }
+
     Scheduler::prepare_to_modify_tss(*this);
     Scheduler::prepare_to_modify_tss(*this);
 
 
     word ret_cs = m_tss.cs;
     word ret_cs = m_tss.cs;

+ 23 - 12
Kernel/TTY.cpp

@@ -37,6 +37,8 @@ TTY::TTY(unsigned major, unsigned minor)
 {
 {
     memset(&m_termios, 0, sizeof(m_termios));
     memset(&m_termios, 0, sizeof(m_termios));
     m_termios.c_lflag |= ISIG | ECHO;
     m_termios.c_lflag |= ISIG | ECHO;
+    static const char default_cc[32] = "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0";
+    memcpy(m_termios.c_cc, default_cc, sizeof(default_cc));
 }
 }
 
 
 TTY::~TTY()
 TTY::~TTY()
@@ -64,23 +66,32 @@ bool TTY::hasDataAvailableForRead() const
 
 
 void TTY::emit(byte ch)
 void TTY::emit(byte ch)
 {
 {
+    if (should_generate_signals()) {
+        if (ch == m_termios.c_cc[VINTR]) {
+            dbgprintf("%s: VINTR pressed!\n", ttyName().characters());
+            generate_signal(SIGINT);
+            return;
+        }
+        if (ch == m_termios.c_cc[VQUIT]) {
+            dbgprintf("%s: VQUIT pressed!\n", ttyName().characters());
+            generate_signal(SIGQUIT);
+            return;
+        }
+    }
     m_buffer.write(&ch, 1);
     m_buffer.write(&ch, 1);
 }
 }
 
 
-void TTY::interrupt()
+void TTY::generate_signal(int signal)
 {
 {
-    if (!should_generate_signals())
+    if (!pgid())
         return;
         return;
-    dbgprintf("%s: Interrupt ^C pressed!\n", ttyName().characters());
-    if (pgid()) {
-        dbgprintf("%s: Send SIGINT to everyone in pgrp %d\n", ttyName().characters(), pgid());
-        InterruptDisabler disabler;
-        Process::for_each_in_pgrp(pgid(), [this] (auto& process) {
-            dbgprintf("%s: Send SIGINT to %d\n", ttyName().characters(), process.pid());
-            process.send_signal(SIGINT, nullptr);
-            return true;
-        });
-    }
+    dbgprintf("%s: Send signal %d to everyone in pgrp %d\n", ttyName().characters(), signal, pgid());
+    InterruptDisabler disabler; // FIXME: Iterate over a set of process handles instead?
+    Process::for_each_in_pgrp(pgid(), [&] (auto& process) {
+        dbgprintf("%s: Send signal %d to %d\n", ttyName().characters(), signal, process.pid());
+        process.send_signal(signal, nullptr);
+        return true;
+    });
 }
 }
 
 
 void TTY::set_termios(const Unix::termios& t)
 void TTY::set_termios(const Unix::termios& t)

+ 5 - 4
Kernel/TTY.h

@@ -49,16 +49,17 @@ public:
     bool in_canonical_mode() const { return m_termios.c_lflag & ICANON; }
     bool in_canonical_mode() const { return m_termios.c_lflag & ICANON; }
 
 
 protected:
 protected:
-    virtual bool isTTY() const final override { return true; }
+    virtual void onTTYWrite(const byte*, size_t) = 0;
 
 
     TTY(unsigned major, unsigned minor);
     TTY(unsigned major, unsigned minor);
     void emit(byte);
     void emit(byte);
 
 
-    virtual void onTTYWrite(const byte*, size_t) = 0;
+private:
+    // ^CharacterDevice
+    virtual bool isTTY() const final override { return true; }
 
 
-    void interrupt();
+    void generate_signal(int signal);
 
 
-private:
     DoubleBuffer m_buffer;
     DoubleBuffer m_buffer;
     pid_t m_pgid { 0 };
     pid_t m_pgid { 0 };
     Unix::termios m_termios;
     Unix::termios m_termios;

+ 11 - 11
Kernel/VirtualConsole.cpp

@@ -378,11 +378,8 @@ void VirtualConsole::put_character_at(unsigned row, unsigned column, byte ch)
     }
     }
 }
 }
 
 
-void VirtualConsole::on_char(byte ch, bool shouldEmit)
+void VirtualConsole::on_char(byte ch)
 {
 {
-    if (shouldEmit)
-        emit(ch);
-
     switch (m_escape_state) {
     switch (m_escape_state) {
     case ExpectBracket:
     case ExpectBracket:
         if (ch == '[')
         if (ch == '[')
@@ -445,12 +442,15 @@ void VirtualConsole::on_char(byte ch, bool shouldEmit)
 
 
 void VirtualConsole::onKeyPress(Keyboard::Key key)
 void VirtualConsole::onKeyPress(Keyboard::Key key)
 {
 {
-    if (key.ctrl() && key.character == 'C') {
-        interrupt();
-        return;
+    if (key.ctrl()) {
+        if (key.character >= 'a' && key.character <= 'z') {
+            emit(key.character - 'a' + 1);
+            return;
+        } else if (key.character == '\\') {
+            emit(0x1c);
+            return;
+        }
     }
     }
-    if (key.ctrl())
-        emit('^');
     emit(key.character);
     emit(key.character);
 }
 }
 
 
@@ -459,7 +459,7 @@ void VirtualConsole::onConsoleReceive(byte ch)
     InterruptDisabler disabler;
     InterruptDisabler disabler;
     auto old_attribute = m_current_attribute;
     auto old_attribute = m_current_attribute;
     m_current_attribute = 0x03;
     m_current_attribute = 0x03;
-    on_char(ch, false);
+    on_char(ch);
     m_current_attribute = old_attribute;
     m_current_attribute = old_attribute;
 }
 }
 
 
@@ -467,7 +467,7 @@ void VirtualConsole::onTTYWrite(const byte* data, size_t size)
 {
 {
     InterruptDisabler disabler;
     InterruptDisabler disabler;
     for (size_t i = 0; i < size; ++i)
     for (size_t i = 0; i < size; ++i)
-        on_char(data[i], false);
+        on_char(data[i]);
 }
 }
 
 
 String VirtualConsole::ttyName() const
 String VirtualConsole::ttyName() const

+ 1 - 1
Kernel/VirtualConsole.h

@@ -27,7 +27,7 @@ private:
     virtual String ttyName() const override;
     virtual String ttyName() const override;
 
 
     void set_active(bool);
     void set_active(bool);
-    void on_char(byte, bool shouldEmit);
+    void on_char(byte);
 
 
     void get_vga_cursor(byte& row, byte& column);
     void get_vga_cursor(byte& row, byte& column);
     void flush_vga_cursor();
     void flush_vga_cursor();

+ 4 - 0
VirtualFileSystem/UnixTypes.h

@@ -4,6 +4,10 @@ extern "C" {
 
 
 namespace Unix {
 namespace Unix {
 
 
+#define SIG_DFL ((void*)0)
+#define SIG_ERR ((void*)-1)
+#define SIG_IGN ((void*)1)
+
 #define SEEK_SET 0
 #define SEEK_SET 0
 #define SEEK_CUR 1
 #define SEEK_CUR 1
 #define SEEK_END 2
 #define SEEK_END 2