From c661d38172e4d481ccda5505a1e19de714be504b Mon Sep 17 00:00:00 2001 From: Rafal Mielniczuk Date: Fri, 14 Jun 2024 17:19:27 +0100 Subject: [PATCH] Support NONBLOCK file open flag --- cykusz-rs/src/arch/x86_64/task/mod.rs | 4 ++-- cykusz-rs/src/drivers/ps2/kbd/handler.rs | 4 ++-- cykusz-rs/src/drivers/ps2/mouse/handler.rs | 4 ++-- cykusz-rs/src/drivers/random.rs | 3 ++- cykusz-rs/src/drivers/tty/mod.rs | 18 +++++++-------- cykusz-rs/src/kernel/fs/ext2/inode.rs | 8 +++---- cykusz-rs/src/kernel/fs/inode.rs | 11 +++++----- cykusz-rs/src/kernel/fs/mod.rs | 4 ++-- cykusz-rs/src/kernel/fs/pipe.rs | 9 ++++---- cykusz-rs/src/kernel/fs/ramfs.rs | 4 ++-- cykusz-rs/src/kernel/fs/vfs.rs | 2 ++ cykusz-rs/src/kernel/net/tcp/socket.rs | 14 ++++++------ cykusz-rs/src/kernel/net/udp/socket.rs | 8 +++---- cykusz-rs/src/kernel/net/unix/socket.rs | 14 ++++++------ .../src/kernel/task/filetable/inode_wrap.rs | 6 ++--- cykusz-rs/src/kernel/task/filetable/mod.rs | 4 ++-- cykusz-rs/src/kernel/utils/buffer.rs | 20 +++++++++++------ cykusz-rs/src/kernel/utils/wait_queue.rs | 22 +++++++++++++++++++ syscall-defs/src/lib.rs | 13 ++++++++++- syscall-defs/src/net.rs | 12 +++++++++- 20 files changed, 118 insertions(+), 66 deletions(-) diff --git a/cykusz-rs/src/arch/x86_64/task/mod.rs b/cykusz-rs/src/arch/x86_64/task/mod.rs index 6da81b57..1b6a818f 100644 --- a/cykusz-rs/src/arch/x86_64/task/mod.rs +++ b/cykusz-rs/src/arch/x86_64/task/mod.rs @@ -3,7 +3,7 @@ use core::mem::size_of; use core::ptr::Unique; use syscall_defs::exec::ExeArgs; -use syscall_defs::{MMapFlags, MMapProt}; +use syscall_defs::{MMapFlags, MMapProt, OpenFlags}; use crate::arch::gdt; use crate::arch::gdt::update_tss_rps0; @@ -124,7 +124,7 @@ fn prepare_tls(vm: &VM, p_table: &mut P4Table, tls: &TlsVmInfo) -> VirtAddr { if let Ok(r) = tls.file.inode().read_at(tls.file_offset + offset, unsafe { frame.address_mapped().as_bytes_mut(to_read) - }) { + }, OpenFlags::empty()) { if r != to_read { panic!("Failed to read tls data"); } diff --git a/cykusz-rs/src/drivers/ps2/kbd/handler.rs b/cykusz-rs/src/drivers/ps2/kbd/handler.rs index c0ae5996..0117a56a 100644 --- a/cykusz-rs/src/drivers/ps2/kbd/handler.rs +++ b/cykusz-rs/src/drivers/ps2/kbd/handler.rs @@ -43,11 +43,11 @@ impl Device for KbdState { } impl INode for KbdState { - fn read_at(&self, _offset: usize, buf: &mut [u8]) -> crate::kernel::fs::vfs::Result { + fn read_at(&self, _offset: usize, buf: &mut [u8], flags: OpenFlags) -> crate::kernel::fs::vfs::Result { if buf.len() % core::mem::size_of::() != 0 { Err(FsError::InvalidParam) } else { - Ok(self.buf.read_data_flags(buf, WaitQueueFlags::IRQ_DISABLE)?) + Ok(self.buf.read_data_flags(buf, WaitQueueFlags::IRQ_DISABLE | WaitQueueFlags::from(flags))?) } } diff --git a/cykusz-rs/src/drivers/ps2/mouse/handler.rs b/cykusz-rs/src/drivers/ps2/mouse/handler.rs index 9396c394..074d09a3 100644 --- a/cykusz-rs/src/drivers/ps2/mouse/handler.rs +++ b/cykusz-rs/src/drivers/ps2/mouse/handler.rs @@ -143,11 +143,11 @@ impl Device for MouseState { } impl INode for MouseState { - fn read_at(&self, _offset: usize, buf: &mut [u8]) -> crate::kernel::fs::vfs::Result { + fn read_at(&self, _offset: usize, buf: &mut [u8], flags: OpenFlags) -> crate::kernel::fs::vfs::Result { if buf.len() % core::mem::size_of::() != 0 { Err(FsError::InvalidParam) } else { - Ok(self.buf.read_data_flags(buf, WaitQueueFlags::IRQ_DISABLE)?) + Ok(self.buf.read_data_flags(buf, WaitQueueFlags::IRQ_DISABLE | WaitQueueFlags::from(flags))?) } } diff --git a/cykusz-rs/src/drivers/random.rs b/cykusz-rs/src/drivers/random.rs index 50fe27cc..28fe95e9 100644 --- a/cykusz-rs/src/drivers/random.rs +++ b/cykusz-rs/src/drivers/random.rs @@ -2,6 +2,7 @@ use alloc::string::String; use alloc::sync::{Arc, Weak}; use rand::{RngCore, SeedableRng}; +use syscall_defs::OpenFlags; use crate::kernel::device::dev_t::DevId; use crate::kernel::device::Device; @@ -38,7 +39,7 @@ impl Random { } impl INode for Random { - fn read_at(&self, _offset: usize, buf: &mut [u8]) -> crate::kernel::fs::vfs::Result { + fn read_at(&self, _offset: usize, buf: &mut [u8], _flags: OpenFlags) -> crate::kernel::fs::vfs::Result { self.rng.lock().fill_bytes(buf); Ok(buf.len()) diff --git a/cykusz-rs/src/drivers/tty/mod.rs b/cykusz-rs/src/drivers/tty/mod.rs index f6a63fe8..220e4a2d 100644 --- a/cykusz-rs/src/drivers/tty/mod.rs +++ b/cykusz-rs/src/drivers/tty/mod.rs @@ -15,12 +15,12 @@ use crate::kernel::device::dev_t::DevId; use crate::kernel::device::Device; use crate::kernel::fs::inode::INode; use crate::kernel::fs::poll::PollTable; +use crate::kernel::fs::vfs; use crate::kernel::fs::vfs::FsError; use crate::kernel::kbd::KeyListener; use crate::kernel::mm::VirtAddr; use crate::kernel::sched::current_task_ref; use crate::kernel::session::{sessions, Group}; -use crate::kernel::signal::{SignalError, SignalResult}; use crate::kernel::sync::{LockApi, Spin, SpinGuard}; use crate::kernel::task::Task; use crate::kernel::tty::TerminalDevice; @@ -133,21 +133,21 @@ impl Tty { }) } - fn read(&self, buf: *mut u8, len: usize) -> SignalResult { + fn read(&self, buf: *mut u8, len: usize, flags: OpenFlags) -> vfs::Result { if let Some(fg) = &*self.fg_group.lock_irq() { let task = current_task_ref(); if !fg.has_process(task.pid()) { task.signal(syscall_defs::signal::SIGTTIN); - return Err(SignalError::Interrupted); + return Err(FsError::Interrupted); } } let mut buffer = self .wait_queue - .wait_lock_for(WaitQueueFlags::IRQ_DISABLE, &self.buffer, |lck| { + .wait_lock_for(WaitQueueFlags::IRQ_DISABLE | WaitQueueFlags::from(flags), &self.buffer, |lck| { lck.has_data() })? - .unwrap(); + .ok_or(FsError::WouldBlock)?; Ok(buffer.read(buf, len)) } @@ -461,21 +461,21 @@ impl TerminalDevice for Tty { } impl INode for Tty { - fn read_at(&self, _offset: usize, buf: &mut [u8]) -> Result { + fn read_at(&self, _offset: usize, buf: &mut [u8], flags: OpenFlags) -> Result { logln2!("try tty read"); - let r = self.read(buf.as_mut_ptr(), buf.len()); + let r = self.read(buf.as_mut_ptr(), buf.len(), flags); logln2!("tty read {:?} {:?}", r, buf); match r { Ok(s) => Ok(s), Err(e) => { - logln2!("tty signal error"); + logln2!("tty error {:?}", e); Err(e.into()) } } } - fn write_at(&self, _offset: usize, buf: &[u8]) -> Result { + fn write_at(&self, _offset: usize, buf: &[u8], _flags: OpenFlags) -> Result { if let Err(_) = self.write_str(unsafe { core::str::from_utf8_unchecked(buf) }) { Err(FsError::InvalidParam) } else { diff --git a/cykusz-rs/src/kernel/fs/ext2/inode.rs b/cykusz-rs/src/kernel/fs/ext2/inode.rs index 28429de3..b17f71f1 100644 --- a/cykusz-rs/src/kernel/fs/ext2/inode.rs +++ b/cykusz-rs/src/kernel/fs/ext2/inode.rs @@ -467,7 +467,7 @@ impl Ext2INode { impl RawAccess for LockedExt2INode { fn read_direct(&self, addr: usize, dest: &mut [u8]) -> Option { - if let Ok(read) = self.read_at(addr, dest) { + if let Ok(read) = self.read_at(addr, dest, OpenFlags::empty()) { Some(read) } else { None @@ -729,7 +729,7 @@ impl INode for LockedExt2INode { Ok(()) } - fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result { + fn read_at(&self, offset: usize, buf: &mut [u8], _flags: OpenFlags) -> Result { if self.ftype()? != FileType::File && self.ftype()? != FileType::Symlink { return Err(FsError::NotFile); } @@ -739,7 +739,7 @@ impl INode for LockedExt2INode { Ok(reader.read(buf)) } - fn write_at(&self, offset: usize, buf: &[u8]) -> Result { + fn write_at(&self, offset: usize, buf: &[u8], _flags: OpenFlags) -> Result { if self.ftype()? != FileType::File && self.ftype()? != FileType::Symlink { return Err(FsError::NotFile); } @@ -846,7 +846,7 @@ impl INode for LockedExt2INode { let new_inode = self.mk_inode(FileType::Symlink)?; - if let Err(e) = new_inode.write_at(0, target.as_bytes()) { + if let Err(e) = new_inode.write_at(0, target.as_bytes(), OpenFlags::empty()) { self.ext2_fs().free_inode(&new_inode.as_ext2_inode()); return Err(e); diff --git a/cykusz-rs/src/kernel/fs/inode.rs b/cykusz-rs/src/kernel/fs/inode.rs index 62f4a44d..5c9d1273 100644 --- a/cykusz-rs/src/kernel/fs/inode.rs +++ b/cykusz-rs/src/kernel/fs/inode.rs @@ -53,20 +53,19 @@ pub trait INode: Send + Sync + DowncastSync { Err(FsError::NotSupported) } - fn read_at(&self, _offset: usize, _buf: &mut [u8]) -> Result { + fn read_at(&self, _offset: usize, _buf: &mut [u8], _flags: OpenFlags) -> Result { Err(FsError::NotSupported) } - fn read_all(&self) -> Vec { + fn read_all(&self) -> Result> { let meta = self.metadata().unwrap(); let mut data = Vec::::new(); data.resize(meta.size, 0); - self.read_at(0, data.as_mut_slice()) - .expect("fstab read failed"); - data + self.read_at(0, data.as_mut_slice(), OpenFlags::empty())?; + Ok(data) } - fn write_at(&self, _offset: usize, _buf: &[u8]) -> Result { + fn write_at(&self, _offset: usize, _buf: &[u8], _flags: OpenFlags) -> Result { Err(FsError::NotSupported) } diff --git a/cykusz-rs/src/kernel/fs/mod.rs b/cykusz-rs/src/kernel/fs/mod.rs index ffed180a..95a000f6 100644 --- a/cykusz-rs/src/kernel/fs/mod.rs +++ b/cykusz-rs/src/kernel/fs/mod.rs @@ -122,7 +122,7 @@ pub fn mount_root() { mount::mark_mounted(root_fs.clone()); if let Ok(fstab) = lookup_by_path(&Path::new("/etc/fstab"), LookupMode::None) { - let data = fstab.inode().read_all(); + let data = fstab.inode().read_all().expect("/etc/fstab read failed"); if let Ok(content) = core::str::from_utf8(data.as_slice()) { for line in content.split("\n") { @@ -165,7 +165,7 @@ pub fn read_link(inode: &Arc) -> Result { let mut offset = 0; loop { - offset += inode.read_at(offset, &mut path.as_mut_slice()[offset..])?; + offset += inode.read_at(offset, &mut path.as_mut_slice()[offset..], OpenFlags::empty())?; if offset == path.len() { path.resize(offset + 128, 0); diff --git a/cykusz-rs/src/kernel/fs/pipe.rs b/cykusz-rs/src/kernel/fs/pipe.rs index c769c303..d88d726b 100644 --- a/cykusz-rs/src/kernel/fs/pipe.rs +++ b/cykusz-rs/src/kernel/fs/pipe.rs @@ -13,6 +13,7 @@ use crate::kernel::fs::vfs::{FsError, Result}; use crate::kernel::sync::{LockApi, Mutex, MutexGuard}; use crate::kernel::utils::buffer::BufferQueue; use crate::kernel::utils::node_map::{NodeMap, NodeMapItem}; +use crate::kernel::utils::wait_queue::WaitQueueFlags; pub struct Pipe { buf: BufferQueue, @@ -87,12 +88,12 @@ impl INode for Pipe { Ok(stat) } - fn read_at(&self, _offset: usize, buf: &mut [u8]) -> Result { - Ok(self.buf.read_data(buf)?) + fn read_at(&self, _offset: usize, buf: &mut [u8], flags: OpenFlags) -> Result { + Ok(self.buf.read_data_flags(buf, WaitQueueFlags::from(flags))?) } - fn write_at(&self, _offset: usize, buf: &[u8]) -> Result { - self.buf.append_data(buf) + fn write_at(&self, _offset: usize, buf: &[u8], flags: OpenFlags) -> Result { + self.buf.append_data_flags(buf, WaitQueueFlags::from(flags)) } fn poll( diff --git a/cykusz-rs/src/kernel/fs/ramfs.rs b/cykusz-rs/src/kernel/fs/ramfs.rs index 70fbb9d1..6981dedf 100644 --- a/cykusz-rs/src/kernel/fs/ramfs.rs +++ b/cykusz-rs/src/kernel/fs/ramfs.rs @@ -126,7 +126,7 @@ impl INode for LockedRamINode { self.make_inode(name, FileType::Dir, |_| Ok(())) } - fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result { + fn read_at(&self, offset: usize, buf: &mut [u8], _flags: OpenFlags) -> Result { let i = self.0.read(); match &i.content { @@ -147,7 +147,7 @@ impl INode for LockedRamINode { } } - fn write_at(&self, offset: usize, buf: &[u8]) -> Result { + fn write_at(&self, offset: usize, buf: &[u8], _flags: OpenFlags) -> Result { let i = self.0.read(); match &i.content { diff --git a/cykusz-rs/src/kernel/fs/vfs.rs b/cykusz-rs/src/kernel/fs/vfs.rs index 1f73c52d..289ea86b 100644 --- a/cykusz-rs/src/kernel/fs/vfs.rs +++ b/cykusz-rs/src/kernel/fs/vfs.rs @@ -18,6 +18,7 @@ pub enum FsError { IsPipe, Interrupted, NoSuchDevice, + WouldBlock } impl From for syscall_defs::SyscallError { @@ -37,6 +38,7 @@ impl From for syscall_defs::SyscallError { FsError::IsPipe => SyscallError::ESPIPE, FsError::Interrupted => SyscallError::EINTR, FsError::NoSuchDevice => SyscallError::ENXIO, + FsError::WouldBlock => SyscallError::EAGAIN, } } } diff --git a/cykusz-rs/src/kernel/net/tcp/socket.rs b/cykusz-rs/src/kernel/net/tcp/socket.rs index f73db62e..6b8943cc 100644 --- a/cykusz-rs/src/kernel/net/tcp/socket.rs +++ b/cykusz-rs/src/kernel/net/tcp/socket.rs @@ -907,7 +907,7 @@ impl Socket { offset, buf, flags.contains(MsgFlags::MSG_PEEK), - WaitQueueFlags::empty(), + WaitQueueFlags::from(flags), )?) } @@ -928,13 +928,13 @@ impl INode for Socket { Ok(stat) } - fn read_at(&self, _offset: usize, buf: &mut [u8]) -> Result { + fn read_at(&self, _offset: usize, buf: &mut [u8], flags: OpenFlags) -> Result { //let data = self.data.lock(); //if data.is_listening() { // return Err(FsError::NotSupported); //} //drop(data); - let r = self.read(0, buf, MsgFlags::empty())?; + let r = self.read(0, buf, MsgFlags::from(flags))?; if r > 0 { self.update_window(); @@ -943,7 +943,7 @@ impl INode for Socket { Ok(r) } - fn write_at(&self, _offset: usize, buf: &[u8]) -> Result { + fn write_at(&self, _offset: usize, buf: &[u8], flags: OpenFlags) -> Result { logln5!("write_at socket, len: {}", buf.len()); let mut data = self.data.lock(); @@ -960,7 +960,7 @@ impl INode for Socket { //println!("[ TCP ] Proxy Buffer avail: {}", data.proxy_buffer.available_size()); - while data.proxy_buffer.available_size() < buf.len() { + while data.proxy_buffer.available_size() < buf.len() && !flags.contains(OpenFlags::NONBLOCK) { if let Err(e) = WaitQueue::wait_lock(data) { data = self.data.lock(); @@ -1122,14 +1122,14 @@ impl SocketService for Socket { Ok(0) } - fn msg_send(&self, hdr: &MsgHdr, _flags: MsgFlags) -> SyscallResult { + fn msg_send(&self, hdr: &MsgHdr, flags: MsgFlags) -> SyscallResult { logln!("tcp msg_send"); let iovecs = hdr.iovecs(); let mut total = 0; for iovec in iovecs { - total += self.write_at(0, iovec.get_bytes())?; + total += self.write_at(0, iovec.get_bytes(), OpenFlags::from(flags))?; } Ok(total) diff --git a/cykusz-rs/src/kernel/net/udp/socket.rs b/cykusz-rs/src/kernel/net/udp/socket.rs index 1a99a315..39af5446 100644 --- a/cykusz-rs/src/kernel/net/udp/socket.rs +++ b/cykusz-rs/src/kernel/net/udp/socket.rs @@ -150,12 +150,12 @@ impl INode for Socket { Ok(stat) } - fn read_at(&self, _offset: usize, buf: &mut [u8]) -> Result { + fn read_at(&self, _offset: usize, buf: &mut [u8], flags: OpenFlags) -> Result { logln4!("udp read {}", buf.len()); let mut data = self .buffer_wq - .wait_lock_for(WaitQueueFlags::empty(), &self.buffer, |l| !l.is_empty())? - .unwrap(); + .wait_lock_for(WaitQueueFlags::from(flags), &self.buffer, |l| !l.is_empty())? + .ok_or(FsError::WouldBlock)?; let packet = data.pop_front().unwrap(); @@ -168,7 +168,7 @@ impl INode for Socket { Ok(size) } - fn write_at(&self, _offset: usize, buf: &[u8]) -> Result { + fn write_at(&self, _offset: usize, buf: &[u8], _flags: OpenFlags) -> Result { self.send(buf, None) } diff --git a/cykusz-rs/src/kernel/net/unix/socket.rs b/cykusz-rs/src/kernel/net/unix/socket.rs index 7d82d5d5..e0840e55 100644 --- a/cykusz-rs/src/kernel/net/unix/socket.rs +++ b/cykusz-rs/src/kernel/net/unix/socket.rs @@ -300,13 +300,13 @@ impl SocketService for Socket { Ok(0) } - fn msg_send(&self, hdr: &MsgHdr, _flags: MsgFlags) -> SyscallResult { + fn msg_send(&self, hdr: &MsgHdr, flags: MsgFlags) -> SyscallResult { let iovecs = hdr.iovecs(); let mut total = 0; for iovec in iovecs { - total += self.write_at(0, iovec.get_bytes())?; + total += self.write_at(0, iovec.get_bytes(), OpenFlags::from(flags))?; } Ok(total) @@ -328,7 +328,7 @@ impl SocketService for Socket { 0 }; - let read = self.read_at(offset, iovec.get_bytes_mut())?; + let read = self.read_at(offset, iovec.get_bytes_mut(), OpenFlags::from(flags))?; if read == 0 { return Ok(total); @@ -357,18 +357,18 @@ impl INode for Socket { Ok(stat) } - fn read_at(&self, _offset: usize, buf: &mut [u8]) -> crate::kernel::fs::vfs::Result { - Ok(self.buffer.read_data(buf)?) + fn read_at(&self, _offset: usize, buf: &mut [u8], flags: OpenFlags) -> crate::kernel::fs::vfs::Result { + Ok(self.buffer.read_data_flags(buf, WaitQueueFlags::from(flags))?) } - fn write_at(&self, _offset: usize, buf: &[u8]) -> crate::kernel::fs::vfs::Result { + fn write_at(&self, _offset: usize, buf: &[u8], flags: OpenFlags) -> crate::kernel::fs::vfs::Result { let target = if let SocketState::Connected(target) = &*self.data.lock() { target.clone() } else { return Err(FsError::NotSupported); }; - Ok(target.buffer.append_data(buf)?) + Ok(target.buffer.append_data_flags(buf, WaitQueueFlags::from(flags))?) } fn poll( diff --git a/cykusz-rs/src/kernel/task/filetable/inode_wrap.rs b/cykusz-rs/src/kernel/task/filetable/inode_wrap.rs index d54cf541..a905798f 100644 --- a/cykusz-rs/src/kernel/task/filetable/inode_wrap.rs +++ b/cykusz-rs/src/kernel/task/filetable/inode_wrap.rs @@ -102,9 +102,9 @@ impl INode for INodeOpsWrap { impl_delegate!(mkdir, vfs::Result, name: &str); impl_delegate!(rmdir, vfs::Result<()>, name: &str); impl_delegate!(unlink, vfs::Result<()>, name: &str); - impl_delegate!(read_at, vfs::Result, offset: usize, buf: &mut [u8]); - impl_delegate!(read_all, Vec); - impl_delegate!(write_at, vfs::Result, offset: usize, buf: &[u8]); + impl_delegate!(read_at, vfs::Result, offset: usize, buf: &mut [u8], flags: OpenFlags); + impl_delegate!(read_all, vfs::Result>); + impl_delegate!(write_at, vfs::Result, offset: usize, buf: &[u8], flags: OpenFlags); impl_delegate!(poll, vfs::Result, poll_table: Option<&mut PollTable>, flags: PollEventFlags); impl_delegate!(fs, Option>); impl_delegate!(create, vfs::Result, parent: DirEntryItem,name: &str, ftype: FileType); diff --git a/cykusz-rs/src/kernel/task/filetable/mod.rs b/cykusz-rs/src/kernel/task/filetable/mod.rs index 8f96b47c..ca9df0e4 100644 --- a/cykusz-rs/src/kernel/task/filetable/mod.rs +++ b/cykusz-rs/src/kernel/task/filetable/mod.rs @@ -77,7 +77,7 @@ impl FileHandle { } pub fn read_at(&self, buf: &mut [u8], offset: usize) -> Result { - Ok(self.inode.read_at(offset, buf)?) + Ok(self.inode.read_at(offset, buf, self.flags())?) } pub fn write_at(&self, buf: &[u8], offset: usize) -> Result { @@ -90,7 +90,7 @@ impl FileHandle { return Err(FsError::NotSupported); } } - None => inode.write_at(offset, buf)?, + None => inode.write_at(offset, buf, self.flags())?, }) } diff --git a/cykusz-rs/src/kernel/utils/buffer.rs b/cykusz-rs/src/kernel/utils/buffer.rs index 557b19e1..3a8f044d 100644 --- a/cykusz-rs/src/kernel/utils/buffer.rs +++ b/cykusz-rs/src/kernel/utils/buffer.rs @@ -1,5 +1,6 @@ use alloc::vec::Vec; use core::sync::atomic::{AtomicBool, Ordering}; +use crate::kernel::fs::vfs; use crate::kernel::fs::vfs::FsError; use crate::kernel::signal::SignalResult; @@ -154,7 +155,7 @@ impl BufferQueue { written } - pub fn append_data(&self, data: &[u8]) -> crate::kernel::fs::vfs::Result { + pub fn append_data_flags(&self, data: &[u8], flags: WaitQueueFlags) -> crate::kernel::fs::vfs::Result { if data.is_empty() { return Ok(0); } @@ -163,11 +164,11 @@ impl BufferQueue { let mut buffer = self .writer_queue - .wait_lock_for(WaitQueueFlags::empty(), &self.buffer, |lck| { + .wait_lock_for(flags, &self.buffer, |lck| { let _ = &lck; !self.has_readers() || lck.available_size() > 0 })? - .unwrap(); + .ok_or(vfs::FsError::WouldBlock)?; if !self.has_readers() { logln!("no readers......"); @@ -183,6 +184,11 @@ impl BufferQueue { self.reader_queue.notify_one(); Ok(written) + + } + + pub fn append_data(&self, data: &[u8]) -> crate::kernel::fs::vfs::Result { + self.append_data_flags(data, WaitQueueFlags::empty()) } pub fn available_size(&self) -> usize { @@ -199,7 +205,7 @@ impl BufferQueue { buf: &mut [u8], transient: bool, wg_flags: WaitQueueFlags, - ) -> SignalResult { + ) -> vfs::Result { if offset > 0 && !transient { return Ok(0); } @@ -210,7 +216,7 @@ impl BufferQueue { .wait_lock_for(wg_flags, &self.buffer, |l| { self.has_data_locked(l) || self.shutting_down() || offset > 0 })? - .unwrap(); + .ok_or(vfs::FsError::WouldBlock)?; logln!("READ DATA STARTING"); let read = if transient { @@ -230,11 +236,11 @@ impl BufferQueue { Ok(read) } - pub fn read_data(&self, buf: &mut [u8]) -> SignalResult { + pub fn read_data(&self, buf: &mut [u8]) -> vfs::Result { self.read_data_from(0, buf, false, WaitQueueFlags::empty()) } - pub fn read_data_flags(&self, buf: &mut [u8], wg_flags: WaitQueueFlags) -> SignalResult { + pub fn read_data_flags(&self, buf: &mut [u8], wg_flags: WaitQueueFlags) -> vfs::Result { self.read_data_from(0, buf, false, wg_flags) } diff --git a/cykusz-rs/src/kernel/utils/wait_queue.rs b/cykusz-rs/src/kernel/utils/wait_queue.rs index 158b73af..657a86d5 100644 --- a/cykusz-rs/src/kernel/utils/wait_queue.rs +++ b/cykusz-rs/src/kernel/utils/wait_queue.rs @@ -1,5 +1,7 @@ use alloc::sync::Arc; use alloc::vec::Vec; +use syscall_defs::net::MsgFlags; +use syscall_defs::OpenFlags; use crate::kernel::sched::{current_task, SleepFlags}; use crate::kernel::signal::{SignalError, SignalResult}; @@ -34,6 +36,26 @@ impl From for SleepFlags { } } +impl From for WaitQueueFlags { + fn from(value: OpenFlags) -> Self { + if value.contains(OpenFlags::NONBLOCK) { + WaitQueueFlags::NO_HANG + } else { + WaitQueueFlags::empty() + } + } +} + +impl From for WaitQueueFlags { + fn from(value: MsgFlags) -> Self { + if value.contains(MsgFlags::MSG_DONTWAIT) { + WaitQueueFlags::NO_HANG + } else { + WaitQueueFlags::empty() + } + } +} + impl<'a> WaitQueueGuard<'a> { pub fn new(wq: &'a WaitQueue, task: &'a Arc) -> WaitQueueGuard<'a> { wq.add_task(task.clone()); diff --git a/syscall-defs/src/lib.rs b/syscall-defs/src/lib.rs index 38c4e647..062a5f16 100644 --- a/syscall-defs/src/lib.rs +++ b/syscall-defs/src/lib.rs @@ -7,6 +7,7 @@ extern crate alloc; #[macro_use] extern crate bitflags; +use crate::net::MsgFlags; use crate::stat::Mode; pub mod events; @@ -260,9 +261,19 @@ bitflags! { } } +impl From for OpenFlags { + fn from(value: MsgFlags) -> Self { + if value.contains(MsgFlags::MSG_DONTWAIT) { + OpenFlags::NONBLOCK + } else { + OpenFlags::empty() + } + } +} + impl OpenFlags { pub fn set_fd_flags_mask() -> usize { - (OpenFlags::APPEND | OpenFlags::ASYNC | OpenFlags::DIRECT | OpenFlags::NOATIME).bits() + (OpenFlags::APPEND | OpenFlags::ASYNC | OpenFlags::DIRECT | OpenFlags::NOATIME | OpenFlags::NONBLOCK).bits() } pub fn is_open_mode(&self, open_mode: OpenFlags) -> bool { diff --git a/syscall-defs/src/net.rs b/syscall-defs/src/net.rs index 1e2a9fca..99a9090d 100644 --- a/syscall-defs/src/net.rs +++ b/syscall-defs/src/net.rs @@ -1,4 +1,4 @@ -use crate::SyscallError; +use crate::{OpenFlags, SyscallError}; #[derive(Debug, Copy, Clone)] pub struct SockTypeFlags(u64); @@ -37,6 +37,16 @@ bitflags! { } } +impl From for MsgFlags { + fn from(value: OpenFlags) -> Self { + if value.contains(OpenFlags::NONBLOCK) { + MsgFlags::MSG_DONTWAIT + } else { + MsgFlags::empty() + } + } +} + #[repr(u64)] #[derive(Debug, Copy, Clone)] pub enum SockType {