Store proc_fd in MaybeUninit with external discriminant.
This commit is contained in:
+18
-11
@@ -11,11 +11,11 @@
|
||||
|
||||
use core::{
|
||||
cell::{SyncUnsafeCell, UnsafeCell},
|
||||
mem::size_of,
|
||||
mem::{size_of, MaybeUninit},
|
||||
};
|
||||
|
||||
use generic_rt::{ExpectTlsFree, GenericTcb};
|
||||
use syscall::{Sigcontrol, O_CLOEXEC};
|
||||
use syscall::Sigcontrol;
|
||||
|
||||
use self::{proc::FdGuard, protocol::ProcMeta, sync::Mutex};
|
||||
|
||||
@@ -196,10 +196,12 @@ pub unsafe fn initialize(#[cfg(feature = "proc")] proc_fd: FdGuard) {
|
||||
ppid: metadata.ppid,
|
||||
|
||||
#[cfg(feature = "proc")]
|
||||
proc_fd: Some(proc_fd),
|
||||
proc_fd: MaybeUninit::new(proc_fd),
|
||||
|
||||
#[cfg(not(feature = "proc"))]
|
||||
proc_fd: None,
|
||||
proc_fd: MaybeUninit::uninit(),
|
||||
|
||||
has_proc_fd: cfg!(feature = "proc"),
|
||||
});
|
||||
|
||||
#[cfg(feature = "proc")]
|
||||
@@ -216,10 +218,12 @@ pub unsafe fn initialize(#[cfg(feature = "proc")] proc_fd: FdGuard) {
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)] // TODO: is this required?
|
||||
pub(crate) struct StaticProcInfo {
|
||||
pid: u32,
|
||||
ppid: u32, // TODO: dynamic
|
||||
proc_fd: Option<FdGuard>,
|
||||
proc_fd: MaybeUninit<FdGuard>,
|
||||
has_proc_fd: bool,
|
||||
}
|
||||
struct DynamicProcInfo {
|
||||
pgid: u32,
|
||||
@@ -234,7 +238,8 @@ struct DynamicProcInfo {
|
||||
static STATIC_PROC_INFO: SyncUnsafeCell<StaticProcInfo> = SyncUnsafeCell::new(StaticProcInfo {
|
||||
pid: 0,
|
||||
ppid: 0,
|
||||
proc_fd: None,
|
||||
proc_fd: MaybeUninit::uninit(),
|
||||
has_proc_fd: false,
|
||||
});
|
||||
static DYNAMIC_PROC_INFO: Mutex<DynamicProcInfo> = Mutex::new(DynamicProcInfo {
|
||||
pgid: u32::MAX,
|
||||
@@ -252,10 +257,9 @@ pub(crate) fn static_proc_info() -> &'static StaticProcInfo {
|
||||
}
|
||||
#[inline]
|
||||
pub fn current_proc_fd() -> &'static FdGuard {
|
||||
static_proc_info()
|
||||
.proc_fd
|
||||
.as_ref()
|
||||
.expect("proc fd must be present")
|
||||
let info = static_proc_info();
|
||||
assert!(info.has_proc_fd);
|
||||
unsafe { info.proc_fd.assume_init_ref() }
|
||||
}
|
||||
|
||||
struct ChildHookCommonArgs {
|
||||
@@ -281,7 +285,10 @@ unsafe fn child_hook_common(args: ChildHookCommonArgs) {
|
||||
.replace(StaticProcInfo {
|
||||
pid: metadata.pid,
|
||||
ppid: metadata.ppid,
|
||||
proc_fd: args.new_proc_fd,
|
||||
has_proc_fd: args.new_proc_fd.is_some(),
|
||||
proc_fd: args
|
||||
.new_proc_fd
|
||||
.map_or_else(MaybeUninit::uninit, MaybeUninit::new),
|
||||
})
|
||||
.proc_fd;
|
||||
drop(old_proc_fd);
|
||||
|
||||
+13
-7
@@ -1,4 +1,7 @@
|
||||
use core::{fmt::Debug, mem::size_of};
|
||||
use core::{
|
||||
fmt::Debug,
|
||||
mem::{size_of, MaybeUninit},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
arch::*,
|
||||
@@ -887,10 +890,12 @@ struct NewChildProc {
|
||||
pub fn new_child_process(args: &ForkArgs<'_>) -> Result<NewChildProc> {
|
||||
match *args {
|
||||
ForkArgs::Managed => {
|
||||
let this_proc_fd = crate::static_proc_info()
|
||||
.proc_fd
|
||||
.as_ref()
|
||||
.expect("cannot use ForkArgs::Managed without an existing proc info");
|
||||
let proc_info = crate::static_proc_info();
|
||||
assert!(
|
||||
proc_info.has_proc_fd,
|
||||
"cannot use ForkArgs::Managed without an existing proc info"
|
||||
);
|
||||
let this_proc_fd = unsafe { proc_info.proc_fd.assume_init_ref() };
|
||||
let child_proc_fd = FdGuard::new(syscall::dup(**this_proc_fd, b"fork")?);
|
||||
let only_thread_fd = FdGuard::new(syscall::dup(*child_proc_fd, b"thread-0")?);
|
||||
let meta = read_proc_meta(&child_proc_fd)?;
|
||||
@@ -961,7 +966,8 @@ pub unsafe fn make_init() -> [&'static FdGuard; 2] {
|
||||
STATIC_PROC_INFO.get().write(crate::StaticProcInfo {
|
||||
pid: 1,
|
||||
ppid: 1,
|
||||
proc_fd: Some(proc_fd),
|
||||
proc_fd: MaybeUninit::new(proc_fd),
|
||||
has_proc_fd: true,
|
||||
});
|
||||
*DYNAMIC_PROC_INFO.lock() = crate::DynamicProcInfo {
|
||||
pgid: 1,
|
||||
@@ -973,7 +979,7 @@ pub unsafe fn make_init() -> [&'static FdGuard; 2] {
|
||||
sgid: 0,
|
||||
};
|
||||
[
|
||||
(*STATIC_PROC_INFO.get()).proc_fd.as_ref().unwrap(),
|
||||
(*STATIC_PROC_INFO.get()).proc_fd.assume_init_ref(),
|
||||
managed_thr_fd,
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
use core::mem::size_of;
|
||||
|
||||
use syscall::{Error, Result, ESRCH, O_CLOEXEC};
|
||||
use syscall::Result;
|
||||
|
||||
use crate::{arch::*, proc::*, signal::tmp_disable_signals, static_proc_info, RtTcb};
|
||||
|
||||
/// Spawns a new context sharing the same address space as the current one (i.e. a new thread).
|
||||
pub unsafe fn rlct_clone_impl(stack: *mut usize) -> Result<FdGuard> {
|
||||
let cur_proc_fd = static_proc_info()
|
||||
.proc_fd
|
||||
.as_ref()
|
||||
.ok_or(Error::new(ESRCH))?;
|
||||
let proc_info = static_proc_info();
|
||||
assert!(proc_info.has_proc_fd);
|
||||
let cur_proc_fd = proc_info.proc_fd.assume_init_ref();
|
||||
|
||||
let cur_thr_fd = RtTcb::current().thread_fd();
|
||||
let new_thr_fd = FdGuard::new(syscall::dup(**cur_proc_fd, b"new-thread")?);
|
||||
|
||||
Reference in New Issue
Block a user