Skip to content

Commit

Permalink
tty: Support SIGTTOU, SIGTTIN behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
klange committed Jan 19, 2024
1 parent b23c2b1 commit d392600
Showing 1 changed file with 28 additions and 0 deletions.
28 changes: 28 additions & 0 deletions kernel/vfs/tty.c
Original file line number Diff line number Diff line change
Expand Up @@ -382,9 +382,24 @@ void close_pty_master(fs_node_t * node) {
return;
}

static int ignoring(int sig) {
if (this_core->current_process->blocked_signals & (1ULL << sig)) return 1;
if (this_core->current_process->signals[sig].handler == 1) return 1;
return 0;
}

ssize_t read_pty_slave(fs_node_t * node, off_t offset, size_t size, uint8_t *buffer) {
pty_t * pty = (pty_t *)node->device;

/* If this process *is* part of this tty's session, but is NOT in the foreground job
* and it tries to read from the TTY, then send it SIGTTIN - but only if it's not
* ignoring it. If it is ignoring, make the write fail with EIO. */
if (pty->ct_proc == this_core->current_process->session && pty->fg_proc && this_core->current_process->job != pty->fg_proc) {
if (ignoring(SIGTTIN)) return -EIO;
group_send_signal(this_core->current_process->job, SIGTTIN, 1);
return -ERESTARTSYS;
}

if (pty->tios.c_lflag & ICANON) {
return ring_buffer_read(pty->in, size, buffer);
} else {
Expand All @@ -406,6 +421,19 @@ ssize_t read_pty_slave(fs_node_t * node, off_t offset, size_t size, uint8_t *buf
ssize_t write_pty_slave(fs_node_t * node, off_t offset, size_t size, uint8_t *buffer) {
pty_t * pty = (pty_t *)node->device;

if (pty->tios.c_lflag & TOSTOP) {
/* If TOSTOP is enabled and this process *is* part of this tty's session but
* is NOT in the foreground job, then send the whole job SIGTTOU - but only
* if we weren't ignoring SIGTTOU ourselves. If we were ignoring it, then
* the write can continue without issue. */
if (pty->ct_proc == this_core->current_process->session && pty->fg_proc && this_core->current_process->job != pty->fg_proc) {
if (!ignoring(SIGTTOU)) {
group_send_signal(this_core->current_process->job, SIGTTOU, 1);
return -ERESTARTSYS;
}
}
}

size_t l = 0;
for (uint8_t * c = buffer; l < size; ++c, ++l) {
output_process_slave(pty, *c);
Expand Down

0 comments on commit d392600

Please sign in to comment.