WIP: use proc manager in non-init fork.
This commit is contained in:
+18
-13
@@ -11,8 +11,11 @@ use syscall::{
|
||||
};
|
||||
|
||||
use crate::{
|
||||
proc::{fork_inner, FdGuard},
|
||||
signal::{get_sigaltstack, inner_c, PosixStackt, RtSigarea, SigStack, PROC_CONTROL_STRUCT},
|
||||
proc::{fork_inner, FdGuard, ForkArgs},
|
||||
signal::{
|
||||
get_sigaltstack, inner_c, PosixStackt, RtSigarea, SigStack,
|
||||
PROC_CONTROL_STRUCT,
|
||||
},
|
||||
Tcb,
|
||||
};
|
||||
|
||||
@@ -92,16 +95,16 @@ pub fn copy_env_regs(cur_pid_fd: usize, new_pid_fd: usize) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
unsafe extern "sysv64" fn fork_impl(initial_rsp: *mut usize) -> usize {
|
||||
Error::mux(fork_inner(initial_rsp))
|
||||
unsafe extern "sysv64" fn fork_impl(initial_rsp: *mut usize, args: &ForkArgs) -> usize {
|
||||
Error::mux(fork_inner(initial_rsp, args))
|
||||
}
|
||||
|
||||
unsafe extern "sysv64" fn child_hook(cur_filetable_fd: usize, new_pid_fd: usize) {
|
||||
unsafe extern "sysv64" fn child_hook(cur_filetable_fd: usize, new_pid_fd: usize, new_thr_fd: usize) {
|
||||
let _ = syscall::close(cur_filetable_fd);
|
||||
crate::child_hook_common(FdGuard::new(new_pid_fd));
|
||||
crate::child_hook_common(FdGuard::new(new_pid_fd), FdGuard::new(new_thr_fd));
|
||||
}
|
||||
|
||||
asmfunction!(__relibc_internal_fork_wrapper -> usize: ["
|
||||
asmfunction!(__relibc_internal_fork_wrapper (usize) -> usize: ["
|
||||
push rbp
|
||||
mov rbp, rsp
|
||||
|
||||
@@ -112,15 +115,16 @@ asmfunction!(__relibc_internal_fork_wrapper -> usize: ["
|
||||
push r14
|
||||
push r15
|
||||
|
||||
sub rsp, 32
|
||||
sub rsp, 48
|
||||
|
||||
stmxcsr [rsp+16]
|
||||
fnstcw [rsp+24]
|
||||
stmxcsr [rsp+32]
|
||||
fnstcw [rsp+40]
|
||||
|
||||
mov rdi, rsp
|
||||
// rsi: &ForkArgs
|
||||
call {fork_impl}
|
||||
|
||||
add rsp, 80
|
||||
add rsp, 96
|
||||
|
||||
pop rbp
|
||||
ret
|
||||
@@ -129,10 +133,11 @@ asmfunction!(__relibc_internal_fork_wrapper -> usize: ["
|
||||
asmfunction!(__relibc_internal_fork_ret: ["
|
||||
mov rdi, [rsp]
|
||||
mov rsi, [rsp + 8]
|
||||
mov rdx, [rsp + 16]
|
||||
call {child_hook}
|
||||
|
||||
ldmxcsr [rsp + 16]
|
||||
fldcw [rsp + 24]
|
||||
ldmxcsr [rsp + 32]
|
||||
fldcw [rsp + 40]
|
||||
|
||||
xor rax, rax
|
||||
|
||||
|
||||
+55
-15
@@ -10,18 +10,20 @@
|
||||
#![forbid(unreachable_patterns)]
|
||||
|
||||
use core::cell::{SyncUnsafeCell, UnsafeCell};
|
||||
use core::mem::size_of;
|
||||
|
||||
use generic_rt::{ExpectTlsFree, GenericTcb};
|
||||
use syscall::{Sigcontrol, O_CLOEXEC};
|
||||
|
||||
use self::proc::FdGuard;
|
||||
use self::protocol::ProcMeta;
|
||||
use self::sync::Mutex;
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! asmfunction(
|
||||
($name:ident $(-> $ret:ty)? : [$($asmstmt:expr),*$(,)?] <= [$($decl:ident = $(sym $symname:ident)?$(const $constval:expr)?),*$(,)?]$(,)? ) => {
|
||||
($name:ident $(($($arg:ty),*))? $(-> $ret:ty)? : [$($asmstmt:expr),*$(,)?] <= [$($decl:ident = $(sym $symname:ident)?$(const $constval:expr)?),*$(,)?]$(,)? ) => {
|
||||
::core::arch::global_asm!(concat!("
|
||||
.p2align 4
|
||||
.section .text.", stringify!($name), ", \"ax\", @progbits
|
||||
@@ -33,7 +35,7 @@ macro_rules! asmfunction(
|
||||
"), $($decl = $(sym $symname)?$(const $constval)?),*);
|
||||
|
||||
extern "C" {
|
||||
pub fn $name() $(-> $ret)?;
|
||||
pub fn $name($($(_: $arg),*)?) $(-> $ret)?;
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -45,6 +47,7 @@ pub mod proc;
|
||||
#[path = "../../src/platform/auxv_defs.rs"]
|
||||
pub mod auxv_defs;
|
||||
|
||||
pub mod protocol;
|
||||
pub mod signal;
|
||||
pub mod sync;
|
||||
pub mod sys;
|
||||
@@ -135,6 +138,7 @@ pub unsafe fn tcb_activate(_tcb: &RtTcb, tls_end: usize, tls_len: usize) {
|
||||
}
|
||||
|
||||
/// Initialize redox-rt in situations where relibc is not used
|
||||
#[cfg(not(feature = "proc"))]
|
||||
pub unsafe fn initialize_freestanding() {
|
||||
// TODO: This code is a hack! Integrate the ld_so TCB code into generic-rt, and then use that
|
||||
// (this function will need pointers to the ELF structs normally passed in auxvs), so the TCB
|
||||
@@ -178,24 +182,48 @@ pub unsafe fn initialize_freestanding() {
|
||||
}
|
||||
initialize();
|
||||
}
|
||||
pub unsafe fn initialize() {
|
||||
#[cfg(feature = "proc")]
|
||||
pub(crate) fn read_proc_meta(proc: &FdGuard) -> syscall::Result<ProcMeta> {
|
||||
let mut bytes = [0_u8; size_of::<ProcMeta>()];
|
||||
let _ = syscall::read(**proc, &mut bytes)?;
|
||||
Ok(*plain::from_bytes::<ProcMeta>(&bytes).unwrap())
|
||||
}
|
||||
pub unsafe fn initialize(
|
||||
#[cfg(feature = "proc")]
|
||||
// Find the PID attached to this process
|
||||
let (pid, ppid) = todo!("getpid");
|
||||
proc_fd: FdGuard,
|
||||
) {
|
||||
#[cfg(feature = "proc")]
|
||||
let metadata = read_proc_meta(&proc_fd).unwrap();
|
||||
|
||||
#[cfg(not(feature = "proc"))]
|
||||
// Bootstrap mode, don't associate proc fds with PIDs
|
||||
let (pid, ppid): (u32, u32) = (0, 0);
|
||||
let metadata = ProcMeta::default();
|
||||
|
||||
STATIC_PROC_INFO.get().write(StaticProcInfo {
|
||||
pid,
|
||||
ppid,
|
||||
pid: metadata.pid,
|
||||
ppid: metadata.ppid,
|
||||
|
||||
#[cfg(feature = "proc")]
|
||||
proc_fd,
|
||||
});
|
||||
|
||||
#[cfg(feature = "proc")]
|
||||
{
|
||||
*DYNAMIC_PROC_INFO.lock() = DynamicProcInfo {
|
||||
pgid: metadata.pgid,
|
||||
egid: metadata.egid,
|
||||
euid: metadata.euid,
|
||||
ruid: metadata.ruid,
|
||||
rgid: metadata.rgid,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
struct StaticProcInfo {
|
||||
pub(crate) struct StaticProcInfo {
|
||||
pid: u32,
|
||||
ppid: u32,
|
||||
|
||||
#[cfg(feature = "proc")]
|
||||
proc_fd: FdGuard,
|
||||
}
|
||||
struct DynamicProcInfo {
|
||||
@@ -209,6 +237,7 @@ struct DynamicProcInfo {
|
||||
static STATIC_PROC_INFO: SyncUnsafeCell<StaticProcInfo> = SyncUnsafeCell::new(StaticProcInfo {
|
||||
pid: 0,
|
||||
ppid: 0,
|
||||
proc_fd: FdGuard::new(usize::MAX),
|
||||
});
|
||||
static DYNAMIC_PROC_INFO: Mutex<DynamicProcInfo> = Mutex::new(DynamicProcInfo {
|
||||
pgid: u32::MAX,
|
||||
@@ -218,13 +247,24 @@ static DYNAMIC_PROC_INFO: Mutex<DynamicProcInfo> = Mutex::new(DynamicProcInfo {
|
||||
rgid: u32::MAX,
|
||||
});
|
||||
|
||||
unsafe fn child_hook_common(new_pid_fd: FdGuard) {
|
||||
pub(crate) fn static_proc_info() -> &'static StaticProcInfo {
|
||||
unsafe { &*STATIC_PROC_INFO.get() }
|
||||
}
|
||||
|
||||
unsafe fn child_hook_common(new_proc_fd: FdGuard, new_thr_fd: FdGuard) {
|
||||
// TODO: just pass PID to child rather than obtaining it via IPC?
|
||||
#[cfg(feature = "proc")]
|
||||
let (pid, ppid): (u32, u32) = todo!("getpid");
|
||||
#[cfg(not(feature = "proc"))]
|
||||
let (pid, ppid): (u32, u32) = (0, 0);
|
||||
let metadata = read_proc_meta(&new_proc_fd).unwrap();
|
||||
|
||||
// TODO: Currently pidfd == threadfd, but this will not be the case later.
|
||||
RtTcb::current().thr_fd.get().write(Some(new_pid_fd));
|
||||
#[cfg(not(feature = "proc"))]
|
||||
let metadata = ProcMeta::default();
|
||||
|
||||
STATIC_PROC_INFO.get().write(StaticProcInfo {
|
||||
pid: metadata.pid,
|
||||
ppid: metadata.ppid,
|
||||
proc_fd: new_proc_fd,
|
||||
});
|
||||
|
||||
// FIXME
|
||||
RtTcb::current().thr_fd.get().write(Some(new_thr_fd));
|
||||
}
|
||||
|
||||
+82
-47
@@ -1,6 +1,6 @@
|
||||
use core::{fmt::Debug, mem::size_of};
|
||||
|
||||
use crate::{arch::*, auxv_defs::*, DYNAMIC_PROC_INFO, STATIC_PROC_INFO};
|
||||
use crate::{arch::*, auxv_defs::*, read_proc_meta, static_proc_info, RtTcb, DYNAMIC_PROC_INFO, STATIC_PROC_INFO};
|
||||
|
||||
use alloc::{boxed::Box, collections::BTreeMap, vec};
|
||||
|
||||
@@ -23,14 +23,14 @@ use syscall::{
|
||||
PAGE_SIZE, PROT_EXEC, PROT_READ, PROT_WRITE,
|
||||
};
|
||||
|
||||
pub enum FexecResult {
|
||||
pub enum FexecResult<'a> {
|
||||
Normal {
|
||||
addrspace_handle: FdGuard,
|
||||
},
|
||||
Interp {
|
||||
path: Box<[u8]>,
|
||||
image_file: FdGuard,
|
||||
open_via_dup: FdGuard,
|
||||
thread_fd: &'a FdGuard,
|
||||
interp_override: InterpOverride,
|
||||
},
|
||||
}
|
||||
@@ -55,9 +55,10 @@ pub struct ExtraInfo<'a> {
|
||||
pub umask: u32,
|
||||
}
|
||||
|
||||
pub fn fexec_impl<A, E>(
|
||||
pub fn fexec_impl<'a, A, E>(
|
||||
image_file: FdGuard,
|
||||
open_via_dup: FdGuard,
|
||||
thread_fd: &'a FdGuard,
|
||||
proc_fd: &FdGuard,
|
||||
memory_scheme_fd: &FdGuard,
|
||||
path: &[u8],
|
||||
args: A,
|
||||
@@ -65,7 +66,7 @@ pub fn fexec_impl<A, E>(
|
||||
total_args_envs_size: usize,
|
||||
extrainfo: &ExtraInfo,
|
||||
mut interp_override: Option<InterpOverride>,
|
||||
) -> Result<FexecResult>
|
||||
) -> Result<FexecResult<'a>>
|
||||
where
|
||||
A: IntoIterator,
|
||||
E: IntoIterator,
|
||||
@@ -81,7 +82,7 @@ where
|
||||
let header = Header::from_bytes(&header_bytes);
|
||||
|
||||
let grants_fd = {
|
||||
let current_addrspace_fd = FdGuard::new(syscall::dup(*open_via_dup, b"addrspace")?);
|
||||
let current_addrspace_fd = FdGuard::new(syscall::dup(**thread_fd, b"addrspace")?);
|
||||
FdGuard::new(syscall::dup(*current_addrspace_fd, b"empty")?)
|
||||
};
|
||||
|
||||
@@ -134,7 +135,7 @@ where
|
||||
return Ok(FexecResult::Interp {
|
||||
path: interp.into_boxed_slice(),
|
||||
image_file,
|
||||
open_via_dup,
|
||||
thread_fd,
|
||||
interp_override: InterpOverride {
|
||||
at_entry: header.e_entry as usize,
|
||||
at_phnum: phnum,
|
||||
@@ -389,7 +390,7 @@ where
|
||||
|
||||
push(argc)?;
|
||||
|
||||
if let Ok(sighandler_fd) = syscall::dup(*open_via_dup, b"sighandler").map(FdGuard::new) {
|
||||
if let Ok(sighandler_fd) = syscall::dup(**thread_fd, b"sighandler").map(FdGuard::new) {
|
||||
let _ = syscall::write(
|
||||
*sighandler_fd,
|
||||
&SetSighandlerData {
|
||||
@@ -402,11 +403,11 @@ where
|
||||
}
|
||||
|
||||
unsafe {
|
||||
deactivate_tcb(*open_via_dup)?;
|
||||
deactivate_tcb(**thread_fd)?;
|
||||
}
|
||||
|
||||
// TODO: Restore old name if exec failed?
|
||||
if let Ok(name_fd) = syscall::dup(*open_via_dup, b"name").map(FdGuard::new) {
|
||||
if let Ok(name_fd) = syscall::dup(**thread_fd, b"name").map(FdGuard::new) {
|
||||
let _ = syscall::write(*name_fd, interp_override.as_ref().map_or(path, |o| &o.name));
|
||||
}
|
||||
if interp_override.is_some() {
|
||||
@@ -416,7 +417,7 @@ where
|
||||
let _ = syscall::write(*mmap_min_fd, &usize::to_ne_bytes(aligned_last_addr));
|
||||
}
|
||||
|
||||
let addrspace_selection_fd = FdGuard::new(syscall::dup(*open_via_dup, b"current-addrspace")?);
|
||||
let addrspace_selection_fd = FdGuard::new(syscall::dup(**thread_fd, b"current-addrspace")?);
|
||||
|
||||
let _ = syscall::write(
|
||||
*addrspace_selection_fd,
|
||||
@@ -635,7 +636,7 @@ pub struct FdGuard {
|
||||
taken: bool,
|
||||
}
|
||||
impl FdGuard {
|
||||
pub fn new(fd: usize) -> Self {
|
||||
pub const fn new(fd: usize) -> Self {
|
||||
Self { fd, taken: false }
|
||||
}
|
||||
pub fn take(&mut self) -> usize {
|
||||
@@ -679,9 +680,9 @@ pub fn create_set_addr_space_buf(
|
||||
/// Spawns a new context which will not share the same address space as the current one. File
|
||||
/// descriptors from other schemes are reobtained with `dup`, and grants referencing such file
|
||||
/// descriptors are reobtained through `fmap`. Other mappings are kept but duplicated using CoW.
|
||||
pub fn fork_impl() -> Result<usize> {
|
||||
pub fn fork_impl(args: &ForkArgs<'_>) -> Result<usize> {
|
||||
let old_mask = crate::signal::get_sigmask()?;
|
||||
let pid = unsafe { Error::demux(__relibc_internal_fork_wrapper())? };
|
||||
let pid = unsafe { Error::demux(__relibc_internal_fork_wrapper(args as *const ForkArgs as usize))? };
|
||||
|
||||
if pid == 0 {
|
||||
crate::signal::set_sigmask(Some(old_mask), None)?;
|
||||
@@ -689,36 +690,45 @@ pub fn fork_impl() -> Result<usize> {
|
||||
Ok(pid)
|
||||
}
|
||||
|
||||
pub fn fork_inner(initial_rsp: *mut usize) -> Result<usize> {
|
||||
let (cur_filetable_fd, new_pid_fd, new_pid);
|
||||
pub enum ForkArgs<'a> {
|
||||
Init { this_thr_fd: &'a FdGuard, auth: &'a FdGuard },
|
||||
Managed,
|
||||
}
|
||||
|
||||
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_pid_fd = FdGuard::new(syscall::open(
|
||||
"/scheme/thisproc/current",
|
||||
O_CLOEXEC,
|
||||
)?);
|
||||
(new_pid_fd, new_pid) = new_child_process(*cur_pid_fd)?;
|
||||
let cur_thr_fd = match args {
|
||||
ForkArgs::Init { this_thr_fd, .. } => this_thr_fd,
|
||||
ForkArgs::Managed => RtTcb::current().thread_fd(),
|
||||
};
|
||||
let NewChildProc { proc_fd, thr_fd, pid } = new_child_process(args)?;
|
||||
new_proc_fd = proc_fd;
|
||||
new_thr_fd = thr_fd;
|
||||
new_pid = pid;
|
||||
|
||||
copy_str(*cur_pid_fd, *new_pid_fd, "name")?;
|
||||
copy_str(**cur_thr_fd, *new_thr_fd, "name")?;
|
||||
|
||||
// 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).
|
||||
{
|
||||
cur_filetable_fd = FdGuard::new(syscall::dup(*cur_pid_fd, b"filetable")?);
|
||||
cur_filetable_fd = FdGuard::new(syscall::dup(**cur_thr_fd, b"filetable")?);
|
||||
|
||||
// This must be done before the address space is copied.
|
||||
unsafe {
|
||||
initial_rsp.write(*cur_filetable_fd);
|
||||
initial_rsp.add(1).write(*new_pid_fd);
|
||||
initial_rsp.add(1).write(*new_proc_fd);
|
||||
initial_rsp.add(2).write(*new_thr_fd);
|
||||
}
|
||||
}
|
||||
|
||||
// CoW-duplicate address space.
|
||||
{
|
||||
let new_addr_space_sel_fd =
|
||||
FdGuard::new(syscall::dup(*new_pid_fd, b"current-addrspace")?);
|
||||
FdGuard::new(syscall::dup(*new_thr_fd, b"current-addrspace")?);
|
||||
|
||||
let cur_addr_space_fd = FdGuard::new(syscall::dup(*cur_pid_fd, b"addrspace")?);
|
||||
let cur_addr_space_fd = FdGuard::new(syscall::dup(**cur_thr_fd, b"addrspace")?);
|
||||
let new_addr_space_fd = FdGuard::new(syscall::dup(*cur_addr_space_fd, b"exclusive")?);
|
||||
|
||||
let mut grant_desc_buf = [GrantDesc::default(); 16];
|
||||
@@ -794,14 +804,14 @@ pub fn fork_inner(initial_rsp: *mut usize) -> 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 = FdGuard::new(syscall::dup(*new_pid_fd, b"sighandler")?);
|
||||
let new_sighandler_fd = FdGuard::new(syscall::dup(*new_thr_fd, b"sighandler")?);
|
||||
let _ = syscall::write(
|
||||
*new_sighandler_fd,
|
||||
&crate::signal::current_setsighandler_struct(),
|
||||
)?;
|
||||
}
|
||||
}
|
||||
copy_env_regs(*cur_pid_fd, *new_pid_fd)?;
|
||||
copy_env_regs(**cur_thr_fd, *new_thr_fd)?;
|
||||
}
|
||||
// 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 --
|
||||
@@ -810,37 +820,57 @@ pub fn fork_inner(initial_rsp: *mut usize) -> Result<usize> {
|
||||
// TODO: Use file descriptor forwarding or something similar to avoid copying the file
|
||||
// table in the kernel.
|
||||
let new_filetable_fd = FdGuard::new(syscall::dup(*cur_filetable_fd, b"copy")?);
|
||||
let new_filetable_sel_fd = FdGuard::new(syscall::dup(*new_pid_fd, b"current-filetable")?);
|
||||
let new_filetable_sel_fd = FdGuard::new(syscall::dup(*new_thr_fd, b"current-filetable")?);
|
||||
let _ = syscall::write(
|
||||
*new_filetable_sel_fd,
|
||||
&usize::to_ne_bytes(*new_filetable_fd),
|
||||
)?;
|
||||
}
|
||||
let start_fd = FdGuard::new(syscall::dup(*new_pid_fd, b"start")?);
|
||||
let start_fd = FdGuard::new(syscall::dup(*new_thr_fd, b"start")?);
|
||||
let _ = syscall::write(*start_fd, &[0])?;
|
||||
|
||||
Ok(new_pid)
|
||||
}
|
||||
|
||||
pub fn new_child_process(cur_pid_fd: usize) -> Result<(FdGuard, usize)> {
|
||||
// Create a new context (fields such as uid/gid will be inherited from the current context).
|
||||
let fd = FdGuard::new(syscall::open(
|
||||
"/scheme/thisproc/new",
|
||||
O_CLOEXEC,
|
||||
)?);
|
||||
|
||||
struct NewChildProc {
|
||||
#[cfg(feature = "proc")]
|
||||
let pid = todo!("child pid");
|
||||
proc_fd: FdGuard,
|
||||
|
||||
#[cfg(not(feature = "proc"))]
|
||||
let pid = 1;
|
||||
|
||||
Ok((fd, pid))
|
||||
thr_fd: FdGuard,
|
||||
pid: usize,
|
||||
}
|
||||
|
||||
pub fn copy_str(cur_pid_fd: usize, new_pid_fd: usize, key: &str) -> Result<()> {
|
||||
pub fn new_child_process(args: &ForkArgs<'_>) -> Result<NewChildProc> {
|
||||
match args {
|
||||
ForkArgs::Managed => {
|
||||
let proc_fd = &static_proc_info().proc_fd;
|
||||
let child_proc_fd = FdGuard::new(syscall::dup(**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)?;
|
||||
Ok(NewChildProc {
|
||||
proc_fd: child_proc_fd,
|
||||
thr_fd: only_thread_fd,
|
||||
pid: meta.pid as usize
|
||||
})
|
||||
}
|
||||
#[cfg(feature = "proc")]
|
||||
ForkArgs::Init { .. } => unreachable!(),
|
||||
|
||||
#[cfg(not(feature = "proc"))]
|
||||
#[cfg(feature = "proc")]
|
||||
ForkArgs::Init { this_thr_fd, auth } => {
|
||||
let thr_fd = FdGuard::new(syscall::dup(*auth, b"new-context")?);
|
||||
Ok(NewChildProc {
|
||||
thr_fd,
|
||||
pid: 0,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn copy_str(cur_pid_fd: usize, new_proc_fd: usize, key: &str) -> Result<()> {
|
||||
let cur_name_fd = FdGuard::new(syscall::dup(cur_pid_fd, key.as_bytes())?);
|
||||
let new_name_fd = FdGuard::new(syscall::dup(new_pid_fd, key.as_bytes())?);
|
||||
let new_name_fd = FdGuard::new(syscall::dup(new_proc_fd, key.as_bytes())?);
|
||||
|
||||
// TODO: Max path size?
|
||||
let mut buf = [0_u8; 256];
|
||||
@@ -852,8 +882,12 @@ pub fn copy_str(cur_pid_fd: usize, new_pid_fd: usize, key: &str) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub unsafe fn make_init() {
|
||||
STATIC_PROC_INFO.get().write(crate::StaticProcInfo { pid: 1, ppid: 1 });
|
||||
pub unsafe fn make_init(this_thr_fd: FdGuard) -> (&'static FdGuard, &'static FdGuard) {
|
||||
let this_thr_fd = &*(*RtTcb::current().thr_fd.get()).insert(this_thr_fd);
|
||||
let proc_fd = FdGuard::new(syscall::open("/scheme/proc/init", syscall::O_CLOEXEC).expect("failed to create init"));
|
||||
syscall::sendfd(*proc_fd, **this_thr_fd, 0, 0).expect("failed to assign current thread to init process");
|
||||
|
||||
STATIC_PROC_INFO.get().write(crate::StaticProcInfo { pid: 1, ppid: 1, proc_fd });
|
||||
*DYNAMIC_PROC_INFO.lock() = crate::DynamicProcInfo {
|
||||
pgid: 1,
|
||||
egid: 0,
|
||||
@@ -861,4 +895,5 @@ pub unsafe fn make_init() {
|
||||
rgid: 0,
|
||||
ruid: 0,
|
||||
};
|
||||
(&(*STATIC_PROC_INFO.get()).proc_fd, this_thr_fd)
|
||||
}
|
||||
|
||||
@@ -26,6 +26,9 @@ pub const AT_RANDOM: usize = 25; /* Address of 16 random bytes. */
|
||||
pub const AT_HWCAP2: usize = 26; /* More machine-dependent hints about*/
|
||||
pub const AT_EXECFN: usize = 31; /* Filename of executable. */
|
||||
|
||||
// TODO: Downgrade aux vectors to getauxval constants on Redox, and use a regular struct for
|
||||
// passing important runtime info between exec (or posix_spawn in the future) calls.
|
||||
|
||||
#[cfg(target_os = "redox")]
|
||||
// XXX: The name AT_CWD is already used in openat... for a completely different purpose.
|
||||
pub const AT_REDOX_INITIAL_CWD_PTR: usize = 32;
|
||||
@@ -46,5 +49,11 @@ pub const AT_REDOX_INITIAL_DEFAULT_SCHEME_PTR: usize = 38;
|
||||
#[cfg(target_os = "redox")]
|
||||
pub const AT_REDOX_INITIAL_DEFAULT_SCHEME_LEN: usize = 39;
|
||||
|
||||
#[cfg(target_os = "redox")]
|
||||
pub const AT_REDOX_PROC_FD: usize = 39;
|
||||
|
||||
#[cfg(target_os = "redox")]
|
||||
pub const AT_REDOX_THR_FD: usize = 39;
|
||||
|
||||
#[cfg(target_os = "redox")]
|
||||
pub const AT_REDOX_UMASK: usize = 40;
|
||||
|
||||
Reference in New Issue
Block a user