fix(redox-rt): close O_CLOEXEC fds individually in fexec_impl
The kernel proc scheme returns EBADF for writes to Filetable/NewFiletable handles, so the bulk FileTableVerb::Close call was silently failing. Close each O_CLOEXEC fd with SYS_CLOSE instead, which updates both the kernel file table and the userspace FILETABLE. This unblocks Command::spawn() parents waiting on the CLOEXEC sync pipe.
This commit is contained in:
+15
-20
@@ -493,11 +493,24 @@ pub fn fexec_impl(
|
||||
let _siglock = crate::signal::tmp_disable_signals();
|
||||
let fds_to_close = {
|
||||
let guard = crate::current_filetable();
|
||||
let old_filetable_fd = guard.fd().as_ref().map(|f| f.as_raw_fd());
|
||||
let mut fds = alloc::vec::Vec::new();
|
||||
for (fd, flags) in guard.iter() {
|
||||
if fd == addrspace_selection_fd.as_raw_fd() {
|
||||
continue; // Will be closed below
|
||||
}
|
||||
if Some(fd) == old_filetable_fd {
|
||||
continue;
|
||||
}
|
||||
if fd == thread_fd.as_raw_fd() {
|
||||
continue;
|
||||
}
|
||||
if fd == proc_fd.as_raw_fd() {
|
||||
continue;
|
||||
}
|
||||
if fd == grants_fd.as_raw_fd() {
|
||||
continue;
|
||||
}
|
||||
|
||||
if flags & O_CLOEXEC == O_CLOEXEC || fd == image_file.as_raw_fd() {
|
||||
fds.push(fd);
|
||||
@@ -507,26 +520,8 @@ pub fn fexec_impl(
|
||||
fds
|
||||
};
|
||||
|
||||
let fds_to_close_bytes: &[u8] = unsafe {
|
||||
core::slice::from_raw_parts(
|
||||
fds_to_close.as_ptr() as *mut u8,
|
||||
fds_to_close.len() * core::mem::size_of::<usize>(),
|
||||
)
|
||||
};
|
||||
|
||||
{
|
||||
let filetable_fd = thread_fd.dup_into_upper(b"filetable-binary")?;
|
||||
let _ = filetable_fd.call_wo(
|
||||
fds_to_close_bytes,
|
||||
CallFlags::empty(),
|
||||
&[syscall::FileTableVerb::Close as u64],
|
||||
);
|
||||
}
|
||||
{
|
||||
let mut guard = crate::current_filetable();
|
||||
for fd in fds_to_close {
|
||||
let _ = guard.remove(fd);
|
||||
}
|
||||
for &fd in &fds_to_close {
|
||||
let _ = crate::sys::close_raw(fd);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
|
||||
Reference in New Issue
Block a user