brush_core/sys/unix/
terminal.rs1use crate::{error, sys, terminal};
4use std::{io::IsTerminal, os::fd::AsFd};
5
6#[derive(Clone, Debug)]
8pub struct Config {
9 termios: nix::sys::termios::Termios,
10}
11
12impl Config {
13 pub fn from_term(fd: impl AsFd) -> Result<Self, error::Error> {
20 let termios = nix::sys::termios::tcgetattr(fd)?;
21 Ok(Self { termios })
22 }
23
24 pub fn apply_to_term(&self, fd: impl AsFd) -> Result<(), error::Error> {
30 nix::sys::termios::tcsetattr(fd, nix::sys::termios::SetArg::TCSANOW, &self.termios)?;
31 Ok(())
32 }
33
34 pub fn update(&mut self, settings: &terminal::Settings) {
41 if let Some(echo_input) = &settings.echo_input {
42 if *echo_input {
43 self.termios.local_flags |= nix::sys::termios::LocalFlags::ECHO;
44 } else {
45 self.termios.local_flags -= nix::sys::termios::LocalFlags::ECHO;
46 }
47 }
48
49 if let Some(line_input) = &settings.line_input {
50 if *line_input {
51 self.termios.local_flags |= nix::sys::termios::LocalFlags::ICANON;
52 } else {
53 self.termios.local_flags -= nix::sys::termios::LocalFlags::ICANON;
54 }
55 }
56
57 if let Some(interrupt_signals) = &settings.interrupt_signals {
58 if *interrupt_signals {
59 self.termios.local_flags |= nix::sys::termios::LocalFlags::ISIG;
60 } else {
61 self.termios.local_flags -= nix::sys::termios::LocalFlags::ISIG;
62 }
63 }
64
65 if let Some(output_nl_as_nlcr) = &settings.output_nl_as_nlcr {
66 if *output_nl_as_nlcr {
67 self.termios.output_flags |=
68 nix::sys::termios::OutputFlags::OPOST | nix::sys::termios::OutputFlags::ONLCR;
69 } else {
70 self.termios.output_flags -= nix::sys::termios::OutputFlags::ONLCR;
71 }
72 }
73 }
74}
75
76pub fn get_parent_process_id() -> Option<sys::process::ProcessId> {
78 Some(nix::unistd::getppid().as_raw())
79}
80
81pub fn get_process_group_id() -> Option<sys::process::ProcessId> {
83 Some(nix::unistd::getpgrp().as_raw())
84}
85
86pub fn get_foreground_pid() -> Option<sys::process::ProcessId> {
88 nix::unistd::tcgetpgrp(std::io::stdin())
89 .ok()
90 .map(|pgid| pgid.as_raw())
91}
92
93pub fn move_to_foreground(pid: sys::process::ProcessId) -> Result<(), error::Error> {
95 nix::unistd::tcsetpgrp(std::io::stdin(), nix::unistd::Pid::from_raw(pid))?;
96 Ok(())
97}
98
99pub fn move_self_to_foreground() -> Result<(), error::Error> {
101 if std::io::stdin().is_terminal() {
102 let pgid = nix::unistd::getpgid(None)?;
103
104 let _ = nix::unistd::tcsetpgrp(std::io::stdin(), pgid);
107 }
108
109 Ok(())
110}