kodegen_bash_shell/core/
terminal.rs1use super::{error, openfiles, sys};
4
5pub struct TerminalControl {
7 prev_fg_pid: Option<sys::process::ProcessId>,
8}
9
10impl TerminalControl {
11 pub fn acquire() -> Result<Self, error::Error> {
13 let prev_fg_pid = sys::terminal::get_foreground_pid();
14
15 let _ = sys::signal::lead_new_process_group();
18
19 sys::terminal::move_self_to_foreground()?;
21
22 sys::signal::mask_sigttou()?;
24
25 Ok(Self { prev_fg_pid })
26 }
27
28 fn try_release(&mut self) {
29 if let Some(pid) = self.prev_fg_pid
31 && sys::terminal::move_to_foreground(pid).is_ok() {
32 self.prev_fg_pid = None;
33 }
34 }
35}
36
37impl Drop for TerminalControl {
38 fn drop(&mut self) {
39 self.try_release();
40 }
41}
42
43#[derive(Default, bon::Builder)]
45pub struct Settings {
46 pub echo_input: Option<bool>,
48 pub line_input: Option<bool>,
50 pub interrupt_signals: Option<bool>,
52 pub output_nl_as_nlcr: Option<bool>,
54}
55
56pub struct AutoModeGuard {
58 initial: sys::terminal::Config,
59 file: openfiles::OpenFile,
60}
61
62impl AutoModeGuard {
63 pub fn new(file: openfiles::OpenFile) -> Result<Self, error::Error> {
69 let initial = sys::terminal::Config::from_term(&file)?;
70 Ok(Self { initial, file })
71 }
72
73 pub fn apply_settings(&self, settings: &Settings) -> Result<(), error::Error> {
79 let mut config = sys::terminal::Config::from_term(&self.file)?;
80 config.update(settings);
81 config.apply_to_term(&self.file)?;
82
83 Ok(())
84 }
85}
86
87impl Drop for AutoModeGuard {
88 fn drop(&mut self) {
89 let _ = self.initial.apply_to_term(&self.file);
90 }
91}