(
&self,
command: &str,
cwd: Option<&str>,
env: Option<HashMap<String, String>>,
)
| 60 | } |
| 61 | |
| 62 | pub async fn create_session( |
| 63 | &self, |
| 64 | command: &str, |
| 65 | cwd: Option<&str>, |
| 66 | env: Option<HashMap<String, String>>, |
| 67 | ) -> Result<PtySession, PtyError> { |
| 68 | let id = format!("pty_{}", uuid::Uuid::new_v4().simple()); |
| 69 | let env_map = env.unwrap_or_default(); |
| 70 | let cwd_str = cwd.unwrap_or(".").to_string(); |
| 71 | |
| 72 | let cmd_string = command.to_string(); |
| 73 | let cwd_clone = cwd_str.clone(); |
| 74 | let env_clone = env_map.clone(); |
| 75 | |
| 76 | // Spawn the PTY on a blocking thread since portable-pty is synchronous |
| 77 | let (master, child, reader) = tokio::task::spawn_blocking(move || { |
| 78 | let pty_system = native_pty_system(); |
| 79 | let pair = pty_system |
| 80 | .openpty(PtySize { |
| 81 | rows: 24, |
| 82 | cols: 80, |
| 83 | pixel_width: 0, |
| 84 | pixel_height: 0, |
| 85 | }) |
| 86 | .map_err(|e| PtyError::SpawnFailed(e.to_string()))?; |
| 87 | |
| 88 | let mut cmd = CommandBuilder::new(&cmd_string); |
| 89 | cmd.cwd(&cwd_clone); |
| 90 | for (k, v) in &env_clone { |
| 91 | cmd.env(k, v); |
| 92 | } |
| 93 | |
| 94 | let child = pair |
| 95 | .slave |
| 96 | .spawn_command(cmd) |
| 97 | .map_err(|e| PtyError::SpawnFailed(e.to_string()))?; |
| 98 | |
| 99 | let reader = pair |
| 100 | .master |
| 101 | .try_clone_reader() |
| 102 | .map_err(|e| PtyError::IoError(e.to_string()))?; |
| 103 | |
| 104 | Ok::<_, PtyError>((pair.master, child, reader)) |
| 105 | }) |
| 106 | .await |
| 107 | .map_err(|e| PtyError::SpawnFailed(e.to_string()))??; |
| 108 | |
| 109 | let writer = master |
| 110 | .take_writer() |
| 111 | .map_err(|e| PtyError::IoError(e.to_string()))?; |
| 112 | let writer = Arc::new(Mutex::new(writer)); |
| 113 | |
| 114 | let output_buffer: Arc<Mutex<Vec<u8>>> = Arc::new(Mutex::new(Vec::new())); |
| 115 | let cursor: Arc<Mutex<usize>> = Arc::new(Mutex::new(0)); |
| 116 | let (output_tx, _) = broadcast::channel::<Vec<u8>>(256); |
| 117 | |
| 118 | let buffer_clone = output_buffer.clone(); |
| 119 | let cursor_clone = cursor.clone(); |
no test coverage detected