login: clear FD_CLOEXEC on stdio before spawning shell (+diag) so the login shell inherits console I/O
This commit is contained in:
+20
@@ -86,6 +86,26 @@ pub fn spawn_shell<T: Default>(user: &User<T>) -> IoResult<i32> {
|
||||
}
|
||||
}
|
||||
|
||||
// The relibc Redox spawn closes, in the child, every inherited fd that has
|
||||
// FD_CLOEXEC set in the parent's filetable (see relibc
|
||||
// platform/redox/mod.rs, the fds_to_close loop). A login shell MUST inherit
|
||||
// its console stdio, but the pty-slave fds can arrive here still carrying
|
||||
// FD_CLOEXEC (login itself keeps using them fine, since CLOEXEC only affects
|
||||
// exec, not use) — which then silently drops the shell's stdin/stdout/stderr
|
||||
// and leaves an interactive shell with no console. Explicitly clear
|
||||
// FD_CLOEXEC on 0/1/2 so they survive the exec into the shell.
|
||||
const F_GETFD: usize = 1;
|
||||
const F_SETFD: usize = 2;
|
||||
const FD_CLOEXEC: usize = 1;
|
||||
for fd in 0..=2 {
|
||||
let fl = fcntl(fd, F_GETFL, 0);
|
||||
let fd_fl = fcntl(fd, F_GETFD, 0);
|
||||
eprintln!("login-diag: fd{fd} F_GETFL={fl:?} F_GETFD={fd_fl:?}");
|
||||
if let Ok(flags) = fd_fl {
|
||||
let _ = fcntl(fd, F_SETFD, flags & !FD_CLOEXEC);
|
||||
}
|
||||
}
|
||||
|
||||
// The login name is read with the `liner` line editor, which switches the
|
||||
// console pty into raw mode (ICANON/ECHO cleared) and does not restore it.
|
||||
// In raw mode the pty's line discipline never flushes a completed line to
|
||||
|
||||
Reference in New Issue
Block a user