diff --git a/Cargo.lock b/Cargo.lock index d0be2734d2..1309baa503 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -256,12 +256,14 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "libredox" -version = "0.1.12" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" +checksum = "1744e39d1d6a9948f4f388969627434e31128196de472883b39f148769bfe30a" dependencies = [ "bitflags", "libc", + "plain", + "redox_syscall", ] [[package]] @@ -445,6 +447,7 @@ dependencies = [ "generic-rt", "goblin", "ioslice", + "libredox", "plain", "redox-path", "redox_syscall", @@ -452,9 +455,9 @@ dependencies = [ [[package]] name = "redox_event" -version = "0.4.3" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c30b73c93693667b5a8e6f54bddcc5a57449ef17c99f4b55c12d5bae4ab79e82" +checksum = "4ea3e412d205440c7b0218af26247226f979ed1201674cda7a33cc70609084b5" dependencies = [ "bitflags", "libredox", @@ -463,9 +466,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d94dd2f7cd932d4dc02cc8b2b50dfd38bd079a4e5d79198b99743d7fcf9a4b4" +checksum = "6ce70a74e890531977d37e532c34d45e9055d2409ed08ddba14529471ed0be16" dependencies = [ "bitflags", ] @@ -487,6 +490,7 @@ dependencies = [ "ioslice", "libc", "libm", + "libredox", "log", "md-5", "memchr", diff --git a/Cargo.toml b/Cargo.toml index fbe1d13c6a..596aacd369 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -105,14 +105,15 @@ features = ["elf", "read_core"] sc = "0.2.7" [target.'cfg(target_os = "redox")'.dependencies] -redox_syscall = "0.7" +redox_syscall = "0.7.3" redox-rt = { path = "redox-rt" } redox-path = "0.3" -redox_event = { version = "0.4.3", default-features = false, features = [ +redox_event = { version = "0.4.6", default-features = false, features = [ "redox_syscall", ] } ioslice = { version = "0.6", default-features = false } redox-ioctl = { path = "redox-ioctl" } +redox_protocols = { package = "libredox", version = "0.1.14", default-features = false, features = ["protocol"] } [features] # to enable trace level, take out this `no_trace` diff --git a/redox-rt/Cargo.toml b/redox-rt/Cargo.toml index 44b5204477..ea9efcaae4 100644 --- a/redox-rt/Cargo.toml +++ b/redox-rt/Cargo.toml @@ -15,6 +15,7 @@ plain = "0.2" ioslice = { version = "0.6", default-features = false } redox_syscall = "0.7" redox-path = "0.3.0" +redox_protocols = { package = "libredox", version = "0.1.14", default-features = false, features = ["protocol"] } generic-rt = { path = "../generic-rt" } diff --git a/redox-rt/src/arch/aarch64.rs b/redox-rt/src/arch/aarch64.rs index 519fe899df..0724c9bb5b 100644 --- a/redox-rt/src/arch/aarch64.rs +++ b/redox-rt/src/arch/aarch64.rs @@ -5,9 +5,9 @@ use syscall::{data::*, error::*}; use crate::{ Tcb, proc::{FdGuard, FdGuardUpper, ForkArgs, fork_inner}, - protocol::{ProcCall, RtSigInfo}, signal::{PosixStackt, RtSigarea, SigStack, inner_c}, }; +use redox_protocols::protocol::{ProcCall, RtSigInfo}; use super::ForkScratchpad; diff --git a/redox-rt/src/arch/i686.rs b/redox-rt/src/arch/i686.rs index 93d7ccfe9f..6461fe5f87 100644 --- a/redox-rt/src/arch/i686.rs +++ b/redox-rt/src/arch/i686.rs @@ -4,9 +4,9 @@ use syscall::*; use crate::{ proc::{FdGuard, FdGuardUpper, ForkArgs, fork_inner}, - protocol::{ProcCall, RtSigInfo}, signal::{PROC_CONTROL_STRUCT, PosixStackt, RtSigarea, SigStack, inner_fastcall}, }; +use redox_protocols::protocol::{ProcCall, RtSigInfo}; use super::ForkScratchpad; diff --git a/redox-rt/src/arch/riscv64.rs b/redox-rt/src/arch/riscv64.rs index 8b99c8e947..8a6dc0fabb 100644 --- a/redox-rt/src/arch/riscv64.rs +++ b/redox-rt/src/arch/riscv64.rs @@ -3,10 +3,10 @@ use core::cell::SyncUnsafeCell; use crate::{ Tcb, proc::{FdGuard, FdGuardUpper, ForkArgs, fork_inner}, - protocol::{ProcCall, RtSigInfo}, signal::{PosixStackt, RtSigarea, SigStack, get_sigaltstack, inner_c}, }; use core::{mem::offset_of, ptr::NonNull, sync::atomic::Ordering}; +use redox_protocols::protocol::{ProcCall, RtSigInfo}; use syscall::{data::*, error::*}; use super::ForkScratchpad; diff --git a/redox-rt/src/arch/x86_64.rs b/redox-rt/src/arch/x86_64.rs index 516f93b2f0..b93c59b1d6 100644 --- a/redox-rt/src/arch/x86_64.rs +++ b/redox-rt/src/arch/x86_64.rs @@ -13,9 +13,9 @@ use syscall::{ use crate::{ Tcb, proc::{FdGuard, FdGuardUpper, ForkArgs, fork_inner}, - protocol::{ProcCall, RtSigInfo}, signal::{PROC_CONTROL_STRUCT, PosixStackt, RtSigarea, SigStack, get_sigaltstack, inner_c}, }; +use redox_protocols::protocol::{ProcCall, RtSigInfo}; use super::ForkScratchpad; diff --git a/redox-rt/src/lib.rs b/redox-rt/src/lib.rs index b9e412c44f..12835a6a7a 100644 --- a/redox-rt/src/lib.rs +++ b/redox-rt/src/lib.rs @@ -9,11 +9,11 @@ use core::cell::UnsafeCell; #[cfg(any(target_arch = "x86_64", target_arch = "x86"))] use generic_rt::ExpectTlsFree; // not used on aarch64 or riscv64 use generic_rt::GenericTcb; +use redox_protocols::protocol::ProcMeta; use syscall::Sigcontrol; use self::{ proc::{FdGuard, FdGuardUpper, STATIC_PROC_INFO}, - protocol::ProcMeta, sync::Mutex, }; @@ -45,7 +45,6 @@ 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; diff --git a/redox-rt/src/proc.rs b/redox-rt/src/proc.rs index 128ab306e2..b850da01ef 100644 --- a/redox-rt/src/proc.rs +++ b/redox-rt/src/proc.rs @@ -4,10 +4,10 @@ use crate::{ DYNAMIC_PROC_INFO, RtTcb, StaticProcInfo, arch::*, auxv_defs::*, - protocol::{ProcCall, ThreadCall}, read_proc_meta, sys::{open, proc_call, thread_call}, }; +use redox_protocols::protocol::{ProcCall, ThreadCall}; use alloc::{boxed::Box, vec}; @@ -260,7 +260,7 @@ pub fn fexec_impl( let mut sp = STACK_TOP; let mut stack_page = Option::::None; - let mut push = |word: usize| { + let mut push = |word: usize| -> Result<()> { let old_page_no = sp / PAGE_SIZE; sp -= size_of::(); let new_page_no = sp / PAGE_SIZE; @@ -344,7 +344,7 @@ pub fn fexec_impl( let mut argc = 0; { - let mut append = |source_slice: &[u8]| { + let mut append = |source_slice: &[u8]| -> Result { // TODO let address = target_args_env_address + offset; @@ -717,7 +717,7 @@ impl FileBufReader { } impl FileBufReader { - fn read_le_u64(&mut self) -> syscall::Result> { + fn read_le_u64(&mut self) -> Result> { if self.pos >= self.cap { debug_assert!(self.pos == self.cap); self.cap = crate::sys::posix_read(self.fd, &mut self.buf)?; diff --git a/redox-rt/src/protocol.rs b/redox-rt/src/protocol.rs deleted file mode 100644 index e9f71c0301..0000000000 --- a/redox-rt/src/protocol.rs +++ /dev/null @@ -1,284 +0,0 @@ -use bitflags::bitflags; - -#[derive(Clone, Copy, Debug, Default)] -#[repr(C)] -pub struct ProcMeta { - pub pid: u32, - pub pgid: u32, - pub ppid: u32, - pub ruid: u32, - pub euid: u32, - pub suid: u32, - pub rgid: u32, - pub egid: u32, - pub sgid: u32, - pub ens: u32, - pub rns: u32, -} -unsafe impl plain::Plain for ProcMeta {} - -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -#[repr(usize)] -pub enum ProcCall { - Waitpid = 0, - Setrens = 1, - Exit = 2, - Waitpgid = 3, - SetResugid = 4, - Setpgid = 5, - Getsid = 6, - Setsid = 7, - Kill = 8, - Sigq = 9, - - // TODO: replace with sendfd equivalent syscall for sending memory - SyncSigPctl = 10, - Sigdeq = 11, - Getppid = 12, - Rename = 13, - DisableSetpgid = 14, - - // Temporary calls for getting process credentials - GetProcCredentials = 15, -} -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -#[repr(usize)] -pub enum ThreadCall { - // TODO: replace with sendfd equivalent syscall for sending memory, or force userspace to - // obtain its TCB memory from this server - SyncSigTctl = 0, - SignalThread = 1, -} - -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -#[repr(usize)] -#[non_exhaustive] -pub enum SocketCall { - Bind = 0, - Connect = 1, - SetSockOpt = 2, - GetSockOpt = 3, - SendMsg = 4, - RecvMsg = 5, - Unbind = 6, - GetToken = 7, - GetPeerName = 8, - Shutdown = 9, -} - -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -#[repr(usize)] -#[non_exhaustive] -pub enum FsCall { - Connect = 0, -} - -impl ProcCall { - pub fn try_from_raw(raw: usize) -> Option { - Some(match raw { - 0 => Self::Waitpid, - 1 => Self::Setrens, - 2 => Self::Exit, - 3 => Self::Waitpgid, - 4 => Self::SetResugid, - 5 => Self::Setpgid, - 6 => Self::Getsid, - 7 => Self::Setsid, - 8 => Self::Kill, - 9 => Self::Sigq, - 10 => Self::SyncSigPctl, - 11 => Self::Sigdeq, - 12 => Self::Getppid, - 13 => Self::Rename, - 14 => Self::DisableSetpgid, - 15 => Self::GetProcCredentials, - _ => return None, - }) - } -} -impl ThreadCall { - pub fn try_from_raw(raw: usize) -> Option { - Some(match raw { - 0 => Self::SyncSigTctl, - 1 => Self::SignalThread, - _ => return None, - }) - } -} - -impl SocketCall { - pub fn try_from_raw(raw: usize) -> Option { - Some(match raw { - 0 => Self::Bind, - 1 => Self::Connect, - 2 => Self::SetSockOpt, - 3 => Self::GetSockOpt, - 4 => Self::SendMsg, - 5 => Self::RecvMsg, - 6 => Self::Unbind, - 7 => Self::GetToken, - 8 => Self::GetPeerName, - 9 => Self::Shutdown, - _ => return None, - }) - } -} - -impl FsCall { - pub fn try_from_raw(raw: usize) -> Option { - Some(match raw { - 0 => Self::Connect, - _ => return None, - }) - } -} - -bitflags! { - #[derive(Clone, Copy, Debug, Default, Eq, Ord, Hash, PartialEq, PartialOrd)] - pub struct WaitFlags: usize { - const WNOHANG = 0x01; - const WUNTRACED = 0x02; - const WCONTINUED = 0x08; - } -} -/// True if status indicates the child is stopped. -pub fn wifstopped(status: usize) -> bool { - (status & 0xff) == 0x7f -} - -/// If wifstopped(status), the signal that stopped the child. -pub fn wstopsig(status: usize) -> usize { - (status >> 8) & 0xff -} - -/// True if status indicates the child continued after a stop. -pub fn wifcontinued(status: usize) -> bool { - status == 0xffff -} - -/// True if STATUS indicates termination by a signal. -pub fn wifsignaled(status: usize) -> bool { - ((status & 0x7f) + 1) as i8 >= 2 -} - -/// If wifsignaled(status), the terminating signal. -pub fn wtermsig(status: usize) -> usize { - status & 0x7f -} - -/// True if status indicates normal termination. -pub fn wifexited(status: usize) -> bool { - wtermsig(status) == 0 -} - -/// If wifexited(status), the exit status. -pub fn wexitstatus(status: usize) -> usize { - (status >> 8) & 0xff -} - -/// True if status indicates a core dump was created. -pub fn wcoredump(status: usize) -> bool { - (status & 0x80) != 0 -} -#[derive(Clone, Copy, Debug)] -pub enum ProcKillTarget { - ThisGroup, - SingleProc(usize), - ProcGroup(usize), - All, -} -impl ProcKillTarget { - pub fn raw(self) -> usize { - match self { - Self::ThisGroup => 0, - Self::SingleProc(p) => p, - Self::ProcGroup(g) => usize::wrapping_neg(g), - Self::All => usize::wrapping_neg(1), - } - } - pub fn from_raw(raw: usize) -> Self { - let raw = raw as isize; - if raw == 0 { - Self::ThisGroup - } else if raw == -1 { - Self::All - } else if raw < 0 { - Self::ProcGroup(raw.wrapping_neg() as usize) - } else { - Self::SingleProc(raw as usize) - } - } -} -#[derive(Copy, Clone, Debug, Default, PartialEq)] -#[repr(C)] -pub struct RtSigInfo { - pub arg: usize, - pub code: i32, - pub uid: u32, - pub pid: u32, // TODO: usize? -} -unsafe impl plain::Plain for RtSigInfo {} - -pub const SIGHUP: usize = 1; -pub const SIGINT: usize = 2; -pub const SIGQUIT: usize = 3; -pub const SIGILL: usize = 4; -pub const SIGTRAP: usize = 5; -pub const SIGABRT: usize = 6; -pub const SIGBUS: usize = 7; -pub const SIGFPE: usize = 8; -pub const SIGKILL: usize = 9; -pub const SIGUSR1: usize = 10; -pub const SIGSEGV: usize = 11; -pub const SIGUSR2: usize = 12; -pub const SIGPIPE: usize = 13; -pub const SIGALRM: usize = 14; -pub const SIGTERM: usize = 15; -pub const SIGSTKFLT: usize = 16; -pub const SIGCHLD: usize = syscall::SIGCHLD; -pub const SIGCONT: usize = 18; -pub const SIGSTOP: usize = 19; -pub const SIGTSTP: usize = syscall::SIGTSTP; -pub const SIGTTIN: usize = syscall::SIGTTIN; -pub const SIGTTOU: usize = syscall::SIGTTOU; -pub const SIGURG: usize = 23; -pub const SIGXCPU: usize = 24; -pub const SIGXFSZ: usize = 25; -pub const SIGVTALRM: usize = 26; -pub const SIGPROF: usize = 27; -pub const SIGWINCH: usize = 28; -pub const SIGIO: usize = 29; -pub const SIGPWR: usize = 30; -pub const SIGSYS: usize = 31; - -bitflags! { - #[derive(Clone, Copy, Debug, Default, Eq, Ord, Hash, PartialEq, PartialOrd)] - pub struct NsPermissions: usize { - /// List schemes in the namespace - const LIST = 1 << 0; - /// Register a new scheme in the namespace - const INSERT = 1 << 1; - /// Delete a scheme from the namespace - const DELETE = 1 << 2; - /// Get scheme creation capabilities of the namespace - const SCHEME_CREATE = 1 << 3; - } -} - -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -#[repr(usize)] -pub enum NsDup { - ForkNs = 0, - ShrinkPermissions = 1, - IssueRegister = 2, -} -impl NsDup { - pub fn try_from_raw(raw: usize) -> Option { - Some(match raw { - 0 => Self::ForkNs, - 1 => Self::ShrinkPermissions, - 2 => Self::IssueRegister, - _ => return None, - }) - } -} diff --git a/redox-rt/src/signal.rs b/redox-rt/src/signal.rs index cb8a8ed7f1..022f8737d1 100644 --- a/redox-rt/src/signal.rs +++ b/redox-rt/src/signal.rs @@ -8,16 +8,16 @@ use syscall::{ use crate::{ RtTcb, Tcb, arch::*, - current_proc_fd, - protocol::{ - ProcCall, RtSigInfo, SIGCHLD, SIGCONT, SIGKILL, SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGURG, - SIGWINCH, ThreadCall, - }, - static_proc_info, + current_proc_fd, static_proc_info, sync::Mutex, sys::{proc_call, this_thread_call}, }; +use redox_protocols::protocol::{ + ProcCall, RtSigInfo, SIGCHLD, SIGCONT, SIGKILL, SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGURG, + SIGWINCH, ThreadCall, +}; + #[cfg(target_arch = "x86_64")] static CPUID_EAX1_ECX: core::sync::atomic::AtomicU32 = core::sync::atomic::AtomicU32::new(0); diff --git a/redox-rt/src/sys.rs b/redox-rt/src/sys.rs index afb2ab9436..37dc909845 100644 --- a/redox-rt/src/sys.rs +++ b/redox-rt/src/sys.rs @@ -7,6 +7,7 @@ use core::{ use ioslice::IoSlice; use syscall::{ CallFlags, EINVAL, ERESTART, TimeSpec, + data::StdFsCallMeta, error::{self, EINTR, ENODEV, ESRCH, Error, Result}, }; @@ -14,11 +15,13 @@ use crate::{ DYNAMIC_PROC_INFO, DynamicProcInfo, RtTcb, Tcb, arch::manually_enter_trampoline, proc::{FdGuard, FdGuardUpper}, - protocol::{NsDup, ProcCall, ProcKillTarget, RtSigInfo, ThreadCall, WaitFlags}, read_proc_meta, signal::tmp_disable_signals, }; use alloc::vec::Vec; +use redox_protocols::protocol::{ + NsDup, ProcCall, ProcKillTarget, RtSigInfo, ThreadCall, WaitFlags, +}; #[inline] fn wrapper(restart: bool, erestart: bool, mut f: impl FnMut() -> Result) -> Result { @@ -385,7 +388,7 @@ pub fn getens() -> Result { read_proc_meta(crate::current_proc_fd()).map(|meta| meta.ens as usize) } pub fn get_proc_credentials(cap_fd: usize, target_pid: usize, buf: &mut [u8]) -> Result { - if buf.len() < size_of::() { + if buf.len() < size_of::() { return Err(Error::new(EINVAL)); } proc_call( @@ -515,3 +518,12 @@ pub fn register_scheme_to_ns(ns_fd: usize, name: &str, cap_fd: usize) -> Result< ns_this_scheme.call_wo(&cap_bytes, CallFlags::FD, &[])?; Ok(()) } +pub fn std_fs_call_ro(fd: usize, payload: &mut [u8], metadata: &StdFsCallMeta) -> Result { + sys_call_ro(fd, payload, CallFlags::STD_FS, metadata) +} +pub fn std_fs_call_wo(fd: usize, payload: &[u8], metadata: &StdFsCallMeta) -> Result { + sys_call_wo(fd, payload, CallFlags::STD_FS, metadata) +} +pub fn std_fs_call_rw(fd: usize, payload: &mut [u8], metadata: &StdFsCallMeta) -> Result { + sys_call_rw(fd, payload, CallFlags::STD_FS, metadata) +} diff --git a/src/platform/mod.rs b/src/platform/mod.rs index e39432938d..c9a26beda9 100644 --- a/src/platform/mod.rs +++ b/src/platform/mod.rs @@ -359,7 +359,7 @@ pub unsafe fn init_inner(auxvs: Box<[[usize; 2]]>) { redox_rt::sys::this_proc_call( &mut [], syscall::CallFlags::empty(), - &[redox_rt::protocol::ProcCall::SyncSigPctl as u64], + &[redox_protocols::protocol::ProcCall::SyncSigPctl as u64], ) .expect("failed to sync signal pctl"); diff --git a/src/platform/redox/libredox.rs b/src/platform/redox/libredox.rs index 0ee415708e..b83f6cefba 100644 --- a/src/platform/redox/libredox.rs +++ b/src/platform/redox/libredox.rs @@ -2,10 +2,8 @@ use core::{slice, str}; use alloc::vec::Vec; use ioslice::IoSlice; -use redox_rt::{ - protocol::{ProcKillTarget, SocketCall, WaitFlags}, - sys::{WaitpidTarget, posix_read, posix_write}, -}; +use redox_protocols::protocol::{ProcKillTarget, SocketCall, WaitFlags}; +use redox_rt::sys::{WaitpidTarget, posix_read, posix_write}; use syscall::{EMFILE, Error, Result}; use crate::{ @@ -13,7 +11,7 @@ use crate::{ bits_time::timespec, errno::EINVAL, signal::sigaction, sys_stat::UTIME_NOW, sys_uio::iovec, }, out::Out, - platform::{PalSignal, types::*}, + platform::{PalSignal, pal::Pal, types::*}, }; use super::Sys; @@ -34,7 +32,7 @@ pub fn open(path: &str, oflag: c_int, mode: mode_t) -> Result { .map(|f| f as usize) } -pub unsafe fn fstat(fd: usize, buf: *mut crate::header::sys_stat::stat) -> syscall::Result<()> { +pub unsafe fn fstat(fd: usize, buf: *mut crate::header::sys_stat::stat) -> Result<()> { let mut redox_buf: syscall::Stat = Default::default(); syscall::fstat(fd, &mut redox_buf)?; @@ -109,7 +107,156 @@ pub unsafe fn futimens(fd: usize, times: *const timespec) -> syscall::Result<()> syscall::futimens(fd as usize, ×)?; Ok(()) } -pub fn clock_gettime(clock: usize, mut tp: Out) -> syscall::Result<()> { +/* std_fs_call +pub fn std_fs_call_getdents(fd: usize, buf: &mut [u8], opaque: u64) -> Result { + //println!("GETDENTS {} into ({:p}+{})", fd, buf.as_ptr(), buf.len()); + + const HEADER_SIZE: usize = mem::size_of::(); + + // Use syscall if it exists. + match std_fs_call_ro( + fd, + buf, + &StdFsCallMeta::new(StdFsCallKind::Getdents, opaque, HEADER_SIZE as u64), + ) { + Err(Error { + errno: EOPNOTSUPP | ENOSYS, + }) => (), + other => { + //println!("REAL GETDENTS {:?}", other); + return Ok(other?); + } + } + + // Otherwise, for legacy schemes, assume the buffer is pre-arranged (all schemes do this in + // practice), and just read the name. If multiple names appear, pretend it didn't happen + // and just use the first entry. + + let (header, name) = buf.split_at_mut(mem::size_of::()); + + let bytes_read = Sys::pread(fd as c_int, name, opaque as i64)? as usize; + if bytes_read == 0 { + return Ok(0); + } + + let (name_len, advance) = match name[..bytes_read].iter().position(|c| *c == b'\n') { + Some(idx) => (idx, idx + 1), + + // Insufficient space for NUL byte, or entire entry was not read. Indicate we need a + // larger buffer. + None if bytes_read == name.len() => return Err(Error::new(EINVAL)), + + None => (bytes_read, name.len()), + }; + name[name_len] = b'\0'; + + let record_len = u16::try_from(mem::size_of::() + name_len + 1) + .map_err(|_| Error::new(ENAMETOOLONG))?; + header.copy_from_slice(&DirentHeader { + inode: 0, + next_opaque_id: opaque + advance as u64, + record_len, + kind: DirentKind::Unspecified as u8, + }); + //println!("EMULATED GETDENTS"); + + Ok(record_len.into()) +} +pub unsafe fn std_fs_call_fstat(fd: usize, buf: *mut crate::header::sys_stat::stat) -> Result<()> { + let mut redox_buf: syscall::Stat = Default::default(); + std_fs_call_ro( + fd, + &mut redox_buf, + &StdFsCallMeta::new(StdFsCallKind::Fstat, 0, 0), + )?; + + if let Some(buf) = unsafe { buf.as_mut() } { + buf.st_dev = redox_buf.st_dev as dev_t; + buf.st_ino = redox_buf.st_ino as ino_t; + buf.st_nlink = redox_buf.st_nlink as nlink_t; + buf.st_mode = redox_buf.st_mode as mode_t; + buf.st_uid = redox_buf.st_uid as uid_t; + buf.st_gid = redox_buf.st_gid as gid_t; + // TODO st_rdev + buf.st_rdev = 0; + buf.st_size = redox_buf.st_size as off_t; + buf.st_blksize = redox_buf.st_blksize as blksize_t; + buf.st_blocks = redox_buf.st_blocks as blkcnt_t; + buf.st_atim = timespec { + tv_sec: redox_buf.st_atime as time_t, + tv_nsec: redox_buf.st_atime_nsec as c_long, + }; + buf.st_mtim = timespec { + tv_sec: redox_buf.st_mtime as time_t, + tv_nsec: redox_buf.st_mtime_nsec as c_long, + }; + buf.st_ctim = timespec { + tv_sec: redox_buf.st_ctime as time_t, + tv_nsec: redox_buf.st_ctime_nsec as c_long, + }; + } + Ok(()) +} +pub unsafe fn std_fs_call_fstatvfs( + fd: usize, + buf: *mut crate::header::sys_statvfs::statvfs, +) -> Result<()> { + let mut kbuf: syscall::StatVfs = Default::default(); + std_fs_call_ro( + fd, + &mut kbuf, + &StdFsCallMeta::new(StdFsCallKind::Fstatvfs, 0, 0), + )?; + + if !buf.is_null() { + unsafe { + (*buf).f_bsize = kbuf.f_bsize as c_ulong; + (*buf).f_frsize = kbuf.f_bsize as c_ulong; + (*buf).f_blocks = kbuf.f_blocks as c_ulong; + (*buf).f_bfree = kbuf.f_bfree as c_ulong; + (*buf).f_bavail = kbuf.f_bavail as c_ulong; + //TODO + (*buf).f_files = 0; + (*buf).f_ffree = 0; + (*buf).f_favail = 0; + (*buf).f_fsid = 0; + (*buf).f_flag = 0; + (*buf).f_namemax = 0; + } + } + Ok(()) +} +pub unsafe fn std_fs_call_futimens(fd: usize, times: *const timespec) -> Result<()> { + let times = if times.is_null() { + // null means set to current time using special UTIME_NOW value (tv_sec is ignored in that case) + [ + syscall::TimeSpec { + tv_sec: 0, + tv_nsec: UTIME_NOW as c_int, + }, + syscall::TimeSpec { + tv_sec: 0, + tv_nsec: UTIME_NOW as c_int, + }, + ] + } else { + unsafe { times.cast::<[timespec; 2]>().read() }.map(|ts| syscall::TimeSpec::from(&ts)) + }; + let redox_buf = unsafe { + slice::from_raw_parts( + times.as_ptr() as *const u8, + times.len() * mem::size_of::(), + ) + }; + std_fs_call_wo( + fd, + redox_buf, + &StdFsCallMeta::new(StdFsCallKind::Futimens, 0, 0), + )?; + Ok(()) +} +*/ +pub fn clock_gettime(clock: usize, mut tp: Out) -> Result<()> { let mut redox_tp = syscall::TimeSpec::default(); syscall::clock_gettime(clock as usize, &mut redox_tp)?; tp.write(timespec { @@ -181,27 +328,46 @@ pub unsafe extern "C" fn redox_write_v1( })) } #[unsafe(no_mangle)] -pub unsafe extern "C" fn redox_fsync_v1(fd: usize) -> RawResult { - Error::mux(syscall::fsync(fd)) -} -#[unsafe(no_mangle)] -pub unsafe extern "C" fn redox_fdatasync_v1(fd: usize) -> RawResult { - // TODO - Error::mux(syscall::fsync(fd)) -} -#[unsafe(no_mangle)] pub unsafe extern "C" fn redox_fchmod_v1(fd: usize, new_mode: u16) -> RawResult { + /* std_fs_call + Error::mux(std_fs_call_wo( + fd, + &[], + &StdFsCallMeta::new(StdFsCallKind::Fchmod, new_mode as u64, 0), + )) + */ Error::mux(syscall::fchmod(fd, new_mode)) } #[unsafe(no_mangle)] pub unsafe extern "C" fn redox_fchown_v1(fd: usize, new_uid: u32, new_gid: u32) -> RawResult { + /* std_fs_call + Error::mux(std_fs_call_wo( + fd, + &[], + &StdFsCallMeta::new( + StdFsCallKind::Fchmod, + (new_uid as u64) | ((new_gid as u64) << 32), + 0, + ), + )) + */ Error::mux(syscall::fchown(fd, new_uid, new_gid)) } #[unsafe(no_mangle)] -pub unsafe extern "C" fn redox_fpath_v1(fd: usize, dst_base: *mut u8, dst_len: usize) -> RawResult { - Error::mux(syscall::fpath(fd, unsafe { - core::slice::from_raw_parts_mut(dst_base, dst_len) - })) +pub unsafe extern "C" fn redox_getdents_v0( + fd: usize, + buf: *mut u8, + buf_len: usize, + opaque: u64, +) -> RawResult { + Error::mux( + Sys::getdents( + fd as c_int, + unsafe { slice::from_raw_parts_mut(buf, buf_len) }, + opaque, + ) + .map_err(Into::into), + ) } #[unsafe(no_mangle)] pub unsafe extern "C" fn redox_fstat_v1( @@ -218,9 +384,64 @@ pub unsafe extern "C" fn redox_fstatvfs_v1( Error::mux(unsafe { fstatvfs(fd, stat) }.map(|()| 0)) } #[unsafe(no_mangle)] +pub unsafe extern "C" fn redox_fsync_v1(fd: usize) -> RawResult { + /* std_fs_call + Error::mux(std_fs_call_wo( + fd, + &[], + &StdFsCallMeta::new(StdFsCallKind::Fsync, 0, 0), + )) + */ + Error::mux(syscall::fsync(fd)) +} +#[unsafe(no_mangle)] +pub unsafe extern "C" fn redox_fdatasync_v1(fd: usize) -> RawResult { + /* std_fs_call + Error::mux(std_fs_call_wo( + fd, + &[], + &StdFsCallMeta::new(StdFsCallKind::Fsync, 0, 0), + )) + */ + // TODO + Error::mux(syscall::fsync(fd)) +} +#[unsafe(no_mangle)] +pub unsafe extern "C" fn redox_ftruncate_v0(fd: usize, len: usize) -> RawResult { + /* std_fs_call + Error::mux(std_fs_call_wo( + fd, + &[], + &StdFsCallMeta::new(StdFsCallKind::Ftruncate, len as u64, 0), + )) + */ + Error::mux(syscall::ftruncate(fd as usize, len as usize)) +} +#[unsafe(no_mangle)] pub unsafe extern "C" fn redox_futimens_v1(fd: usize, times: *const timespec) -> RawResult { Error::mux(unsafe { futimens(fd, times) }.map(|()| 0)) } +/* TODO: Support unlinkat +#[unsafe(no_mangle)] +pub unsafe extern "C" fn redox_unlinkat_v0( + fd: usize, + path_base: *const u8, + path_len: usize, + flags: u32, +) -> RawResult { + Error::mux(std_fs_call_wo( + fd, + unsafe { slice::from_raw_parts(path_base, path_len) }, + &StdFsCallMeta::new(StdFsCallKind::Unlinkat, flags as u64, 0), + )) +} +*/ +#[unsafe(no_mangle)] +pub unsafe extern "C" fn redox_fpath_v1(fd: usize, dst_base: *mut u8, dst_len: usize) -> RawResult { + Error::mux(syscall::fpath(fd, unsafe { + core::slice::from_raw_parts_mut(dst_base, dst_len) + })) +} #[unsafe(no_mangle)] pub unsafe extern "C" fn redox_close_v1(fd: usize) -> RawResult { Error::mux(syscall::close(fd)) diff --git a/src/platform/redox/mod.rs b/src/platform/redox/mod.rs index 88cb901bec..494b2c9f2b 100644 --- a/src/platform/redox/mod.rs +++ b/src/platform/redox/mod.rs @@ -5,9 +5,9 @@ use core::{ ptr, slice, str, }; use object::bytes_of_slice_mut; +use redox_protocols::protocol::{WaitFlags, wifstopped}; use redox_rt::{ RtTcb, - protocol::{WaitFlags, wifstopped}, sys::{Resugid, WaitpidTarget}, }; use syscall::{ diff --git a/src/platform/redox/signal.rs b/src/platform/redox/signal.rs index f3c755e538..ed21900a8c 100644 --- a/src/platform/redox/signal.rs +++ b/src/platform/redox/signal.rs @@ -15,11 +15,9 @@ use crate::{ }, }; use core::mem::offset_of; -use redox_rt::{ - protocol::ProcKillTarget, - signal::{ - PosixStackt, SigStack, Sigaction, SigactionFlags, SigactionKind, Sigaltstack, SignalHandler, - }, +use redox_protocols::protocol::ProcKillTarget; +use redox_rt::signal::{ + PosixStackt, SigStack, Sigaction, SigactionFlags, SigactionKind, Sigaltstack, SignalHandler, }; const _: () = { diff --git a/src/platform/redox/socket.rs b/src/platform/redox/socket.rs index 2f5b2231c8..166d0251cc 100644 --- a/src/platform/redox/socket.rs +++ b/src/platform/redox/socket.rs @@ -1,9 +1,7 @@ use alloc::vec::Vec; use core::{cmp, mem, ptr, slice, str}; -use redox_rt::{ - proc::FdGuard, - protocol::{FsCall, SocketCall}, -}; +use redox_protocols::protocol::{FsCall, SocketCall}; +use redox_rt::proc::FdGuard; use syscall::{self, flag::*}; use super::{