mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-09 05:16:47 +00:00
Add trait FileIo and refactor current devices
This commit is contained in:
parent
43fd1a52fa
commit
001326110e
@ -12,6 +12,8 @@ pub use pty::{PtyMaster, PtySlave};
|
||||
pub use random::Random;
|
||||
pub use urandom::Urandom;
|
||||
|
||||
use self::tty::get_n_tty;
|
||||
|
||||
/// Init the device node in fs, must be called after mounting rootfs.
|
||||
pub fn init() -> Result<()> {
|
||||
let null = Arc::new(null::Null);
|
||||
@ -19,7 +21,9 @@ pub fn init() -> Result<()> {
|
||||
let zero = Arc::new(zero::Zero);
|
||||
add_node(zero, "zero")?;
|
||||
tty::init();
|
||||
let tty = tty::get_n_tty().clone();
|
||||
let console = get_n_tty().clone();
|
||||
add_node(console, "console")?;
|
||||
let tty = Arc::new(tty::TtyDevice);
|
||||
add_node(tty, "tty")?;
|
||||
let random = Arc::new(random::Random);
|
||||
add_node(random, "random")?;
|
||||
|
@ -1,5 +1,8 @@
|
||||
use super::*;
|
||||
use crate::events::IoEvents;
|
||||
use crate::fs::inode_handle::FileIo;
|
||||
use crate::prelude::*;
|
||||
use crate::process::signal::Poller;
|
||||
|
||||
pub struct Null;
|
||||
|
||||
@ -12,7 +15,9 @@ impl Device for Null {
|
||||
// Same value with Linux
|
||||
DeviceId::new(1, 3)
|
||||
}
|
||||
}
|
||||
|
||||
impl FileIo for Null {
|
||||
fn read(&self, _buf: &mut [u8]) -> Result<usize> {
|
||||
Ok(0)
|
||||
}
|
||||
@ -20,4 +25,9 @@ impl Device for Null {
|
||||
fn write(&self, buf: &[u8]) -> Result<usize> {
|
||||
Ok(buf.len())
|
||||
}
|
||||
|
||||
fn poll(&self, mask: IoEvents, poller: Option<&Poller>) -> IoEvents {
|
||||
let events = IoEvents::IN | IoEvents::OUT;
|
||||
events & mask
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,8 @@
|
||||
use crate::events::IoEvents;
|
||||
use crate::fs::device::{Device, DeviceId, DeviceType};
|
||||
use crate::fs::inode_handle::FileIo;
|
||||
use crate::prelude::*;
|
||||
use crate::process::signal::Poller;
|
||||
|
||||
pub struct Random;
|
||||
|
||||
@ -19,7 +22,9 @@ impl Device for Random {
|
||||
// The same value as Linux
|
||||
DeviceId::new(1, 8)
|
||||
}
|
||||
}
|
||||
|
||||
impl FileIo for Random {
|
||||
fn read(&self, buf: &mut [u8]) -> Result<usize> {
|
||||
Self::getrandom(buf)
|
||||
}
|
||||
@ -27,6 +32,11 @@ impl Device for Random {
|
||||
fn write(&self, buf: &[u8]) -> Result<usize> {
|
||||
Ok(buf.len())
|
||||
}
|
||||
|
||||
fn poll(&self, mask: IoEvents, poller: Option<&Poller>) -> IoEvents {
|
||||
let events = IoEvents::IN | IoEvents::OUT;
|
||||
events & mask
|
||||
}
|
||||
}
|
||||
|
||||
impl From<getrandom::Error> for Error {
|
||||
|
@ -1,5 +1,8 @@
|
||||
use crate::events::IoEvents;
|
||||
use crate::fs::device::{Device, DeviceId, DeviceType};
|
||||
use crate::fs::inode_handle::FileIo;
|
||||
use crate::prelude::*;
|
||||
use crate::process::signal::Poller;
|
||||
|
||||
pub struct Urandom;
|
||||
|
||||
@ -19,7 +22,9 @@ impl Device for Urandom {
|
||||
// The same value as Linux
|
||||
DeviceId::new(1, 9)
|
||||
}
|
||||
}
|
||||
|
||||
impl FileIo for Urandom {
|
||||
fn read(&self, buf: &mut [u8]) -> Result<usize> {
|
||||
Self::getrandom(buf)
|
||||
}
|
||||
@ -27,4 +32,9 @@ impl Device for Urandom {
|
||||
fn write(&self, buf: &[u8]) -> Result<usize> {
|
||||
Ok(buf.len())
|
||||
}
|
||||
|
||||
fn poll(&self, mask: IoEvents, poller: Option<&Poller>) -> IoEvents {
|
||||
let events = IoEvents::IN | IoEvents::OUT;
|
||||
events & mask
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,8 @@
|
||||
use super::*;
|
||||
use crate::events::IoEvents;
|
||||
use crate::fs::inode_handle::FileIo;
|
||||
use crate::prelude::*;
|
||||
use crate::process::signal::Poller;
|
||||
|
||||
pub struct Zero;
|
||||
|
||||
@ -12,7 +15,9 @@ impl Device for Zero {
|
||||
// Same value with Linux
|
||||
DeviceId::new(1, 5)
|
||||
}
|
||||
}
|
||||
|
||||
impl FileIo for Zero {
|
||||
fn read(&self, buf: &mut [u8]) -> Result<usize> {
|
||||
for byte in buf.iter_mut() {
|
||||
*byte = 0;
|
||||
@ -23,4 +28,9 @@ impl Device for Zero {
|
||||
fn write(&self, buf: &[u8]) -> Result<usize> {
|
||||
Ok(buf.len())
|
||||
}
|
||||
|
||||
fn poll(&self, mask: IoEvents, poller: Option<&Poller>) -> IoEvents {
|
||||
let events = IoEvents::IN | IoEvents::OUT;
|
||||
events & mask
|
||||
}
|
||||
}
|
||||
|
@ -1,33 +1,21 @@
|
||||
use crate::events::IoEvents;
|
||||
use crate::fs::fs_resolver::{FsPath, FsResolver};
|
||||
use crate::fs::utils::Dentry;
|
||||
use crate::fs::utils::{InodeMode, InodeType, IoctlCmd};
|
||||
use crate::fs::utils::{InodeMode, InodeType};
|
||||
use crate::prelude::*;
|
||||
use crate::process::signal::Poller;
|
||||
|
||||
use super::inode_handle::FileIo;
|
||||
|
||||
/// The abstract of device
|
||||
pub trait Device: Sync + Send {
|
||||
pub trait Device: Sync + Send + FileIo {
|
||||
/// Return the device type.
|
||||
fn type_(&self) -> DeviceType;
|
||||
|
||||
/// Return the device ID.
|
||||
fn id(&self) -> DeviceId;
|
||||
|
||||
/// Read from the device.
|
||||
fn read(&self, buf: &mut [u8]) -> Result<usize>;
|
||||
|
||||
/// Write to the device.
|
||||
fn write(&self, buf: &[u8]) -> Result<usize>;
|
||||
|
||||
/// Poll on the device.
|
||||
fn poll(&self, mask: IoEvents, poller: Option<&Poller>) -> IoEvents {
|
||||
let events = IoEvents::IN | IoEvents::OUT;
|
||||
events & mask
|
||||
}
|
||||
|
||||
/// Ioctl on the device.
|
||||
fn ioctl(&self, cmd: IoctlCmd, arg: usize) -> Result<i32> {
|
||||
return_errno_with_message!(Errno::EINVAL, "ioctl is not supported");
|
||||
/// Open a device.
|
||||
fn open(&self) -> Result<Option<Arc<dyn FileIo>>> {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,106 +0,0 @@
|
||||
use crate::events::IoEvents;
|
||||
use crate::fs::file_handle::FileLike;
|
||||
use crate::prelude::*;
|
||||
use crate::process::signal::Poller;
|
||||
|
||||
use super::*;
|
||||
|
||||
use crate::device::PtyMaster;
|
||||
|
||||
/// Pty master inode for the master device.
|
||||
pub struct PtyMasterInode(Arc<PtyMaster>);
|
||||
|
||||
impl PtyMasterInode {
|
||||
pub fn new(device: Arc<PtyMaster>) -> Arc<Self> {
|
||||
Arc::new(Self(device))
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for PtyMasterInode {
|
||||
fn drop(&mut self) {
|
||||
// Remove the slave from fs.
|
||||
let fs = self.0.ptmx().fs();
|
||||
let devpts = fs.downcast_ref::<DevPts>().unwrap();
|
||||
|
||||
let index = self.0.index();
|
||||
devpts.remove_slave(index);
|
||||
}
|
||||
}
|
||||
|
||||
impl Inode for PtyMasterInode {
|
||||
/// Do not cache dentry in DCACHE.
|
||||
///
|
||||
/// Each file descriptor obtained by opening "/dev/ptmx" is an independent pty master
|
||||
/// with its own associated pty slave.
|
||||
fn is_dentry_cacheable(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn len(&self) -> usize {
|
||||
self.0.ptmx().metadata().size
|
||||
}
|
||||
|
||||
fn resize(&self, new_size: usize) {}
|
||||
|
||||
fn metadata(&self) -> Metadata {
|
||||
self.0.ptmx().metadata()
|
||||
}
|
||||
|
||||
fn type_(&self) -> InodeType {
|
||||
self.0.ptmx().metadata().type_
|
||||
}
|
||||
|
||||
fn mode(&self) -> InodeMode {
|
||||
self.0.ptmx().metadata().mode
|
||||
}
|
||||
|
||||
fn set_mode(&self, mode: InodeMode) {}
|
||||
|
||||
fn atime(&self) -> Duration {
|
||||
self.0.ptmx().metadata().atime
|
||||
}
|
||||
|
||||
fn set_atime(&self, time: Duration) {}
|
||||
|
||||
fn mtime(&self) -> Duration {
|
||||
self.0.ptmx().metadata().mtime
|
||||
}
|
||||
|
||||
fn set_mtime(&self, time: Duration) {}
|
||||
|
||||
fn read_page(&self, idx: usize, frame: &VmFrame) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_page(&self, idx: usize, frame: &VmFrame) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize> {
|
||||
self.0.read(buf)
|
||||
}
|
||||
|
||||
fn read_direct_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize> {
|
||||
self.0.read(buf)
|
||||
}
|
||||
|
||||
fn write_at(&self, offset: usize, buf: &[u8]) -> Result<usize> {
|
||||
self.0.write(buf)
|
||||
}
|
||||
|
||||
fn write_direct_at(&self, offset: usize, buf: &[u8]) -> Result<usize> {
|
||||
self.0.write(buf)
|
||||
}
|
||||
|
||||
fn ioctl(&self, cmd: IoctlCmd, arg: usize) -> Result<i32> {
|
||||
self.0.ioctl(cmd, arg)
|
||||
}
|
||||
|
||||
fn poll(&self, mask: IoEvents, poller: Option<&Poller>) -> IoEvents {
|
||||
self.0.poll(mask, poller)
|
||||
}
|
||||
|
||||
fn fs(&self) -> Arc<dyn FileSystem> {
|
||||
self.0.ptmx().fs()
|
||||
}
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
use crate::device::PtyMaster;
|
||||
use crate::fs::device::{Device, DeviceId, DeviceType};
|
||||
use crate::fs::utils::{
|
||||
DirentVisitor, FileSystem, FsFlags, Inode, InodeMode, InodeType, IoctlCmd, Metadata,
|
||||
@ -9,11 +10,9 @@ use core::time::Duration;
|
||||
use jinux_frame::vm::VmFrame;
|
||||
use jinux_util::{id_allocator::IdAlloc, slot_vec::SlotVec};
|
||||
|
||||
use self::master::PtyMasterInode;
|
||||
use self::ptmx::Ptmx;
|
||||
use self::slave::PtySlaveInode;
|
||||
|
||||
mod master;
|
||||
mod ptmx;
|
||||
mod slave;
|
||||
|
||||
@ -52,7 +51,7 @@ impl DevPts {
|
||||
}
|
||||
|
||||
/// Create the master and slave pair.
|
||||
fn create_master_slave_pair(&self) -> Result<(Arc<PtyMasterInode>, Arc<PtySlaveInode>)> {
|
||||
fn create_master_slave_pair(&self) -> Result<(Arc<PtyMaster>, Arc<PtySlaveInode>)> {
|
||||
let index = self
|
||||
.index_alloc
|
||||
.lock()
|
||||
@ -61,17 +60,16 @@ impl DevPts {
|
||||
|
||||
let (master, slave) = crate::device::new_pty_pair(index as u32, self.root.ptmx.clone())?;
|
||||
|
||||
let master_inode = PtyMasterInode::new(master);
|
||||
let slave_inode = PtySlaveInode::new(slave, self.this.clone());
|
||||
self.root.add_slave(index.to_string(), slave_inode.clone());
|
||||
|
||||
Ok((master_inode, slave_inode))
|
||||
Ok((master, slave_inode))
|
||||
}
|
||||
|
||||
/// Remove the slave from fs.
|
||||
///
|
||||
/// This is called when the master is being dropped.
|
||||
fn remove_slave(&self, index: u32) -> Option<Arc<PtySlaveInode>> {
|
||||
pub fn remove_slave(&self, index: u32) -> Option<Arc<PtySlaveInode>> {
|
||||
let removed_slave = self.root.remove_slave(&index.to_string());
|
||||
if removed_slave.is_some() {
|
||||
self.index_alloc.lock().free(index as usize);
|
||||
@ -241,7 +239,7 @@ impl Inode for RootInode {
|
||||
let inode = match name {
|
||||
"." | ".." => self.fs().root_inode(),
|
||||
// Call the "open" method of ptmx to create a master and slave pair.
|
||||
"ptmx" => self.ptmx.open()?,
|
||||
"ptmx" => self.ptmx.clone(),
|
||||
slave => self
|
||||
.slaves
|
||||
.read()
|
||||
|
@ -1,4 +1,8 @@
|
||||
use crate::device::PtyMaster;
|
||||
use crate::events::IoEvents;
|
||||
use crate::fs::inode_handle::FileIo;
|
||||
use crate::prelude::*;
|
||||
use crate::process::signal::Poller;
|
||||
|
||||
use super::*;
|
||||
|
||||
@ -14,12 +18,14 @@ const PTMX_MINOR_NUM: u32 = 2;
|
||||
pub struct Ptmx {
|
||||
inner: Inner,
|
||||
metadata: Metadata,
|
||||
fs: Weak<DevPts>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Inner(Weak<DevPts>);
|
||||
|
||||
impl Ptmx {
|
||||
pub fn new(sb: &SuperBlock, fs: Weak<DevPts>) -> Arc<Self> {
|
||||
let inner = Inner;
|
||||
let inner = Inner(fs);
|
||||
Arc::new(Self {
|
||||
metadata: Metadata::new_device(
|
||||
PTMX_INO,
|
||||
@ -28,20 +34,19 @@ impl Ptmx {
|
||||
&inner,
|
||||
),
|
||||
inner,
|
||||
fs,
|
||||
})
|
||||
}
|
||||
|
||||
/// The open method for ptmx.
|
||||
///
|
||||
/// Creates a master and slave pair and returns the master inode.
|
||||
pub fn open(&self) -> Result<Arc<PtyMasterInode>> {
|
||||
pub fn open(&self) -> Result<Arc<PtyMaster>> {
|
||||
let (master, _) = self.devpts().create_master_slave_pair()?;
|
||||
Ok(master)
|
||||
}
|
||||
|
||||
pub fn devpts(&self) -> Arc<DevPts> {
|
||||
self.fs.upgrade().unwrap()
|
||||
self.inner.0.upgrade().unwrap()
|
||||
}
|
||||
|
||||
pub fn device_type(&self) -> DeviceType {
|
||||
@ -121,13 +126,10 @@ impl Inode for Ptmx {
|
||||
}
|
||||
|
||||
fn as_device(&self) -> Option<Arc<dyn Device>> {
|
||||
Some(Arc::new(self.inner))
|
||||
Some(Arc::new(self.inner.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
struct Inner;
|
||||
|
||||
impl Device for Inner {
|
||||
fn type_(&self) -> DeviceType {
|
||||
DeviceType::CharDevice
|
||||
@ -137,13 +139,23 @@ impl Device for Inner {
|
||||
DeviceId::new(PTMX_MAJOR_NUM, PTMX_MINOR_NUM)
|
||||
}
|
||||
|
||||
fn open(&self) -> Result<Option<Arc<dyn FileIo>>> {
|
||||
let devpts = self.0.upgrade().unwrap();
|
||||
let (master, _) = devpts.create_master_slave_pair()?;
|
||||
Ok(Some(master as _))
|
||||
}
|
||||
}
|
||||
|
||||
impl FileIo for Inner {
|
||||
fn read(&self, buf: &mut [u8]) -> Result<usize> {
|
||||
// do nothing because it should not be used to read.
|
||||
Ok(0)
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
fn write(&self, buf: &[u8]) -> Result<usize> {
|
||||
// do nothing because it should not be used to write.
|
||||
Ok(buf.len())
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
fn poll(&self, mask: IoEvents, poller: Option<&Poller>) -> IoEvents {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
use crate::events::IoEvents;
|
||||
use crate::fs::inode_handle::FileIo;
|
||||
use crate::prelude::*;
|
||||
use crate::process::signal::Poller;
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
//! Opend File Handle
|
||||
|
||||
use crate::events::Observer;
|
||||
use crate::events::{IoEvents, Observer};
|
||||
use crate::fs::device::Device;
|
||||
use crate::fs::utils::{AccessMode, IoEvents, IoctlCmd, Metadata, Poller, SeekFrom, StatusFlags};
|
||||
use crate::fs::utils::{AccessMode, IoctlCmd, Metadata, SeekFrom, StatusFlags};
|
||||
use crate::net::socket::Socket;
|
||||
use crate::prelude::*;
|
||||
use crate::process::signal::Poller;
|
||||
|
@ -27,7 +27,7 @@ impl FileTable {
|
||||
pub fn new_with_stdio() -> Self {
|
||||
let mut table = SlotVec::new();
|
||||
let fs_resolver = FsResolver::new();
|
||||
let tty_path = FsPath::new(AT_FDCWD, "/dev/tty").expect("cannot find tty");
|
||||
let tty_path = FsPath::new(AT_FDCWD, "/dev/console").expect("cannot find tty");
|
||||
let stdin = {
|
||||
let flags = AccessMode::O_RDONLY as u32;
|
||||
let mode = InodeMode::S_IRUSR;
|
||||
|
@ -21,8 +21,16 @@ impl InodeHandle<Rights> {
|
||||
if access_mode.is_writable() && inode.type_() == InodeType::Dir {
|
||||
return_errno_with_message!(Errno::EISDIR, "Directory cannot open to write");
|
||||
}
|
||||
|
||||
let file_io = if let Some(device) = inode.as_device() {
|
||||
device.open()?
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let inner = Arc::new(InodeHandle_ {
|
||||
dentry,
|
||||
file_io,
|
||||
offset: Mutex::new(0),
|
||||
access_mode,
|
||||
status_flags: AtomicU32::new(status_flags.bits()),
|
||||
@ -42,6 +50,7 @@ impl InodeHandle<Rights> {
|
||||
if !self.1.contains(Rights::READ) {
|
||||
return_errno_with_message!(Errno::EBADF, "File is not readable");
|
||||
}
|
||||
|
||||
self.0.read_to_end(buf)
|
||||
}
|
||||
|
||||
@ -75,11 +84,11 @@ impl FileLike for InodeHandle<Rights> {
|
||||
}
|
||||
|
||||
fn poll(&self, mask: IoEvents, poller: Option<&Poller>) -> IoEvents {
|
||||
self.dentry().inode().poll(mask, poller)
|
||||
self.0.poll(mask, poller)
|
||||
}
|
||||
|
||||
fn ioctl(&self, cmd: IoctlCmd, arg: usize) -> Result<i32> {
|
||||
self.dentry().inode().ioctl(cmd, arg)
|
||||
self.0.ioctl(cmd, arg)
|
||||
}
|
||||
|
||||
fn metadata(&self) -> Metadata {
|
||||
@ -109,6 +118,6 @@ impl FileLike for InodeHandle<Rights> {
|
||||
}
|
||||
|
||||
fn as_device(&self) -> Option<Arc<dyn Device>> {
|
||||
self.dentry().vnode().as_device()
|
||||
self.dentry().inode().as_device()
|
||||
}
|
||||
}
|
||||
|
@ -5,12 +5,14 @@ mod static_cap;
|
||||
|
||||
use core::sync::atomic::{AtomicU32, Ordering};
|
||||
|
||||
use crate::events::IoEvents;
|
||||
use crate::fs::device::Device;
|
||||
use crate::fs::file_handle::FileLike;
|
||||
use crate::fs::utils::{
|
||||
AccessMode, Dentry, DirentVisitor, InodeType, IoctlCmd, Metadata, SeekFrom, StatusFlags,
|
||||
};
|
||||
use crate::prelude::*;
|
||||
use crate::process::signal::Poller;
|
||||
use jinux_rights::Rights;
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -18,6 +20,10 @@ pub struct InodeHandle<R = Rights>(Arc<InodeHandle_>, R);
|
||||
|
||||
struct InodeHandle_ {
|
||||
dentry: Arc<Dentry>,
|
||||
/// `file_io` is Similar to `file_private` field in `file` structure in linux. If
|
||||
/// `file_io` is Some, typical file operations including `read`, `write`, `poll`,
|
||||
/// `ioctl` will be provided by `file_io`, instead of `dentry`.
|
||||
file_io: Option<Arc<dyn FileIo>>,
|
||||
offset: Mutex<usize>,
|
||||
access_mode: AccessMode,
|
||||
status_flags: AtomicU32,
|
||||
@ -26,6 +32,11 @@ struct InodeHandle_ {
|
||||
impl InodeHandle_ {
|
||||
pub fn read(&self, buf: &mut [u8]) -> Result<usize> {
|
||||
let mut offset = self.offset.lock();
|
||||
|
||||
if let Some(ref file_io) = self.file_io {
|
||||
return file_io.read(buf);
|
||||
}
|
||||
|
||||
let len = if self.status_flags().contains(StatusFlags::O_DIRECT) {
|
||||
self.dentry.inode().read_direct_at(*offset, buf)?
|
||||
} else {
|
||||
@ -38,6 +49,11 @@ impl InodeHandle_ {
|
||||
|
||||
pub fn write(&self, buf: &[u8]) -> Result<usize> {
|
||||
let mut offset = self.offset.lock();
|
||||
|
||||
if let Some(ref file_io) = self.file_io {
|
||||
return file_io.write(buf);
|
||||
}
|
||||
|
||||
if self.status_flags().contains(StatusFlags::O_APPEND) {
|
||||
*offset = self.dentry.inode_len();
|
||||
}
|
||||
@ -52,6 +68,10 @@ impl InodeHandle_ {
|
||||
}
|
||||
|
||||
pub fn read_to_end(&self, buf: &mut Vec<u8>) -> Result<usize> {
|
||||
if self.file_io.is_some() {
|
||||
return_errno_with_message!(Errno::EINVAL, "file io does not support read to end");
|
||||
}
|
||||
|
||||
let len = if self.status_flags().contains(StatusFlags::O_DIRECT) {
|
||||
self.dentry.inode().read_direct_to_end(buf)?
|
||||
} else {
|
||||
@ -118,6 +138,22 @@ impl InodeHandle_ {
|
||||
*offset += read_cnt;
|
||||
Ok(read_cnt)
|
||||
}
|
||||
|
||||
fn poll(&self, mask: IoEvents, poller: Option<&Poller>) -> IoEvents {
|
||||
if let Some(ref file_io) = self.file_io {
|
||||
return file_io.poll(mask, poller);
|
||||
}
|
||||
|
||||
self.dentry.inode().poll(mask, poller)
|
||||
}
|
||||
|
||||
fn ioctl(&self, cmd: IoctlCmd, arg: usize) -> Result<i32> {
|
||||
if let Some(ref file_io) = self.file_io {
|
||||
return file_io.ioctl(cmd, arg);
|
||||
}
|
||||
|
||||
self.dentry.inode().ioctl(cmd, arg)
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for InodeHandle_ {
|
||||
@ -137,3 +173,15 @@ impl<R> InodeHandle<R> {
|
||||
&self.0.dentry
|
||||
}
|
||||
}
|
||||
|
||||
pub trait FileIo: Send + Sync + 'static {
|
||||
fn read(&self, buf: &mut [u8]) -> Result<usize>;
|
||||
|
||||
fn write(&self, buf: &[u8]) -> Result<usize>;
|
||||
|
||||
fn poll(&self, mask: IoEvents, poller: Option<&Poller>) -> IoEvents;
|
||||
|
||||
fn ioctl(&self, cmd: IoctlCmd, arg: usize) -> Result<i32> {
|
||||
return_errno_with_message!(Errno::EINVAL, "ioctl is not supported");
|
||||
}
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ impl DirOps for RootDirOps {
|
||||
SelfSymOps::new_inode(this_ptr.clone())
|
||||
} else if let Ok(pid) = name.parse::<Pid>() {
|
||||
let process_ref =
|
||||
process_table::pid_to_process(pid).ok_or_else(|| Error::new(Errno::ENOENT))?;
|
||||
process_table::get_process(&pid).ok_or_else(|| Error::new(Errno::ENOENT))?;
|
||||
PidDirOps::new_inode(process_ref, this_ptr.clone())
|
||||
} else {
|
||||
return_errno!(Errno::ENOENT);
|
||||
|
Loading…
x
Reference in New Issue
Block a user