term_session_server/
session.rs1use portable_pty::{CommandBuilder, PtySize};
2use term_wm_pty_engine::{Pty, PtyResult};
3
4pub struct Session {
5 pub id: u64,
6 pub pty: Pty,
7 pub title: Option<String>,
8 pub exited: bool,
9 pub exit_code: Option<i32>,
10 pub cols: u16,
11 pub rows: u16,
12}
13
14fn default_shell_command() -> CommandBuilder {
15 #[cfg(not(windows))]
16 let shell = std::env::var("SHELL").unwrap_or_else(|_| "bash".to_string());
17 #[cfg(windows)]
18 let shell = std::env::var("COMSPEC").unwrap_or_else(|_| "cmd.exe".to_string());
19 let mut cmd = CommandBuilder::new(shell);
20 if let Ok(cwd) = std::env::current_dir() {
21 cmd.cwd(cwd);
22 }
23 cmd
24}
25
26impl Session {
27 pub fn spawn(id: u64, cmd: Option<Vec<String>>, cols: u16, rows: u16) -> PtyResult<Self> {
28 let size = PtySize {
29 rows,
30 cols,
31 pixel_width: 0,
32 pixel_height: 0,
33 };
34 let pty = if let Some(cmd_parts) = &cmd {
35 let mut builder = CommandBuilder::new(&cmd_parts[0]);
36 for arg in &cmd_parts[1..] {
37 builder.arg(arg);
38 }
39 if let Ok(cwd) = std::env::current_dir() {
40 builder.cwd(cwd);
41 }
42 Pty::spawn(builder, size)?
43 } else {
44 Pty::spawn(default_shell_command(), size)?
45 };
46 Ok(Self {
47 id,
48 pty,
49 title: None,
50 exited: false,
51 exit_code: None,
52 cols,
53 rows,
54 })
55 }
56
57 pub fn read_output(&mut self) -> Vec<u8> {
58 self.pty.screen();
60 if let Some(title) = self.pty.take_pending_title() {
62 self.title = Some(title);
63 }
64 self.pty.drain_pending()
65 }
66
67 pub fn sync_screen(&mut self) {
72 self.pty.screen();
73 if let Some(title) = self.pty.take_pending_title() {
74 self.title = Some(title);
75 }
76 }
77
78 pub fn check_exited(&mut self) -> bool {
79 if !self.exited && self.pty.has_exited() {
80 self.exited = true;
81 self.exit_code = self.pty.exit_status().map(|s| s.exit_code() as i32);
82 true
83 } else {
84 false
85 }
86 }
87
88 pub fn take_exit_code(&mut self) -> Option<i32> {
89 self.exit_code.take()
90 }
91
92 pub fn generate_snapshot(&mut self) -> Vec<u8> {
93 self.pty.generate_snapshot()
94 }
95}