mirror of
https://github.com/rcore-os/rCore.git
synced 2024-11-23 00:16:17 +04:00
update fs. support poll for INode.
This commit is contained in:
parent
56cb8654ae
commit
a712f37c65
4
kernel/Cargo.lock
generated
4
kernel/Cargo.lock
generated
@ -345,12 +345,12 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "rcore-fs"
|
name = "rcore-fs"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/rcore-os/rcore-fs#c611248f800e946acf44d64b218aeb8fc6751640"
|
source = "git+https://github.com/rcore-os/rcore-fs#d7a2006cc316c98b7050aec63a2770dd690a4a80"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rcore-fs-sfs"
|
name = "rcore-fs-sfs"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/rcore-os/rcore-fs#c611248f800e946acf44d64b218aeb8fc6751640"
|
source = "git+https://github.com/rcore-os/rcore-fs#d7a2006cc316c98b7050aec63a2770dd690a4a80"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitvec 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitvec 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use alloc::{string::String, sync::Arc};
|
use alloc::{string::String, sync::Arc};
|
||||||
|
|
||||||
use rcore_fs::vfs::{FsError, INode, Metadata, Result};
|
use rcore_fs::vfs::{FsError, INode, Metadata, PollStatus, Result};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct FileHandle {
|
pub struct FileHandle {
|
||||||
@ -108,4 +108,12 @@ impl FileHandle {
|
|||||||
self.offset += 1;
|
self.offset += 1;
|
||||||
Ok(name)
|
Ok(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn poll(&self) -> Result<PollStatus> {
|
||||||
|
self.inode.poll()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn io_control(&self, cmd: u32, arg: u32) -> Result<()> {
|
||||||
|
self.inode.io_control(cmd, arg)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,9 @@ use core::fmt;
|
|||||||
|
|
||||||
use super::FileHandle;
|
use super::FileHandle;
|
||||||
use crate::net::Socket;
|
use crate::net::Socket;
|
||||||
use crate::syscall::SysResult;
|
use crate::syscall::{SysError, SysResult};
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
|
use rcore_fs::vfs::PollStatus;
|
||||||
|
|
||||||
// TODO: merge FileLike to FileHandle ?
|
// TODO: merge FileLike to FileHandle ?
|
||||||
// TODO: fix dup and remove Clone
|
// TODO: fix dup and remove Clone
|
||||||
@ -30,12 +31,22 @@ impl FileLike {
|
|||||||
}
|
}
|
||||||
pub fn ioctl(&mut self, request: usize, arg1: usize, arg2: usize, arg3: usize) -> SysResult {
|
pub fn ioctl(&mut self, request: usize, arg1: usize, arg2: usize, arg3: usize) -> SysResult {
|
||||||
match self {
|
match self {
|
||||||
FileLike::File(file) => {
|
FileLike::File(file) => file.io_control(request as u32, arg1 as u32)?,
|
||||||
warn!("ioctl not implemented for file");
|
FileLike::Socket(socket) => {
|
||||||
|
socket.ioctl(request, arg1, arg2, arg3)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
FileLike::Socket(socket) => socket.ioctl(request, arg1, arg2, arg3),
|
pub fn poll(&self) -> Result<PollStatus, SysError> {
|
||||||
|
let status = match self {
|
||||||
|
FileLike::File(file) => file.poll()?,
|
||||||
|
FileLike::Socket(socket) => {
|
||||||
|
let (read, write, error) = socket.poll();
|
||||||
|
PollStatus { read, write, error }
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
Ok(status)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +57,9 @@ impl Pipe {
|
|||||||
// TODO: better way to provide default impl?
|
// TODO: better way to provide default impl?
|
||||||
macro_rules! impl_inode {
|
macro_rules! impl_inode {
|
||||||
() => {
|
() => {
|
||||||
|
fn poll(&self) -> Result<PollStatus> { Err(FsError::NotSupported) }
|
||||||
fn metadata(&self) -> Result<Metadata> { Err(FsError::NotSupported) }
|
fn metadata(&self) -> Result<Metadata> { Err(FsError::NotSupported) }
|
||||||
|
fn set_metadata(&self, _metadata: &Metadata) -> Result<()> { Ok(()) }
|
||||||
fn sync_all(&self) -> Result<()> { Ok(()) }
|
fn sync_all(&self) -> Result<()> { Ok(()) }
|
||||||
fn sync_data(&self) -> Result<()> { Ok(()) }
|
fn sync_data(&self) -> Result<()> { Ok(()) }
|
||||||
fn resize(&self, _len: usize) -> Result<()> { Err(FsError::NotSupported) }
|
fn resize(&self, _len: usize) -> Result<()> { Err(FsError::NotSupported) }
|
||||||
@ -67,9 +69,9 @@ macro_rules! impl_inode {
|
|||||||
fn move_(&self, _old_name: &str, _target: &Arc<INode>, _new_name: &str) -> Result<()> { Err(FsError::NotDir) }
|
fn move_(&self, _old_name: &str, _target: &Arc<INode>, _new_name: &str) -> Result<()> { Err(FsError::NotDir) }
|
||||||
fn find(&self, _name: &str) -> Result<Arc<INode>> { Err(FsError::NotDir) }
|
fn find(&self, _name: &str) -> Result<Arc<INode>> { Err(FsError::NotDir) }
|
||||||
fn get_entry(&self, _id: usize) -> Result<String> { Err(FsError::NotDir) }
|
fn get_entry(&self, _id: usize) -> Result<String> { Err(FsError::NotDir) }
|
||||||
|
fn io_control(&self, _cmd: u32, _data: u32) -> Result<()> { Err(FsError::NotSupported) }
|
||||||
fn fs(&self) -> Arc<FileSystem> { unimplemented!() }
|
fn fs(&self) -> Arc<FileSystem> { unimplemented!() }
|
||||||
fn as_any_ref(&self) -> &Any { self }
|
fn as_any_ref(&self) -> &Any { self }
|
||||||
fn chmod(&self, _mode: u16) -> Result<()> { Ok(()) }
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,6 +47,7 @@ lazy_static! {
|
|||||||
macro_rules! impl_inode {
|
macro_rules! impl_inode {
|
||||||
() => {
|
() => {
|
||||||
fn metadata(&self) -> Result<Metadata> { Err(FsError::NotSupported) }
|
fn metadata(&self) -> Result<Metadata> { Err(FsError::NotSupported) }
|
||||||
|
fn set_metadata(&self, _metadata: &Metadata) -> Result<()> { Ok(()) }
|
||||||
fn sync_all(&self) -> Result<()> { Ok(()) }
|
fn sync_all(&self) -> Result<()> { Ok(()) }
|
||||||
fn sync_data(&self) -> Result<()> { Ok(()) }
|
fn sync_data(&self) -> Result<()> { Ok(()) }
|
||||||
fn resize(&self, _len: usize) -> Result<()> { Err(FsError::NotSupported) }
|
fn resize(&self, _len: usize) -> Result<()> { Err(FsError::NotSupported) }
|
||||||
@ -56,20 +57,27 @@ macro_rules! impl_inode {
|
|||||||
fn move_(&self, _old_name: &str, _target: &Arc<INode>, _new_name: &str) -> Result<()> { Err(FsError::NotDir) }
|
fn move_(&self, _old_name: &str, _target: &Arc<INode>, _new_name: &str) -> Result<()> { Err(FsError::NotDir) }
|
||||||
fn find(&self, _name: &str) -> Result<Arc<INode>> { Err(FsError::NotDir) }
|
fn find(&self, _name: &str) -> Result<Arc<INode>> { Err(FsError::NotDir) }
|
||||||
fn get_entry(&self, _id: usize) -> Result<String> { Err(FsError::NotDir) }
|
fn get_entry(&self, _id: usize) -> Result<String> { Err(FsError::NotDir) }
|
||||||
|
fn io_control(&self, _cmd: u32, _data: u32) -> Result<()> { Err(FsError::NotSupported) }
|
||||||
fn fs(&self) -> Arc<FileSystem> { unimplemented!() }
|
fn fs(&self) -> Arc<FileSystem> { unimplemented!() }
|
||||||
fn as_any_ref(&self) -> &Any { self }
|
fn as_any_ref(&self) -> &Any { self }
|
||||||
fn chmod(&self, _mode: u16) -> Result<()> { Ok(()) }
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
impl INode for Stdin {
|
impl INode for Stdin {
|
||||||
fn read_at(&self, _offset: usize, buf: &mut [u8]) -> Result<usize> {
|
fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize> {
|
||||||
buf[0] = self.pop() as u8;
|
buf[0] = self.pop() as u8;
|
||||||
Ok(1)
|
Ok(1)
|
||||||
}
|
}
|
||||||
fn write_at(&self, _offset: usize, _buf: &[u8]) -> Result<usize> {
|
fn write_at(&self, _offset: usize, _buf: &[u8]) -> Result<usize> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
fn poll(&self) -> Result<PollStatus> {
|
||||||
|
Ok(PollStatus {
|
||||||
|
read: self.can_read(),
|
||||||
|
write: false,
|
||||||
|
error: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
impl_inode!();
|
impl_inode!();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,5 +92,12 @@ impl INode for Stdout {
|
|||||||
print!("{}", s);
|
print!("{}", s);
|
||||||
Ok(buf.len())
|
Ok(buf.len())
|
||||||
}
|
}
|
||||||
|
fn poll(&self) -> Result<PollStatus> {
|
||||||
|
Ok(PollStatus {
|
||||||
|
read: false,
|
||||||
|
write: true,
|
||||||
|
error: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
impl_inode!();
|
impl_inode!();
|
||||||
}
|
}
|
||||||
|
@ -88,34 +88,24 @@ pub fn sys_poll(ufds: *mut PollFd, nfds: usize, timeout_msecs: usize) -> SysResu
|
|||||||
let proc = process();
|
let proc = process();
|
||||||
let mut events = 0;
|
let mut events = 0;
|
||||||
for poll in polls.iter_mut() {
|
for poll in polls.iter_mut() {
|
||||||
poll.revents = PE::NONE;
|
poll.revents = PE::empty();
|
||||||
match proc.files.get(&(poll.fd as usize)) {
|
if let Some(file_like) = proc.files.get(&(poll.fd as usize)) {
|
||||||
Some(FileLike::File(_)) => {
|
let status = file_like.poll()?;
|
||||||
// FIXME: assume it is stdin for now
|
if status.error {
|
||||||
if poll.events.contains(PE::IN) && STDIN.can_read() {
|
poll.revents |= PE::HUP;
|
||||||
poll.revents = poll.revents | PE::IN;
|
events += 1;
|
||||||
events = events + 1;
|
|
||||||
}
|
}
|
||||||
|
if status.read && poll.events.contains(PE::IN) {
|
||||||
|
poll.revents |= PE::IN;
|
||||||
|
events += 1;
|
||||||
}
|
}
|
||||||
Some(FileLike::Socket(socket)) => {
|
if status.write && poll.events.contains(PE::OUT) {
|
||||||
let (input, output, err) = socket.poll();
|
poll.revents |= PE::OUT;
|
||||||
if err {
|
events += 1;
|
||||||
poll.revents = poll.revents | PE::HUP;
|
|
||||||
events = events + 1;
|
|
||||||
}
|
|
||||||
if input && poll.events.contains(PE::IN) {
|
|
||||||
poll.revents = poll.revents | PE::IN;
|
|
||||||
events = events + 1;
|
|
||||||
}
|
|
||||||
if output && poll.events.contains(PE::OUT) {
|
|
||||||
poll.revents = poll.revents | PE::OUT;
|
|
||||||
events = events + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
poll.revents = poll.revents | PE::ERR;
|
|
||||||
events = events + 1;
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
poll.revents |= PE::ERR;
|
||||||
|
events += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
drop(proc);
|
drop(proc);
|
||||||
@ -163,33 +153,21 @@ pub fn sys_select(
|
|||||||
let proc = process();
|
let proc = process();
|
||||||
let mut events = 0;
|
let mut events = 0;
|
||||||
for (&fd, file_like) in proc.files.iter() {
|
for (&fd, file_like) in proc.files.iter() {
|
||||||
if fd < nfds {
|
if fd >= nfds {
|
||||||
match file_like {
|
continue;
|
||||||
FileLike::File(_) => {
|
|
||||||
// FIXME: assume it is stdin for now
|
|
||||||
if STDIN.can_read() {
|
|
||||||
if read_fds.contains(fd) {
|
|
||||||
read_fds.set(fd);
|
|
||||||
events = events + 1;
|
|
||||||
}
|
}
|
||||||
}
|
let status = file_like.poll()?;
|
||||||
}
|
if status.error && err_fds.contains(fd) {
|
||||||
FileLike::Socket(socket) => {
|
|
||||||
let (input, output, err) = socket.poll();
|
|
||||||
if err && err_fds.contains(fd) {
|
|
||||||
err_fds.set(fd);
|
err_fds.set(fd);
|
||||||
events = events + 1;
|
events += 1;
|
||||||
}
|
}
|
||||||
if input && read_fds.contains(fd) {
|
if status.read && read_fds.contains(fd) {
|
||||||
read_fds.set(fd);
|
read_fds.set(fd);
|
||||||
events = events + 1;
|
events += 1;
|
||||||
}
|
}
|
||||||
if output && write_fds.contains(fd) {
|
if status.write && write_fds.contains(fd) {
|
||||||
write_fds.set(fd);
|
write_fds.set(fd);
|
||||||
events = events + 1;
|
events += 1;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
drop(proc);
|
drop(proc);
|
||||||
@ -1165,8 +1143,6 @@ pub struct PollFd {
|
|||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
pub struct PollEvents: u16 {
|
pub struct PollEvents: u16 {
|
||||||
/// Nothing Happens
|
|
||||||
const NONE = 0x0000;
|
|
||||||
/// There is data to read.
|
/// There is data to read.
|
||||||
const IN = 0x0001;
|
const IN = 0x0001;
|
||||||
/// Writing is now possible.
|
/// Writing is now possible.
|
||||||
|
Loading…
Reference in New Issue
Block a user