From f8c88baeea2f935124992483f0294d6b2ad54d21 Mon Sep 17 00:00:00 2001 From: PanQL Date: Mon, 20 May 2019 10:28:27 +0800 Subject: [PATCH] nonblock stdin for mgba keyboard support --- kernel/src/fs/file.rs | 20 +++++++++++++++++++- kernel/src/fs/file_like.rs | 10 ++++++++++ kernel/src/fs/stdio.rs | 11 +++++++---- kernel/src/process/structs.rs | 3 +++ kernel/src/syscall/fs.rs | 13 +++++++++++++ kernel/src/syscall/mod.rs | 5 ++++- 6 files changed, 56 insertions(+), 6 deletions(-) diff --git a/kernel/src/fs/file.rs b/kernel/src/fs/file.rs index aefd349..5d8505e 100644 --- a/kernel/src/fs/file.rs +++ b/kernel/src/fs/file.rs @@ -19,6 +19,7 @@ pub struct OpenOptions { pub write: bool, /// Before each write, the file offset is positioned at the end of the file. pub append: bool, + pub nonblock: bool, } #[derive(Debug)] @@ -48,7 +49,17 @@ impl FileHandle { if !self.options.read { return Err(FsError::InvalidParam); // FIXME: => EBADF } - let len = self.inode.read_at(offset, buf)?; + let mut len : usize = 0; + if !self.options.nonblock { // block + loop { + len = self.inode.read_at(offset, buf)?; + if len > 0 { + break; + } + } + }else{ + len = self.inode.read_at(offset, buf)?; + } Ok(len) } @@ -123,6 +134,13 @@ impl FileHandle { pub fn inode(&self) -> Arc { self.inode.clone() } + + pub fn fcntl(&mut self, cmd: usize, arg: usize) -> Result<()> { + if arg == 2048 && cmd == 4 { + self.options.nonblock = true; + } + Ok(()) + } } impl fmt::Debug for FileHandle { diff --git a/kernel/src/fs/file_like.rs b/kernel/src/fs/file_like.rs index 5e847f1..d489e01 100644 --- a/kernel/src/fs/file_like.rs +++ b/kernel/src/fs/file_like.rs @@ -56,6 +56,16 @@ impl FileLike { }; Ok(status) } + + pub fn fcntl(&mut self, cmd: usize, arg: usize) -> SysResult { + match self { + FileLike::File(file) => file.fcntl(cmd, arg)?, + FileLike::Socket(socket) => { + //TODO + } + } + Ok(0) + } } impl fmt::Debug for FileLike { diff --git a/kernel/src/fs/stdio.rs b/kernel/src/fs/stdio.rs index db70ec8..ccb8204 100644 --- a/kernel/src/fs/stdio.rs +++ b/kernel/src/fs/stdio.rs @@ -35,8 +35,7 @@ impl Stdin { match buf_lock.pop_front() { Some(c) => return c, None => { - //self.pushed.wait(buf_lock); - return 0 as char; + self.pushed.wait(buf_lock); } } } @@ -92,8 +91,12 @@ macro_rules! impl_inode { impl INode for Stdin { fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result { - buf[0] = self.pop() as u8; - Ok(1) + if self.can_read() { + buf[0] = self.pop() as u8; + Ok(1) + }else{ + Ok(0) + } } fn write_at(&self, _offset: usize, _buf: &[u8]) -> Result { unimplemented!() diff --git a/kernel/src/process/structs.rs b/kernel/src/process/structs.rs index 3f7c272..5a3a88e 100644 --- a/kernel/src/process/structs.rs +++ b/kernel/src/process/structs.rs @@ -260,6 +260,7 @@ impl Thread { read: true, write: false, append: false, + nonblock: false, }, String::from("stdin"), )), @@ -272,6 +273,7 @@ impl Thread { read: false, write: true, append: false, + nonblock: false, }, String::from("stdout"), )), @@ -284,6 +286,7 @@ impl Thread { read: false, write: true, append: false, + nonblock: false, }, String::from("stderr"), )), diff --git a/kernel/src/syscall/fs.rs b/kernel/src/syscall/fs.rs index f997f5f..ef11a83 100644 --- a/kernel/src/syscall/fs.rs +++ b/kernel/src/syscall/fs.rs @@ -703,6 +703,7 @@ impl Syscall<'_> { read: true, write: false, append: false, + nonblock: false, }, String::from("pipe_r:[]"), ))); @@ -713,6 +714,7 @@ impl Syscall<'_> { read: false, write: true, append: false, + nonblock: false, }, String::from("pipe_w:[]"), ))); @@ -828,6 +830,16 @@ impl Syscall<'_> { ); return Ok(total_written); } + + pub fn sys_fcntl(&mut self, fd : usize, cmd : usize, arg : usize) -> SysResult{ + info!( + "fcntl: fd: {}, cmd: {:x}, arg: {}", + fd, cmd, arg + ); + let mut proc = self.process(); + let file_like = proc.get_file_like(fd)?; + file_like.fcntl(cmd, arg) + } } impl Process { @@ -978,6 +990,7 @@ impl OpenFlags { read: self.readable(), write: self.writable(), append: self.contains(OpenFlags::APPEND), + nonblock: false, } } } diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 896d5d1..268771c 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -99,7 +99,10 @@ impl Syscall<'_> { SYS_READV => self.sys_readv(args[0], args[1] as *const IoVec, args[2]), SYS_WRITEV => self.sys_writev(args[0], args[1] as *const IoVec, args[2]), SYS_SENDFILE => self.sys_sendfile(args[0], args[1], args[2] as *mut usize, args[3]), - SYS_FCNTL => self.unimplemented("fcntl", Ok(0)), + SYS_FCNTL => { + info!("SYS_FCNTL : {} {} {} {}", args[0], args[1], args[2], args[3]); + self.sys_fcntl(args[0], args[1], args[2]) + }, SYS_FLOCK => self.unimplemented("flock", Ok(0)), SYS_FSYNC => self.sys_fsync(args[0]), SYS_FDATASYNC => self.sys_fdatasync(args[0]),