1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 04:38:11 +00:00

Refactor TTY signal generation a bit.

We now respect the VINTR and VQUIT control characters in the termios.
This commit is contained in:
Andreas Kling 2018-11-16 20:18:58 +01:00
parent 4e2c2b9748
commit a788e85c09
7 changed files with 51 additions and 30 deletions

View file

@ -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;
} }

View file

@ -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;

View file

@ -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()); dbgprintf("%s: Send signal %d to everyone in pgrp %d\n", ttyName().characters(), signal, pgid());
if (pgid()) { InterruptDisabler disabler; // FIXME: Iterate over a set of process handles instead?
dbgprintf("%s: Send SIGINT to everyone in pgrp %d\n", ttyName().characters(), pgid()); Process::for_each_in_pgrp(pgid(), [&] (auto& process) {
InterruptDisabler disabler; dbgprintf("%s: Send signal %d to %d\n", ttyName().characters(), signal, process.pid());
Process::for_each_in_pgrp(pgid(), [this] (auto& process) { process.send_signal(signal, nullptr);
dbgprintf("%s: Send SIGINT to %d\n", ttyName().characters(), process.pid()); return true;
process.send_signal(SIGINT, nullptr); });
return true;
});
}
} }
void TTY::set_termios(const Unix::termios& t) void TTY::set_termios(const Unix::termios& t)

View file

@ -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;
void interrupt();
private: private:
// ^CharacterDevice
virtual bool isTTY() const final override { return true; }
void generate_signal(int signal);
DoubleBuffer m_buffer; DoubleBuffer m_buffer;
pid_t m_pgid { 0 }; pid_t m_pgid { 0 };
Unix::termios m_termios; Unix::termios m_termios;

View file

@ -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') { if (key.ctrl()) {
interrupt(); if (key.character >= 'a' && key.character <= 'z') {
return; 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

View file

@ -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();

View file

@ -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