diff --git a/kernel/src/device/pty/master.rs b/kernel/src/device/pty/master.rs index 801f87b19..7ecff014c 100644 --- a/kernel/src/device/pty/master.rs +++ b/kernel/src/device/pty/master.rs @@ -80,12 +80,17 @@ impl Pollable for PtyMaster { } impl FileIo for PtyMaster { - fn read(&self, writer: &mut VmWriter, _status_flags: StatusFlags) -> Result { - // TODO: Add support for non-blocking mode and timeout + fn read(&self, writer: &mut VmWriter, status_flags: StatusFlags) -> Result { + // TODO: Add support for timeout. let mut buf = vec![0u8; writer.avail().min(IO_CAPACITY)]; - let read_len = self.wait_events(IoEvents::IN, None, || { - self.slave.driver().try_read(&mut buf) - })?; + let is_nonblocking = status_flags.contains(StatusFlags::O_NONBLOCK); + let read_len = if is_nonblocking { + self.slave.driver().try_read(&mut buf)? + } else { + self.wait_events(IoEvents::IN, None, || { + self.slave.driver().try_read(&mut buf) + })? + }; self.slave.driver().pollee().invalidate(); self.slave.notify_output(); @@ -94,14 +99,19 @@ impl FileIo for PtyMaster { Ok(read_len) } - fn write(&self, reader: &mut VmReader, _status_flags: StatusFlags) -> Result { + fn write(&self, reader: &mut VmReader, status_flags: StatusFlags) -> Result { let mut buf = vec![0u8; reader.remain().min(IO_CAPACITY)]; let write_len = reader.read_fallible(&mut buf.as_mut_slice().into())?; - // TODO: Add support for non-blocking mode and timeout - let len = self.wait_events(IoEvents::OUT, None, || { - self.slave.push_input(&buf[..write_len]) - })?; + // TODO: Add support for timeout. + let is_nonblocking = status_flags.contains(StatusFlags::O_NONBLOCK); + let len = if is_nonblocking { + self.slave.push_input(&buf[..write_len])? + } else { + self.wait_events(IoEvents::OUT, None, || { + self.slave.push_input(&buf[..write_len]) + })? + }; self.slave.driver().pollee().invalidate(); Ok(len) } diff --git a/kernel/src/device/tty/mod.rs b/kernel/src/device/tty/mod.rs index fdb169b8c..c6155d4cd 100644 --- a/kernel/src/device/tty/mod.rs +++ b/kernel/src/device/tty/mod.rs @@ -241,17 +241,21 @@ impl Pollable for Tty { } impl FileIo for Tty { - fn read(&self, writer: &mut VmWriter, _status_flags: StatusFlags) -> Result { + fn read(&self, writer: &mut VmWriter, status_flags: StatusFlags) -> Result { if self.driver.is_closed() { return Ok(0); } self.job_control.wait_until_in_foreground()?; - // TODO: Add support for non-blocking mode and timeout + // TODO: Add support for timeout. let mut buf = vec![0u8; writer.avail().min(IO_CAPACITY)]; - let read_len = - self.wait_events(IoEvents::IN, None, || self.ldisc.lock().try_read(&mut buf))?; + let is_nonblocking = status_flags.contains(StatusFlags::O_NONBLOCK); + let read_len = if is_nonblocking { + self.ldisc.lock().try_read(&mut buf)? + } else { + self.wait_events(IoEvents::IN, None, || self.ldisc.lock().try_read(&mut buf))? + }; self.pollee.invalidate(); self.driver.notify_input(); @@ -260,14 +264,19 @@ impl FileIo for Tty { Ok(read_len) } - fn write(&self, reader: &mut VmReader, _status_flags: StatusFlags) -> Result { + fn write(&self, reader: &mut VmReader, status_flags: StatusFlags) -> Result { let mut buf = vec![0u8; reader.remain().min(IO_CAPACITY)]; let write_len = reader.read_fallible(&mut buf.as_mut_slice().into())?; - // TODO: Add support for non-blocking mode and timeout - let len = self.wait_events(IoEvents::OUT, None, || { - self.driver.push_output(&buf[..write_len]) - })?; + // TODO: Add support for timeout. + let is_nonblocking = status_flags.contains(StatusFlags::O_NONBLOCK); + let len = if is_nonblocking { + self.driver.push_output(&buf[..write_len])? + } else { + self.wait_events(IoEvents::OUT, None, || { + self.driver.push_output(&buf[..write_len]) + })? + }; self.pollee.invalidate(); Ok(len) } diff --git a/test/src/syscall/gvisor/blocklists/pty_test b/test/src/syscall/gvisor/blocklists/pty_test index 9a1b84db1..45a4c36ab 100644 --- a/test/src/syscall/gvisor/blocklists/pty_test +++ b/test/src/syscall/gvisor/blocklists/pty_test @@ -1,25 +1,14 @@ PtyTrunc.Truncate -PtyTest.MasterTermiosUnchangable -PtyTest.TermiosICRNL -PtyTest.TermiosONLCR +PtyTest.TermiosIGNCR PtyTest.TermiosINLCR +PtyTest.TermiosONOCR PtyTest.TermiosOCRNL -PtyTest.SwitchCanonToNonCanonNewline PtyTest.TermiosICANONNewline PtyTest.TermiosICANONEOF PtyTest.CanonDiscard -PtyTest.CanonMultiline -PtyTest.SimpleEcho -PtyTest.TermiosIGNCR -PtyTest.TermiosONOCR PtyTest.VEOLTermination -PtyTest.CanonBigWrite PtyTest.SwitchCanonToNoncanon -PtyTest.SwitchNoncanonToCanonNewlineBig -PtyTest.SwitchNoncanonToCanonNoNewline PtyTest.SwitchNoncanonToCanonNoNewlineBig -PtyTest.NoncanonBigWrite -PtyTest.SwitchNoncanonToCanonMultiline PtyTest.SwitchTwiceMultiline JobControlTest.SetTTYBadArg JobControlTest.SetTTYDifferentSession