mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
fix: handle broken pipe errors gracefully
When a broken pipe error occurs, we want to exit gracefully with a success exit code. This matches existing Unix convention.
This commit is contained in:
parent
2770e0259c
commit
79819fcae8
2 changed files with 33 additions and 4 deletions
|
|
@ -2,10 +2,37 @@ yazi_macro::mod_pub!(package);
|
|||
|
||||
yazi_macro::mod_flat!(args);
|
||||
|
||||
use std::process::ExitCode;
|
||||
|
||||
use clap::Parser;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
async fn main() -> ExitCode {
|
||||
match run().await {
|
||||
Ok(()) => ExitCode::SUCCESS,
|
||||
Err(err) => {
|
||||
// Look for a broken pipe error. In this case, we generally want
|
||||
// to exit "gracefully" with a success exit code. This matches
|
||||
// existing Unix convention. We need to handle this explicitly
|
||||
// since the Rust runtime doesn't ask for PIPE signals, and thus
|
||||
// we get an I/O error instead. Traditional C Unix applications
|
||||
// quit by getting a PIPE signal that they don't handle, and thus
|
||||
// the unhandled signal causes the process to unceremoniously
|
||||
// terminate.
|
||||
for cause in err.chain() {
|
||||
if let Some(ioerr) = cause.downcast_ref::<std::io::Error>() {
|
||||
if ioerr.kind() == std::io::ErrorKind::BrokenPipe {
|
||||
return ExitCode::from(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
eprintln!("{:#}", err);
|
||||
ExitCode::FAILURE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn run() -> anyhow::Result<()> {
|
||||
yazi_shared::init();
|
||||
yazi_fs::init();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
use std::io::{self, Write};
|
||||
|
||||
use anyhow::{Context, Result, bail};
|
||||
use tokio::fs;
|
||||
use toml_edit::{Array, DocumentMut, InlineTable, Item, Value};
|
||||
|
|
@ -78,13 +80,13 @@ impl Package {
|
|||
};
|
||||
|
||||
let deps = deps.as_array().context("`deps` must be an array")?;
|
||||
println!("{section}s:");
|
||||
writeln!(io::stdout(), "{section}s:")?;
|
||||
|
||||
for dep in deps {
|
||||
let Some(dep) = dep.as_inline_table() else { continue };
|
||||
match (dep.get("use").and_then(Value::as_str), dep.get("rev").and_then(Value::as_str)) {
|
||||
(Some(use_), None) => println!("\t{use_}"),
|
||||
(Some(use_), Some(rev)) => println!("\t{use_} ({rev})"),
|
||||
(Some(use_), None) => writeln!(io::stdout(), "\t{use_}")?,
|
||||
(Some(use_), Some(rev)) => writeln!(io::stdout(), "\t{use_} ({rev})")?,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue