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:
parent
4e2c2b9748
commit
a788e85c09
7 changed files with 51 additions and 30 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
11
Kernel/TTY.h
11
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;
|
|
||||||
|
|
||||||
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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue