ok/jj
1
0
Fork 0
forked from mirrors/jj

cli: ensure child processes are wait()ed on I/O error

This commit is contained in:
Yuya Nishihara 2024-03-02 20:31:38 +09:00
parent c8023dbd8b
commit 2817e30fc6
2 changed files with 17 additions and 24 deletions

View file

@ -94,30 +94,22 @@ fn pinentry_get_pw(url: &str) -> Option<String> {
.stdout(Stdio::piped()) .stdout(Stdio::piped())
.spawn() .spawn()
.ok()?; .ok()?;
let mut interact = || -> std::io::Result<_> {
#[rustfmt::skip] #[rustfmt::skip]
pinentry let req = format!(
.stdin
.take()
.unwrap()
.write_all(
format!(
"SETTITLE jj passphrase\n\ "SETTITLE jj passphrase\n\
SETDESC Enter passphrase for {url}\n\ SETDESC Enter passphrase for {url}\n\
SETPROMPT Passphrase:\n\ SETPROMPT Passphrase:\n\
GETPIN\n" GETPIN\n"
) );
.as_bytes(), pinentry.stdin.take().unwrap().write_all(req.as_bytes())?;
)
.ok()?;
let mut out = String::new(); let mut out = String::new();
pinentry pinentry.stdout.take().unwrap().read_to_string(&mut out)?;
.stdout Ok(out)
.take() };
.unwrap() let maybe_out = interact();
.read_to_string(&mut out)
.ok()?;
_ = pinentry.wait(); _ = pinentry.wait();
for line in out.split('\n') { for line in maybe_out.ok()?.split('\n') {
if !line.starts_with("D ") { if !line.starts_with("D ") {
continue; continue;
} }

View file

@ -552,7 +552,7 @@ pub fn generate_diff(
tool_binary: tool.program.clone(), tool_binary: tool.program.clone(),
source, source,
})?; })?;
io::copy(&mut child.stdout.take().unwrap(), writer).map_err(ExternalToolError::Io)?; let copy_result = io::copy(&mut child.stdout.take().unwrap(), writer);
// Non-zero exit code isn't an error. For example, the traditional diff command // Non-zero exit code isn't an error. For example, the traditional diff command
// will exit with 1 if inputs are different. // will exit with 1 if inputs are different.
let exit_status = child.wait().map_err(ExternalToolError::Io)?; let exit_status = child.wait().map_err(ExternalToolError::Io)?;
@ -560,6 +560,7 @@ pub fn generate_diff(
if !exit_status.success() { if !exit_status.success() {
writeln!(ui.warning(), "{}", format_tool_aborted(&exit_status)).ok(); writeln!(ui.warning(), "{}", format_tool_aborted(&exit_status)).ok();
} }
copy_result.map_err(ExternalToolError::Io)?;
Ok(()) Ok(())
} }