WIP: use upper fd table

This commit is contained in:
Jeremy Soller
2025-11-14 12:31:48 -07:00
parent 74e3ad1c2c
commit 0844e6fc90
25 changed files with 404 additions and 451 deletions
+1 -1
View File
@@ -334,7 +334,7 @@ pub unsafe fn init(auxvs: Box<[[usize; 2]]>) {
let Some(proc_fd) = get_auxv(&auxvs, AT_REDOX_PROC_FD) else {
panic!("Missing proc and thread fd!");
};
redox_rt::initialize(FdGuard::new(proc_fd));
redox_rt::initialize(FdGuard::new(proc_fd).to_upper().unwrap());
// TODO: Is it safe to assume setup_sighandler has been called at this point?
redox_rt::sys::this_proc_call(
+13 -8
View File
@@ -16,13 +16,13 @@ use crate::{
use redox_rt::{
RtTcb,
proc::{ExtraInfo, FdGuard, FexecResult, InterpOverride},
proc::{ExtraInfo, FdGuard, FdGuardUpper, FexecResult, InterpOverride},
sys::Resugid,
};
use syscall::{data::Stat, error::*, flag::*};
fn fexec_impl(
exec_file: FdGuard,
exec_file: FdGuardUpper,
path: &[u8],
args: &[&[u8]],
envs: &[&[u8]],
@@ -30,7 +30,7 @@ fn fexec_impl(
extrainfo: &ExtraInfo,
interp_override: Option<InterpOverride>,
) -> Result<Infallible> {
let memory = FdGuard::new(syscall::open("/scheme/memory", 0)?);
let memory = FdGuard::open("/scheme/memory", 0)?.to_upper()?;
let addrspace_selection_fd = match redox_rt::proc::fexec_impl(
exec_file,
@@ -231,8 +231,13 @@ pub fn execve(
// scenarios. While execve() is undefined according to POSIX if there exist sibling
// threads, it could still be allowed by keeping certain file descriptors and instead
// set the active file table.
let files_fd =
File::new(syscall::dup(**RtTcb::current().thread_fd(), b"filetable")? as c_int);
let files_fd = File::new(
c_int::try_from(syscall::dup(
RtTcb::current().thread_fd().as_raw_fd(),
b"filetable",
)?)
.unwrap(),
);
for line in BufReader::new(files_fd).lines() {
let line = match line {
Ok(l) => l,
@@ -252,7 +257,7 @@ pub fn execve(
}
// TODO: Convert image_file to FdGuard earlier?
let exec_fd_guard = FdGuard::new(image_file.fd as usize);
let exec_fd_guard = FdGuard::new(image_file.fd as usize).to_upper().unwrap();
core::mem::forget(image_file);
let sigprocmask = redox_rt::signal::get_sigmask().unwrap();
@@ -263,8 +268,8 @@ pub fn execve(
sigignmask: redox_rt::signal::get_sigignmask_to_inherit(),
sigprocmask,
umask: redox_rt::sys::get_umask(),
thr_fd: **RtTcb::current().thread_fd(),
proc_fd: **redox_rt::current_proc_fd(),
thr_fd: RtTcb::current().thread_fd().as_raw_fd(),
proc_fd: redox_rt::current_proc_fd().as_raw_fd(),
};
fexec_impl(
exec_fd_guard,
+6 -6
View File
@@ -22,14 +22,14 @@ pub unsafe extern "C" fn redox_fpath(fd: c_int, buf: *mut c_void, count: size_t)
pub fn pipe2(flags: usize) -> syscall::error::Result<[c_int; 2]> {
let read_flags = flags | O_RDONLY;
let write_flags = flags | O_WRONLY;
let mut read_fd = FdGuard::new(syscall::open("/scheme/pipe", read_flags)?);
let mut write_fd = FdGuard::new(syscall::dup(*read_fd, b"write")?);
syscall::fcntl(*write_fd, F_SETFL, write_flags)?;
syscall::fcntl(*write_fd, F_SETFD, write_flags)?;
let mut read_fd = FdGuard::open("/scheme/pipe", read_flags)?;
let mut write_fd = read_fd.dup(b"write")?;
write_fd.fcntl(F_SETFL, write_flags)?;
write_fd.fcntl(F_SETFD, write_flags)?;
let fds = [
c_int::try_from(*read_fd).map_err(|_| Error::new(EMFILE))?,
c_int::try_from(*write_fd).map_err(|_| Error::new(EMFILE))?,
c_int::try_from(read_fd.as_raw_fd()).map_err(|_| Error::new(EMFILE))?,
c_int::try_from(write_fd.as_raw_fd()).map_err(|_| Error::new(EMFILE))?,
];
read_fd.take();
+3 -2
View File
@@ -146,6 +146,7 @@ pub unsafe extern "C" fn redox_openat_v1(
fd,
str::from_utf8_unchecked(slice::from_raw_parts(path_base, path_len)),
flags as usize,
0, //TODO: openat fcntl_flags
))
}
#[unsafe(no_mangle)]
@@ -386,12 +387,12 @@ pub unsafe extern "C" fn redox_mkns_v1(
// ABI-UNSTABLE
#[unsafe(no_mangle)]
pub unsafe extern "C" fn redox_cur_procfd_v0() -> usize {
**redox_rt::current_proc_fd()
redox_rt::current_proc_fd().as_raw_fd()
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn redox_cur_thrfd_v0() -> usize {
**redox_rt::RtTcb::current().thread_fd()
redox_rt::RtTcb::current().thread_fd().as_raw_fd()
}
#[unsafe(no_mangle)]
+7 -7
View File
@@ -112,7 +112,7 @@ impl Pal for Sys {
let mut stat = syscall::Stat::default();
syscall::fstat(*fd as usize, &mut stat)?;
fd.fstat(&mut stat)?;
let Resugid { ruid, rgid, .. } = redox_rt::sys::posix_getresugid();
@@ -500,8 +500,8 @@ impl Pal for Sys {
}
//TODO: store fd internally
let fd = FdGuard::new(syscall::open(path, open_flags)?);
Ok(syscall::read(*fd, buf)?)
let fd = FdGuard::open(path, open_flags)?;
Ok(fd.read(buf)?)
}
fn getresgid(
@@ -578,8 +578,8 @@ impl Pal for Sys {
fn gettid() -> pid_t {
// This is used by pthread mutexes for reentrant checks and must be nonzero
// and unique for each thread in the same process (but not cross-process)
Self::current_os_tid()
.thread_fd
let thread_fd = Self::current_os_tid().thread_fd;
(thread_fd & !syscall::UPPER_FDTBL_TAG)
.checked_add(1)
.unwrap()
.try_into()
@@ -861,7 +861,7 @@ impl Pal for Sys {
}
fn current_os_tid() -> crate::pthread::OsTid {
crate::pthread::OsTid {
thread_fd: **RtTcb::current().thread_fd(),
thread_fd: RtTcb::current().thread_fd().as_raw_fd(),
}
}
@@ -1070,7 +1070,7 @@ impl Pal for Sys {
}
let path = format!("/scheme/time/{clock_id}");
let timerfd = FdGuard::new(libredox::open(&path, O_RDWR, 0)?);
let timerfd = FdGuard::open(&path, syscall::O_RDWR)?;
let eventfd = FdGuard::new(Error::demux(unsafe {
event::redox_event_queue_create_v1(0)
})?);
+1 -1
View File
@@ -156,7 +156,7 @@ pub fn open(path: &str, flags: usize) -> Result<usize> {
let resolve_flags = O_CLOEXEC | O_SYMLINK | O_RDONLY;
let resolve_fd = FdGuard::new(syscall::open(&*canon, resolve_flags)?);
let bytes_read = syscall::read(*resolve_fd, &mut resolve_buf)?;
let bytes_read = resolve_fd.read(&mut resolve_buf)?;
// TODO: make resolve_buf PATH_MAX + 1 bytes?
if bytes_read == resolve_buf.len() {
return Err(Error::new(ENAMETOOLONG));
+21 -17
View File
@@ -281,7 +281,7 @@ unsafe fn serialize_ancillary_data_to_stream(
let fds_slice = slice::from_raw_parts(fds_ptr, fd_count);
for &fd in fds_slice.iter() {
let fd_to_send = FdGuard::new(syscall::dup(fd as usize, b"")?);
syscall::sendfd(socket as usize, *fd_to_send as usize, 0, 0)?;
syscall::sendfd(socket as usize, fd_to_send.as_raw_fd(), 0, 0)?;
}
}
@@ -562,12 +562,12 @@ impl PalSocket for Sys {
)?;
let fs_bind_result = (|| -> Result<()> {
let dirfd = FdGuard::new(syscall::open(
let dirfd = FdGuard::open(
&dir_path,
syscall::O_RDONLY | syscall::O_DIRECTORY | syscall::O_CLOEXEC,
)?);
)?;
let fd_to_send = FdGuard::new(syscall::dup(socket as usize, &[])?);
let _ = syscall::sendfd(*dirfd, *fd_to_send, 0, 0)?;
syscall::sendfd(dirfd.as_raw_fd(), fd_to_send.as_raw_fd(), 0, 0)?;
Ok(())
})();
@@ -628,14 +628,14 @@ impl PalSocket for Sys {
let (_, fd_path) = dir_path_and_fd_path(&path)?;
let target_path = format!("/{fd_path}");
let socket_file_fd = FdGuard::new(syscall::open(&target_path, syscall::O_RDWR)?);
let socket_file_fd = FdGuard::open(&target_path, syscall::O_RDWR)?;
const TOKEN_BUF_SIZE: usize = 16;
let mut token_buf = [0u8; TOKEN_BUF_SIZE];
redox_rt::sys::sys_call(
*socket_file_fd,
socket_file_fd.as_raw_fd(),
&mut token_buf,
CallFlags::empty(),
&[FsCall::Connect as u64],
@@ -809,9 +809,11 @@ impl PalSocket for Sys {
Self::read(socket, slice::from_raw_parts_mut(buf as *mut u8, len))
} else {
let fd = FdGuard::new(syscall::dup(socket as usize, b"listen")?);
Self::getpeername(*fd as c_int, address, address_len)?;
Self::read(*fd as c_int, slice::from_raw_parts_mut(buf as *mut u8, len))
Self::getpeername(fd.as_c_fd().unwrap(), address, address_len)?;
Self::read(
fd.as_c_fd().unwrap(),
slice::from_raw_parts_mut(buf as *mut u8, len),
)
}
}
@@ -976,7 +978,10 @@ impl PalSocket for Sys {
Self::write(socket, slice::from_raw_parts(buf as *const u8, len))
} else {
let fd = FdGuard::new(bind_or_connect!(connect copy, socket, dest_addr, dest_len)?);
Self::write(*fd as c_int, slice::from_raw_parts(buf as *const u8, len))
Self::write(
fd.as_c_fd().unwrap(),
slice::from_raw_parts(buf as *const u8, len),
)
}
}
@@ -1009,7 +1014,7 @@ impl PalSocket for Sys {
tv_nsec,
};
Self::write(*fd as c_int, &timespec)?;
Self::write(fd.as_c_fd().unwrap(), &timespec)?;
Ok(())
};
@@ -1078,28 +1083,27 @@ impl PalSocket for Sys {
match (domain, kind) {
(AF_UNIX, SOCK_STREAM) => {
let listener = FdGuard::new(syscall::open("/scheme/uds_stream", flags | O_CREAT)?);
let listener = FdGuard::open("/scheme/uds_stream", flags | O_CREAT)?;
// For now, uds_stream: lets connects be instant, and instead blocks
// on any I/O performed. So we don't need to mark this as
// nonblocking.
let mut fd0 = FdGuard::new(syscall::dup(*listener, b"connect")?);
let mut fd1 = FdGuard::new(syscall::dup(*listener, b"listen")?);
let mut fd0 = listener.dup(b"connect")?;
let mut fd1 = listener.dup(b"listen")?;
sv[0] = fd0.take() as c_int;
sv[1] = fd1.take() as c_int;
Ok(())
}
(AF_UNIX, SOCK_DGRAM) => {
let listener = FdGuard::new(syscall::open("/scheme/uds_dgram", flags | O_CREAT)?);
let listener = FdGuard::open("/scheme/uds_dgram", flags | O_CREAT)?;
// For now, uds_dgram: lets connects be instant, and instead blocks
// on any I/O performed. So we don't need to mark this as
// nonblocking.
let mut fd0 = FdGuard::new(syscall::dup(*listener, b"connect")?);
let mut fd0 = listener.dup(b"connect")?;
sv[0] = fd0.take() as c_int;
sv[1] = listener.take() as c_int;