Support nonblocking mode for tty and pty
This commit is contained in:
parent
c4ee351639
commit
a41db92b4e
|
|
@ -80,12 +80,17 @@ impl Pollable for PtyMaster {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FileIo for PtyMaster {
|
impl FileIo for PtyMaster {
|
||||||
fn read(&self, writer: &mut VmWriter, _status_flags: StatusFlags) -> Result<usize> {
|
fn read(&self, writer: &mut VmWriter, status_flags: StatusFlags) -> Result<usize> {
|
||||||
// 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 mut buf = vec![0u8; writer.avail().min(IO_CAPACITY)];
|
||||||
let read_len = self.wait_events(IoEvents::IN, None, || {
|
let is_nonblocking = status_flags.contains(StatusFlags::O_NONBLOCK);
|
||||||
self.slave.driver().try_read(&mut buf)
|
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.driver().pollee().invalidate();
|
||||||
self.slave.notify_output();
|
self.slave.notify_output();
|
||||||
|
|
||||||
|
|
@ -94,14 +99,19 @@ impl FileIo for PtyMaster {
|
||||||
Ok(read_len)
|
Ok(read_len)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write(&self, reader: &mut VmReader, _status_flags: StatusFlags) -> Result<usize> {
|
fn write(&self, reader: &mut VmReader, status_flags: StatusFlags) -> Result<usize> {
|
||||||
let mut buf = vec![0u8; reader.remain().min(IO_CAPACITY)];
|
let mut buf = vec![0u8; reader.remain().min(IO_CAPACITY)];
|
||||||
let write_len = reader.read_fallible(&mut buf.as_mut_slice().into())?;
|
let write_len = reader.read_fallible(&mut buf.as_mut_slice().into())?;
|
||||||
|
|
||||||
// TODO: Add support for non-blocking mode and timeout
|
// TODO: Add support for timeout.
|
||||||
let len = self.wait_events(IoEvents::OUT, None, || {
|
let is_nonblocking = status_flags.contains(StatusFlags::O_NONBLOCK);
|
||||||
self.slave.push_input(&buf[..write_len])
|
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();
|
self.slave.driver().pollee().invalidate();
|
||||||
Ok(len)
|
Ok(len)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -241,17 +241,21 @@ impl<D: TtyDriver> Pollable for Tty<D> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: TtyDriver> FileIo for Tty<D> {
|
impl<D: TtyDriver> FileIo for Tty<D> {
|
||||||
fn read(&self, writer: &mut VmWriter, _status_flags: StatusFlags) -> Result<usize> {
|
fn read(&self, writer: &mut VmWriter, status_flags: StatusFlags) -> Result<usize> {
|
||||||
if self.driver.is_closed() {
|
if self.driver.is_closed() {
|
||||||
return Ok(0);
|
return Ok(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.job_control.wait_until_in_foreground()?;
|
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 mut buf = vec![0u8; writer.avail().min(IO_CAPACITY)];
|
||||||
let read_len =
|
let is_nonblocking = status_flags.contains(StatusFlags::O_NONBLOCK);
|
||||||
self.wait_events(IoEvents::IN, None, || self.ldisc.lock().try_read(&mut buf))?;
|
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.pollee.invalidate();
|
||||||
self.driver.notify_input();
|
self.driver.notify_input();
|
||||||
|
|
||||||
|
|
@ -260,14 +264,19 @@ impl<D: TtyDriver> FileIo for Tty<D> {
|
||||||
Ok(read_len)
|
Ok(read_len)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write(&self, reader: &mut VmReader, _status_flags: StatusFlags) -> Result<usize> {
|
fn write(&self, reader: &mut VmReader, status_flags: StatusFlags) -> Result<usize> {
|
||||||
let mut buf = vec![0u8; reader.remain().min(IO_CAPACITY)];
|
let mut buf = vec![0u8; reader.remain().min(IO_CAPACITY)];
|
||||||
let write_len = reader.read_fallible(&mut buf.as_mut_slice().into())?;
|
let write_len = reader.read_fallible(&mut buf.as_mut_slice().into())?;
|
||||||
|
|
||||||
// TODO: Add support for non-blocking mode and timeout
|
// TODO: Add support for timeout.
|
||||||
let len = self.wait_events(IoEvents::OUT, None, || {
|
let is_nonblocking = status_flags.contains(StatusFlags::O_NONBLOCK);
|
||||||
self.driver.push_output(&buf[..write_len])
|
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();
|
self.pollee.invalidate();
|
||||||
Ok(len)
|
Ok(len)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,14 @@
|
||||||
PtyTrunc.Truncate
|
PtyTrunc.Truncate
|
||||||
PtyTest.MasterTermiosUnchangable
|
PtyTest.TermiosIGNCR
|
||||||
PtyTest.TermiosICRNL
|
|
||||||
PtyTest.TermiosONLCR
|
|
||||||
PtyTest.TermiosINLCR
|
PtyTest.TermiosINLCR
|
||||||
|
PtyTest.TermiosONOCR
|
||||||
PtyTest.TermiosOCRNL
|
PtyTest.TermiosOCRNL
|
||||||
PtyTest.SwitchCanonToNonCanonNewline
|
|
||||||
PtyTest.TermiosICANONNewline
|
PtyTest.TermiosICANONNewline
|
||||||
PtyTest.TermiosICANONEOF
|
PtyTest.TermiosICANONEOF
|
||||||
PtyTest.CanonDiscard
|
PtyTest.CanonDiscard
|
||||||
PtyTest.CanonMultiline
|
|
||||||
PtyTest.SimpleEcho
|
|
||||||
PtyTest.TermiosIGNCR
|
|
||||||
PtyTest.TermiosONOCR
|
|
||||||
PtyTest.VEOLTermination
|
PtyTest.VEOLTermination
|
||||||
PtyTest.CanonBigWrite
|
|
||||||
PtyTest.SwitchCanonToNoncanon
|
PtyTest.SwitchCanonToNoncanon
|
||||||
PtyTest.SwitchNoncanonToCanonNewlineBig
|
|
||||||
PtyTest.SwitchNoncanonToCanonNoNewline
|
|
||||||
PtyTest.SwitchNoncanonToCanonNoNewlineBig
|
PtyTest.SwitchNoncanonToCanonNoNewlineBig
|
||||||
PtyTest.NoncanonBigWrite
|
|
||||||
PtyTest.SwitchNoncanonToCanonMultiline
|
|
||||||
PtyTest.SwitchTwiceMultiline
|
PtyTest.SwitchTwiceMultiline
|
||||||
JobControlTest.SetTTYBadArg
|
JobControlTest.SetTTYBadArg
|
||||||
JobControlTest.SetTTYDifferentSession
|
JobControlTest.SetTTYDifferentSession
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue