1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 11:08: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)
emit(shift_map[ch]);
else if (m_modifiers & Mod_Ctrl)
emit(shift_map[ch]);
emit(map[ch]);
}
//break;
}

View file

@ -777,6 +777,11 @@ void Process::dispatch_signal(byte 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);
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));
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()
@ -64,23 +66,32 @@ bool TTY::hasDataAvailableForRead() const
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);
}
void TTY::interrupt()
void TTY::generate_signal(int signal)
{
if (!should_generate_signals())
if (!pgid())
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)

View file

@ -49,16 +49,17 @@ public:
bool in_canonical_mode() const { return m_termios.c_lflag & ICANON; }
protected:
virtual bool isTTY() const final override { return true; }
virtual void onTTYWrite(const byte*, size_t) = 0;
TTY(unsigned major, unsigned minor);
void emit(byte);
virtual void onTTYWrite(const byte*, size_t) = 0;
void interrupt();
private:
// ^CharacterDevice
virtual bool isTTY() const final override { return true; }
void generate_signal(int signal);
DoubleBuffer m_buffer;
pid_t m_pgid { 0 };
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) {
case ExpectBracket:
if (ch == '[')
@ -445,12 +442,15 @@ void VirtualConsole::on_char(byte ch, bool shouldEmit)
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);
}
@ -459,7 +459,7 @@ void VirtualConsole::onConsoleReceive(byte ch)
InterruptDisabler disabler;
auto old_attribute = m_current_attribute;
m_current_attribute = 0x03;
on_char(ch, false);
on_char(ch);
m_current_attribute = old_attribute;
}
@ -467,7 +467,7 @@ void VirtualConsole::onTTYWrite(const byte* data, size_t size)
{
InterruptDisabler disabler;
for (size_t i = 0; i < size; ++i)
on_char(data[i], false);
on_char(data[i]);
}
String VirtualConsole::ttyName() const

View file

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

View file

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