From 4e146ec491a6dbcf7b89b7a6c8d3003722281be3 Mon Sep 17 00:00:00 2001 From: WangRunji Date: Tue, 26 Feb 2019 17:01:38 +0800 Subject: [PATCH] impl sys_lseek --- kernel/src/fs/file.rs | 28 ++++++++++++++++++++++------ kernel/src/syscall/fs.rs | 21 ++++++++++++++++++++- kernel/src/syscall/mod.rs | 2 +- 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/kernel/src/fs/file.rs b/kernel/src/fs/file.rs index 6a0cb246..6efa7c3c 100644 --- a/kernel/src/fs/file.rs +++ b/kernel/src/fs/file.rs @@ -7,7 +7,7 @@ use rcore_fs::vfs::{Metadata, INode, Result, FsError}; #[derive(Clone)] pub struct FileHandle { inode: Arc, - offset: usize, + offset: u64, options: OpenOptions, } @@ -19,6 +19,13 @@ pub struct OpenOptions { pub append: bool, } +#[derive(Debug)] +pub enum SeekFrom { + Start(u64), + End(i64), + Current(i64), +} + impl FileHandle { pub fn new(inode: Arc, options: OpenOptions) -> Self { FileHandle { @@ -32,8 +39,8 @@ impl FileHandle { if !self.options.read { return Err(FsError::InvalidParam); // FIXME: => EBADF } - let len = self.inode.read_at(self.offset, buf)?; - self.offset += len; + let len = self.inode.read_at(self.offset as usize, buf)?; + self.offset += len as u64; Ok(len) } @@ -43,13 +50,22 @@ impl FileHandle { } if self.options.append { let info = self.inode.metadata()?; - self.offset = info.size; + self.offset = info.size as u64; } - let len = self.inode.write_at(self.offset, buf)?; - self.offset += len; + let len = self.inode.write_at(self.offset as usize, buf)?; + self.offset += len as u64; Ok(len) } + pub fn seek(&mut self, pos: SeekFrom) -> Result { + self.offset = match pos { + SeekFrom::Start(offset) => offset, + SeekFrom::End(offset) => (self.inode.metadata()?.size as i64 + offset) as u64, + SeekFrom::Current(offset) => (self.offset as i64 + offset) as u64, + }; + Ok(self.offset) + } + pub fn info(&self) -> Result { self.inode.metadata() } diff --git a/kernel/src/syscall/fs.rs b/kernel/src/syscall/fs.rs index ea41ac4f..1934a730 100644 --- a/kernel/src/syscall/fs.rs +++ b/kernel/src/syscall/fs.rs @@ -2,7 +2,7 @@ use super::*; -use crate::fs::{ROOT_INODE, OpenOptions}; +use crate::fs::*; use rcore_fs::vfs::Timespec; pub fn sys_read(fd: usize, base: *mut u8, len: usize) -> SysResult { @@ -89,6 +89,21 @@ pub fn sys_fstat(fd: usize, stat_ptr: *mut Stat) -> SysResult { Ok(0) } +pub fn sys_lseek(fd: usize, offset: i64, whence: u8) -> SysResult { + let pos = match whence { + SEEK_SET => SeekFrom::Start(offset as u64), + SEEK_END => SeekFrom::End(offset), + SEEK_CUR => SeekFrom::Current(offset), + _ => return Err(SysError::Inval), + }; + info!("lseek: fd: {}, pos: {:?}", fd, pos); + + let mut proc = process(); + let file = get_file(&mut proc, fd)?; + let offset = file.seek(pos)?; + Ok(offset as isize) +} + /// entry_id = dentry.offset / 256 /// dentry.name = entry_name /// dentry.offset += 256 @@ -309,3 +324,7 @@ impl From for Stat { } } } + +const SEEK_SET: u8 = 1; +const SEEK_CUR: u8 = 2; +const SEEK_END: u8 = 4; diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 6998e4c7..ff45f709 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -36,7 +36,7 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { // 004 => sys_stat(), 005 => sys_fstat(args[0], args[1] as *mut Stat), // 007 => sys_poll(), -// 008 => sys_lseek(), + 008 => sys_lseek(args[0], args[1] as i64, args[2] as u8), 009 => sys_mmap(args[0], args[1], MmapProt::from_bits_truncate(args[2]), MmapFlags::from_bits_truncate(args[3]), args[4] as i32, args[5]), 011 => sys_munmap(args[0], args[1]), // 019 => sys_readv(),