diff --git a/bootstrap/src/exec.rs b/bootstrap/src/exec.rs index ab64c0be03..610a3442d1 100644 --- a/bootstrap/src/exec.rs +++ b/bootstrap/src/exec.rs @@ -6,10 +6,11 @@ use core::str::FromStr; use hashbrown::HashMap; use redox_scheme::Socket; -use syscall::CallFlags; +use libredox::protocol::O_CLOEXEC; use syscall::data::{GlobalSchemes, KernelSchemeInfo}; -use syscall::flag::{O_CLOEXEC, O_RDONLY, O_STAT}; -use syscall::{EINTR, Error}; +use syscall::flag::{O_DIRECTORY, O_RDONLY, O_STAT}; +use syscall::CallFlags; +use syscall::{Error, EINTR}; use redox_rt::proc::*; @@ -26,7 +27,7 @@ impl log::Log for Logger { let line = record.line().unwrap_or(0); let level = record.level(); let msg = record.args(); - let _ = libredox::call::write( + let _ = syscall::write( 1, alloc::format!("[{file}:{line} {level}] {msg}\n").as_bytes(), ); @@ -72,13 +73,13 @@ pub fn main() -> ! { let mut env_bytes = [0_u8; 4096]; let mut envs = { let fd = FdGuard::new( - libredox::call::openat( + redox_rt::sys::openat( kernel_schemes .get(GlobalSchemes::Sys) .expect("failed to get sys fd") .as_raw_fd(), "env", - (O_RDONLY | O_CLOEXEC) as i32, + O_RDONLY | O_CLOEXEC, 0, ) .expect("bootstrap: failed to open env"), @@ -207,12 +208,16 @@ pub fn main() -> ! { // from this point, this_thr_fd is no longer valid const CWD: &[u8] = b"/scheme/initfs"; - let cwd_fd = FdGuard::new( - libredox::call::openat(initns_fd.as_raw_fd(), "/scheme/initfs", O_STAT as i32, 0) - .expect("failed to open cwd fd"), - ) - .to_upper() - .unwrap(); + + let initfs_root_fd = initns_fd + .openat_into_upper("/scheme/initfs", O_DIRECTORY, 0) + .expect("failed to open initfs root fd"); + let cwd_fd = initfs_root_fd + .openat_into_upper("", O_STAT, 0) + .expect("failed to open cwd fd"); + let filetable_binary_fd = init_thr_fd + .dup_into_upper(b"filetable-binary") + .expect("faild to create filetable-binary fd"); let extrainfo = ExtraInfo { cwd: Some(CWD), sigprocmask: 0, @@ -222,25 +227,23 @@ pub fn main() -> ! { proc_fd: init_proc_fd.as_raw_fd(), ns_fd: Some(initns_fd.take()), cwd_fd: Some(cwd_fd.as_raw_fd()), - filetable_fd: None, - same_process: false, + filetable_fd: Some(filetable_binary_fd.as_raw_fd()), + same_process: true, }; - let path = "/scheme/initfs/bin/init"; + let exe_path = "/scheme/initfs/bin/init"; + let exe_reference = "bin/init"; - let image_file = FdGuard::new( - libredox::call::openat(extrainfo.ns_fd.unwrap(), path, (O_RDONLY | O_CLOEXEC) as i32, 0) - .expect("failed to open init"), - ) - .to_upper() - .unwrap(); + let image_file = initfs_root_fd + .openat_into_upper(exe_reference, O_RDONLY | O_CLOEXEC, 0) + .expect("failed to open init"); - let exe_path = alloc::format!("/scheme/initfs{}", path); + drop(initfs_root_fd); - let Some(FexecResult::Interp { + let FexecResult::Interp { path: interp_path, interp_override, - }) = fexec_impl( + } = fexec_impl( image_file, init_thr_fd, init_proc_fd, @@ -250,29 +253,33 @@ pub fn main() -> ! { &extrainfo, None, ) - .map_err(|e| { - let _ = libredox::call::write(1, alloc::format!("fexec_impl failed: {}\n", e).as_bytes()); - e - }) - .expect("failed to execute init") - else { - panic!("fexec_impl returned None for init"); - }; + .ok() + .flatten() + .expect("failed to execute init"); // According to elf(5), PT_INTERP requires that the interpreter path be // null-terminated. Violating this should therefore give the "format error" ENOEXEC. let interp_cstr = CStr::from_bytes_with_nul(&interp_path).expect("interpreter not valid C str"); - let interp_file = FdGuard::new( - libredox::call::openat( + let interp_path = interp_cstr.to_str().expect("interpreter not UTF-8"); + let root_fd = FdGuard::new( + redox_rt::sys::openat_into_upper( extrainfo.ns_fd.unwrap(), // initns, not initfs! - interp_cstr.to_str().expect("interpreter not UTF-8"), - (O_RDONLY | O_CLOEXEC) as i32, + interp_path, + O_RDONLY | O_CLOEXEC, 0, ) - .expect("failed to open dynamic linker"), + .expect("failed to open root fd"), ) .to_upper() .unwrap(); + let redox_path = redox_path::RedoxPath::from_absolute(interp_path) + .expect("interpreter path is not a Scheme-rooted path"); + let (_, reference) = redox_path + .as_parts() + .expect("redox_path is not scheme root path"); + let interp_file = root_fd + .openat_into_upper(reference.as_ref(), O_RDONLY | O_CLOEXEC, 0) + .expect("failed to open dynamic linker"); fexec_impl( interp_file, @@ -299,13 +306,13 @@ pub(crate) fn spawn( inner: impl FnOnce(FdGuard, Socket, FdGuard, KernelSchemeMap) -> !, ) -> (FdGuard, FdGuard, KernelSchemeMap, FdGuard) { let read = FdGuard::new( - libredox::call::openat( + redox_rt::sys::openat( kernel_schemes .get(GlobalSchemes::Pipe) .expect("failed to get pipe fd") .as_raw_fd(), "", - O_CLOEXEC as i32, + O_CLOEXEC, 0, ) .expect("failed to open sync read pipe"), @@ -313,7 +320,7 @@ pub(crate) fn spawn( // The write pipe will not inherit O_CLOEXEC, but is closed by the daemon later. let write = FdGuard::new( - libredox::call::dup(read.as_raw_fd(), b"write").expect("failed to open sync write pipe"), + redox_rt::sys::dup(read.as_raw_fd(), b"write").expect("failed to open sync write pipe"), ); match fork_impl(&ForkArgs::Init { @@ -325,15 +332,11 @@ pub(crate) fn spawn( } // Continue serving the scheme as the child. Ok(0) => { - let _ = libredox::call::write(1, b"SP:0\n"); drop(read); - let _ = libredox::call::write(1, b"SP:1\n"); let socket = Socket::create_inner(scheme_creation_cap.as_raw_fd(), nonblock) .expect("failed to open proc scheme socket"); - let _ = libredox::call::write(1, b"SP:2\n"); drop(scheme_creation_cap); - let _ = libredox::call::write(1, b"SP:3\n"); inner(write, socket, auth, kernel_schemes) } @@ -349,7 +352,7 @@ pub(crate) fn spawn( ) }; loop { - match syscall::call_ro( + match redox_rt::sys::sys_call_ro( read.as_raw_fd(), fd_bytes, CallFlags::FD | CallFlags::FD_UPPER,