From 1a17cee7041d089fdbecd1ff0e5578078fb7e480 Mon Sep 17 00:00:00 2001 From: LI Qing Date: Fri, 30 Dec 2022 11:22:04 +0800 Subject: [PATCH] Add essential vfs support --- .../libs/jinux-std/src/fs/file_handle.rs | 63 ++++++++ .../libs/jinux-std/src/fs/file_table.rs | 15 +- .../jinux-std/src/fs/inode_handle/dyn_cap.rs | 66 ++++++++ .../libs/jinux-std/src/fs/inode_handle/mod.rs | 146 ++++++++++++++++++ .../src/fs/inode_handle/static_cap.rs | 22 +++ src/services/libs/jinux-std/src/fs/mod.rs | 3 + .../jinux-std/src/fs/utils/access_mode.rs | 53 +++++++ .../jinux-std/src/fs/utils/dirent_writer.rs | 31 ++++ .../libs/jinux-std/src/fs/utils/fs.rs | 27 ++++ .../libs/jinux-std/src/fs/utils/inode.rs | 137 ++++++++++++++++ .../libs/jinux-std/src/fs/utils/mod.rs | 20 +++ .../jinux-std/src/fs/utils/status_flags.rs | 23 +++ src/services/libs/jinux-std/src/prelude.rs | 2 +- src/services/libs/jinux-std/src/rights.rs | 2 + .../libs/jinux-std/src/syscall/ioctl.rs | 2 +- .../libs/jinux-std/src/syscall/openat.rs | 3 +- .../libs/jinux-std/src/syscall/poll.rs | 2 +- 17 files changed, 606 insertions(+), 11 deletions(-) create mode 100644 src/services/libs/jinux-std/src/fs/file_handle.rs create mode 100644 src/services/libs/jinux-std/src/fs/inode_handle/dyn_cap.rs create mode 100644 src/services/libs/jinux-std/src/fs/inode_handle/mod.rs create mode 100644 src/services/libs/jinux-std/src/fs/inode_handle/static_cap.rs create mode 100644 src/services/libs/jinux-std/src/fs/utils/access_mode.rs create mode 100644 src/services/libs/jinux-std/src/fs/utils/dirent_writer.rs create mode 100644 src/services/libs/jinux-std/src/fs/utils/fs.rs create mode 100644 src/services/libs/jinux-std/src/fs/utils/inode.rs create mode 100644 src/services/libs/jinux-std/src/fs/utils/mod.rs create mode 100644 src/services/libs/jinux-std/src/fs/utils/status_flags.rs diff --git a/src/services/libs/jinux-std/src/fs/file_handle.rs b/src/services/libs/jinux-std/src/fs/file_handle.rs new file mode 100644 index 000000000..680cc513d --- /dev/null +++ b/src/services/libs/jinux-std/src/fs/file_handle.rs @@ -0,0 +1,63 @@ +use crate::prelude::*; +use crate::rights::{ReadOp, WriteOp}; +use alloc::sync::Arc; + +use super::file::File; +use super::inode_handle::InodeHandle; + +#[derive(Clone)] +pub struct FileHandle { + inner: Inner, +} + +#[derive(Clone)] +enum Inner { + File(Arc), + Inode(InodeHandle), +} + +impl FileHandle { + pub fn new_file(file: Arc) -> Self { + let inner = Inner::File(file); + Self { inner } + } + + pub fn new_inode_handle(inode_handle: InodeHandle) -> Self { + let inner = Inner::Inode(inode_handle); + Self { inner } + } + + pub fn as_file(&self) -> Option<&Arc> { + match &self.inner { + Inner::File(file) => Some(file), + _ => None, + } + } + + pub fn as_inode_handle(&self) -> Option<&InodeHandle> { + match &self.inner { + Inner::Inode(inode_handle) => Some(inode_handle), + _ => None, + } + } + + pub fn read(&self, buf: &mut [u8]) -> Result { + match &self.inner { + Inner::File(file) => file.read(buf), + Inner::Inode(inode_handle) => { + let static_handle = inode_handle.clone().to_static::()?; + static_handle.read(buf) + } + } + } + + pub fn write(&self, buf: &[u8]) -> Result { + match &self.inner { + Inner::File(file) => file.write(buf), + Inner::Inode(inode_handle) => { + let static_handle = inode_handle.clone().to_static::()?; + static_handle.write(buf) + } + } + } +} diff --git a/src/services/libs/jinux-std/src/fs/file_table.rs b/src/services/libs/jinux-std/src/fs/file_table.rs index 82b056eeb..a533015c9 100644 --- a/src/services/libs/jinux-std/src/fs/file_table.rs +++ b/src/services/libs/jinux-std/src/fs/file_table.rs @@ -1,13 +1,14 @@ use crate::prelude::*; use super::{ - file::{File, FileDescripter}, + file::FileDescripter, + file_handle::FileHandle, stdio::{Stderr, Stdin, Stdout, FD_STDERR, FD_STDIN, FD_STDOUT}, }; #[derive(Clone)] pub struct FileTable { - table: BTreeMap>, + table: BTreeMap, } impl FileTable { @@ -22,9 +23,9 @@ impl FileTable { let stdin = Stdin::new_with_default_console(); let stdout = Stdout::new_with_default_console(); let stderr = Stderr::new_with_default_console(); - table.insert(FD_STDIN, Arc::new(stdin) as Arc); - table.insert(FD_STDOUT, Arc::new(stdout) as Arc); - table.insert(FD_STDERR, Arc::new(stderr) as Arc); + table.insert(FD_STDIN, FileHandle::new_file(Arc::new(stdin))); + table.insert(FD_STDOUT, FileHandle::new_file(Arc::new(stdout))); + table.insert(FD_STDERR, FileHandle::new_file(Arc::new(stderr))); Self { table } } @@ -50,7 +51,7 @@ impl FileTable { self.table.iter().map(|(fd, _)| fd.clone()).max().unwrap() } - pub fn insert(&mut self, item: Arc) -> FileDescripter { + pub fn insert(&mut self, item: FileHandle) -> FileDescripter { let fd = self.max_fd() + 1; self.table.insert(fd, item); fd @@ -60,7 +61,7 @@ impl FileTable { self.table.remove(&fd); } - pub fn get_file(&self, fd: FileDescripter) -> Result<&Arc> { + pub fn get_file(&self, fd: FileDescripter) -> Result<&FileHandle> { self.table .get(&fd) .ok_or(Error::with_message(Errno::EBADF, "fd not exits")) diff --git a/src/services/libs/jinux-std/src/fs/inode_handle/dyn_cap.rs b/src/services/libs/jinux-std/src/fs/inode_handle/dyn_cap.rs new file mode 100644 index 000000000..7b56a6f64 --- /dev/null +++ b/src/services/libs/jinux-std/src/fs/inode_handle/dyn_cap.rs @@ -0,0 +1,66 @@ +use crate::prelude::*; + +use crate::rights::{Rights, TRights}; + +use super::*; + +impl InodeHandle { + pub fn new( + inode: Arc, + access_mode: AccessMode, + status_flags: StatusFlags, + ) -> Result { + let inode_info = inode.metadata(); + if access_mode.is_readable() && !inode_info.mode.is_readable() { + return_errno_with_message!(Errno::EACCES, "File is not readable"); + } + if access_mode.is_writable() && !inode_info.mode.is_writable() { + return_errno_with_message!(Errno::EACCES, "File is not writable"); + } + if access_mode.is_writable() && inode_info.type_ == InodeType::Dir { + return_errno_with_message!(Errno::EISDIR, "Directory cannot open to write"); + } + let inner = Arc::new(InodeHandle_ { + inode, + offset: Mutex::new(0), + access_mode, + status_flags: Mutex::new(status_flags), + }); + Ok(Self(inner, Rights::from(access_mode))) + } + + pub fn to_static(self) -> Result> { + let rights = Rights::from_bits(R1::BITS).ok_or(Error::new(Errno::EBADF))?; + if !self.1.contains(rights) { + return_errno_with_message!(Errno::EBADF, "check rights failed"); + } + Ok(InodeHandle(self.0, R1::new())) + } + + pub fn read(&self, buf: &mut [u8]) -> Result { + if !self.1.contains(Rights::READ) { + return_errno_with_message!(Errno::EBADF, "File is not readable"); + } + self.0.read(buf) + } + + pub fn write(&self, buf: &[u8]) -> Result { + if !self.1.contains(Rights::WRITE) { + return_errno_with_message!(Errno::EBADF, "File is not writable"); + } + self.0.write(buf) + } + + pub fn readdir(&self, writer: &mut dyn DirentWriter) -> Result { + if !self.1.contains(Rights::READ) { + return_errno_with_message!(Errno::EBADF, "File is not readable"); + } + self.0.readdir(writer) + } +} + +impl Clone for InodeHandle { + fn clone(&self) -> Self { + Self(self.0.clone(), self.1.clone()) + } +} diff --git a/src/services/libs/jinux-std/src/fs/inode_handle/mod.rs b/src/services/libs/jinux-std/src/fs/inode_handle/mod.rs new file mode 100644 index 000000000..5d59c8143 --- /dev/null +++ b/src/services/libs/jinux-std/src/fs/inode_handle/mod.rs @@ -0,0 +1,146 @@ +//! Opend File Handle + +mod dyn_cap; +mod static_cap; + +use super::utils::{ + AccessMode, DirentWriter, DirentWriterContext, Inode, InodeType, SeekFrom, StatusFlags, +}; +use crate::prelude::*; +use crate::rights::Rights; +use alloc::sync::Arc; + +pub struct InodeHandle(Arc, R); + +struct InodeHandle_ { + inode: Arc, + offset: Mutex, + access_mode: AccessMode, + status_flags: Mutex, +} + +impl InodeHandle_ { + pub fn read(&self, buf: &mut [u8]) -> Result { + let mut offset = self.offset.lock(); + let file_size = self.inode.metadata().size; + let start = file_size.min(*offset); + let end = file_size.min(*offset + buf.len()); + let len = if self.status_flags.lock().contains(StatusFlags::O_DIRECT) { + self.inode.read_at(start, &mut buf[0..start - end])? + } else { + self.inode.read_at(start, &mut buf[0..start - end])? + // TODO: use page cache + // self.inode.pages().read_at(start, buf[0..start - end])? + }; + + *offset += len; + Ok(len) + } + + pub fn write(&self, buf: &[u8]) -> Result { + let mut offset = self.offset.lock(); + let file_size = self.inode.metadata().size; + if self.status_flags.lock().contains(StatusFlags::O_APPEND) { + *offset = file_size; + } + let len = if self.status_flags.lock().contains(StatusFlags::O_DIRECT) { + self.inode.write_at(*offset, buf)? + } else { + self.inode.write_at(*offset, buf)? + // TODO: use page cache + // let len = self.inode.pages().write_at(*offset, buf)?; + // if offset + len > file_size { + // self.inode.resize(offset + len)?; + // } + // len + }; + + *offset += len; + Ok(len) + } + + pub fn seek(&self, pos: SeekFrom) -> Result { + let mut offset = self.offset.lock(); + let new_offset: i64 = match pos { + SeekFrom::Start(off /* as u64 */) => { + if off > i64::max_value() as u64 { + return_errno_with_message!(Errno::EINVAL, "file offset is too large"); + } + off as i64 + } + SeekFrom::End(off /* as i64 */) => { + let file_size = self.inode.metadata().size as i64; + assert!(file_size >= 0); + file_size + .checked_add(off) + .ok_or_else(|| Error::with_message(Errno::EOVERFLOW, "file offset overflow"))? + } + SeekFrom::Current(off /* as i64 */) => (*offset as i64) + .checked_add(off) + .ok_or_else(|| Error::with_message(Errno::EOVERFLOW, "file offset overflow"))?, + }; + if new_offset < 0 { + return_errno_with_message!(Errno::EINVAL, "file offset must not be negative"); + } + // Invariant: 0 <= new_offset <= i64::max_value() + let new_offset = new_offset as usize; + *offset = new_offset; + Ok(new_offset) + } + + pub fn offset(&self) -> usize { + let offset = self.offset.lock(); + *offset + } + + pub fn access_mode(&self) -> AccessMode { + self.access_mode + } + + pub fn status_flags(&self) -> StatusFlags { + let status_flags = self.status_flags.lock(); + *status_flags + } + + pub fn set_status_flags(&self, new_status_flags: StatusFlags) { + let mut status_flags = self.status_flags.lock(); + // Can change only the O_APPEND, O_ASYNC, O_NOATIME, and O_NONBLOCK flags + let valid_flags_mask = StatusFlags::O_APPEND + | StatusFlags::O_ASYNC + | StatusFlags::O_NOATIME + | StatusFlags::O_NONBLOCK; + status_flags.remove(valid_flags_mask); + status_flags.insert(new_status_flags & valid_flags_mask); + } + + pub fn readdir(&self, writer: &mut dyn DirentWriter) -> Result { + let mut offset = self.offset.lock(); + let mut dir_writer_ctx = DirentWriterContext::new(*offset, writer); + let written_size = self.inode.readdir(&mut dir_writer_ctx)?; + *offset = dir_writer_ctx.pos(); + Ok(written_size) + } +} + +/// Methods for both dyn and static +impl InodeHandle { + pub fn seek(&self, pos: SeekFrom) -> Result { + self.0.seek(pos) + } + + pub fn offset(&self) -> usize { + self.0.offset() + } + + pub fn access_mode(&self) -> AccessMode { + self.0.access_mode() + } + + pub fn status_flags(&self) -> StatusFlags { + self.0.status_flags() + } + + pub fn set_status_flags(&self, new_status_flags: StatusFlags) { + self.0.set_status_flags(new_status_flags) + } +} diff --git a/src/services/libs/jinux-std/src/fs/inode_handle/static_cap.rs b/src/services/libs/jinux-std/src/fs/inode_handle/static_cap.rs new file mode 100644 index 000000000..6e9ed09da --- /dev/null +++ b/src/services/libs/jinux-std/src/fs/inode_handle/static_cap.rs @@ -0,0 +1,22 @@ +use crate::prelude::*; +use crate::rights::*; +use jinux_rights_proc::require; + +use super::*; + +impl InodeHandle { + #[require(R > Read)] + pub fn read(&self, buf: &mut [u8]) -> Result { + self.0.read(buf) + } + + #[require(R > Write)] + pub fn write(&self, buf: &[u8]) -> Result { + self.0.write(buf) + } + + #[require(R > Read)] + pub fn readdir(&self, writer: &mut dyn DirentWriter) -> Result { + self.0.readdir(writer) + } +} diff --git a/src/services/libs/jinux-std/src/fs/mod.rs b/src/services/libs/jinux-std/src/fs/mod.rs index c8beb460b..00ff10abf 100644 --- a/src/services/libs/jinux-std/src/fs/mod.rs +++ b/src/services/libs/jinux-std/src/fs/mod.rs @@ -1,8 +1,11 @@ pub mod events; pub mod fcntl; pub mod file; +pub mod file_handle; pub mod file_table; +pub mod inode_handle; pub mod ioctl; pub mod poll; pub mod stat; pub mod stdio; +pub mod utils; diff --git a/src/services/libs/jinux-std/src/fs/utils/access_mode.rs b/src/services/libs/jinux-std/src/fs/utils/access_mode.rs new file mode 100644 index 000000000..4a1becd08 --- /dev/null +++ b/src/services/libs/jinux-std/src/fs/utils/access_mode.rs @@ -0,0 +1,53 @@ +use crate::rights::Rights; + +#[allow(non_camel_case_types)] +#[derive(Clone, Copy, Debug)] +#[repr(u8)] +pub enum AccessMode { + /// read only + O_RDONLY = 0, + /// write only + O_WRONLY = 1, + /// read write + O_RDWR = 2, +} + +impl AccessMode { + pub fn is_readable(&self) -> bool { + match *self { + AccessMode::O_RDONLY | AccessMode::O_RDWR => true, + _ => false, + } + } + + pub fn is_writable(&self) -> bool { + match *self { + AccessMode::O_WRONLY | AccessMode::O_RDWR => true, + _ => false, + } + } +} + +impl From for AccessMode { + fn from(rights: Rights) -> AccessMode { + if rights.contains(Rights::READ) && rights.contains(Rights::WRITE) { + AccessMode::O_RDWR + } else if rights.contains(Rights::READ) { + AccessMode::O_RDONLY + } else if rights.contains(Rights::WRITE) { + AccessMode::O_WRONLY + } else { + panic!("invalid rights"); + } + } +} + +impl From for Rights { + fn from(access_mode: AccessMode) -> Rights { + match access_mode { + AccessMode::O_RDONLY => Rights::READ, + AccessMode::O_WRONLY => Rights::WRITE, + AccessMode::O_RDWR => Rights::READ | Rights::WRITE, + } + } +} diff --git a/src/services/libs/jinux-std/src/fs/utils/dirent_writer.rs b/src/services/libs/jinux-std/src/fs/utils/dirent_writer.rs new file mode 100644 index 000000000..cb07ad66c --- /dev/null +++ b/src/services/libs/jinux-std/src/fs/utils/dirent_writer.rs @@ -0,0 +1,31 @@ +use super::InodeType; +use crate::prelude::*; + +/// DirentWriterContext is a wrapper of DirentWriter with directory position +/// After a successful write, the position increases correspondingly +pub struct DirentWriterContext<'a> { + pos: usize, + writer: &'a mut dyn DirentWriter, +} + +impl<'a> DirentWriterContext<'a> { + pub fn new(pos: usize, writer: &'a mut dyn DirentWriter) -> Self { + Self { pos, writer } + } + + pub fn write_entry(&mut self, name: &str, ino: u64, type_: InodeType) -> Result { + let written_len = self.writer.write_entry(name, ino, type_)?; + self.pos += 1; + Ok(written_len) + } + + pub fn pos(&self) -> usize { + self.pos + } +} + +/// DirentWriter is used to write directory entry, +/// the object which implements it can decide how to format the data +pub trait DirentWriter: Sync + Send { + fn write_entry(&mut self, name: &str, ino: u64, type_: InodeType) -> Result; +} diff --git a/src/services/libs/jinux-std/src/fs/utils/fs.rs b/src/services/libs/jinux-std/src/fs/utils/fs.rs new file mode 100644 index 000000000..4d7c9ec74 --- /dev/null +++ b/src/services/libs/jinux-std/src/fs/utils/fs.rs @@ -0,0 +1,27 @@ +use alloc::sync::Arc; + +use super::Inode; +use crate::prelude::*; + +#[derive(Debug, Clone)] +pub struct SuperBlock { + pub magic: usize, + pub bsize: usize, + pub blocks: usize, + pub bfree: usize, + pub bavail: usize, + pub files: usize, + pub ffree: usize, + pub fsid: usize, + pub namelen: usize, + pub frsize: usize, + pub flags: usize, +} + +pub trait FileSystem: Sync + Send { + fn sync(&self) -> Result<()>; + + fn root_inode(&self) -> Arc; + + fn sb(&self) -> SuperBlock; +} diff --git a/src/services/libs/jinux-std/src/fs/utils/inode.rs b/src/services/libs/jinux-std/src/fs/utils/inode.rs new file mode 100644 index 000000000..c8fb36313 --- /dev/null +++ b/src/services/libs/jinux-std/src/fs/utils/inode.rs @@ -0,0 +1,137 @@ +use alloc::string::String; +use alloc::sync::Arc; +use bitflags::bitflags; +use core::any::Any; + +use super::{DirentWriterContext, FileSystem}; +use crate::fs::ioctl::IoctlCmd; +use crate::prelude::*; + +#[repr(u32)] +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum InodeType { + File = 1, + Dir = 2, + SymLink = 3, + CharDevice = 4, + BlockDevice = 5, +} + +bitflags! { + pub struct InodeMode: u16 { + /// set-user-ID + const S_ISUID = 0o4000; + /// set-group-ID + const S_ISGID = 0o2000; + /// sticky bit + const S_ISVTX = 0o1000; + /// read by owner + const S_IRUSR = 0o0400; + /// write by owner + const S_IWUSR = 0o0200; + /// execute/search by owner + const S_IXUSR = 0o0100; + /// read by group + const S_IRGRP = 0o0040; + /// write by group + const S_IWGRP = 0o0020; + /// execute/search by group + const S_IXGRP = 0o0010; + /// read by others + const S_IROTH = 0o0004; + /// write by others + const S_IWOTH = 0o0002; + /// execute/search by others + const S_IXOTH = 0o0001; + } +} + +impl InodeMode { + pub fn is_readable(&self) -> bool { + self.contains(Self::S_IRUSR) + } + + pub fn is_writable(&self) -> bool { + self.contains(Self::S_IWUSR) + } + + pub fn is_executable(&self) -> bool { + self.contains(Self::S_IXUSR) + } + + pub fn has_sticky_bit(&self) -> bool { + self.contains(Self::S_ISVTX) + } + + pub fn has_set_uid(&self) -> bool { + self.contains(Self::S_ISUID) + } + + pub fn has_set_gid(&self) -> bool { + self.contains(Self::S_ISGID) + } +} + +#[derive(Debug, Clone)] +pub struct Metadata { + pub dev: usize, + pub ino: usize, + pub size: usize, + pub blk_size: usize, + pub blocks: usize, + pub atime: Timespec, + pub mtime: Timespec, + pub ctime: Timespec, + pub type_: InodeType, + pub mode: InodeMode, + pub nlinks: usize, + pub uid: usize, + pub gid: usize, + pub rdev: usize, +} + +#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] +pub struct Timespec { + pub sec: i64, + pub nsec: i64, +} + +pub trait Inode: Any + Sync + Send { + fn resize(&self, new_size: usize) -> Result<()>; + + fn metadata(&self) -> Metadata; + + fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result; + + fn write_at(&self, offset: usize, buf: &[u8]) -> Result; + + fn mknod(&self, name: &str, type_: InodeType, mode: InodeMode) -> Result>; + + fn readdir(&self, ctx: &mut DirentWriterContext) -> Result; + + fn link(&self, old: &Arc, name: &str) -> Result<()>; + + fn unlink(&self, name: &str) -> Result<()>; + + fn lookup(&self, name: &str) -> Result>; + + fn rename(&self, old_name: &str, target: &Arc, new_name: &str) -> Result<()>; + + fn read_link(&self) -> Result; + + fn write_link(&self, target: &str) -> Result<()>; + + fn ioctl(&self, cmd: &IoctlCmd) -> Result<()>; + + fn sync(&self) -> Result<()>; + + fn fs(&self) -> Arc; + + fn as_any_ref(&self) -> &dyn Any; +} + +impl dyn Inode { + pub fn downcast_ref(&self) -> Option<&T> { + self.as_any_ref().downcast_ref::() + } +} diff --git a/src/services/libs/jinux-std/src/fs/utils/mod.rs b/src/services/libs/jinux-std/src/fs/utils/mod.rs new file mode 100644 index 000000000..e744896dd --- /dev/null +++ b/src/services/libs/jinux-std/src/fs/utils/mod.rs @@ -0,0 +1,20 @@ +//! VFS components + +pub use access_mode::AccessMode; +pub use dirent_writer::{DirentWriter, DirentWriterContext}; +pub use fs::{FileSystem, SuperBlock}; +pub use inode::{Inode, InodeMode, InodeType, Metadata, Timespec}; +pub use status_flags::StatusFlags; + +mod access_mode; +mod dirent_writer; +mod fs; +mod inode; +mod status_flags; + +#[derive(Copy, PartialEq, Eq, Clone, Debug)] +pub enum SeekFrom { + Start(u64), + End(i64), + Current(i64), +} diff --git a/src/services/libs/jinux-std/src/fs/utils/status_flags.rs b/src/services/libs/jinux-std/src/fs/utils/status_flags.rs new file mode 100644 index 000000000..2645c332b --- /dev/null +++ b/src/services/libs/jinux-std/src/fs/utils/status_flags.rs @@ -0,0 +1,23 @@ +use bitflags::bitflags; + +bitflags! { + pub struct StatusFlags: u32 { + /// append on each write + const O_APPEND = 1 << 10; + /// non block + const O_NONBLOCK = 1 << 11; + /// synchronized I/O, data + const O_DSYNC = 1 << 12; + /// signal-driven I/O + const O_ASYNC = 1 << 13; + /// direct I/O + const O_DIRECT = 1 << 14; + /// on x86_64, O_LARGEFILE is 0 + /// not update st_atime + const O_NOATIME = 1 << 18; + /// synchronized I/O, data and metadata + const O_SYNC = 1 << 20; + /// equivalent of POSIX.1's O_EXEC + const O_PATH = 1 << 21; + } +} diff --git a/src/services/libs/jinux-std/src/prelude.rs b/src/services/libs/jinux-std/src/prelude.rs index b035a605f..70c7a1e9a 100644 --- a/src/services/libs/jinux-std/src/prelude.rs +++ b/src/services/libs/jinux-std/src/prelude.rs @@ -15,7 +15,7 @@ pub(crate) use core::ffi::CStr; pub(crate) use jinux_frame::config::PAGE_SIZE; pub(crate) use jinux_frame::vm::Vaddr; pub(crate) use jinux_frame::{debug, error, info, print, println, trace, warn}; -pub(crate) use spin::Mutex; +pub(crate) use spin::{Mutex, RwLock}; #[macro_export] macro_rules! current { diff --git a/src/services/libs/jinux-std/src/rights.rs b/src/services/libs/jinux-std/src/rights.rs index b7296abe1..8988f8706 100644 --- a/src/services/libs/jinux-std/src/rights.rs +++ b/src/services/libs/jinux-std/src/rights.rs @@ -47,3 +47,5 @@ typeflags! { /// The full set of access rights. pub type Full = TRights![Dup, Read, Write, Exec, Signal]; +pub type ReadOp = TRights![Read]; +pub type WriteOp = TRights![Write]; diff --git a/src/services/libs/jinux-std/src/syscall/ioctl.rs b/src/services/libs/jinux-std/src/syscall/ioctl.rs index 14e3191e6..67be4ece1 100644 --- a/src/services/libs/jinux-std/src/syscall/ioctl.rs +++ b/src/services/libs/jinux-std/src/syscall/ioctl.rs @@ -16,6 +16,6 @@ pub fn sys_ioctl(fd: FileDescripter, cmd: u32, arg: Vaddr) -> Result; + let tty_file = FileHandle::new_file(get_console().clone() as Arc); let current = current!(); let mut file_table = current.file_table().lock(); let fd = file_table.insert(tty_file); diff --git a/src/services/libs/jinux-std/src/syscall/poll.rs b/src/services/libs/jinux-std/src/syscall/poll.rs index 98ba2b84d..77bd2a8c1 100644 --- a/src/services/libs/jinux-std/src/syscall/poll.rs +++ b/src/services/libs/jinux-std/src/syscall/poll.rs @@ -39,7 +39,7 @@ pub fn sys_poll(fds: Vaddr, nfds: c_nfds, timeout: i32) -> Result match file { Err(_) => return Some(Err(Error::new(Errno::EBADF))), Ok(file) => { - let file_events = file.poll(); + let file_events = file.as_file().unwrap().poll(); let polled_events = pollfd.events.intersection(file_events); if !polled_events.is_empty() { ready_files += 1;