diff --git a/src/platform/redox/mod.rs b/src/platform/redox/mod.rs index 92614ac0e7..890cbddec5 100644 --- a/src/platform/redox/mod.rs +++ b/src/platform/redox/mod.rs @@ -22,19 +22,20 @@ use self::{ }; use super::{Pal, Read, types::*}; use crate::{ + alloc::string::ToString, c_str::{CStr, CString}, error::{Errno, Result}, fs::File, header::{ errno::{ EBADF, EBADFD, EEXIST, EFAULT, EFBIG, EINTR, EINVAL, EIO, ENAMETOOLONG, ENOENT, - ENOEXEC, ENOMEM, ENOSYS, EOPNOTSUPP, EPERM, + ENOEXEC, ENOMEM, ENOSYS, ENOTDIR, EOPNOTSUPP, EPERM, }, fcntl::{ self, AT_EACCESS, AT_EMPTY_PATH, AT_FDCWD, AT_REMOVEDIR, AT_SYMLINK_FOLLOW, F_GETLK, F_OFD_GETLK, F_OFD_SETLK, F_RDLCK, F_SETLK, F_SETLKW, F_UNLCK, F_WRLCK, flock, }, - limits, + limits::{self, NAME_MAX}, pthread::{pthread_cancel, pthread_create}, signal::{NSIG, SIGEV_NONE, SIGEV_SIGNAL, SIGEV_THREAD, SIGRTMIN, sigevent}, stdio::RENAME_NOREPLACE, @@ -45,7 +46,7 @@ use crate::{ sys_random, sys_resource::{RLIM_INFINITY, rlimit, rusage}, sys_select::timeval, - sys_stat::{S_ISVTX, stat}, + sys_stat::{self, S_ISVTX, stat}, sys_statvfs::statvfs, sys_time::timezone, sys_utsname::{UTSLENGTH, utsname}, @@ -1211,7 +1212,9 @@ impl Pal for Sys { let child = redox_rt::proc::new_child_process(&redox_rt::proc::ForkArgs::Managed)?; let executable = File::open(program, fcntl::O_RDONLY)?; - let cwd = path::clone_cwd().unwrap(); + let original_cwd = path::clone_cwd().unwrap().to_string(); + let mut cwd = original_cwd.clone(); + cwd.reserve_exact(NAME_MAX - cwd.len()); let proc_fd = child.proc_fd.unwrap(); let curr_proc_fd = redox_rt::current_proc_fd(); let file_table = RtTcb::current() @@ -1224,28 +1227,6 @@ impl Pal for Sys { new_file_table.write(&file_table.as_raw_fd().to_ne_bytes())?; } - let mut extra_info = redox_rt::proc::ExtraInfo { - cwd: Some(cwd.as_bytes()), - sigignmask: redox_rt::signal::get_sigignmask_to_inherit(), - sigprocmask: if let Some(fat) = fat - && Flags::from_bits(fat.flags) - .unwrap() - .contains(Flags::POSIX_SPAWN_SETSIGMASK) - { - fat.sigmask - } else { - redox_rt::signal::get_sigmask().unwrap() - }, - umask: redox_rt::sys::get_umask(), - thr_fd: child.thr_fd.as_raw_fd(), - proc_fd: proc_fd.as_raw_fd(), - ns_fd: redox_rt::current_namespace_fd().ok(), - cwd_fd: path::current_dir() - .ok() - .map(|fd| fd.as_ref().unwrap().fd.as_raw_fd()), - same_process: false, - }; - let mut args = Vec::new(); let mut envs = Vec::new(); @@ -1282,7 +1263,6 @@ impl Pal for Sys { 0, u64::try_from(fd).map_err(|_| Errno(EBADFD))?, )?; - core::mem::forget(src_fd); } crate::header::spawn::Operation::Close(fd) => { new_file_table.call_wo( @@ -1291,8 +1271,21 @@ impl Pal for Sys { &[syscall::flag::FileTableVerb::Close as u64], )?; } - crate::header::spawn::Operation::Chdir(_) => todo!(), - crate::header::spawn::Operation::FChdir(_) => todo!(), + crate::header::spawn::Operation::Chdir(path) => { + let path = unsafe { CStr::from_ptr(path) }; + let mut stat = sys_stat::stat::default(); + let fd = Sys::stat(path, Out::from_mut(&mut stat))?; + + if sys_stat::S_IFDIR & sys_stat::S_IFMT != sys_stat::S_IFDIR { + return Err(Errno(ENOTDIR)); + } + cwd = path.to_str().unwrap().to_string(); + path::chdir(cwd.as_str())?; + } + crate::header::spawn::Operation::FChdir(fd) => { + path::fchdir(fd)?; + path::getcwd(Out::from_mut(unsafe { cwd.as_bytes_mut() }))?; + } crate::header::spawn::Operation::Dup2(old, new) => { new_file_table.call_wo( [(old as usize).to_ne_bytes(), (new as usize).to_ne_bytes()] @@ -1314,6 +1307,28 @@ impl Pal for Sys { )?; } + let mut extra_info = redox_rt::proc::ExtraInfo { + cwd: Some(cwd.as_bytes()), + sigignmask: redox_rt::signal::get_sigignmask_to_inherit(), + sigprocmask: if let Some(fat) = fat + && Flags::from_bits(fat.flags) + .unwrap() + .contains(Flags::POSIX_SPAWN_SETSIGMASK) + { + fat.sigmask + } else { + redox_rt::signal::get_sigmask().unwrap() + }, + umask: redox_rt::sys::get_umask(), + thr_fd: child.thr_fd.as_raw_fd(), + proc_fd: proc_fd.as_raw_fd(), + ns_fd: redox_rt::current_namespace_fd().ok(), + cwd_fd: path::current_dir() + .ok() + .map(|fd| fd.as_ref().unwrap().fd.as_raw_fd()), + same_process: false, + }; + if let Some(attr) = fat { let flags = Flags::from_bits(attr.flags).ok_or(Errno(EINVAL))?; @@ -1392,6 +1407,8 @@ impl Pal for Sys { .unwrap(); } + path::chdir(original_cwd.as_str())?; + let start_fd = child.thr_fd.dup(b"start")?; start_fd.write(&[0])?;