Save session exit status in the recording file as "x" event

This commit is contained in:
Marcin Kulik
2025-05-29 18:12:04 +02:00
parent 0c16f90f8b
commit 2aec6f690b
7 changed files with 24 additions and 4 deletions

View File

@@ -51,6 +51,7 @@ pub enum EventData {
Input(String), Input(String),
Resize(u16, u16), Resize(u16, u16),
Marker(String), Marker(String),
Exit(i32),
Other(char, String), Other(char, String),
} }
@@ -175,6 +176,13 @@ impl Event {
data: EventData::Marker(label), data: EventData::Marker(label),
} }
} }
pub fn exit(time: u64, status: i32) -> Self {
Event {
time,
data: EventData::Exit(status),
}
}
} }
pub fn limit_idle_time( pub fn limit_idle_time(

View File

@@ -195,6 +195,7 @@ impl V2Encoder {
Input(data) => ('i', self.to_json_string(data)), Input(data) => ('i', self.to_json_string(data)),
Resize(cols, rows) => ('r', self.to_json_string(&format!("{cols}x{rows}"))), Resize(cols, rows) => ('r', self.to_json_string(&format!("{cols}x{rows}"))),
Marker(data) => ('m', self.to_json_string(data)), Marker(data) => ('m', self.to_json_string(data)),
Exit(data) => ('x', self.to_json_string(&data.to_string())),
Other(code, data) => (*code, self.to_json_string(data)), Other(code, data) => (*code, self.to_json_string(data)),
}; };

View File

@@ -60,6 +60,7 @@ enum V3EventCode {
Input, Input,
Resize, Resize,
Marker, Marker,
Exit,
Other(char), Other(char),
} }
@@ -150,6 +151,7 @@ impl Parser {
}, },
V3EventCode::Marker => EventData::Marker(event.data), V3EventCode::Marker => EventData::Marker(event.data),
V3EventCode::Exit => EventData::Exit(event.data.parse()?),
V3EventCode::Other(c) => EventData::Other(c, event.data), V3EventCode::Other(c) => EventData::Other(c, event.data),
}; };
@@ -174,6 +176,7 @@ where
"i" => Ok(Input), "i" => Ok(Input),
"r" => Ok(Resize), "r" => Ok(Resize),
"m" => Ok(Marker), "m" => Ok(Marker),
"x" => Ok(Exit),
"" => Err(Error::custom("missing event code")), "" => Err(Error::custom("missing event code")),
s => Ok(Other(s.chars().next().unwrap())), s => Ok(Other(s.chars().next().unwrap())),
} }
@@ -211,6 +214,7 @@ impl V3Encoder {
Input(data) => ('i', self.to_json_string(data)), Input(data) => ('i', self.to_json_string(data)),
Resize(cols, rows) => ('r', self.to_json_string(&format!("{cols}x{rows}"))), Resize(cols, rows) => ('r', self.to_json_string(&format!("{cols}x{rows}"))),
Marker(data) => ('m', self.to_json_string(data)), Marker(data) => ('m', self.to_json_string(data)),
Exit(data) => ('x', self.to_json_string(&data.to_string())),
Other(code, data) => (*code, self.to_json_string(data)), Other(code, data) => (*code, self.to_json_string(data)),
}; };

View File

@@ -97,6 +97,7 @@ impl From<session::Event> for asciicast::Event {
asciicast::Event::resize(time, tty_size.into()) asciicast::Event::resize(time, tty_size.into())
} }
session::Event::Marker(time, label) => asciicast::Event::marker(time, label), session::Event::Marker(time, label) => asciicast::Event::marker(time, label),
session::Event::Exit(time, status) => asciicast::Event::exit(time, status),
} }
} }
} }

View File

@@ -32,7 +32,7 @@ pub trait Handler {
fn output(&mut self, time: Duration, data: &[u8]) -> bool; fn output(&mut self, time: Duration, data: &[u8]) -> bool;
fn input(&mut self, time: Duration, data: &[u8]) -> bool; fn input(&mut self, time: Duration, data: &[u8]) -> bool;
fn resize(&mut self, time: Duration, tty_size: TtySize) -> bool; fn resize(&mut self, time: Duration, tty_size: TtySize) -> bool;
fn stop(self) -> Self; fn stop(self, time: Duration, exit_status: i32) -> Self;
} }
pub fn exec<S: AsRef<str>, T: Tty, H: Handler, R: HandlerStarter<H>>( pub fn exec<S: AsRef<str>, T: Tty, H: Handler, R: HandlerStarter<H>>(
@@ -49,7 +49,7 @@ pub fn exec<S: AsRef<str>, T: Tty, H: Handler, R: HandlerStarter<H>>(
match result { match result {
pty::ForkptyResult::Parent { child, master } => { pty::ForkptyResult::Parent { child, master } => {
handle_parent(master, child, tty, &mut handler, epoch) handle_parent(master, child, tty, &mut handler, epoch)
.map(|code| (code, handler.stop())) .map(|code| (code, handler.stop(epoch.elapsed(), code)))
} }
pty::ForkptyResult::Child => { pty::ForkptyResult::Child => {
@@ -419,7 +419,7 @@ mod tests {
true true
} }
fn stop(self) -> Self { fn stop(self, _time: Duration, _exit_status: i32) -> Self {
self self
} }
} }

View File

@@ -38,6 +38,7 @@ pub enum Event {
Input(u64, String), Input(u64, String),
Resize(u64, TtySize), Resize(u64, TtySize),
Marker(u64, String), Marker(u64, String),
Exit(u64, i32),
} }
impl<N: Notifier> SessionStarter<N> { impl<N: Notifier> SessionStarter<N> {
@@ -214,7 +215,10 @@ impl<N: Notifier> pty::Handler for Session<N> {
true true
} }
fn stop(self) -> Self { fn stop(self, time: Duration, exit_status: i32) -> Self {
let msg = Event::Exit(self.elapsed_time(time), exit_status);
self.sender.send(msg).expect("exit send should succeed");
self self
} }
} }

View File

@@ -111,6 +111,8 @@ async fn run(
let _ = broadcast_tx.send(Event::Marker(last_event_id, time, label)); let _ = broadcast_tx.send(Event::Marker(last_event_id, time, label));
stream_time = time; stream_time = time;
} }
session::Event::Exit(_time, _status) => {}
} }
} }