mirror of
https://github.com/narrrl/proton-drive-linux.git
synced 2026-11-03 16:41:26 +01:00
fix(cli): stop quietly when stdout is closed
`pdfs ls | head` ended in a "Broken pipe" panic once `head` had its lines, because std's `println!` panics on a failed write. The CLI now shadows `println!` and `print!` with versions that exit 0 on a closed pipe and report any other write error, such as a full disk, with exit 1. Restoring the default SIGPIPE would also stop the panic, but the same binary runs the daemon, which must not die when a socket's peer goes away.
This commit is contained in:
1 parent
eb53d122cc
commit
8cde79b8e3
1 file changed
+33
@@ -20,6 +20,39 @@ use pdfs_core::control::{
|
||||
use pdfs_core::db::Db;
|
||||
use pdfs_core::service;
|
||||
|
||||
/// `println!` for this binary, shadowing std's, which panics when stdout is
|
||||
/// closed: `pdfs ls | head` ended in a "Broken pipe" panic once `head` had its
|
||||
/// lines. This one hands the failure to [`stdout_written`] instead.
|
||||
///
|
||||
/// Restoring the default `SIGPIPE` would also stop the panic, but the same
|
||||
/// binary runs the daemon, which must not die when a socket's peer goes away.
|
||||
macro_rules! println {
|
||||
($($arg:tt)*) => {{
|
||||
use std::io::Write as _;
|
||||
$crate::stdout_written(writeln!(std::io::stdout(), $($arg)*))
|
||||
}};
|
||||
}
|
||||
|
||||
/// [`println!`] without the newline.
|
||||
macro_rules! print {
|
||||
($($arg:tt)*) => {{
|
||||
use std::io::Write as _;
|
||||
$crate::stdout_written(write!(std::io::stdout(), $($arg)*))
|
||||
}};
|
||||
}
|
||||
|
||||
/// Exit on a failed write to stdout. A closed pipe means the reader has all it
|
||||
/// wanted, so that exit is a success.
|
||||
fn stdout_written(result: std::io::Result<()>) {
|
||||
if let Err(error) = result {
|
||||
if error.kind() == std::io::ErrorKind::BrokenPipe {
|
||||
std::process::exit(0);
|
||||
}
|
||||
eprintln!("Error: writing to stdout: {error}");
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(
|
||||
name = "pdfs",
|
||||
|
||||
Reference in new issue
Block a user