diff --git a/src/scheme/acpi.rs b/src/scheme/acpi.rs index 9ab6de1..9fe6020 100644 --- a/src/scheme/acpi.rs +++ b/src/scheme/acpi.rs @@ -9,9 +9,9 @@ use alloc::vec::Vec; use syscall::data::Stat; use syscall::error::{EACCES, EBADF, EBADFD, EINVAL, EIO, EISDIR, ENOENT, ENOTDIR}; use syscall::flag::{O_ACCMODE, O_DIRECTORY, O_RDWR, O_STAT, O_WRONLY}; -use syscall::scheme::Scheme; +use syscall::scheme::{calc_seek_offset_usize, Scheme}; use syscall::{Error, Result}; -use syscall::{MODE_DIR, MODE_FILE, SEEK_CUR, SEEK_END, SEEK_SET}; +use syscall::{MODE_DIR, MODE_FILE}; use spin::{Mutex, RwLock}; @@ -336,13 +336,13 @@ impl Scheme for AcpiScheme { } Ok(0) } - fn seek(&self, id: usize, pos: usize, whence: usize) -> Result { + fn seek(&self, id: usize, pos: isize, whence: usize) -> Result { let handles_guard = self.handles.read(); let mut handle = handles_guard.get(&id).ok_or(Error::new(EBADF))?.lock(); let (cur_offset, length) = match &*handle { &Handle::TopLevel(offset) => (offset, TOPLEVEL_DIR_CONTENTS.len()), - &Handle::Tables(offset) => (offset, self.tables.len() * 35), + &Handle::Tables(offset) => (offset, (self.tables.len() * 35)), &Handle::Table { name, oem_id, @@ -355,16 +355,11 @@ impl Scheme for AcpiScheme { .len, ), }; - let new_offset = match whence { - SEEK_CUR => core::cmp::min(cur_offset + pos, length), - SEEK_END => core::cmp::min(length + pos, length), - SEEK_SET => core::cmp::min(length, pos), - _ => return Err(Error::new(EINVAL)), - }; + let new_offset = calc_seek_offset_usize(cur_offset, pos, whence, length)?; match &mut *handle { &mut Handle::Table { ref mut offset, .. } | &mut Handle::Tables(ref mut offset) - | &mut Handle::TopLevel(ref mut offset) => *offset = new_offset, + | &mut Handle::TopLevel(ref mut offset) => *offset = new_offset as usize, } Ok(new_offset) } diff --git a/src/scheme/initfs.rs b/src/scheme/initfs.rs index 5af8b3b..d5d6447 100644 --- a/src/scheme/initfs.rs +++ b/src/scheme/initfs.rs @@ -1,12 +1,12 @@ use alloc::collections::BTreeMap; -use core::{cmp, str}; +use core::str; use core::sync::atomic::{AtomicUsize, Ordering}; use spin::RwLock; use crate::syscall::data::Stat; use crate::syscall::error::*; -use crate::syscall::flag::{MODE_DIR, MODE_FILE, SEEK_SET, SEEK_CUR, SEEK_END}; -use crate::syscall::scheme::Scheme; +use crate::syscall::flag::{MODE_DIR, MODE_FILE}; +use crate::syscall::scheme::{calc_seek_offset_usize, Scheme}; #[cfg(test)] mod gen { @@ -77,18 +77,12 @@ impl Scheme for InitFsScheme { Ok(i) } - fn seek(&self, id: usize, pos: usize, whence: usize) -> Result { + fn seek(&self, id: usize, pos: isize, whence: usize) -> Result { let mut handles = self.handles.write(); let handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?; - - handle.seek = match whence { - SEEK_SET => cmp::min(handle.data.len(), pos), - SEEK_CUR => cmp::max(0, cmp::min(handle.data.len() as isize, handle.seek as isize + pos as isize)) as usize, - SEEK_END => cmp::max(0, cmp::min(handle.data.len() as isize, handle.data.len() as isize + pos as isize)) as usize, - _ => return Err(Error::new(EINVAL)) - }; - - Ok(handle.seek) + let new_offset = calc_seek_offset_usize(handle.seek, pos, whence, handle.data.len())?; + handle.seek = new_offset as usize; + Ok(new_offset) } fn fcntl(&self, id: usize, _cmd: usize, _arg: usize) -> Result { diff --git a/src/scheme/irq.rs b/src/scheme/irq.rs index 66e0ee0..d5938d0 100644 --- a/src/scheme/irq.rs +++ b/src/scheme/irq.rs @@ -14,8 +14,8 @@ use crate::event; use crate::interrupt::irq::acknowledge; use crate::scheme::{AtomicSchemeId, SchemeId}; use crate::syscall::error::*; -use crate::syscall::flag::{EventFlags, EVENT_READ, O_DIRECTORY, O_CREAT, O_STAT, MODE_CHR, MODE_DIR, SEEK_CUR, SEEK_END, SEEK_SET}; -use crate::syscall::scheme::Scheme; +use crate::syscall::flag::{EventFlags, EVENT_READ, O_DIRECTORY, O_CREAT, O_STAT, MODE_CHR, MODE_DIR}; +use crate::syscall::scheme::{calc_seek_offset_usize, Scheme}; pub static IRQ_SCHEME_ID: AtomicSchemeId = AtomicSchemeId::default(); @@ -252,20 +252,15 @@ impl Scheme for IrqScheme { } } - fn seek(&self, id: usize, pos: usize, whence: usize) -> Result { + fn seek(&self, id: usize, pos: isize, whence: usize) -> Result { let handles_guard = HANDLES.read(); let handle = handles_guard.as_ref().unwrap().get(&id).ok_or(Error::new(EBADF))?; match handle { &Handle::Avail(_, ref buf, ref offset) | &Handle::TopLevel(ref buf, ref offset) => { let cur_offset = offset.load(Ordering::SeqCst); - let new_offset = match whence { - SEEK_CUR => core::cmp::min(cur_offset + pos, buf.len()), - SEEK_END => core::cmp::min(buf.len() + pos, buf.len()), - SEEK_SET => core::cmp::min(buf.len(), pos), - _ => return Err(Error::new(EINVAL)), - }; - offset.store(new_offset, Ordering::SeqCst); + let new_offset = calc_seek_offset_usize(cur_offset, pos, whence, buf.len())?; + offset.store(new_offset as usize, Ordering::SeqCst); Ok(new_offset) } _ => return Err(Error::new(ESPIPE)), diff --git a/src/scheme/pipe.rs b/src/scheme/pipe.rs index 46dd2ac..f2c1b46 100644 --- a/src/scheme/pipe.rs +++ b/src/scheme/pipe.rs @@ -142,7 +142,7 @@ impl Scheme for PipeScheme { Ok(0) } - fn seek(&self, _id: usize, _pos: usize, _whence: usize) -> Result { + fn seek(&self, _id: usize, _pos: isize, _whence: usize) -> Result { Err(Error::new(ESPIPE)) } } diff --git a/src/scheme/proc.rs b/src/scheme/proc.rs index d5a95b9..c45c345 100644 --- a/src/scheme/proc.rs +++ b/src/scheme/proc.rs @@ -7,7 +7,7 @@ use crate::{ data::{FloatRegisters, IntRegisters, PtraceEvent, Stat}, error::*, flag::*, - scheme::Scheme, + scheme::{calc_seek_offset_usize, Scheme}, self, validate, }, @@ -319,18 +319,13 @@ impl Scheme for ProcScheme { self.open(&path, info.flags, uid, gid) } - fn seek(&self, id: usize, pos: usize, whence: usize) -> Result { + fn seek(&self, id: usize, pos: isize, whence: usize) -> Result { let mut handles = self.handles.write(); let handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?; let mut memory = handle.data.mem_data().ok_or(Error::new(EBADF))?; - let value = match whence { - SEEK_SET => pos, - SEEK_CUR => cmp::max(0, memory.offset.get() as isize + pos as isize) as usize, - SEEK_END => cmp::max(0, isize::max_value() + pos as isize) as usize, - _ => return Err(Error::new(EBADF)) - }; - memory.offset = VirtualAddress::new(value); + let value = calc_seek_offset_usize(memory.offset.get(), pos, whence, isize::max_value() as usize)?; + memory.offset = VirtualAddress::new(value as usize); Ok(value) } diff --git a/src/scheme/root.rs b/src/scheme/root.rs index dfaf486..ca5e789 100644 --- a/src/scheme/root.rs +++ b/src/scheme/root.rs @@ -2,15 +2,15 @@ use alloc::sync::Arc; use alloc::boxed::Box; use alloc::collections::BTreeMap; use alloc::vec::Vec; -use core::{cmp, str}; +use core::str; use core::sync::atomic::{AtomicUsize, Ordering}; use spin::{Mutex, RwLock}; use crate::context; use crate::syscall::data::Stat; use crate::syscall::error::*; -use crate::syscall::flag::{EventFlags, O_CREAT, MODE_FILE, MODE_DIR, SEEK_SET, SEEK_CUR, SEEK_END}; -use crate::syscall::scheme::Scheme; +use crate::syscall::flag::{EventFlags, O_CREAT, MODE_FILE, MODE_DIR}; +use crate::syscall::scheme::{calc_seek_offset_usize, Scheme}; use crate::scheme::{self, SchemeNamespace, SchemeId}; use crate::scheme::user::{UserInner, UserScheme}; @@ -33,16 +33,11 @@ impl FolderInner { Ok(i) } - fn seek(&self, pos: usize, whence: usize) -> Result { + fn seek(&self, pos: isize, whence: usize) -> Result { let mut seek = self.pos.lock(); - *seek = match whence { - SEEK_SET => cmp::min(self.data.len(), pos), - SEEK_CUR => cmp::max(0, cmp::min(self.data.len() as isize, *seek as isize + pos as isize)) as usize, - SEEK_END => cmp::max(0, cmp::min(self.data.len() as isize, self.data.len() as isize + pos as isize)) as usize, - _ => return Err(Error::new(EINVAL)) - }; - - Ok(*seek) + let new_offset = calc_seek_offset_usize(*seek, pos, whence, self.data.len())?; + *seek = new_offset as usize; + Ok(new_offset) } } @@ -206,7 +201,7 @@ impl Scheme for RootScheme { } } - fn seek(&self, file: usize, pos: usize, whence: usize) -> Result { + fn seek(&self, file: usize, pos: isize, whence: usize) -> Result { let handle = { let handles = self.handles.read(); let handle = handles.get(&file).ok_or(Error::new(EBADF))?; diff --git a/src/scheme/sys/mod.rs b/src/scheme/sys/mod.rs index 8b65632..f0a03d0 100644 --- a/src/scheme/sys/mod.rs +++ b/src/scheme/sys/mod.rs @@ -1,14 +1,14 @@ use alloc::boxed::Box; use alloc::collections::BTreeMap; use alloc::vec::Vec; -use core::{cmp, str}; +use core::str; use core::sync::atomic::{AtomicUsize, Ordering}; use spin::RwLock; use crate::syscall::data::Stat; -use crate::syscall::error::{Error, EBADF, EINVAL, ENOENT, Result}; -use crate::syscall::flag::{MODE_DIR, MODE_FILE, SEEK_CUR, SEEK_END, SEEK_SET}; -use crate::syscall::scheme::Scheme; +use crate::syscall::error::{Error, EBADF, ENOENT, Result}; +use crate::syscall::flag::{MODE_DIR, MODE_FILE}; +use crate::syscall::scheme::{calc_seek_offset_usize, Scheme}; use crate::arch::interrupt::irq; mod block; @@ -118,18 +118,13 @@ impl Scheme for SysScheme { Ok(i) } - fn seek(&self, id: usize, pos: usize, whence: usize) -> Result { + fn seek(&self, id: usize, pos: isize, whence: usize) -> Result { let mut handles = self.handles.write(); let handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?; - handle.seek = match whence { - SEEK_SET => cmp::min(handle.data.len(), pos), - SEEK_CUR => cmp::max(0, cmp::min(handle.data.len() as isize, handle.seek as isize + pos as isize)) as usize, - SEEK_END => cmp::max(0, cmp::min(handle.data.len() as isize, handle.data.len() as isize + pos as isize)) as usize, - _ => return Err(Error::new(EINVAL)) - }; - - Ok(handle.seek) + let new_offset = calc_seek_offset_usize(handle.seek, pos, whence, handle.data.len())?; + handle.seek = new_offset as usize; + Ok(new_offset) } fn fpath(&self, id: usize, buf: &mut [u8]) -> Result { diff --git a/src/scheme/user.rs b/src/scheme/user.rs index 24278f5..1c083bc 100644 --- a/src/scheme/user.rs +++ b/src/scheme/user.rs @@ -3,6 +3,7 @@ use alloc::boxed::Box; use alloc::collections::BTreeMap; use core::sync::atomic::{AtomicBool, AtomicU64, Ordering}; use core::{mem, slice, usize}; +use core::convert::TryFrom; use spin::{Mutex, RwLock}; use crate::context::{self, Context}; @@ -334,9 +335,10 @@ impl Scheme for UserScheme { result } - fn seek(&self, file: usize, position: usize, whence: usize) -> Result { + fn seek(&self, file: usize, position: isize, whence: usize) -> Result { let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?; - inner.call(SYS_LSEEK, file, position, whence) + let new_offset = inner.call(SYS_LSEEK, file, position as usize, whence)?; + isize::try_from(new_offset).or_else(|_| Err(Error::new(EOVERFLOW))) } fn fchmod(&self, file: usize, mode: u16) -> Result { diff --git a/syscall b/syscall index 7552c31..fcebe8f 160000 --- a/syscall +++ b/syscall @@ -1 +1 @@ -Subproject commit 7552c31f50608cdd90cffe300400fa062fd3f22b +Subproject commit fcebe8f225142830fa5880a27d9faa6ed6b2aeb8