diff --git a/redox-rt/src/sys.rs b/redox-rt/src/sys.rs index 27c9be31c6..a536e73c98 100644 --- a/redox-rt/src/sys.rs +++ b/redox-rt/src/sys.rs @@ -965,7 +965,25 @@ impl FdTbl { pub fn from_binary_fd(filetable_fd: FdGuardUpper) -> Result { let mut fdtbl = Self::new(); let files_reader_fd = filetable_fd.as_raw_fd(); - let _ = filetable_fd.lseek(0, syscall::flag::SEEK_SET); + // Refresh the inherited filetable's data before reading it, so an + // exec'd process reconstructs its fd table from the LATEST parent state + // rather than a stale snapshot. Without this, some inherited fds (e.g. + // an interactive shell's pty-slave stdin) are left desynchronized and + // reads return nothing even though writes to sibling fds work. + // Upstream relibc 580eab8b ("Refresh filetable data before filetable + // creation"). A plain lseek did not force the underlying scheme to + // re-materialize the current descriptor set. + let buf = b"refresh"; + unsafe { + syscall::syscall4( + syscall::SYS_DUP2, + files_reader_fd, + files_reader_fd, + buf.as_ptr() as usize, + buf.len(), + ) + }?; + fdtbl.resize(Self::DEFAULT_CAPACITY); let mut reader = crate::proc::FileBufReader::from_fd(files_reader_fd);