diff --git a/Cargo.toml b/Cargo.toml index 2772ba6..c88a5da 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "redox_syscall" -version = "0.1.21" +version = "0.1.22" description = "A Rust library to access raw Redox system calls" license = "MIT" authors = ["Jeremy Soller "] diff --git a/src/call.rs b/src/call.rs index 7ce3349..4e42593 100644 --- a/src/call.rs +++ b/src/call.rs @@ -121,6 +121,11 @@ pub fn ftruncate(fd: usize, len: usize) -> Result { unsafe { syscall2(SYS_FTRUNCATE, fd, len) } } +// Change modify and/or access times +pub fn futimens(fd: usize, times: &[TimeSpec]) -> Result { + unsafe { syscall3(SYS_FUTIMENS, fd, times.as_ptr() as usize, times.len() * mem::size_of::()) } +} + /// Fast userspace mutex - TODO: Document pub unsafe fn futex(addr: *mut i32, op: usize, val: i32, val2: usize, addr2: *mut i32) -> Result { syscall5(SYS_FUTEX, addr as usize, op, (val as isize) as usize, val2, addr2 as usize) diff --git a/src/number.rs b/src/number.rs index 5d656dc..507433a 100644 --- a/src/number.rs +++ b/src/number.rs @@ -31,6 +31,7 @@ pub const SYS_FSTAT: usize = SYS_CLASS_FILE | SYS_ARG_MSLICE | 28; pub const SYS_FSTATVFS: usize = SYS_CLASS_FILE | SYS_ARG_MSLICE | 100; pub const SYS_FSYNC: usize = SYS_CLASS_FILE | 118; pub const SYS_FTRUNCATE: usize =SYS_CLASS_FILE | 93; +pub const SYS_FUTIMENS: usize = SYS_CLASS_FILE | SYS_ARG_SLICE | 320; pub const SYS_BRK: usize = 45; pub const SYS_CHDIR: usize = 12; diff --git a/src/scheme.rs b/src/scheme.rs index d322f0b..d58bd29 100644 --- a/src/scheme.rs +++ b/src/scheme.rs @@ -18,12 +18,24 @@ pub trait Scheme { SYS_FEVENT => self.fevent(packet.b, packet.c), SYS_FMAP => self.fmap(packet.b, packet.c, packet.d), SYS_FPATH => self.fpath(packet.b, unsafe { slice::from_raw_parts_mut(packet.c as *mut u8, packet.d) }), - SYS_FSTAT => if packet.d >= mem::size_of::() { self.fstat(packet.b, unsafe { &mut *(packet.c as *mut Stat) }) } else { Err(Error::new(EFAULT)) }, - SYS_FSTATVFS => if packet.d >= mem::size_of::() { self.fstatvfs(packet.b, unsafe { &mut *(packet.c as *mut StatVfs) }) } else { Err(Error::new(EFAULT)) }, + SYS_FSTAT => if packet.d >= mem::size_of::() { + self.fstat(packet.b, unsafe { &mut *(packet.c as *mut Stat) }) + } else { + Err(Error::new(EFAULT)) + }, + SYS_FSTATVFS => if packet.d >= mem::size_of::() { + self.fstatvfs(packet.b, unsafe { &mut *(packet.c as *mut StatVfs) }) + } else { + Err(Error::new(EFAULT)) + }, SYS_FSYNC => self.fsync(packet.b), SYS_FTRUNCATE => self.ftruncate(packet.b, packet.c), + SYS_FUTIMENS => if packet.d >= mem::size_of::() { + self.futimens(packet.b, unsafe { slice::from_raw_parts(packet.c as *const TimeSpec, packet.d / mem::size_of::()) }) + } else { + Err(Error::new(EFAULT)) + }, SYS_CLOSE => self.close(packet.b), - _ => Err(Error::new(ENOSYS)) }); } @@ -111,6 +123,11 @@ pub trait Scheme { Err(Error::new(EBADF)) } + #[allow(unused_variables)] + fn futimens(&self, id: usize, times: &[TimeSpec]) -> Result { + Err(Error::new(EBADF)) + } + #[allow(unused_variables)] fn close(&self, id: usize) -> Result { Err(Error::new(EBADF)) @@ -133,12 +150,24 @@ pub trait SchemeMut { SYS_FEVENT => self.fevent(packet.b, packet.c), SYS_FMAP => self.fmap(packet.b, packet.c, packet.d), SYS_FPATH => self.fpath(packet.b, unsafe { slice::from_raw_parts_mut(packet.c as *mut u8, packet.d) }), - SYS_FSTAT => if packet.d >= mem::size_of::() { self.fstat(packet.b, unsafe { &mut *(packet.c as *mut Stat) }) } else { Err(Error::new(EFAULT)) }, - SYS_FSTATVFS => if packet.d >= mem::size_of::() { self.fstatvfs(packet.b, unsafe { &mut *(packet.c as *mut StatVfs) }) } else { Err(Error::new(EFAULT)) }, + SYS_FSTAT => if packet.d >= mem::size_of::() { + self.fstat(packet.b, unsafe { &mut *(packet.c as *mut Stat) }) + } else { + Err(Error::new(EFAULT)) + }, + SYS_FSTATVFS => if packet.d >= mem::size_of::() { + self.fstatvfs(packet.b, unsafe { &mut *(packet.c as *mut StatVfs) }) + } else { + Err(Error::new(EFAULT)) + }, SYS_FSYNC => self.fsync(packet.b), SYS_FTRUNCATE => self.ftruncate(packet.b, packet.c), + SYS_FUTIMENS => if packet.d >= mem::size_of::() { + self.futimens(packet.b, unsafe { slice::from_raw_parts(packet.c as *const TimeSpec, packet.d / mem::size_of::()) }) + } else { + Err(Error::new(EFAULT)) + }, SYS_CLOSE => self.close(packet.b), - _ => Err(Error::new(ENOSYS)) }); } @@ -150,7 +179,7 @@ pub trait SchemeMut { } #[allow(unused_variables)] - fn chmod(&self, path: &[u8], mode: u16, uid: u32, gid: u32) -> Result { + fn chmod(&mut self, path: &[u8], mode: u16, uid: u32, gid: u32) -> Result { Err(Error::new(ENOENT)) } @@ -225,6 +254,11 @@ pub trait SchemeMut { Err(Error::new(EBADF)) } + #[allow(unused_variables)] + fn futimens(&mut self, id: usize, times: &[TimeSpec]) -> Result { + Err(Error::new(EBADF)) + } + #[allow(unused_variables)] fn close(&mut self, id: usize) -> Result { Err(Error::new(EBADF))