From: Tulio A M Mendes Date: Fri, 17 Apr 2026 21:46:32 +0000 (-0300) Subject: Fix job control TIOCSPGRP: allow session leader to claim TTY/PTY X-Git-Url: https://projects.tadryanom.me/?a=commitdiff_plain;h=14c06366895af067d50c336eca5ff2d1cf6bb8e3;p=AdrOS.git Fix job control TIOCSPGRP: allow session leader to claim TTY/PTY When fulltest runs from the shell, the TTY's tty_session_id is already set to the shell's session. The test's leader child calls setsid() then TIOCSPGRP, which fails with EPERM because the new session doesn't match tty_session_id. The kernel never allowed a new session leader to claim the TTY as its controlling terminal. Fix: in TIOCSPGRP handler for both tty.c and pty.c, allow a session leader (session_id == pid) to claim the terminal by updating the session when it explicitly sets its own pgrp as foreground. This matches POSIX semantics where a session leader may establish a new controlling terminal. Test results: 103/103 smoke test PASS, 16/16 battery PASS. --- diff --git a/src/kernel/pty.c b/src/kernel/pty.c index df231142..26237c9c 100644 --- a/src/kernel/pty.c +++ b/src/kernel/pty.c @@ -528,7 +528,17 @@ int pty_slave_ioctl_idx(int idx, uint32_t cmd, void* user_arg) { return 0; } - if (current_process->session_id != p->session_id) return -EPERM; + if (current_process->session_id != p->session_id) { + /* Allow a session leader to claim the PTY as its controlling + * terminal by setting its own process group as foreground. */ + if (current_process->session_id == current_process->pid && + (uint32_t)fg == current_process->pgrp_id) { + p->session_id = current_process->session_id; + p->fg_pgrp = (uint32_t)fg; + return 0; + } + return -EPERM; + } if (fg < 0) return -EINVAL; p->fg_pgrp = (uint32_t)fg; return 0; diff --git a/src/kernel/tty.c b/src/kernel/tty.c index 074ba08f..4c6cbcaa 100644 --- a/src/kernel/tty.c +++ b/src/kernel/tty.c @@ -276,7 +276,19 @@ int tty_ioctl(uint32_t cmd, void* user_arg) { return 0; } - if (current_process->session_id != tty_session_id) return -EPERM; + if (current_process->session_id != tty_session_id) { + /* Allow a session leader to claim the TTY as its controlling + * terminal by setting its own process group as foreground. + * POSIX: a session leader may take control of a terminal + * when explicitly establishing a new controlling terminal. */ + if (current_process->session_id == current_process->pid && + (uint32_t)fg == current_process->pgrp_id) { + tty_session_id = current_process->session_id; + tty_fg_pgrp = (uint32_t)fg; + return 0; + } + return -EPERM; + } if (fg < 0) return -EINVAL; tty_fg_pgrp = (uint32_t)fg; return 0;