Fix startup command and holder fallback
ci / test (push) Has been cancelled
ci / fuzz-smoke (push) Has been cancelled
ci / windows-client (push) Has been cancelled
ci / package-release (linux-x86_64, ubuntu-latest) (push) Has been cancelled
ci / package-release (macos-aarch64, macos-14) (push) Has been cancelled
ci / package-release (macos-x86_64, macos-13) (push) Has been cancelled
ci / package-release (windows-x86_64, windows-latest) (push) Has been cancelled
ci / remote-bench (push) Has been cancelled
ci / test (push) Has been cancelled
ci / fuzz-smoke (push) Has been cancelled
ci / windows-client (push) Has been cancelled
ci / package-release (linux-x86_64, ubuntu-latest) (push) Has been cancelled
ci / package-release (macos-aarch64, macos-14) (push) Has been cancelled
ci / package-release (macos-x86_64, macos-13) (push) Has been cancelled
ci / package-release (windows-x86_64, windows-latest) (push) Has been cancelled
ci / remote-bench (push) Has been cancelled
This commit is contained in:
@@ -1048,7 +1048,7 @@ fn startup_command(args: &[String]) -> Option<Vec<u8>> {
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let mut command = args.join(" ");
|
let mut command = args.join(" ");
|
||||||
command.push('\n');
|
command.push('\r');
|
||||||
Some(command.into_bytes())
|
Some(command.into_bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1121,7 +1121,7 @@ fn expand_command_extension(template: &str, args: &[String]) -> String {
|
|||||||
|
|
||||||
fn startup_command_from_string(command: &str) -> Vec<u8> {
|
fn startup_command_from_string(command: &str) -> Vec<u8> {
|
||||||
let mut command = command.to_string();
|
let mut command = command.to_string();
|
||||||
command.push('\n');
|
command.push('\r');
|
||||||
command.into_bytes()
|
command.into_bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5540,6 +5540,7 @@ mod tests {
|
|||||||
assert!(Predictor::predictable(b"hello world"));
|
assert!(Predictor::predictable(b"hello world"));
|
||||||
assert!(!Predictor::predictable(b""));
|
assert!(!Predictor::predictable(b""));
|
||||||
assert!(!Predictor::predictable(b"\n"));
|
assert!(!Predictor::predictable(b"\n"));
|
||||||
|
assert!(!Predictor::predictable(b"\r"));
|
||||||
assert!(!Predictor::predictable(b"\x1b[A"));
|
assert!(!Predictor::predictable(b"\x1b[A"));
|
||||||
assert!(!Predictor::predictable("snowman: \u{2603}".as_bytes()));
|
assert!(!Predictor::predictable("snowman: \u{2603}".as_bytes()));
|
||||||
assert!(!Predictor::predictable("wide: 你".as_bytes()));
|
assert!(!Predictor::predictable("wide: 你".as_bytes()));
|
||||||
@@ -5760,10 +5761,10 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn startup_command_joins_args_for_remote_shell() {
|
fn startup_command_joins_args_for_remote_shell() {
|
||||||
assert_eq!(startup_command(&[]), None);
|
assert_eq!(startup_command(&[]), None);
|
||||||
assert_eq!(startup_command(&["tm".to_string()]), Some(b"tm\n".to_vec()));
|
assert_eq!(startup_command(&["tm".to_string()]), Some(b"tm\r".to_vec()));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
startup_command(&["tm".to_string(), "work".to_string()]),
|
startup_command(&["tm".to_string(), "work".to_string()]),
|
||||||
Some(b"tm work\n".to_vec())
|
Some(b"tm work\r".to_vec())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5845,7 +5846,7 @@ mod tests {
|
|||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
resolved_startup_command(&["tm".into(), "work space".into()], &config, &host),
|
resolved_startup_command(&["tm".into(), "work space".into()], &config, &host),
|
||||||
Some(b"tm 'work space'\n".to_vec())
|
Some(b"tm 'work space'\r".to_vec())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5872,7 +5873,7 @@ mod tests {
|
|||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
resolved_startup_command(&["tm".into(), "dosh".into()], &config, &host),
|
resolved_startup_command(&["tm".into(), "dosh".into()], &config, &host),
|
||||||
Some(b"/opt/tm/bin/tm --remote 'dosh'\n".to_vec())
|
Some(b"/opt/tm/bin/tm --remote 'dosh'\r".to_vec())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5913,11 +5914,11 @@ mod tests {
|
|||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
resolved_startup_command(&["echo".into(), "ok".into()], &config, &host),
|
resolved_startup_command(&["echo".into(), "ok".into()], &config, &host),
|
||||||
Some(b"echo ok\n".to_vec())
|
Some(b"echo ok\r".to_vec())
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
resolved_startup_command(&[], &config, &host),
|
resolved_startup_command(&[], &config, &host),
|
||||||
Some(b"tm\n".to_vec())
|
Some(b"tm\r".to_vec())
|
||||||
);
|
);
|
||||||
|
|
||||||
host.default_command = None;
|
host.default_command = None;
|
||||||
|
|||||||
+5
-1
@@ -28,6 +28,7 @@ use std::time::Duration;
|
|||||||
/// One-byte commands a server sends to a holder over its control socket after
|
/// One-byte commands a server sends to a holder over its control socket after
|
||||||
/// the holder has handed back the master fd.
|
/// the holder has handed back the master fd.
|
||||||
const HOLDER_CMD_SHUTDOWN: u8 = b'X';
|
const HOLDER_CMD_SHUTDOWN: u8 = b'X';
|
||||||
|
const HOLDER_STARTUP_TIMEOUT: Duration = Duration::from_millis(750);
|
||||||
|
|
||||||
/// Magic written into a holder's `meta` file, bumped if the on-disk layout
|
/// Magic written into a holder's `meta` file, bumped if the on-disk layout
|
||||||
/// changes so a stale holder from an incompatible build is ignored.
|
/// changes so a stale holder from an incompatible build is ignored.
|
||||||
@@ -236,11 +237,14 @@ pub fn spawn_holder(
|
|||||||
// Wait (briefly) for the holder to come up. The holder forks/setsids before
|
// Wait (briefly) for the holder to come up. The holder forks/setsids before
|
||||||
// creating the socket; once the socket exists we can connect. We also reap
|
// creating the socket; once the socket exists we can connect. We also reap
|
||||||
// the short-lived launcher child so it never becomes a zombie.
|
// the short-lived launcher child so it never becomes a zombie.
|
||||||
let deadline = std::time::Instant::now() + Duration::from_secs(5);
|
let deadline = std::time::Instant::now() + HOLDER_STARTUP_TIMEOUT;
|
||||||
loop {
|
loop {
|
||||||
if sock.exists() {
|
if sock.exists() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if let Some(status) = child.try_wait().context("wait holder launcher")? {
|
||||||
|
bail!("holder launcher for session {session} exited before socket was ready: {status}");
|
||||||
|
}
|
||||||
if std::time::Instant::now() >= deadline {
|
if std::time::Instant::now() >= deadline {
|
||||||
let _ = child.kill();
|
let _ = child.kill();
|
||||||
let _ = child.wait();
|
let _ = child.wait();
|
||||||
|
|||||||
Reference in New Issue
Block a user