Merge branch 'avoid-blocking-nsmgr' into 'master'
refactor: Move fd allocation logic into userspace See merge request redox-os/relibc!1479
This commit is contained in:
Generated
+6
-6
@@ -262,9 +262,9 @@ checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
|
||||
|
||||
[[package]]
|
||||
name = "libredox"
|
||||
version = "0.1.17"
|
||||
version = "0.1.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f02ab6bace2054fb888a3c16f990117b579d14a3088e472d63c6011fa185c9d3"
|
||||
checksum = "c943259e342f1e06ff2da7a83eabdfe7f92ce10262688dbf1895ff0b3e6e4652"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"libc",
|
||||
@@ -467,9 +467,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "redox_event"
|
||||
version = "0.4.7"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c07d0d6d291e3a951bd847b1cd4af32fc6243d64116cf7702838c02797688b7"
|
||||
checksum = "c5018d583d6d2f5499352aea8d177e9067d1eb03ab17c78169d5ba7a30001b15"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"libredox",
|
||||
@@ -478,9 +478,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.8.1"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b44b894f2a6e36457d665d1e08c3866add6ed5e70050c1b4ba8a8ddedb02ce7"
|
||||
checksum = "c5102a6aaa05aa011a238e178e6bca86d2cb56fc9f586d37cb80f5bca6e07759"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
+4
-3
@@ -69,8 +69,9 @@ bitflags = "2"
|
||||
ioslice = { version = "0.6", default-features = false }
|
||||
plain = "0.2"
|
||||
redox-path = "0.3"
|
||||
redox_protocols = { package = "libredox", version = "0.1.17", default-features = false, features = ["protocol"] }
|
||||
redox_syscall = "0.8.1"
|
||||
redox_protocols = { package = "libredox", version = "0.1.18", default-features = false, features = ["protocol"] }
|
||||
redox_syscall = "0.9.0"
|
||||
|
||||
[build-dependencies]
|
||||
cc = "1"
|
||||
|
||||
@@ -123,7 +124,7 @@ sc = "0.2.7"
|
||||
redox_syscall.workspace = true
|
||||
redox-rt = { path = "redox-rt" }
|
||||
redox-path.workspace = true
|
||||
redox_event = { version = "0.4.7", default-features = false, features = ["redox_syscall"] }
|
||||
redox_event = { version = "0.4.8", default-features = false, features = ["redox_syscall"] }
|
||||
ioslice.workspace = true
|
||||
redox-ioctl = { path = "redox-ioctl" }
|
||||
redox_protocols.workspace = true
|
||||
|
||||
@@ -8,6 +8,6 @@ description = "Ioctl definitions and (de)serialization for Redox"
|
||||
|
||||
[dependencies]
|
||||
drm-sys = "0.8.0"
|
||||
redox_syscall = "0.8.1"
|
||||
redox_syscall = "0.9.0"
|
||||
|
||||
[features]
|
||||
|
||||
@@ -79,11 +79,12 @@ pub struct ArchIntRegs {
|
||||
pub unsafe fn deactivate_tcb(open_via_dup: &FdGuardUpper) -> Result<()> {
|
||||
let mut env = syscall::EnvRegisters::default();
|
||||
|
||||
let file = open_via_dup.dup(b"regs/env")?;
|
||||
let file = open_via_dup.dup_into_upper(b"regs/env")?;
|
||||
|
||||
env.tpidr_el0 = 0;
|
||||
|
||||
file.write(&mut env)?;
|
||||
crate::TLS_ACTIVATED.store(false, core::sync::atomic::Ordering::Relaxed);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -93,7 +94,7 @@ unsafe extern "C" fn fork_impl(args: &ForkArgs, initial_rsp: *mut usize) -> usiz
|
||||
|
||||
unsafe extern "C" fn child_hook(scratchpad: &ForkScratchpad) {
|
||||
//let _ = syscall::write(1, alloc::format!("CUR{cur_filetable_fd}PROC{new_proc_fd}THR{new_thr_fd}\n").as_bytes());
|
||||
let _ = syscall::close(scratchpad.cur_filetable_fd);
|
||||
let _ = crate::sys::close(scratchpad.cur_filetable_fd);
|
||||
unsafe {
|
||||
crate::child_hook_common(crate::ChildHookCommonArgs {
|
||||
new_thr_fd: FdGuard::new(scratchpad.new_thr_fd),
|
||||
@@ -102,6 +103,9 @@ unsafe extern "C" fn child_hook(scratchpad: &ForkScratchpad) {
|
||||
} else {
|
||||
Some(FdGuard::new(scratchpad.new_proc_fd))
|
||||
},
|
||||
new_filetable_fd: FdGuard::new(scratchpad.new_filetable_fd)
|
||||
.to_upper()
|
||||
.unwrap(),
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
@@ -61,12 +61,13 @@ pub struct ArchIntRegs {
|
||||
pub unsafe fn deactivate_tcb(open_via_dup: &FdGuardUpper) -> Result<()> {
|
||||
let mut env = syscall::EnvRegisters::default();
|
||||
|
||||
let file = open_via_dup.dup(b"regs/env")?;
|
||||
let file = open_via_dup.dup_into_upper(b"regs/env")?;
|
||||
|
||||
env.fsbase = 0;
|
||||
env.gsbase = 0;
|
||||
|
||||
file.write(&mut env)?;
|
||||
crate::TLS_ACTIVATED.store(false, core::sync::atomic::Ordering::Relaxed);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -76,7 +77,7 @@ unsafe extern "fastcall" fn fork_impl(args: &ForkArgs, initial_rsp: *mut usize)
|
||||
|
||||
// TODO: duplicate code with x86_64
|
||||
unsafe extern "cdecl" fn child_hook(scratchpad: ForkScratchpad) {
|
||||
let _ = syscall::close(scratchpad.cur_filetable_fd);
|
||||
let _ = crate::sys::close(scratchpad.cur_filetable_fd);
|
||||
unsafe {
|
||||
crate::child_hook_common(crate::ChildHookCommonArgs {
|
||||
new_thr_fd: FdGuard::new(scratchpad.new_thr_fd),
|
||||
@@ -85,6 +86,9 @@ unsafe extern "cdecl" fn child_hook(scratchpad: ForkScratchpad) {
|
||||
} else {
|
||||
Some(FdGuard::new(scratchpad.new_proc_fd))
|
||||
},
|
||||
new_filetable_fd: FdGuard::new(scratchpad.new_filetable_fd)
|
||||
.to_upper()
|
||||
.unwrap(),
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ pub mod riscv64;
|
||||
#[repr(C)]
|
||||
pub struct ForkScratchpad {
|
||||
pub cur_filetable_fd: usize,
|
||||
pub new_filetable_fd: usize,
|
||||
pub new_proc_fd: usize,
|
||||
pub new_thr_fd: usize,
|
||||
}
|
||||
|
||||
@@ -55,11 +55,12 @@ pub struct ArchIntRegs {
|
||||
pub unsafe fn deactivate_tcb(open_via_dup: &FdGuardUpper) -> Result<()> {
|
||||
let mut env = syscall::EnvRegisters::default();
|
||||
|
||||
let file = open_via_dup.dup(b"regs/env")?;
|
||||
let file = open_via_dup.dup_into_upper(b"regs/env")?;
|
||||
|
||||
env.tp = 0;
|
||||
|
||||
file.write(&mut env)?;
|
||||
crate::TLS_ACTIVATED.store(false, core::sync::atomic::Ordering::Relaxed);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -68,7 +69,7 @@ unsafe extern "C" fn fork_impl(args: &ForkArgs, initial_rsp: *mut usize) -> usiz
|
||||
}
|
||||
|
||||
unsafe extern "C" fn child_hook(scratchpad: &ForkScratchpad) {
|
||||
let _ = syscall::close(scratchpad.cur_filetable_fd);
|
||||
let _ = crate::sys::close(scratchpad.cur_filetable_fd);
|
||||
unsafe {
|
||||
crate::child_hook_common(crate::ChildHookCommonArgs {
|
||||
new_thr_fd: FdGuard::new(scratchpad.new_thr_fd),
|
||||
@@ -77,6 +78,9 @@ unsafe extern "C" fn child_hook(scratchpad: &ForkScratchpad) {
|
||||
} else {
|
||||
Some(FdGuard::new(scratchpad.new_proc_fd))
|
||||
},
|
||||
new_filetable_fd: FdGuard::new(scratchpad.new_filetable_fd)
|
||||
.to_upper()
|
||||
.unwrap(),
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
@@ -75,12 +75,13 @@ pub struct ArchIntRegs {
|
||||
pub unsafe fn deactivate_tcb(open_via_dup: &FdGuardUpper) -> Result<()> {
|
||||
let mut env = syscall::EnvRegisters::default();
|
||||
|
||||
let file = open_via_dup.dup(b"regs/env")?;
|
||||
let file = open_via_dup.dup_into_upper(b"regs/env")?;
|
||||
|
||||
env.fsbase = 0;
|
||||
env.gsbase = 0;
|
||||
|
||||
file.write(&mut env)?;
|
||||
crate::TLS_ACTIVATED.store(false, core::sync::atomic::Ordering::Relaxed);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -90,7 +91,7 @@ unsafe extern "sysv64" fn fork_impl(args: &ForkArgs, initial_rsp: *mut usize) ->
|
||||
|
||||
#[allow(unsafe_op_in_unsafe_fn)]
|
||||
unsafe extern "sysv64" fn child_hook(scratchpad: &ForkScratchpad) {
|
||||
let _ = syscall::close(scratchpad.cur_filetable_fd);
|
||||
let _ = crate::sys::close(scratchpad.cur_filetable_fd);
|
||||
crate::child_hook_common(crate::ChildHookCommonArgs {
|
||||
new_thr_fd: FdGuard::new(scratchpad.new_thr_fd),
|
||||
new_proc_fd: if scratchpad.new_proc_fd == usize::MAX {
|
||||
@@ -98,6 +99,9 @@ unsafe extern "sysv64" fn child_hook(scratchpad: &ForkScratchpad) {
|
||||
} else {
|
||||
Some(FdGuard::new(scratchpad.new_proc_fd))
|
||||
},
|
||||
new_filetable_fd: FdGuard::new(scratchpad.new_filetable_fd)
|
||||
.to_upper()
|
||||
.unwrap(),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+65
-10
@@ -15,6 +15,7 @@ use syscall::Sigcontrol;
|
||||
use self::{
|
||||
proc::{FdGuard, FdGuardUpper, STATIC_PROC_INFO},
|
||||
sync::Mutex,
|
||||
sys::FdTbl,
|
||||
};
|
||||
|
||||
extern crate alloc;
|
||||
@@ -67,6 +68,11 @@ impl RtTcb {
|
||||
|
||||
pub type Tcb = GenericTcb<RtTcb>;
|
||||
|
||||
// TODO: Remove this by keeping the TCB initialized during exec
|
||||
// and informing ld.so through some other way.
|
||||
pub static TLS_ACTIVATED: core::sync::atomic::AtomicBool =
|
||||
core::sync::atomic::AtomicBool::new(false);
|
||||
|
||||
/// OS and architecture specific code to activate TLS - Redox aarch64
|
||||
#[allow(unsafe_op_in_unsafe_fn)]
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
@@ -78,6 +84,7 @@ pub unsafe fn tcb_activate(_tcb: &RtTcb, tls_end: usize, tls_len: usize) {
|
||||
"msr tpidr_el0, {}",
|
||||
in(reg) abi_ptr,
|
||||
);
|
||||
TLS_ACTIVATED.store(true, core::sync::atomic::Ordering::Relaxed);
|
||||
}
|
||||
|
||||
/// OS and architecture specific code to activate TLS - Redox x86
|
||||
@@ -86,16 +93,18 @@ pub unsafe fn tcb_activate(_tcb: &RtTcb, tls_end: usize, tls_len: usize) {
|
||||
pub unsafe fn tcb_activate(tcb: &RtTcb, tls_end: usize, _tls_len: usize) {
|
||||
let mut env = syscall::EnvRegisters::default();
|
||||
|
||||
let file = tcb
|
||||
.thread_fd()
|
||||
.dup(b"regs/env")
|
||||
let file_fd = crate::sys::dup_into_upper_raw(tcb.thread_fd().as_raw_fd(), b"regs/env")
|
||||
.expect_notls("failed to open handle for process registers");
|
||||
|
||||
file.read(&mut env).expect_notls("failed to read gsbase");
|
||||
syscall::read(file_fd, &mut env).expect_notls("failed to read gsbase");
|
||||
|
||||
env.gsbase = tls_end as u32;
|
||||
|
||||
file.write(&env).expect_notls("failed to write gsbase");
|
||||
syscall::write(file_fd, &env).expect_notls("failed to write gsbase");
|
||||
|
||||
let _ = crate::sys::close_raw(file_fd);
|
||||
|
||||
TLS_ACTIVATED.store(true, core::sync::atomic::Ordering::Relaxed);
|
||||
}
|
||||
|
||||
/// OS and architecture specific code to activate TLS - Redox x86_64
|
||||
@@ -104,16 +113,18 @@ pub unsafe fn tcb_activate(tcb: &RtTcb, tls_end: usize, _tls_len: usize) {
|
||||
pub unsafe fn tcb_activate(tcb: &RtTcb, tls_end_and_tcb_start: usize, _tls_len: usize) {
|
||||
let mut env = syscall::EnvRegisters::default();
|
||||
|
||||
let file = tcb
|
||||
.thread_fd()
|
||||
.dup(b"regs/env")
|
||||
let file_fd = crate::sys::dup_into_upper_raw(tcb.thread_fd().as_raw_fd(), b"regs/env")
|
||||
.expect_notls("failed to open handle for process registers");
|
||||
|
||||
file.read(&mut env).expect_notls("failed to read fsbase");
|
||||
syscall::read(file_fd, &mut env).expect_notls("failed to read fsbase");
|
||||
|
||||
env.fsbase = tls_end_and_tcb_start as u64;
|
||||
|
||||
file.write(&env).expect_notls("failed to write fsbase");
|
||||
syscall::write(file_fd, &env).expect_notls("failed to write fsbase");
|
||||
|
||||
let _ = crate::sys::close_raw(file_fd);
|
||||
|
||||
TLS_ACTIVATED.store(true, core::sync::atomic::Ordering::Relaxed);
|
||||
}
|
||||
|
||||
/// OS and architecture specific code to activate TLS - Redox riscv64
|
||||
@@ -129,6 +140,7 @@ pub unsafe fn tcb_activate(_tcb: &RtTcb, tls_end: usize, tls_len: usize) {
|
||||
"mv tp, {}",
|
||||
in(reg) tls_start
|
||||
);
|
||||
TLS_ACTIVATED.store(true, core::sync::atomic::Ordering::Relaxed);
|
||||
}
|
||||
|
||||
/// Initialize redox-rt in situations where relibc is not used
|
||||
@@ -158,6 +170,17 @@ pub unsafe fn initialize_freestanding(this_thr_fd: FdGuardUpper) -> &'static FdG
|
||||
page.tcb_len = syscall::PAGE_SIZE;
|
||||
page.tls_end = (page as *mut Tcb).cast();
|
||||
|
||||
let cur_filetable_fd = syscall::dup_into(
|
||||
this_thr_fd.as_raw_fd(),
|
||||
this_thr_fd.as_raw_fd() + 1,
|
||||
b"filetable-binary",
|
||||
)
|
||||
.expect("failed to open filetable-binary");
|
||||
|
||||
*current_filetable() =
|
||||
FdTbl::from_binary_fd(FdGuard::new(cur_filetable_fd).to_upper().unwrap())
|
||||
.expect("failed to populate fds");
|
||||
|
||||
// Make sure to use ptr::write to prevent dropping the existing FdGuard
|
||||
page.os_specific.thr_fd.get().write(Some(this_thr_fd));
|
||||
|
||||
@@ -176,6 +199,8 @@ pub unsafe fn initialize_freestanding(this_thr_fd: FdGuardUpper) -> &'static FdG
|
||||
let abi_ptr = core::ptr::addr_of_mut!(page.tcb_ptr) as usize;
|
||||
core::arch::asm!("mv tp, {}", in(reg) (abi_ptr + 8));
|
||||
}
|
||||
TLS_ACTIVATED.store(true, core::sync::atomic::Ordering::Relaxed);
|
||||
|
||||
initialize();
|
||||
|
||||
(*page.os_specific.thr_fd.get()).as_ref().unwrap()
|
||||
@@ -275,9 +300,30 @@ pub fn current_namespace_fd() -> syscall::Result<usize> {
|
||||
struct ChildHookCommonArgs {
|
||||
new_thr_fd: FdGuard,
|
||||
new_proc_fd: Option<FdGuard>,
|
||||
new_filetable_fd: FdGuardUpper,
|
||||
}
|
||||
|
||||
unsafe fn child_hook_common(args: ChildHookCommonArgs) {
|
||||
let new_filetable_fd = args.new_filetable_fd;
|
||||
|
||||
let old_filetable_fd;
|
||||
{
|
||||
let mut guard = current_filetable();
|
||||
old_filetable_fd = guard.take();
|
||||
guard.set_fd(new_filetable_fd);
|
||||
guard
|
||||
.override_at(args.new_thr_fd.as_raw_fd(), args.new_thr_fd.as_raw_fd())
|
||||
.expect("failed to add new_thr_fd");
|
||||
if let Some(new_proc_fd) = args.new_proc_fd.as_ref() {
|
||||
guard
|
||||
.override_at(new_proc_fd.as_raw_fd(), new_proc_fd.as_raw_fd())
|
||||
.expect("failed to add new_proc_fd");
|
||||
}
|
||||
if let Some(ref old) = old_filetable_fd {
|
||||
let _ = guard.remove(old.as_raw_fd());
|
||||
}
|
||||
}
|
||||
|
||||
let new_thr_fd = args.new_thr_fd.to_upper().unwrap();
|
||||
let new_proc_fd = args.new_proc_fd.map(|x| x.to_upper().unwrap());
|
||||
|
||||
@@ -310,4 +356,13 @@ unsafe fn child_hook_common(args: ChildHookCommonArgs) {
|
||||
|
||||
let old_thr_fd = unsafe { RtTcb::current().thr_fd.get().replace(Some(new_thr_fd)) };
|
||||
drop(old_thr_fd);
|
||||
|
||||
drop(old_filetable_fd);
|
||||
}
|
||||
|
||||
static FILETABLE: Mutex<FdTbl> = Mutex::new(FdTbl::new());
|
||||
|
||||
#[inline]
|
||||
pub fn current_filetable() -> crate::sync::MutexGuard<'static, FdTbl> {
|
||||
FILETABLE.lock()
|
||||
}
|
||||
|
||||
+124
-63
@@ -7,7 +7,7 @@ use crate::{
|
||||
read_proc_meta,
|
||||
sys::{fstat, open, proc_call, thread_call},
|
||||
};
|
||||
use redox_protocols::protocol::{ProcCall, ThreadCall};
|
||||
use redox_protocols::protocol::{O_CLOEXEC, ProcCall, ThreadCall};
|
||||
|
||||
use alloc::{boxed::Box, vec};
|
||||
|
||||
@@ -25,8 +25,8 @@ use goblin::elf64::{
|
||||
};
|
||||
|
||||
use syscall::{
|
||||
CallFlags, F_GETFD, GrantDesc, GrantFlags, MAP_FIXED_NOREPLACE, MAP_SHARED, Map, O_CLOEXEC,
|
||||
PAGE_SIZE, PROT_EXEC, PROT_READ, PROT_WRITE, SetSighandlerData,
|
||||
CallFlags, GrantDesc, GrantFlags, MAP_FIXED_NOREPLACE, MAP_SHARED, Map, PAGE_SIZE, PROT_EXEC,
|
||||
PROT_READ, PROT_WRITE, SetSighandlerData,
|
||||
error::*,
|
||||
flag::{MapFlags, SEEK_SET},
|
||||
};
|
||||
@@ -63,6 +63,8 @@ pub struct ExtraInfo<'a> {
|
||||
pub ns_fd: Option<usize>,
|
||||
/// CWD handle
|
||||
pub cwd_fd: Option<usize>,
|
||||
/// Filetable handle
|
||||
pub filetable_fd: Option<usize>,
|
||||
/// If the process for which the image is to be loaded the same as the currently running process
|
||||
pub same_process: bool,
|
||||
}
|
||||
@@ -93,9 +95,10 @@ pub fn fexec_impl(
|
||||
let grants_fd = if let Some(interp) = interp_override.as_ref() {
|
||||
FdGuard::new(interp.grants_fd).to_upper()?
|
||||
} else {
|
||||
let current_addrspace_fd = thread_fd.dup(b"addrspace")?;
|
||||
current_addrspace_fd.dup(b"empty")?.to_upper()?
|
||||
let current_addrspace_fd = thread_fd.dup_into_upper(b"addrspace")?;
|
||||
current_addrspace_fd.dup_into_upper(b"empty")?
|
||||
};
|
||||
grants_fd.fcntl(syscall::F_SETFD, O_CLOEXEC)?;
|
||||
|
||||
// Never allow more than 1 MiB of program headers.
|
||||
const MAX_PH_SIZE: usize = 1024 * 1024;
|
||||
@@ -404,6 +407,8 @@ pub fn fexec_impl(
|
||||
push(AT_REDOX_NS_FD)?;
|
||||
push(extrainfo.cwd_fd.unwrap_or(usize::MAX))?;
|
||||
push(AT_REDOX_CWD_FD)?;
|
||||
push(extrainfo.filetable_fd.unwrap_or(usize::MAX))?;
|
||||
push(AT_REDOX_FILETABLE_FD)?;
|
||||
|
||||
push(0)?;
|
||||
|
||||
@@ -421,7 +426,7 @@ pub fn fexec_impl(
|
||||
|
||||
push(argc)?;
|
||||
|
||||
if let Ok(sighandler_fd) = thread_fd.dup(b"sighandler") {
|
||||
if let Ok(sighandler_fd) = thread_fd.dup_into_upper(b"sighandler") {
|
||||
let _ = sighandler_fd.write(&SetSighandlerData {
|
||||
user_handler: 0,
|
||||
excp_handler: 0,
|
||||
@@ -456,11 +461,11 @@ pub fn fexec_impl(
|
||||
);
|
||||
|
||||
if interp_override.is_some() {
|
||||
let mmap_min_fd = grants_fd.dup(b"mmap-min-addr")?;
|
||||
let mmap_min_fd = grants_fd.dup_into_upper(b"mmap-min-addr")?;
|
||||
let _ = mmap_min_fd.write(&usize::to_ne_bytes(min_mmap_addr));
|
||||
}
|
||||
|
||||
let addrspace_selection_fd = thread_fd.dup(b"current-addrspace")?.to_upper()?;
|
||||
let addrspace_selection_fd = thread_fd.dup_into_upper(b"current-addrspace")?;
|
||||
|
||||
let _ = addrspace_selection_fd.write(&create_set_addr_space_buf(
|
||||
grants_fd.as_raw_fd(),
|
||||
@@ -474,29 +479,55 @@ pub fn fexec_impl(
|
||||
// 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 = syscall::dup(thread_fd.as_raw_fd(), b"filetable-binary")?;
|
||||
let mut files_reader = FileBufReader::from_fd(files_fd);
|
||||
loop {
|
||||
let fd = match files_reader.read_le_u64()? {
|
||||
None => break,
|
||||
Some(fd) => fd,
|
||||
};
|
||||
let fd = usize::try_from(fd).unwrap();
|
||||
let _siglock = crate::signal::tmp_disable_signals();
|
||||
let fds_to_close = {
|
||||
let guard = crate::current_filetable();
|
||||
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 fd == addrspace_selection_fd.as_raw_fd() || fd == files_fd {
|
||||
continue; // Will be closed below
|
||||
if flags & O_CLOEXEC == O_CLOEXEC || fd == image_file.as_raw_fd() {
|
||||
fds.push(fd);
|
||||
}
|
||||
}
|
||||
|
||||
let flags = syscall::fcntl(fd, F_GETFD, 0)?;
|
||||
fds
|
||||
};
|
||||
|
||||
if flags & O_CLOEXEC == O_CLOEXEC {
|
||||
let _ = syscall::close(fd);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
unsafe {
|
||||
deactivate_tcb(&thread_fd)?;
|
||||
}
|
||||
|
||||
let old_filetable_fd = {
|
||||
let mut guard = crate::current_filetable();
|
||||
guard.take()
|
||||
};
|
||||
drop(old_filetable_fd);
|
||||
|
||||
// Dropping this FD will cause the address space switch.
|
||||
drop(addrspace_selection_fd);
|
||||
unreachable!();
|
||||
@@ -705,7 +736,7 @@ impl<'a> Drop for MmapGuard<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
struct FileBufReader {
|
||||
pub(crate) struct FileBufReader {
|
||||
fd: usize,
|
||||
buf: [u8; 8192],
|
||||
pos: usize,
|
||||
@@ -724,10 +755,10 @@ impl FileBufReader {
|
||||
}
|
||||
|
||||
impl FileBufReader {
|
||||
fn read_le_u64(&mut self) -> Result<Option<u64>> {
|
||||
pub fn read_le_u64(&mut self) -> Result<Option<u64>> {
|
||||
if self.pos >= self.cap {
|
||||
debug_assert!(self.pos == self.cap);
|
||||
self.cap = crate::sys::posix_read(self.fd, &mut self.buf)?;
|
||||
self.cap = syscall::read(self.fd, &mut self.buf)?;
|
||||
self.pos = 0;
|
||||
}
|
||||
|
||||
@@ -746,7 +777,6 @@ impl FileBufReader {
|
||||
Ok(Some(num))
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct FdGuard<const UPPER: bool = false> {
|
||||
fd: usize,
|
||||
@@ -757,18 +787,24 @@ impl FdGuard<false> {
|
||||
pub fn new(fd: usize) -> Self {
|
||||
Self { fd }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn open<T: AsRef<str>>(path: T, flags: usize) -> Result<Self> {
|
||||
open(path, flags).map(Self::new)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn open_into_upper<T: AsRef<str>>(path: T, flags: usize) -> Result<FdGuardUpper> {
|
||||
crate::sys::open_into_upper(path, flags)
|
||||
.map(FdGuard::new)?
|
||||
.to_upper()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn to_upper(self) -> Result<FdGuardUpper> {
|
||||
// Move to upper table if necessary
|
||||
let fd = if self.fd & syscall::UPPER_FDTBL_TAG == 0 {
|
||||
//TODO: use F_DUPFD_CLOEXEC?
|
||||
let fd = syscall::fcntl(self.fd, syscall::F_DUPFD, syscall::UPPER_FDTBL_TAG)?;
|
||||
let fd = crate::sys::fcntl(self.fd, syscall::F_DUPFD, syscall::UPPER_FDTBL_TAG)?;
|
||||
drop(self);
|
||||
fd
|
||||
} else {
|
||||
@@ -791,16 +827,35 @@ impl<const UPPER: bool> FdGuard<UPPER> {
|
||||
flags: usize,
|
||||
fcntl_flags: usize,
|
||||
) -> Result<FdGuard<false>> {
|
||||
syscall::openat(self.fd, path, flags, fcntl_flags).map(FdGuard::new)
|
||||
crate::sys::openat(self.fd, path, flags, fcntl_flags).map(FdGuard::new)
|
||||
}
|
||||
#[inline]
|
||||
pub fn openat_into_upper<T: AsRef<str>>(
|
||||
&self,
|
||||
path: T,
|
||||
flags: usize,
|
||||
fcntl_flags: usize,
|
||||
) -> Result<FdGuardUpper> {
|
||||
crate::sys::openat_into_upper(self.fd, path, flags, fcntl_flags)
|
||||
.map(FdGuard::new)?
|
||||
.to_upper()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn dup(&self, buf: &[u8]) -> Result<FdGuard<false>> {
|
||||
syscall::dup(self.fd, buf).map(FdGuard::new)
|
||||
crate::sys::dup(self.fd, buf).map(FdGuard::new)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn dup_into_upper(&self, buf: &[u8]) -> Result<FdGuardUpper> {
|
||||
crate::sys::dup_into_upper(self.fd, buf)
|
||||
.map(FdGuard::new)?
|
||||
.to_upper()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn fcntl(&self, cmd: usize, arg: usize) -> Result<usize> {
|
||||
syscall::fcntl(self.fd, cmd, arg)
|
||||
crate::sys::fcntl(self.fd, cmd, arg)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -825,17 +880,17 @@ impl<const UPPER: bool> FdGuard<UPPER> {
|
||||
|
||||
#[inline]
|
||||
pub fn call_ro(&self, payload: &mut [u8], flags: CallFlags, metadata: &[u64]) -> Result<usize> {
|
||||
syscall::call_ro(self.fd, payload, flags, metadata)
|
||||
crate::sys::sys_call_ro(self.fd, payload, flags, metadata)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn call_wo(&self, payload: &[u8], flags: CallFlags, metadata: &[u64]) -> Result<usize> {
|
||||
syscall::call_wo(self.fd, payload, flags, metadata)
|
||||
crate::sys::sys_call_wo(self.fd, payload, flags, metadata)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn call_rw(&self, payload: &mut [u8], flags: CallFlags, metadata: &[u64]) -> Result<usize> {
|
||||
syscall::call_rw(self.fd, payload, flags, metadata)
|
||||
crate::sys::sys_call_rw(self.fd, payload, flags, metadata)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -853,7 +908,7 @@ impl<const UPPER: bool> FdGuard<UPPER> {
|
||||
impl<const UPPER: bool> Drop for FdGuard<UPPER> {
|
||||
#[inline]
|
||||
fn drop(&mut self) {
|
||||
let _ = syscall::close(self.fd);
|
||||
let _ = crate::sys::close(self.fd);
|
||||
}
|
||||
}
|
||||
impl Debug for FdGuard<false> {
|
||||
@@ -912,7 +967,7 @@ pub enum ForkArgs<'a> {
|
||||
}
|
||||
|
||||
pub fn fork_inner(initial_rsp: *mut usize, args: &ForkArgs) -> Result<usize> {
|
||||
let (cur_filetable_fd, new_proc_fd, new_thr_fd, new_pid);
|
||||
let (cur_filetable_fd, new_filetable_fd, new_proc_fd, new_thr_fd, new_pid);
|
||||
|
||||
{
|
||||
let cur_thr_fd = match args {
|
||||
@@ -931,7 +986,8 @@ pub fn fork_inner(initial_rsp: *mut usize, args: &ForkArgs) -> Result<usize> {
|
||||
// Copy existing files into new file table, but do not reuse the same file table (i.e. new
|
||||
// parent FDs will not show up for the child).
|
||||
let scratchpad = {
|
||||
cur_filetable_fd = cur_thr_fd.dup(b"filetable")?;
|
||||
cur_filetable_fd = cur_thr_fd.dup_into_upper(b"filetable-binary")?;
|
||||
new_filetable_fd = cur_filetable_fd.dup_into_upper(b"copy")?;
|
||||
|
||||
// This must be done before the address space is copied.
|
||||
let proc_fd = new_proc_fd.as_ref().map_or(usize::MAX, |p| p.as_raw_fd());
|
||||
@@ -939,6 +995,7 @@ pub fn fork_inner(initial_rsp: *mut usize, args: &ForkArgs) -> Result<usize> {
|
||||
|
||||
ForkScratchpad {
|
||||
cur_filetable_fd: cur_filetable_fd.as_raw_fd(),
|
||||
new_filetable_fd: new_filetable_fd.as_raw_fd(),
|
||||
new_proc_fd: proc_fd,
|
||||
new_thr_fd: new_thr_fd.as_raw_fd(),
|
||||
}
|
||||
@@ -960,10 +1017,10 @@ pub fn fork_inner(initial_rsp: *mut usize, args: &ForkArgs) -> Result<usize> {
|
||||
|
||||
// CoW-duplicate address space.
|
||||
{
|
||||
let new_addr_space_sel_fd = new_thr_fd.dup(b"current-addrspace")?;
|
||||
let new_addr_space_sel_fd = new_thr_fd.dup_into_upper(b"current-addrspace")?;
|
||||
|
||||
let cur_addr_space_fd = cur_thr_fd.dup(b"addrspace")?.to_upper()?;
|
||||
let new_addr_space_fd = cur_addr_space_fd.dup(b"exclusive")?.to_upper()?;
|
||||
let cur_addr_space_fd = cur_thr_fd.dup_into_upper(b"addrspace")?;
|
||||
let new_addr_space_fd = cur_addr_space_fd.dup_into_upper(b"exclusive")?;
|
||||
|
||||
let mut grant_desc_buf = [GrantDesc::default(); 16];
|
||||
loop {
|
||||
@@ -1006,7 +1063,7 @@ pub fn fork_inner(initial_rsp: *mut usize, args: &ForkArgs) -> Result<usize> {
|
||||
buf = alloc::format!("grant-fd-{:>08x}", grant.base).into_bytes();
|
||||
}
|
||||
|
||||
let grant_fd = cur_addr_space_fd.dup(&buf)?.to_upper()?;
|
||||
let grant_fd = cur_addr_space_fd.dup_into_upper(&buf)?;
|
||||
|
||||
let mut flags = MAP_SHARED | MAP_FIXED_NOREPLACE;
|
||||
|
||||
@@ -1049,7 +1106,7 @@ pub fn fork_inner(initial_rsp: *mut usize, args: &ForkArgs) -> Result<usize> {
|
||||
// Do this after the address space is cloned, since the kernel will get a shared
|
||||
// reference to the TCB and whatever pages stores the signal proc control struct.
|
||||
{
|
||||
let new_sighandler_fd = new_thr_fd.dup(b"sighandler")?;
|
||||
let new_sighandler_fd = new_thr_fd.dup_into_upper(b"sighandler")?;
|
||||
new_sighandler_fd.write(&crate::signal::current_setsighandler_struct())?;
|
||||
}
|
||||
if let Some(ref proc_fd) = new_proc_fd {
|
||||
@@ -1069,25 +1126,26 @@ pub fn fork_inner(initial_rsp: *mut usize, args: &ForkArgs) -> Result<usize> {
|
||||
}
|
||||
{
|
||||
// Copy environment registers.
|
||||
let cur_env_regs_fd = cur_thr_fd.dup(b"regs/env")?;
|
||||
let new_env_regs_fd = new_thr_fd.dup(b"regs/env")?;
|
||||
let cur_env_regs_fd = cur_thr_fd.dup_into_upper(b"regs/env")?;
|
||||
let new_env_regs_fd = new_thr_fd.dup_into_upper(b"regs/env")?;
|
||||
|
||||
let mut env_regs = syscall::EnvRegisters::default();
|
||||
cur_env_regs_fd.read(&mut env_regs)?;
|
||||
new_env_regs_fd.write(&env_regs)?;
|
||||
}
|
||||
}
|
||||
// Copy the file table. We do this last to ensure that all previously used file descriptors are
|
||||
// closed. The only exception -- the filetable selection fd and the current filetable fd --
|
||||
// will be closed by the child process.
|
||||
{
|
||||
// TODO: Use file descriptor forwarding or something similar to avoid copying the file
|
||||
// table in the kernel.
|
||||
let new_filetable_fd = cur_filetable_fd.dup(b"copy")?;
|
||||
let new_filetable_sel_fd = new_thr_fd.dup(b"current-filetable")?;
|
||||
let new_filetable_sel_fd = new_thr_fd.dup_into_upper(b"current-filetable")?;
|
||||
new_filetable_sel_fd.write(&usize::to_ne_bytes(new_filetable_fd.as_raw_fd()))?;
|
||||
}
|
||||
let start_fd = new_thr_fd.dup(b"start")?;
|
||||
new_filetable_fd.call_wo(
|
||||
&new_filetable_fd.as_raw_fd().to_ne_bytes(),
|
||||
syscall::CallFlags::FD | syscall::CallFlags::FD_CLONE,
|
||||
&[new_filetable_fd.as_raw_fd() as u64],
|
||||
)?;
|
||||
let start_fd = new_thr_fd.dup_into_upper(b"start")?;
|
||||
start_fd.write(&[0])?;
|
||||
Ok(new_pid)
|
||||
}
|
||||
@@ -1107,8 +1165,8 @@ pub fn new_child_process(args: &ForkArgs<'_>) -> Result<NewChildProc> {
|
||||
.proc_fd
|
||||
.as_ref()
|
||||
.expect("cannot use ForkArgs::Managed without an existing proc info");
|
||||
let child_proc_fd = this_proc_fd.dup(b"fork")?.to_upper()?;
|
||||
let only_thread_fd = child_proc_fd.dup(b"thread-0")?.to_upper()?;
|
||||
let child_proc_fd = this_proc_fd.dup_into_upper(b"fork")?;
|
||||
let only_thread_fd = child_proc_fd.dup_into_upper(b"thread-0")?;
|
||||
let meta = read_proc_meta(&child_proc_fd)?;
|
||||
Ok(NewChildProc {
|
||||
proc_fd: Some(child_proc_fd),
|
||||
@@ -1121,7 +1179,7 @@ pub fn new_child_process(args: &ForkArgs<'_>) -> Result<NewChildProc> {
|
||||
|
||||
#[cfg(not(feature = "proc"))]
|
||||
ForkArgs::Init { this_thr_fd, auth } => {
|
||||
let thr_fd = auth.dup(b"new-context")?.to_upper()?;
|
||||
let thr_fd = auth.dup_into_upper(b"new-context")?;
|
||||
let buf = syscall::ProcSchemeAttrs {
|
||||
pid: 0,
|
||||
euid: 0,
|
||||
@@ -1134,8 +1192,8 @@ pub fn new_child_process(args: &ForkArgs<'_>) -> Result<NewChildProc> {
|
||||
buf
|
||||
},
|
||||
};
|
||||
let attr_fd =
|
||||
thr_fd.dup(alloc::format!("auth-{}-attrs", auth.as_raw_fd()).as_bytes())?;
|
||||
let attr_fd = thr_fd
|
||||
.dup_into_upper(alloc::format!("auth-{}-attrs", auth.as_raw_fd()).as_bytes())?;
|
||||
attr_fd.write(&buf)?;
|
||||
Ok(NewChildProc {
|
||||
thr_fd,
|
||||
@@ -1148,24 +1206,27 @@ pub fn new_child_process(args: &ForkArgs<'_>) -> Result<NewChildProc> {
|
||||
|
||||
pub unsafe fn make_init(proc_cap: usize) -> (&'static FdGuardUpper, &'static FdGuardUpper) {
|
||||
let proc_fd = FdGuard::new(
|
||||
syscall::openat(proc_cap, "init", syscall::O_CLOEXEC, 0).expect("failed to create init"),
|
||||
crate::sys::openat_into_upper(proc_cap, "init", 0, 0).expect("failed to create init"),
|
||||
)
|
||||
.to_upper()
|
||||
.unwrap();
|
||||
|
||||
syscall::sendfd(
|
||||
crate::sys::sys_call_wo(
|
||||
proc_fd.as_raw_fd(),
|
||||
RtTcb::current().thread_fd().dup(&[]).unwrap().take(),
|
||||
0,
|
||||
0,
|
||||
&RtTcb::current()
|
||||
.thread_fd()
|
||||
.dup_into_upper(&[])
|
||||
.unwrap()
|
||||
.take()
|
||||
.to_ne_bytes(),
|
||||
syscall::CallFlags::FD,
|
||||
&[],
|
||||
)
|
||||
.expect("failed to assign current thread to init process");
|
||||
|
||||
let managed_thr_fd = proc_fd
|
||||
.dup(b"thread-0")
|
||||
.expect("failed to get managed thread for init")
|
||||
.to_upper()
|
||||
.unwrap();
|
||||
.dup_into_upper(b"thread-0")
|
||||
.expect("failed to get managed thread for init");
|
||||
|
||||
let managed_thr_fd = unsafe { (*RtTcb::current().thr_fd.get()).insert(managed_thr_fd) };
|
||||
|
||||
|
||||
+10
-3
@@ -538,10 +538,14 @@ fn current_sigctl() -> &'static Sigcontrol {
|
||||
}
|
||||
|
||||
pub struct TmpDisableSignalsGuard {
|
||||
_inner: (),
|
||||
active: bool,
|
||||
}
|
||||
|
||||
pub fn tmp_disable_signals() -> TmpDisableSignalsGuard {
|
||||
if !crate::TLS_ACTIVATED.load(Ordering::Relaxed) {
|
||||
return TmpDisableSignalsGuard { active: false };
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let ctl = ¤t_sigctl().control_flags;
|
||||
ctl.store(
|
||||
@@ -554,10 +558,13 @@ pub fn tmp_disable_signals() -> TmpDisableSignalsGuard {
|
||||
(*Tcb::current().unwrap().os_specific.arch.get()).disable_signals_depth += 1;
|
||||
}
|
||||
|
||||
TmpDisableSignalsGuard { _inner: () }
|
||||
TmpDisableSignalsGuard { active: true }
|
||||
}
|
||||
impl Drop for TmpDisableSignalsGuard {
|
||||
fn drop(&mut self) {
|
||||
if !self.active {
|
||||
return;
|
||||
}
|
||||
unsafe {
|
||||
let depth =
|
||||
&mut (*Tcb::current().unwrap().os_specific.arch.get()).disable_signals_depth;
|
||||
@@ -666,7 +673,7 @@ pub fn setup_sighandler(tcb: &RtTcb, first_thread: bool) {
|
||||
|
||||
let fd = tcb
|
||||
.thread_fd()
|
||||
.dup(b"sighandler")
|
||||
.dup_into_upper(b"sighandler")
|
||||
.expect("failed to open sighandler fd");
|
||||
fd.write(&data).expect("failed to write to sighandler fd");
|
||||
this_thread_call(
|
||||
|
||||
+1453
-25
File diff suppressed because it is too large
Load Diff
+11
-8
@@ -10,12 +10,12 @@ pub unsafe fn rlct_clone_impl(stack: *mut usize, tcb: &RtTcb) -> Result<usize> {
|
||||
let cur_proc_fd = proc_info.proc_fd.as_ref().unwrap();
|
||||
|
||||
let cur_thr_fd = RtTcb::current().thread_fd();
|
||||
let new_thr_fd = cur_proc_fd.dup(b"new-thread")?.to_upper().unwrap();
|
||||
let new_thr_fd = cur_proc_fd.dup_into_upper(b"new-thread")?;
|
||||
|
||||
// Inherit existing address space
|
||||
{
|
||||
let cur_addr_space_fd = cur_thr_fd.dup(b"addrspace")?;
|
||||
let new_addr_space_sel_fd = new_thr_fd.dup(b"current-addrspace")?;
|
||||
let cur_addr_space_fd = cur_thr_fd.dup_into_upper(b"addrspace")?;
|
||||
let new_addr_space_sel_fd = new_thr_fd.dup_into_upper(b"current-addrspace")?;
|
||||
|
||||
let buf = create_set_addr_space_buf(
|
||||
cur_addr_space_fd.as_raw_fd(),
|
||||
@@ -27,8 +27,8 @@ pub unsafe fn rlct_clone_impl(stack: *mut usize, tcb: &RtTcb) -> Result<usize> {
|
||||
|
||||
// Inherit reference to file table
|
||||
{
|
||||
let cur_filetable_fd = cur_thr_fd.dup(b"filetable")?;
|
||||
let new_filetable_sel_fd = new_thr_fd.dup(b"current-filetable")?;
|
||||
let cur_filetable_fd = cur_thr_fd.dup_into_upper(b"filetable")?;
|
||||
let new_filetable_sel_fd = new_thr_fd.dup_into_upper(b"current-filetable")?;
|
||||
|
||||
new_filetable_sel_fd.write(&usize::to_ne_bytes(cur_filetable_fd.as_raw_fd()))?;
|
||||
}
|
||||
@@ -38,7 +38,7 @@ pub unsafe fn rlct_clone_impl(stack: *mut usize, tcb: &RtTcb) -> Result<usize> {
|
||||
// the same process) will be discarded. Process-specific signals will ignore this new thread,
|
||||
// until it has initialized its own signal handler.
|
||||
|
||||
let start_fd = new_thr_fd.dup(b"start")?;
|
||||
let start_fd = new_thr_fd.dup_into_upper(b"start")?;
|
||||
|
||||
let fd = new_thr_fd.as_raw_fd();
|
||||
unsafe {
|
||||
@@ -56,9 +56,12 @@ pub unsafe fn exit_this_thread(stack_base: *mut (), stack_size: usize) -> ! {
|
||||
|
||||
let tcb = RtTcb::current();
|
||||
// TODO: modify interface so it writes directly to the thread fd?
|
||||
let status_fd = tcb.thread_fd().dup(b"status").unwrap();
|
||||
let status_fd = tcb.thread_fd().dup_into_upper(b"status").unwrap();
|
||||
|
||||
let _ = unsafe { syscall::funmap(tcb as *const RtTcb as usize, syscall::PAGE_SIZE) };
|
||||
let tcb_ptr = unsafe { crate::Tcb::current_ptr() };
|
||||
if let Some(tcb_ptr) = tcb_ptr {
|
||||
let _ = unsafe { syscall::funmap(tcb_ptr as usize, syscall::PAGE_SIZE) };
|
||||
}
|
||||
|
||||
let mut buf = [0; size_of::<usize>() * 3];
|
||||
plain::slice_from_mut_bytes(&mut buf)
|
||||
|
||||
@@ -18,7 +18,7 @@ mod drm;
|
||||
// TODO: some of the structs passed as T have padding bytes, so casting to a byte slice is UB
|
||||
|
||||
fn dup_read<T>(fd: c_int, name: &str, t: &mut T) -> syscall::Result<usize> {
|
||||
let dup = FdGuard::new(syscall::dup(fd as usize, name.as_bytes())?);
|
||||
let dup = FdGuard::new(redox_rt::sys::dup(fd as usize, name.as_bytes())?);
|
||||
|
||||
let size = mem::size_of::<T>();
|
||||
|
||||
@@ -29,7 +29,7 @@ fn dup_read<T>(fd: c_int, name: &str, t: &mut T) -> syscall::Result<usize> {
|
||||
|
||||
// FIXME: unsound
|
||||
fn dup_write<T>(fd: c_int, name: &str, t: &T) -> Result<usize> {
|
||||
let dup = FdGuard::new(syscall::dup(fd as usize, name.as_bytes())?);
|
||||
let dup = FdGuard::new(redox_rt::sys::dup(fd as usize, name.as_bytes())?);
|
||||
|
||||
let size = mem::size_of::<T>();
|
||||
|
||||
|
||||
+2
-2
@@ -159,7 +159,7 @@ pub unsafe fn init(
|
||||
|
||||
{
|
||||
let file = thr_fd
|
||||
.dup(b"regs/env")
|
||||
.dup_into_upper(b"regs/env")
|
||||
.expect_notls("failed to open handle for process registers");
|
||||
|
||||
file.read(&mut env).expect_notls("failed to read gsbase");
|
||||
@@ -173,7 +173,7 @@ pub unsafe fn init(
|
||||
|
||||
{
|
||||
let file = thr_fd
|
||||
.dup(b"regs/env")
|
||||
.dup_into_upper(b"regs/env")
|
||||
.expect_notls("failed to open handle for process registers");
|
||||
|
||||
file.read(&mut env).expect_notls("failed to read fsbase");
|
||||
|
||||
@@ -317,6 +317,23 @@ fn stage2(
|
||||
let thr_fd = crate::platform::get_auxv_raw(auxv, redox_rt::auxv_defs::AT_REDOX_THR_FD)
|
||||
.expect_notls("no thread fd present");
|
||||
|
||||
#[cfg(target_os = "redox")]
|
||||
{
|
||||
if redox_rt::current_filetable().fd().is_none() {
|
||||
let filetable_fd = crate::platform::get_auxv_raw(
|
||||
sp.auxv().cast(),
|
||||
redox_rt::auxv_defs::AT_REDOX_FILETABLE_FD,
|
||||
)
|
||||
.expect_notls("no filetable fd present");
|
||||
let filetable_guard = redox_rt::proc::FdGuard::new(filetable_fd)
|
||||
.to_upper()
|
||||
.expect_notls("failed to move filetable fd to upper table");
|
||||
*redox_rt::current_filetable() =
|
||||
redox_rt::sys::FdTbl::from_binary_fd(filetable_guard)
|
||||
.expect_notls("failed to initialize FILETABLE");
|
||||
}
|
||||
}
|
||||
|
||||
let tcb = Tcb::new(0).expect_notls("[ld.so]: failed to allocate bootstrap TCB");
|
||||
tcb.activate(
|
||||
#[cfg(target_os = "redox")]
|
||||
|
||||
@@ -58,3 +58,6 @@ pub const AT_REDOX_NS_FD: usize = 43;
|
||||
|
||||
#[cfg(target_os = "redox")]
|
||||
pub const AT_REDOX_CWD_FD: usize = 44;
|
||||
|
||||
#[cfg(target_os = "redox")]
|
||||
pub const AT_REDOX_FILETABLE_FD: usize = 45;
|
||||
|
||||
@@ -83,5 +83,5 @@ pub unsafe extern "C" fn redox_event_queue_ctl_v1(
|
||||
}
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn redox_event_queue_destroy_v1(queue: usize) -> RawResult {
|
||||
Error::mux(syscall::close(queue))
|
||||
Error::mux(redox_rt::sys::close(queue))
|
||||
}
|
||||
|
||||
@@ -41,6 +41,10 @@ fn fexec_impl(
|
||||
)?
|
||||
.unwrap();
|
||||
|
||||
if let Some(filetable_fd) = extrainfo.filetable_fd {
|
||||
let _ = redox_rt::sys::close(filetable_fd);
|
||||
}
|
||||
|
||||
// According to elf(5), PT_INTERP requires that the interpreter path be
|
||||
// null-terminated. Violating this should therefore give the "format error" ENOEXEC.
|
||||
let path_cstr = CStr::from_bytes_with_nul(&path).map_err(|_| Error::new(ENOEXEC))?;
|
||||
@@ -228,6 +232,9 @@ pub fn execve(
|
||||
|
||||
let sigprocmask = redox_rt::signal::get_sigmask().unwrap();
|
||||
|
||||
let filetable_binary_fd = RtTcb::current()
|
||||
.thread_fd()
|
||||
.dup_into_upper(b"filetable-binary")?;
|
||||
let extrainfo = ExtraInfo {
|
||||
cwd: Some(cwd.as_bytes()),
|
||||
sigignmask: redox_rt::signal::get_sigignmask_to_inherit(),
|
||||
@@ -239,6 +246,7 @@ pub fn execve(
|
||||
cwd_fd: super::path::current_dir()
|
||||
.ok()
|
||||
.map(|fd| fd.as_ref().unwrap().fd.as_raw_fd()),
|
||||
filetable_fd: Some(filetable_binary_fd.as_raw_fd()),
|
||||
same_process: true,
|
||||
};
|
||||
|
||||
|
||||
@@ -38,9 +38,9 @@ pub fn open(path: &str, flags: usize) -> Result<usize> {
|
||||
|
||||
// Linux seems to allow you to read from or write to any of /dev/{stdin,stderr,stdout}
|
||||
match basename {
|
||||
"stderr" => syscall::dup(2, &[]),
|
||||
"stdin" => syscall::dup(0, &[]),
|
||||
"stdout" => syscall::dup(1, &[]),
|
||||
"stderr" => redox_rt::sys::dup(2, &[]),
|
||||
"stdin" => redox_rt::sys::dup(0, &[]),
|
||||
"stdout" => redox_rt::sys::dup(1, &[]),
|
||||
"tty" => {
|
||||
if let Some(tty) = env_str!("TTY") {
|
||||
return redox_rt::sys::open(tty, flags);
|
||||
|
||||
@@ -32,7 +32,7 @@ pub fn openat(dirfd: c_int, path: &str, oflag: c_int, mode: mode_t) -> Result<us
|
||||
|
||||
c_int::try_from(usize_fd)
|
||||
.map_err(|_| {
|
||||
let _ = syscall::close(usize_fd);
|
||||
let _ = redox_rt::sys::close(usize_fd);
|
||||
Error::new(EMFILE)
|
||||
})
|
||||
.map(|f| f as usize)
|
||||
@@ -241,7 +241,7 @@ pub unsafe extern "C" fn redox_openat_v1(
|
||||
flags: u32,
|
||||
fcntl_flags: u32,
|
||||
) -> RawResult {
|
||||
Error::mux(syscall::openat(
|
||||
Error::mux(redox_rt::sys::openat(
|
||||
fd,
|
||||
unsafe { str::from_utf8_unchecked(slice::from_raw_parts(path_base, path_len)) },
|
||||
flags as usize,
|
||||
@@ -250,7 +250,7 @@ pub unsafe extern "C" fn redox_openat_v1(
|
||||
}
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn redox_dup_v1(fd: usize, buf: *const u8, len: usize) -> RawResult {
|
||||
Error::mux(syscall::dup(fd, unsafe {
|
||||
Error::mux(redox_rt::sys::dup(fd, unsafe {
|
||||
core::slice::from_raw_parts(buf, len)
|
||||
}))
|
||||
}
|
||||
@@ -261,7 +261,7 @@ pub unsafe extern "C" fn redox_dup2_v1(
|
||||
buf: *const u8,
|
||||
len: usize,
|
||||
) -> RawResult {
|
||||
Error::mux(syscall::dup2(old_fd, new_fd, unsafe {
|
||||
Error::mux(redox_rt::sys::dup2(old_fd, new_fd, unsafe {
|
||||
core::slice::from_raw_parts(buf, len)
|
||||
}))
|
||||
}
|
||||
@@ -359,7 +359,7 @@ pub unsafe extern "C" fn redox_fpath_v1(fd: usize, dst_base: *mut u8, dst_len: u
|
||||
}
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn redox_close_v1(fd: usize) -> RawResult {
|
||||
Error::mux(syscall::close(fd))
|
||||
Error::mux(redox_rt::sys::close(fd))
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
@@ -569,12 +569,18 @@ pub unsafe extern "C" fn redox_sys_call_v0(
|
||||
metadata: *const u64,
|
||||
metadata_len: usize,
|
||||
) -> RawResult {
|
||||
Error::mux(redox_rt::sys::sys_call(
|
||||
fd,
|
||||
unsafe { slice::from_raw_parts_mut(payload, payload_len) },
|
||||
syscall::CallFlags::from_bits_retain(flags),
|
||||
unsafe { slice::from_raw_parts(metadata, metadata_len) },
|
||||
))
|
||||
let flags = syscall::CallFlags::from_bits_retain(flags);
|
||||
let read = flags.contains(syscall::CallFlags::READ);
|
||||
let write = flags.contains(syscall::CallFlags::WRITE);
|
||||
let payload = unsafe { slice::from_raw_parts_mut(payload, payload_len) };
|
||||
let metadata = unsafe { slice::from_raw_parts(metadata, metadata_len) };
|
||||
|
||||
Error::mux(match (read, write) {
|
||||
(true, true) => redox_rt::sys::sys_call_rw(fd, payload, flags, metadata),
|
||||
(true, false) => redox_rt::sys::sys_call_ro(fd, payload, flags, metadata),
|
||||
(false, true) => redox_rt::sys::sys_call_wo(fd, payload, flags, metadata),
|
||||
(false, false) => redox_rt::sys::sys_call(fd, payload, flags, metadata),
|
||||
})
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
@@ -630,3 +636,8 @@ pub unsafe extern "C" fn redox_relpathat_v0(
|
||||
&StdFsCallMeta::new(StdFsCallKind::Relpathat, 0, 0),
|
||||
))
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn redox_fcntl_v0(fd: usize, cmd: usize, arg: usize) -> RawResult {
|
||||
Error::mux(redox_rt::sys::fcntl(fd, cmd, arg))
|
||||
}
|
||||
|
||||
+59
-23
@@ -239,12 +239,12 @@ impl Pal for Sys {
|
||||
}
|
||||
|
||||
fn close(fd: c_int) -> Result<()> {
|
||||
syscall::close(fd as usize)?;
|
||||
redox_rt::sys::close(fd as usize)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn dup2(fd1: c_int, fd2: c_int) -> Result<c_int> {
|
||||
Ok(syscall::dup2(fd1 as usize, fd2 as usize, &[])? as c_int)
|
||||
Ok(redox_rt::sys::dup2(fd1 as usize, fd2 as usize, &[])? as c_int)
|
||||
}
|
||||
|
||||
fn exit(status: c_int) -> ! {
|
||||
@@ -442,7 +442,7 @@ impl Pal for Sys {
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Ok(syscall::fcntl(fd as usize, cmd as usize, args as usize)? as c_int)
|
||||
Ok(redox_rt::sys::fcntl(fd as usize, cmd as usize, args as usize)? as c_int)
|
||||
}
|
||||
|
||||
fn fdatasync(fd: c_int) -> Result<()> {
|
||||
@@ -484,7 +484,7 @@ impl Pal for Sys {
|
||||
let file = openat2(dirfd, path, flags, fcntl::O_PATH)?;
|
||||
// Close the file descriptor after fstat(2) regardless of success or failure.
|
||||
let fstat_res = unsafe { libredox::fstat(*file as usize, buf.as_mut_ptr()) };
|
||||
let close_res = syscall::close(*file as usize);
|
||||
let close_res = redox_rt::sys::close(*file as usize);
|
||||
if let Err(err) = fstat_res {
|
||||
return Err(err.into());
|
||||
}
|
||||
@@ -664,7 +664,7 @@ impl Pal for Sys {
|
||||
"/scheme/rand"
|
||||
};
|
||||
|
||||
let mut open_flags = syscall::O_RDONLY | syscall::O_CLOEXEC;
|
||||
let mut open_flags = syscall::O_RDONLY | redox_protocols::protocol::O_CLOEXEC;
|
||||
if flags & sys_random::GRND_NONBLOCK != 0 {
|
||||
open_flags |= syscall::O_NONBLOCK;
|
||||
}
|
||||
@@ -1215,13 +1215,11 @@ impl Pal for Sys {
|
||||
let mut cwd_fd = FdGuard::open(cwd.as_str(), syscall::O_STAT)?.to_upper()?;
|
||||
let proc_fd = child.proc_fd.unwrap();
|
||||
let curr_proc_fd = redox_rt::current_proc_fd();
|
||||
let file_table = RtTcb::current()
|
||||
.thread_fd()
|
||||
.dup(b"filetable")?
|
||||
.dup(b"copy")?;
|
||||
let cur_filetable_fd = RtTcb::current().thread_fd().dup_into_upper(b"filetable")?;
|
||||
let file_table = cur_filetable_fd.dup_into_upper(b"copy")?;
|
||||
|
||||
{
|
||||
let new_file_table = child.thr_fd.dup(b"current-filetable")?;
|
||||
let new_file_table = child.thr_fd.dup_into_upper(b"current-filetable")?;
|
||||
new_file_table.write(&file_table.as_raw_fd().to_ne_bytes())?;
|
||||
}
|
||||
|
||||
@@ -1240,7 +1238,7 @@ impl Pal for Sys {
|
||||
|
||||
args[0] = &program.to_bytes();
|
||||
|
||||
let new_file_table = child.thr_fd.dup(b"filetable")?;
|
||||
let new_file_table = child.thr_fd.dup_into_upper(b"filetable-binary")?;
|
||||
|
||||
if let Some(fac) = fac {
|
||||
for action in fac {
|
||||
@@ -1262,11 +1260,10 @@ impl Pal for Sys {
|
||||
flag,
|
||||
mode,
|
||||
)? as usize;
|
||||
syscall::sendfd(
|
||||
new_file_table.as_raw_fd(),
|
||||
src_fd,
|
||||
0,
|
||||
u64::try_from(fd).map_err(|_| Errno(EBADFD))?,
|
||||
new_file_table.call_wo(
|
||||
&src_fd.to_ne_bytes(),
|
||||
syscall::CallFlags::FD,
|
||||
&[u64::try_from(fd).map_err(|_| Errno(EBADFD))?],
|
||||
)?;
|
||||
}
|
||||
crate::header::spawn::Action::Close(fd) => {
|
||||
@@ -1336,9 +1333,47 @@ impl Pal for Sys {
|
||||
// );
|
||||
|
||||
new_file_table.call_wo(
|
||||
&[],
|
||||
syscall::CallFlags::empty(),
|
||||
&[syscall::flag::FileTableVerb::CloseCloExec as u64],
|
||||
&new_file_table.as_raw_fd().to_ne_bytes(),
|
||||
syscall::CallFlags::FD | syscall::CallFlags::FD_CLONE,
|
||||
&[new_file_table.as_raw_fd() as u64],
|
||||
)?;
|
||||
|
||||
{
|
||||
let fds_to_close = {
|
||||
let guard = redox_rt::current_filetable();
|
||||
let mut fds = alloc::vec::Vec::new();
|
||||
for (fd, flags) in guard.iter() {
|
||||
if flags & redox_protocols::protocol::O_CLOEXEC
|
||||
== redox_protocols::protocol::O_CLOEXEC
|
||||
|| fd == executable.as_raw_fd()
|
||||
{
|
||||
fds.push(fd);
|
||||
}
|
||||
}
|
||||
|
||||
fds.push(cur_filetable_fd.as_raw_fd());
|
||||
|
||||
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 _ = new_file_table.call_wo(
|
||||
fds_to_close_bytes,
|
||||
syscall::CallFlags::empty(),
|
||||
&[syscall::FileTableVerb::Close as u64],
|
||||
);
|
||||
}
|
||||
|
||||
new_file_table.call_wo(
|
||||
&cwd_fd.as_raw_fd().to_ne_bytes(),
|
||||
syscall::CallFlags::FD | syscall::CallFlags::FD_CLONE,
|
||||
&[cwd_fd.as_raw_fd() as u64],
|
||||
)?;
|
||||
|
||||
let extra_info = redox_rt::proc::ExtraInfo {
|
||||
@@ -1360,6 +1395,7 @@ impl Pal for Sys {
|
||||
proc_fd: proc_fd.as_raw_fd(),
|
||||
ns_fd: redox_rt::current_namespace_fd().ok(),
|
||||
cwd_fd: Some(cwd_fd.as_raw_fd()),
|
||||
filetable_fd: Some(new_file_table.as_raw_fd()),
|
||||
same_process: false,
|
||||
};
|
||||
|
||||
@@ -1460,7 +1496,7 @@ impl Pal for Sys {
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
let start_fd = child.thr_fd.dup(b"start")?;
|
||||
let start_fd = child.thr_fd.dup_into_upper(b"start")?;
|
||||
start_fd.write(&[0])?;
|
||||
|
||||
Ok(pid_t::try_from(child.pid).unwrap())
|
||||
@@ -1507,7 +1543,7 @@ impl Pal for Sys {
|
||||
CLOCK_MONOTONIC => "/scheme/time/4",
|
||||
_ => return Err(Errno(EINVAL)),
|
||||
};
|
||||
let timerfd = FdGuard::open(&path, syscall::O_RDWR)?.to_upper()?;
|
||||
let timerfd = FdGuard::open_into_upper(&path, syscall::O_RDWR)?;
|
||||
let eventfd = FdGuard::new(Error::demux(unsafe {
|
||||
event::redox_event_queue_create_v1(0)
|
||||
})?)
|
||||
@@ -1561,8 +1597,8 @@ impl Pal for Sys {
|
||||
return Err(Errno(EINVAL));
|
||||
}
|
||||
let timer_st = unsafe { timer_internal_t::from_raw(timerid) };
|
||||
let _ = syscall::close(timer_st.timerfd);
|
||||
let _ = syscall::close(timer_st.eventfd);
|
||||
let _ = redox_rt::sys::close(timer_st.timerfd);
|
||||
let _ = redox_rt::sys::close(timer_st.eventfd);
|
||||
if !timer_st.thread.is_null() {
|
||||
let _ = unsafe { pthread_cancel(timer_st.thread) };
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ use core::{
|
||||
ffi::c_int,
|
||||
str::{self, FromStr},
|
||||
};
|
||||
use redox_protocols::protocol::O_CLOEXEC;
|
||||
use redox_rt::{proc::FdGuardUpper, signal::tmp_disable_signals};
|
||||
use syscall::{data::Stat, error::*, flag::*};
|
||||
|
||||
@@ -97,9 +98,7 @@ pub fn chdir(path: &str) -> Result<()> {
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.fd
|
||||
.openat(&path, O_STAT, 0)?
|
||||
.to_upper()
|
||||
.unwrap();
|
||||
.openat_into_upper(&path, O_STAT, 0)?;
|
||||
let mut stat = Stat::default();
|
||||
if fd.fstat(&mut stat).is_err() || (stat.st_mode & MODE_TYPE) != MODE_DIR {
|
||||
return Err(Error::new(ENOTDIR));
|
||||
@@ -138,7 +137,7 @@ pub fn fchdir(fd: c_int) -> Result<()> {
|
||||
let res = Sys::fpath(fd, buf.as_bytes_mut())?;
|
||||
buf.set_len(res);
|
||||
}
|
||||
let fd = FdGuard::new(syscall::fcntl(
|
||||
let fd = FdGuard::new(redox_rt::sys::fcntl(
|
||||
fd as usize,
|
||||
syscall::F_DUPFD,
|
||||
syscall::UPPER_FDTBL_TAG,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use alloc::vec::Vec;
|
||||
use core::{cmp, mem, ptr, slice, str};
|
||||
use redox_protocols::protocol::{FsCall, SocketCall};
|
||||
use redox_protocols::protocol::{FsCall, O_CLOEXEC, SocketCall};
|
||||
use redox_rt::proc::FdGuard;
|
||||
use syscall::{self, flag::*};
|
||||
|
||||
@@ -83,7 +83,7 @@ unsafe fn bind_or_connect(
|
||||
},
|
||||
_ => return Err(Errno(EAFNOSUPPORT)),
|
||||
};
|
||||
let fd = syscall::dup(socket as usize, path.as_bytes())?;
|
||||
let fd = redox_rt::sys::dup(socket as usize, path.as_bytes())?;
|
||||
Ok(fd)
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ pub unsafe fn bind_or_connect_into(
|
||||
) -> Result<c_int, Errno> {
|
||||
// Duplicate the socket, and then duplicate the copy back to the original fd
|
||||
let fd = FdGuard::new(unsafe { bind_or_connect(op, socket, address, address_len) }?);
|
||||
syscall::dup2(fd.as_raw_fd(), socket as usize, &[])?;
|
||||
redox_rt::sys::dup2(fd.as_raw_fd(), socket as usize, &[])?;
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
@@ -537,10 +537,10 @@ impl PalSocket for Sys {
|
||||
address: *mut sockaddr,
|
||||
address_len: *mut socklen_t,
|
||||
) -> Result<c_int> {
|
||||
let stream = syscall::dup(socket as usize, b"listen")?;
|
||||
let stream = redox_rt::sys::dup(socket as usize, b"listen")?;
|
||||
if address != ptr::null_mut() && address_len != ptr::null_mut() {
|
||||
if let Err(err) = unsafe { Self::getpeername(stream as c_int, address, address_len) } {
|
||||
let _ = syscall::close(stream);
|
||||
let _ = redox_rt::sys::close(stream);
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
@@ -588,10 +588,17 @@ impl PalSocket for Sys {
|
||||
let fs_bind_result = (|| -> Result<()> {
|
||||
let dirfd = FdGuard::open(
|
||||
&dir_path,
|
||||
syscall::O_RDONLY | syscall::O_DIRECTORY | syscall::O_CLOEXEC,
|
||||
syscall::O_RDONLY | syscall::O_DIRECTORY | O_CLOEXEC,
|
||||
)?;
|
||||
let fd_to_send =
|
||||
FdGuard::new(redox_rt::sys::dup_into_upper(socket as usize, &[])?)
|
||||
.to_upper()
|
||||
.unwrap();
|
||||
dirfd.call_wo(
|
||||
&fd_to_send.as_raw_fd().to_ne_bytes(),
|
||||
syscall::CallFlags::FD,
|
||||
&[],
|
||||
)?;
|
||||
let fd_to_send = FdGuard::new(syscall::dup(socket as usize, &[])?);
|
||||
syscall::sendfd(dirfd.as_raw_fd(), fd_to_send.as_raw_fd(), 0, 0)?;
|
||||
Ok(())
|
||||
})();
|
||||
|
||||
@@ -1027,7 +1034,7 @@ impl PalSocket for Sys {
|
||||
|
||||
let timeval = unsafe { &*(option_value as *const timeval) };
|
||||
|
||||
let fd = FdGuard::new(syscall::dup(socket as usize, timeout_name)?);
|
||||
let fd = FdGuard::new(redox_rt::sys::dup(socket as usize, timeout_name)?);
|
||||
|
||||
let Some(tv_nsec) = timeval.tv_usec.checked_mul(1000) else {
|
||||
return Err(Errno(EDOM));
|
||||
|
||||
@@ -174,6 +174,24 @@ pub unsafe extern "C" fn relibc_start_v1(
|
||||
.to_upper()
|
||||
.expect_notls("failed to move thread fd to upper table");
|
||||
|
||||
#[cfg(target_os = "redox")]
|
||||
{
|
||||
if redox_rt::current_filetable().fd().is_none() {
|
||||
let filetable_fd = unsafe {
|
||||
crate::platform::get_auxv_raw(
|
||||
sp.auxv().cast(),
|
||||
redox_rt::auxv_defs::AT_REDOX_FILETABLE_FD,
|
||||
)
|
||||
}
|
||||
.expect_notls("no filetable fd present");
|
||||
let filetable_guard = redox_rt::proc::FdGuard::new(filetable_fd)
|
||||
.to_upper()
|
||||
.expect_notls("failed to move filetable fd to upper table");
|
||||
*redox_rt::current_filetable() = redox_rt::sys::FdTbl::from_binary_fd(filetable_guard)
|
||||
.expect_notls("failed to initialize FILETABLE");
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize TLS, if necessary
|
||||
unsafe {
|
||||
ld_so::init(
|
||||
|
||||
Reference in New Issue
Block a user