mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-16 08:46:48 +00:00
Add support for lseek syscall
This commit is contained in:
parent
116b687cae
commit
4e3dfe93da
@ -2,7 +2,7 @@ use crate::prelude::*;
|
|||||||
use crate::tty::get_n_tty;
|
use crate::tty::get_n_tty;
|
||||||
use core::any::Any;
|
use core::any::Any;
|
||||||
|
|
||||||
use crate::fs::utils::{IoEvents, IoctlCmd, Metadata};
|
use crate::fs::utils::{IoEvents, IoctlCmd, Metadata, SeekFrom};
|
||||||
|
|
||||||
/// The basic operations defined on a file
|
/// The basic operations defined on a file
|
||||||
pub trait File: Send + Sync + Any {
|
pub trait File: Send + Sync + Any {
|
||||||
@ -36,4 +36,8 @@ pub trait File: Send + Sync + Any {
|
|||||||
fn metadata(&self) -> Metadata {
|
fn metadata(&self) -> Metadata {
|
||||||
panic!("metadata unsupported");
|
panic!("metadata unsupported");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn seek(&self, seek_from: SeekFrom) -> Result<usize> {
|
||||||
|
panic!("seek unsupported");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,28 +70,28 @@ impl InodeHandle_ {
|
|||||||
|
|
||||||
pub fn seek(&self, pos: SeekFrom) -> Result<usize> {
|
pub fn seek(&self, pos: SeekFrom) -> Result<usize> {
|
||||||
let mut offset = self.offset.lock();
|
let mut offset = self.offset.lock();
|
||||||
let new_offset: i64 = match pos {
|
let new_offset: isize = match pos {
|
||||||
SeekFrom::Start(off /* as u64 */) => {
|
SeekFrom::Start(off /* as usize */) => {
|
||||||
if off > i64::max_value() as u64 {
|
if off > isize::max_value() as usize {
|
||||||
return_errno_with_message!(Errno::EINVAL, "file offset is too large");
|
return_errno_with_message!(Errno::EINVAL, "file offset is too large");
|
||||||
}
|
}
|
||||||
off as i64
|
off as isize
|
||||||
}
|
}
|
||||||
SeekFrom::End(off /* as i64 */) => {
|
SeekFrom::End(off /* as isize */) => {
|
||||||
let file_size = self.dentry.vnode().inode().metadata().size as i64;
|
let file_size = self.dentry.vnode().inode().metadata().size as isize;
|
||||||
assert!(file_size >= 0);
|
assert!(file_size >= 0);
|
||||||
file_size
|
file_size
|
||||||
.checked_add(off)
|
.checked_add(off)
|
||||||
.ok_or_else(|| Error::with_message(Errno::EOVERFLOW, "file offset overflow"))?
|
.ok_or_else(|| Error::with_message(Errno::EOVERFLOW, "file offset overflow"))?
|
||||||
}
|
}
|
||||||
SeekFrom::Current(off /* as i64 */) => (*offset as i64)
|
SeekFrom::Current(off /* as isize */) => (*offset as isize)
|
||||||
.checked_add(off)
|
.checked_add(off)
|
||||||
.ok_or_else(|| Error::with_message(Errno::EOVERFLOW, "file offset overflow"))?,
|
.ok_or_else(|| Error::with_message(Errno::EOVERFLOW, "file offset overflow"))?,
|
||||||
};
|
};
|
||||||
if new_offset < 0 {
|
if new_offset < 0 {
|
||||||
return_errno_with_message!(Errno::EINVAL, "file offset must not be negative");
|
return_errno_with_message!(Errno::EINVAL, "file offset must not be negative");
|
||||||
}
|
}
|
||||||
// Invariant: 0 <= new_offset <= i64::max_value()
|
// Invariant: 0 <= new_offset <= isize::max_value()
|
||||||
let new_offset = new_offset as usize;
|
let new_offset = new_offset as usize;
|
||||||
*offset = new_offset;
|
*offset = new_offset;
|
||||||
Ok(new_offset)
|
Ok(new_offset)
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
mod file;
|
mod file;
|
||||||
mod inode_handle;
|
mod inode_handle;
|
||||||
|
|
||||||
use crate::fs::utils::Metadata;
|
use crate::fs::utils::{Metadata, SeekFrom};
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::rights::{ReadOp, WriteOp};
|
use crate::rights::{ReadOp, WriteOp};
|
||||||
use alloc::sync::Arc;
|
use alloc::sync::Arc;
|
||||||
@ -74,6 +74,13 @@ impl FileHandle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn seek(&self, seek_from: SeekFrom) -> Result<usize> {
|
||||||
|
match &self.inner {
|
||||||
|
Inner::File(file) => file.seek(seek_from),
|
||||||
|
Inner::Inode(inode_handle) => inode_handle.seek(seek_from),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn clean_for_close(&self) -> Result<()> {
|
pub fn clean_for_close(&self) -> Result<()> {
|
||||||
match &self.inner {
|
match &self.inner {
|
||||||
Inner::Inode(inode_handle) => {
|
Inner::Inode(inode_handle) => {
|
||||||
|
@ -3,7 +3,7 @@ use crate::tty::{get_n_tty, Tty};
|
|||||||
|
|
||||||
use super::file_handle::File;
|
use super::file_handle::File;
|
||||||
use super::file_table::FileDescripter;
|
use super::file_table::FileDescripter;
|
||||||
use super::utils::{InodeMode, InodeType, IoEvents, Metadata};
|
use super::utils::{InodeMode, InodeType, IoEvents, Metadata, SeekFrom};
|
||||||
|
|
||||||
pub const FD_STDIN: FileDescripter = 0;
|
pub const FD_STDIN: FileDescripter = 0;
|
||||||
pub const FD_STDOUT: FileDescripter = 1;
|
pub const FD_STDOUT: FileDescripter = 1;
|
||||||
@ -46,6 +46,11 @@ impl File for Stdin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn seek(&self, seek_from: SeekFrom) -> Result<usize> {
|
||||||
|
// TODO: do real seek
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
|
||||||
fn metadata(&self) -> Metadata {
|
fn metadata(&self) -> Metadata {
|
||||||
Metadata {
|
Metadata {
|
||||||
dev: 0,
|
dev: 0,
|
||||||
@ -82,6 +87,11 @@ impl File for Stdout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn seek(&self, seek_from: SeekFrom) -> Result<usize> {
|
||||||
|
// TODO: do real seek
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
|
||||||
fn metadata(&self) -> Metadata {
|
fn metadata(&self) -> Metadata {
|
||||||
Metadata {
|
Metadata {
|
||||||
dev: 0,
|
dev: 0,
|
||||||
@ -119,6 +129,11 @@ impl File for Stderr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn seek(&self, seek_from: SeekFrom) -> Result<usize> {
|
||||||
|
// TODO: do real seek
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
|
||||||
fn metadata(&self) -> Metadata {
|
fn metadata(&self) -> Metadata {
|
||||||
Metadata {
|
Metadata {
|
||||||
dev: 0,
|
dev: 0,
|
||||||
|
@ -32,9 +32,9 @@ mod vnode;
|
|||||||
|
|
||||||
#[derive(Copy, PartialEq, Eq, Clone, Debug)]
|
#[derive(Copy, PartialEq, Eq, Clone, Debug)]
|
||||||
pub enum SeekFrom {
|
pub enum SeekFrom {
|
||||||
Start(u64),
|
Start(usize),
|
||||||
End(i64),
|
End(isize),
|
||||||
Current(i64),
|
Current(isize),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Maximum bytes in a path
|
/// Maximum bytes in a path
|
||||||
|
@ -1,12 +1,27 @@
|
|||||||
|
use crate::fs::{file_table::FileDescripter, utils::SeekFrom};
|
||||||
use crate::log_syscall_entry;
|
use crate::log_syscall_entry;
|
||||||
use crate::{fs::file_table::FileDescripter, prelude::*};
|
use crate::prelude::*;
|
||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use super::SYS_LSEEK;
|
use super::SYS_LSEEK;
|
||||||
|
|
||||||
pub fn sys_lseek(fd: FileDescripter, offset: usize, whence: u32) -> Result<SyscallReturn> {
|
pub fn sys_lseek(fd: FileDescripter, offset: isize, whence: u32) -> Result<SyscallReturn> {
|
||||||
log_syscall_entry!(SYS_LSEEK);
|
log_syscall_entry!(SYS_LSEEK);
|
||||||
debug!("fd = {}, offset = {}, whence = {}", fd, offset, whence);
|
debug!("fd = {}, offset = {}, whence = {}", fd, offset, whence);
|
||||||
// TODO: do lseek
|
let seek_from = match whence {
|
||||||
Ok(SyscallReturn::Return(0))
|
0 => {
|
||||||
|
if offset < 0 {
|
||||||
|
return_errno!(Errno::EINVAL);
|
||||||
|
}
|
||||||
|
SeekFrom::Start(offset as usize)
|
||||||
|
}
|
||||||
|
1 => SeekFrom::Current(offset),
|
||||||
|
2 => SeekFrom::End(offset),
|
||||||
|
_ => return_errno!(Errno::EINVAL),
|
||||||
|
};
|
||||||
|
let current = current!();
|
||||||
|
let file_table = current.file_table().lock();
|
||||||
|
let file = file_table.get_file(fd)?;
|
||||||
|
let offset = file.seek(seek_from)?;
|
||||||
|
Ok(SyscallReturn::Return(offset as _))
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user