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