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 _siglock = crate::signal::tmp_disable_signals();
|
||||||
let fds_to_close = {
|
let fds_to_close = {
|
||||||
let guard = crate::current_filetable();
|
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();
|
let mut fds = alloc::vec::Vec::new();
|
||||||
for (fd, flags) in guard.iter() {
|
for (fd, flags) in guard.iter() {
|
||||||
if fd == addrspace_selection_fd.as_raw_fd() {
|
if fd == addrspace_selection_fd.as_raw_fd() {
|
||||||
continue; // Will be closed below
|
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() {
|
if flags & O_CLOEXEC == O_CLOEXEC || fd == image_file.as_raw_fd() {
|
||||||
fds.push(fd);
|
fds.push(fd);
|
||||||
@@ -507,26 +520,8 @@ pub fn fexec_impl(
|
|||||||
fds
|
fds
|
||||||
};
|
};
|
||||||
|
|
||||||
let fds_to_close_bytes: &[u8] = unsafe {
|
for &fd in &fds_to_close {
|
||||||
core::slice::from_raw_parts(
|
let _ = crate::sys::close_raw(fd);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|||||||
Reference in New Issue
Block a user