]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
Fix job control TIOCSPGRP: allow session leader to claim TTY/PTY
authorTulio A M Mendes <[email protected]>
Fri, 17 Apr 2026 21:46:32 +0000 (18:46 -0300)
committerTulio A M Mendes <[email protected]>
Fri, 17 Apr 2026 21:46:32 +0000 (18:46 -0300)
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.

src/kernel/pty.c
src/kernel/tty.c

index df2311423a4b7decd1a160e01033d704f997f30a..26237c9c839dfec84e968b198e8a00cc5e76d894 100644 (file)
@@ -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;
index 074ba08fc161b37a44d82a3f66bd5dbfd8dc7edd..4c6cbcaa07a2db67f575cff8afe50f4b08a4a596 100644 (file)
@@ -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;