Fix terminal handling

This commit is contained in:
Armin Ronacher 2025-06-16 17:34:53 +02:00
parent 936806edd6
commit 3e3f81b892
3 changed files with 33 additions and 3 deletions

View file

@ -58,6 +58,12 @@ struct CreateSessionRequest {
command: Vec<String>,
#[serde(rename = "workingDir")]
working_dir: Option<String>,
#[serde(default = "default_term_value")]
term: String,
}
fn default_term_value() -> String {
"xterm".to_string()
}
#[derive(Debug, Deserialize)]
@ -465,6 +471,7 @@ fn handle_create_session(
let session_id_clone = session_id.clone();
let cmdline_clone = cmdline.clone();
let working_dir_clone = current_dir.clone();
let term_clone = create_request.term.clone();
std::thread::Builder::new()
.name(format!("session-{}", session_id_clone))
@ -519,6 +526,9 @@ fn handle_create_session(
.to_string();
tty_spawn.session_name(session_name);
// Set the TERM environment variable
tty_spawn.term(term_clone);
// Enable detached mode for API-created sessions
tty_spawn.detached(true);
@ -1015,7 +1025,7 @@ fn handle_session_stream_direct(control_path: &PathBuf, path: &str, req: &mut Ht
"width": 80,
"height": 24,
"timestamp": start_time as u64,
"env": { "TERM": "xterm-256color" }
"env": { "TERM": session_entry.session_info.term.clone() }
});
let data = format!(
"data: {}
@ -1035,7 +1045,7 @@ fn handle_session_stream_direct(control_path: &PathBuf, path: &str, req: &mut Ht
"width": 80,
"height": 24,
"timestamp": start_time as u64,
"env": { "TERM": "xterm-256color" }
"env": { "TERM": session_entry.session_info.term.clone() }
});
let data = format!(
"data: {}
@ -1204,7 +1214,7 @@ fn handle_stream_all_sessions(control_path: &PathBuf, req: &mut HttpRequest) {
"width": 80,
"height": 24,
"timestamp": start_time as u64,
"env": { "TERM": "xterm-256color" }
"env": { "TERM": "xterm" }
});
let header_data = format!(
"data: {}

View file

@ -16,6 +16,12 @@ pub struct SessionInfo {
pub started_at: Option<Timestamp>,
#[serde(default)]
pub waiting: bool,
#[serde(default = "default_term")]
pub term: String,
}
fn default_term() -> String {
"xterm".to_string()
}
#[derive(Serialize)]

View file

@ -63,6 +63,7 @@ impl TtySpawn {
session_json_path: None,
session_name: None,
detached: false,
term: "xterm".to_string(),
}),
}
}
@ -148,6 +149,12 @@ impl TtySpawn {
Ok(self)
}
/// Sets the TERM environment variable for the spawned process.
pub fn term<S: AsRef<str>>(&mut self, term: S) -> &mut Self {
self.options_mut().term = term.as_ref().to_string();
self
}
/// Spawns the application in the TTY.
pub fn spawn(&mut self) -> Result<i32, io::Error> {
Ok(spawn(
@ -168,6 +175,7 @@ struct SpawnOptions {
session_json_path: Option<PathBuf>,
session_name: Option<String>,
detached: bool,
term: String,
}
/// Creates a new session JSON file with the provided information
@ -176,6 +184,7 @@ pub fn create_session_info(
cmdline: Vec<String>,
name: String,
cwd: String,
term: String,
) -> Result<(), io::Error> {
let session_info = SessionInfo {
cmdline,
@ -186,6 +195,7 @@ pub fn create_session_info(
exit_code: None,
started_at: Some(Timestamp::now()),
waiting: false,
term,
};
let session_info_str = serde_json::to_string(&session_info)?;
@ -281,6 +291,7 @@ fn spawn(mut opts: SpawnOptions) -> Result<i32, Errno> {
cmdline.clone(),
session_name.clone(),
current_dir.clone(),
opts.term.clone(),
)
.map_err(|e| Errno::from_raw(e.raw_os_error().unwrap_or(libc::EIO)))?;
@ -449,6 +460,9 @@ fn spawn(mut opts: SpawnOptions) -> Result<i32, Errno> {
drop(pty.master);
if detached {
// Set TERM environment variable for the child process
env::set_var("TERM", &opts.term);
// In detached mode, manually set up file descriptors without login_tty
// This prevents the child from connecting to the current terminal