From fd030e0780156b8565a736a5f1cd595dc93ba66a Mon Sep 17 00:00:00 2001 From: Robert Grimm Date: Mon, 23 Dec 2024 06:38:30 -0500 Subject: [PATCH] switch to connection-oriented interface for Config, since Windows needs to read from and write to both handles --- crates/prettytty/src/conn.rs | 10 +++++---- crates/prettytty/src/sys/unix.rs | 9 ++++---- crates/prettytty/src/sys/windows.rs | 34 ++++++++++++++++++++--------- 3 files changed, 35 insertions(+), 18 deletions(-) diff --git a/crates/prettytty/src/conn.rs b/crates/prettytty/src/conn.rs index 1560e8b..81b5b01 100644 --- a/crates/prettytty/src/conn.rs +++ b/crates/prettytty/src/conn.rs @@ -44,7 +44,7 @@ impl Connection { let connection = RawConnection::open(&options) .map_err(|e| Error::new(ErrorKind::ConnectionRefused, e))?; - let config = Config::read(connection.input())?; + let config = Config::read(&connection)?; let verbose = options.verbose(); if verbose { println!("terminal::config {:?}", &config); @@ -55,9 +55,11 @@ impl Connection { if verbose { println!("terminal::reconfig {:?}", &reconfig); } - reconfig.write(connection.output())?; + reconfig.write(&connection)?; if verbose { - println!("terminal::reconfigured") + // We need explicit carriage-return and line-feed characters + // because the reconfiguratio just took effect. + print!("terminal::reconfigured\r\n") } Ok(Some(config)) }, @@ -147,7 +149,7 @@ impl Drop for Connection { let _ = w.flush(); }); if let Some(cfg) = &self.config { - let _ = cfg.write(self.connection.output()); + let _ = cfg.write(&self.connection); } } } diff --git a/crates/prettytty/src/sys/unix.rs b/crates/prettytty/src/sys/unix.rs index 7c9c1ae..77f915b 100644 --- a/crates/prettytty/src/sys/unix.rs +++ b/crates/prettytty/src/sys/unix.rs @@ -147,9 +147,9 @@ pub(crate) struct Config { impl Config { /// Read the configuration. - pub fn read(input: RawInput) -> Result { + pub fn read(connection: &RawConnection) -> Result { let mut state = std::mem::MaybeUninit::uninit(); - unsafe { libc::tcgetattr(input.handle(), state.as_mut_ptr()) }.into_result()?; + unsafe { libc::tcgetattr(connection.input().handle(), state.as_mut_ptr()) }.into_result()?; Ok(Self { state: unsafe { state.assume_init() }, }) @@ -175,8 +175,8 @@ impl Config { } /// Write the configuration. - pub fn write(&self, output: RawOutput) -> Result<()> { - unsafe { libc::tcsetattr(output.handle(), libc::TCSAFLUSH, from_ref(&self.state)) } + pub fn write(&self, connection: &RawConnection) -> Result<()> { + unsafe { libc::tcsetattr(connection.input().handle(), libc::TCSAFLUSH, from_ref(&self.state)) } .into_result()?; Ok(()) } @@ -327,6 +327,7 @@ impl RawOutput { Self { handle } } + #[allow(dead_code)] #[inline] fn handle(&self) -> RawHandle { self.handle diff --git a/crates/prettytty/src/sys/windows.rs b/crates/prettytty/src/sys/windows.rs index fbb45d4..600e75c 100644 --- a/crates/prettytty/src/sys/windows.rs +++ b/crates/prettytty/src/sys/windows.rs @@ -99,10 +99,10 @@ pub(crate) struct Config { } impl Config { - pub fn read(input: RawInput) -> Result { - let input_modes = Self::read_mode(&input)?; + pub fn read(connection: &RawConnection) -> Result { + let input_modes = Self::read_mode(connection.input())?; let input_encoding = unsafe { Console::GetConsoleCP() }.into_result()?; - let output_modes = Self::read_mode(&input)?; + let output_modes = Self::read_mode(connection.output())?; let output_encoding = unsafe { Console::GetConsoleOutputCP() }.into_result()?; Ok(Self { @@ -113,9 +113,9 @@ impl Config { }) } - fn read_mode(input: &RawInput) -> Result { + fn read_mode(handle: impl Into) -> Result { let mut mode = 0; - unsafe { Console::GetConsoleMode(input.handle(), from_mut(&mut mode)) }.into_result()?; + unsafe { Console::GetConsoleMode(handle.into(), from_mut(&mut mode)) }.into_result()?; Ok(mode) } @@ -156,18 +156,18 @@ impl Config { }) } - pub fn write(&self, output: RawOutput) -> Result<()> { - let result1 = Self::write_mode(&output, self.input_modes); + pub fn write(&self, connection: &RawConnection) -> Result<()> { + let result1 = Self::write_mode(connection.input(), self.input_modes); let result2 = unsafe { Console::SetConsoleCP(self.input_encoding) }.into_result(); - let result3 = Self::write_mode(&output, self.output_modes); + let result3 = Self::write_mode(connection.output(), self.output_modes); let result4 = unsafe { Console::SetConsoleOutputCP(self.output_encoding) }.into_result(); result1.and(result2).and(result3).and(result4)?; Ok(()) } - fn write_mode(output: &RawOutput, mode: ConsoleMode) -> Result<()> { - unsafe { Console::SetConsoleMode(output.handle(), mode) }.into_result()?; + fn write_mode(handle: impl Into, mode: ConsoleMode) -> Result<()> { + unsafe { Console::SetConsoleMode(handle.into(), mode) }.into_result()?; Ok(()) } @@ -243,6 +243,7 @@ impl RawInput { Self { handle, timeout } } + #[allow(dead_code)] #[inline] fn handle(&self) -> RawHandle { self.handle @@ -255,6 +256,12 @@ impl RawInput { // for wrapped handles, too. Also, access to raw input is gated by a mutex. unsafe impl Send for RawInput {} +impl From for RawHandle { + fn from(value: RawInput) -> Self { + value.handle + } +} + impl Read for RawInput { fn read(&mut self, buf: &mut [u8]) -> Result { let status = unsafe { Threading::WaitForSingleObject(self.handle, self.timeout) }; @@ -296,6 +303,7 @@ impl RawOutput { Self { handle } } + #[allow(dead_code)] #[inline] pub fn handle(&self) -> RawHandle { self.handle @@ -308,6 +316,12 @@ impl RawOutput { // for wrapped handles, too. Also, access to raw input is gated by a mutex. unsafe impl Send for RawOutput {} +impl From for RawHandle { + fn from(value: RawOutput) -> Self { + value.handle + } +} + impl Write for RawOutput { fn write(&mut self, buf: &[u8]) -> Result { let mut did_write: u32 = 0;