forked from NotAShelf/beer
pty: propagate the shell's exit status
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: I9f33a222a19794b6ad2910fb6029796f6a6a6964
This commit is contained in:
parent
5690e0e883
commit
56907b4115
2 changed files with 21 additions and 9 deletions
|
|
@ -23,7 +23,7 @@ struct Cli {
|
||||||
fn main() -> ExitCode {
|
fn main() -> ExitCode {
|
||||||
init_logging();
|
init_logging();
|
||||||
match run(Cli::parse()) {
|
match run(Cli::parse()) {
|
||||||
Ok(()) => ExitCode::SUCCESS,
|
Ok(code) => code,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
tracing::error!("{err:#}");
|
tracing::error!("{err:#}");
|
||||||
eprintln!("beer: {err:#}");
|
eprintln!("beer: {err:#}");
|
||||||
|
|
@ -45,10 +45,9 @@ fn init_logging() {
|
||||||
.init();
|
.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(cli: Cli) -> anyhow::Result<()> {
|
fn run(cli: Cli) -> anyhow::Result<ExitCode> {
|
||||||
if cli.server {
|
if cli.server {
|
||||||
tracing::info!("starting beer server");
|
anyhow::bail!("server mode is not implemented yet");
|
||||||
todo!("server mode")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tracing::info!("starting beer");
|
tracing::info!("starting beer");
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@
|
||||||
//! event loop, so the PTY master fd and timers share one loop.
|
//! event loop, so the PTY master fd and timers share one loop.
|
||||||
|
|
||||||
use std::os::fd::OwnedFd;
|
use std::os::fd::OwnedFd;
|
||||||
|
use std::os::unix::process::ExitStatusExt;
|
||||||
|
use std::process::ExitCode;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
|
|
@ -45,8 +47,8 @@ const DEFAULT_H: u32 = 600;
|
||||||
const FONT_FAMILY: &str = "monospace";
|
const FONT_FAMILY: &str = "monospace";
|
||||||
const FONT_SIZE_PX: u32 = 16;
|
const FONT_SIZE_PX: u32 = 16;
|
||||||
|
|
||||||
/// Run a single window until it is closed.
|
/// Run a single window until it is closed, returning the shell's exit code.
|
||||||
pub fn run() -> anyhow::Result<()> {
|
pub fn run() -> anyhow::Result<ExitCode> {
|
||||||
let conn = Connection::connect_to_env().context("connect to Wayland compositor")?;
|
let conn = Connection::connect_to_env().context("connect to Wayland compositor")?;
|
||||||
let (globals, event_queue) =
|
let (globals, event_queue) =
|
||||||
registry_queue_init(&conn).context("initialize Wayland registry")?;
|
registry_queue_init(&conn).context("initialize Wayland registry")?;
|
||||||
|
|
@ -127,6 +129,7 @@ pub fn run() -> anyhow::Result<()> {
|
||||||
height: DEFAULT_H,
|
height: DEFAULT_H,
|
||||||
dirty: false,
|
dirty: false,
|
||||||
exit: false,
|
exit: false,
|
||||||
|
exit_code: ExitCode::SUCCESS,
|
||||||
};
|
};
|
||||||
|
|
||||||
while !app.exit {
|
while !app.exit {
|
||||||
|
|
@ -138,7 +141,7 @@ pub fn run() -> anyhow::Result<()> {
|
||||||
app.dirty = false;
|
app.dirty = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(app.exit_code)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Columns and rows that fit a `width`×`height` px window at `metrics`.
|
/// Columns and rows that fit a `width`×`height` px window at `metrics`.
|
||||||
|
|
@ -180,6 +183,8 @@ struct App {
|
||||||
/// The grid changed and the window needs repainting.
|
/// The grid changed and the window needs repainting.
|
||||||
dirty: bool,
|
dirty: bool,
|
||||||
exit: bool,
|
exit: bool,
|
||||||
|
/// Exit code to return, taken from the shell when it exits.
|
||||||
|
exit_code: ExitCode,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
|
|
@ -213,10 +218,18 @@ impl App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The child shell has gone away; reap it and tear the window down.
|
/// The child shell has gone away; reap it, capture its code, and tear the
|
||||||
|
/// window down.
|
||||||
fn child_exited(&mut self) {
|
fn child_exited(&mut self) {
|
||||||
match self.pty.wait() {
|
match self.pty.wait() {
|
||||||
Ok(status) => tracing::info!("shell exited: {status}"),
|
Ok(status) => {
|
||||||
|
tracing::info!("shell exited: {status}");
|
||||||
|
// Mirror the shell's status: its code, or 128+signal if killed.
|
||||||
|
let code = status
|
||||||
|
.code()
|
||||||
|
.unwrap_or_else(|| 128 + status.signal().unwrap_or(0));
|
||||||
|
self.exit_code = ExitCode::from(code as u8);
|
||||||
|
}
|
||||||
Err(err) => tracing::warn!("reap shell: {err}"),
|
Err(err) => tracing::warn!("reap shell: {err}"),
|
||||||
}
|
}
|
||||||
self.exit = true;
|
self.exit = true;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue