diff --git a/src/posix/termios.rs b/src/posix/termios.rs index f53af807..b6007300 100644 --- a/src/posix/termios.rs +++ b/src/posix/termios.rs @@ -5,6 +5,7 @@ use crate::{DataBits, FlowControl, Parity, Result, StopBits}; use nix::libc; use std::os::unix::prelude::*; +use std::time::Duration; cfg_if! { if #[cfg(any( @@ -183,6 +184,12 @@ pub(crate) fn set_flow_control(termios: &mut Termios, flow_control: FlowControl) }; } +pub(crate) fn set_timeout(termios: &mut Termios, timeout: Duration) { + let timeout = u128::min(timeout.as_millis() / 100, u8::MAX as u128) as u8; + termios.c_cc[libc::VMIN as usize] = 0; + termios.c_cc[libc::VTIME as usize] = timeout; +} + pub(crate) fn set_data_bits(termios: &mut Termios, data_bits: DataBits) { let size = match data_bits { DataBits::Five => libc::CS5, diff --git a/src/posix/tty.rs b/src/posix/tty.rs index b1d68cff..ba3e3f43 100644 --- a/src/posix/tty.rs +++ b/src/posix/tty.rs @@ -134,7 +134,9 @@ impl TTYPort { nix::errno::Errno::result(unsafe { tcgetattr(fd.0, termios.as_mut_ptr()) })?; let mut termios = unsafe { termios.assume_init() }; - // setup TTY for binary serial port access + // Setup TTY for binary serial port access + // Enable non-canonical mode + termios.c_lflag &= !libc::ICANON; // Enable reading from the port and ignore all modem control lines termios.c_cflag |= libc::CREAD | libc::CLOCAL; // Enable raw mode which disables any implicit processing of the input or output data streams @@ -175,6 +177,8 @@ impl TTYPort { termios::set_flow_control(&mut termios, builder.flow_control); termios::set_data_bits(&mut termios, builder.data_bits); termios::set_stop_bits(&mut termios, builder.stop_bits); + // Set termios read to non-blocking, as we handle blocking ourselves (with unix::poll) + termios::set_timeout(&mut termios, Duration::from_millis(0)); #[cfg(not(any(target_os = "ios", target_os = "macos")))] termios::set_baud_rate(&mut termios, builder.baud_rate); #[cfg(any(target_os = "ios", target_os = "macos"))]