1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-29 16:42:13 +03:00
wezterm/mux/src/tmux_pty.rs

170 lines
4.5 KiB
Rust
Raw Normal View History

use crate::tmux::{RefTmuxRemotePane, TmuxCmdQueue, TmuxDomainState};
use crate::tmux_commands::{Resize, SendKeys};
2022-01-18 00:15:41 +03:00
use crate::DomainId;
use filedescriptor::FileDescriptor;
use parking_lot::{Condvar, Mutex};
2022-01-17 23:29:40 +03:00
use portable_pty::{Child, ChildKiller, ExitStatus, MasterPty};
use std::io::{Read, Write};
use std::sync::Arc;
2021-08-26 16:02:34 +03:00
2021-09-23 06:45:51 +03:00
/// A local tmux pane(tab) based on a tmux pty
2022-01-18 00:15:41 +03:00
#[derive(Debug)]
2021-08-26 16:02:34 +03:00
pub(crate) struct TmuxPty {
2022-01-18 00:15:41 +03:00
pub domain_id: DomainId,
2021-08-29 11:34:36 +03:00
pub master_pane: RefTmuxRemotePane,
2022-01-18 00:15:41 +03:00
pub reader: FileDescriptor,
2021-09-15 06:14:39 +03:00
pub cmd_queue: Arc<Mutex<TmuxCmdQueue>>,
2022-01-18 00:15:41 +03:00
}
2021-09-23 06:45:51 +03:00
2022-01-18 00:15:41 +03:00
struct TmuxPtyWriter {
domain_id: DomainId,
master_pane: RefTmuxRemotePane,
cmd_queue: Arc<Mutex<TmuxCmdQueue>>,
}
impl Write for TmuxPtyWriter {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
let pane_id = {
let pane_lock = self.master_pane.lock();
2022-01-18 00:15:41 +03:00
pane_lock.pane_id
};
log::trace!("pane:{}, content:{:?}", &pane_id, buf);
let mut cmd_queue = self.cmd_queue.lock();
2022-01-18 00:15:41 +03:00
cmd_queue.push_back(Box::new(SendKeys {
pane: pane_id,
keys: buf.to_vec(),
}));
TmuxDomainState::schedule_send_next_command(self.domain_id);
Ok(0)
}
fn flush(&mut self) -> std::io::Result<()> {
Ok(())
}
2021-08-26 16:02:34 +03:00
}
impl Write for TmuxPty {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
2021-09-15 06:14:39 +03:00
let pane_id = {
let pane_lock = self.master_pane.lock();
2021-09-15 06:14:39 +03:00
pane_lock.pane_id
};
2021-09-23 14:50:17 +03:00
log::trace!("pane:{}, content:{:?}", &pane_id, buf);
let mut cmd_queue = self.cmd_queue.lock();
2021-09-15 06:14:39 +03:00
cmd_queue.push_back(Box::new(SendKeys {
pane: pane_id,
keys: buf.to_vec(),
}));
2021-09-23 06:45:51 +03:00
TmuxDomainState::schedule_send_next_command(self.domain_id);
2021-08-26 16:02:34 +03:00
Ok(0)
}
fn flush(&mut self) -> std::io::Result<()> {
Ok(())
}
}
2022-01-18 00:15:41 +03:00
#[derive(Clone, Debug)]
pub(crate) struct TmuxChild {
pub active_lock: Arc<(Mutex<bool>, Condvar)>,
}
impl Child for TmuxChild {
2021-08-29 11:34:36 +03:00
fn try_wait(&mut self) -> std::io::Result<Option<portable_pty::ExitStatus>> {
todo!()
}
fn wait(&mut self) -> std::io::Result<portable_pty::ExitStatus> {
let &(ref lock, ref var) = &*self.active_lock;
let mut released = lock.lock();
2021-09-01 06:29:37 +03:00
while !*released {
var.wait(&mut released);
2021-09-01 06:29:37 +03:00
}
return Ok(ExitStatus::with_exit_code(0));
2021-08-29 11:34:36 +03:00
}
fn process_id(&self) -> Option<u32> {
Some(0)
}
2021-09-19 06:46:37 +03:00
#[cfg(windows)]
fn as_raw_handle(&self) -> Option<std::os::windows::io::RawHandle> {
None
}
2021-08-29 11:34:36 +03:00
}
2022-01-17 23:29:40 +03:00
#[derive(Clone, Debug)]
struct TmuxChildKiller {}
impl ChildKiller for TmuxChildKiller {
fn kill(&mut self) -> std::io::Result<()> {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
"TmuxChildKiller: kill not implemented!",
))
}
fn clone_killer(&self) -> Box<dyn ChildKiller + Send + Sync> {
Box::new(self.clone())
}
}
2022-01-18 00:15:41 +03:00
impl ChildKiller for TmuxChild {
2022-01-17 23:29:40 +03:00
fn kill(&mut self) -> std::io::Result<()> {
Err(std::io::Error::new(
std::io::ErrorKind::Other,
"TmuxPty: kill not implemented!",
))
}
fn clone_killer(&self) -> Box<dyn ChildKiller + Send + Sync> {
Box::new(TmuxChildKiller {})
}
}
2021-08-26 16:02:34 +03:00
impl MasterPty for TmuxPty {
fn resize(&self, size: portable_pty::PtySize) -> Result<(), anyhow::Error> {
let mut cmd_queue = self.cmd_queue.lock();
cmd_queue.push_back(Box::new(Resize { size }));
TmuxDomainState::schedule_send_next_command(self.domain_id);
2021-08-26 16:02:34 +03:00
Ok(())
}
fn get_size(&self) -> Result<portable_pty::PtySize, anyhow::Error> {
let pane = self.master_pane.lock();
2021-08-26 16:02:34 +03:00
Ok(portable_pty::PtySize {
rows: pane.pane_height as u16,
cols: pane.pane_width as u16,
pixel_width: 0,
pixel_height: 0,
})
}
2022-01-18 00:15:41 +03:00
fn try_clone_reader(&self) -> Result<Box<dyn Read + Send>, anyhow::Error> {
Ok(Box::new(self.reader.try_clone()?))
2021-08-26 16:02:34 +03:00
}
fn take_writer(&self) -> Result<Box<dyn Write + Send>, anyhow::Error> {
2022-01-18 00:15:41 +03:00
Ok(Box::new(TmuxPtyWriter {
2021-09-15 06:14:39 +03:00
domain_id: self.domain_id,
2021-08-26 16:02:34 +03:00
master_pane: self.master_pane.clone(),
2021-09-15 06:14:39 +03:00
cmd_queue: self.cmd_queue.clone(),
2021-08-26 16:02:34 +03:00
}))
}
2021-09-19 06:46:37 +03:00
#[cfg(unix)]
2021-08-26 16:02:34 +03:00
fn process_group_leader(&self) -> Option<libc::pid_t> {
return None;
}
#[cfg(unix)]
fn as_raw_fd(&self) -> Option<std::os::fd::RawFd> {
None
}
#[cfg(unix)]
fn tty_name(&self) -> Option<std::path::PathBuf> {
None
}
2021-08-26 16:02:34 +03:00
}