Close tempfile explicitly after the command to exist

This commit is contained in:
Weihang Lo 2022-04-10 01:44:40 +08:00
parent 5e8827f26e
commit 7146111afe
No known key found for this signature in database
GPG Key ID: D7DBF189825E82E7

View File

@ -226,8 +226,10 @@ impl ProcessBuilder {
Ok(mut child) => return child.wait(), Ok(mut child) => return child.wait(),
} }
} }
let (mut cmd, _argfile) = self.build_command_with_argfile()?; let (mut cmd, argfile) = self.build_command_with_argfile()?;
cmd.spawn()?.wait() let status = cmd.spawn()?.wait();
close_tempfile_and_log_error(argfile);
status
} }
/// Runs the process, waiting for completion, and mapping non-success exit codes to an error. /// Runs the process, waiting for completion, and mapping non-success exit codes to an error.
@ -279,8 +281,10 @@ impl ProcessBuilder {
Ok(child) => return child.wait_with_output(), Ok(child) => return child.wait_with_output(),
} }
} }
let (mut cmd, _argfile) = self.build_command_with_argfile()?; let (mut cmd, argfile) = self.build_command_with_argfile()?;
piped(&mut cmd).spawn()?.wait_with_output() let output = piped(&mut cmd).spawn()?.wait_with_output();
close_tempfile_and_log_error(argfile);
output
} }
/// Executes the process, returning the stdio output, or an error if non-zero exit status. /// Executes the process, returning the stdio output, or an error if non-zero exit status.
@ -334,7 +338,7 @@ impl ProcessBuilder {
let status = (|| { let status = (|| {
let cmd = self.build_command(); let cmd = self.build_command();
let (mut child, _argfile) = spawn(cmd)?; let (mut child, argfile) = spawn(cmd)?;
let out = child.stdout.take().unwrap(); let out = child.stdout.take().unwrap();
let err = child.stderr.take().unwrap(); let err = child.stderr.take().unwrap();
read2(out, err, &mut |is_out, data, eof| { read2(out, err, &mut |is_out, data, eof| {
@ -380,7 +384,11 @@ impl ProcessBuilder {
data.drain(..idx); data.drain(..idx);
*pos = 0; *pos = 0;
})?; })?;
child.wait() let status = child.wait();
if let Some(argfile) = argfile {
close_tempfile_and_log_error(argfile);
}
status
})() })()
.with_context(|| ProcessError::could_not_execute(self))?; .with_context(|| ProcessError::could_not_execute(self))?;
let output = Output { let output = Output {
@ -526,26 +534,38 @@ fn piped(cmd: &mut Command) -> &mut Command {
.stdin(Stdio::null()) .stdin(Stdio::null())
} }
fn close_tempfile_and_log_error(file: NamedTempFile) {
file.close().unwrap_or_else(|e| {
log::warn!("failed to close temporary file: {e}");
});
}
#[cfg(unix)] #[cfg(unix)]
mod imp { mod imp {
use super::{debug_force_argfile, ProcessBuilder, ProcessError}; use super::{close_tempfile_and_log_error, debug_force_argfile, ProcessBuilder, ProcessError};
use anyhow::Result; use anyhow::Result;
use std::io; use std::io;
use std::os::unix::process::CommandExt; use std::os::unix::process::CommandExt;
pub fn exec_replace(process_builder: &ProcessBuilder) -> Result<()> { pub fn exec_replace(process_builder: &ProcessBuilder) -> Result<()> {
let mut error; let mut error;
let mut file = None;
if debug_force_argfile(process_builder.retry_with_argfile) { if debug_force_argfile(process_builder.retry_with_argfile) {
let (mut command, _argfile) = process_builder.build_command_with_argfile()?; let (mut command, argfile) = process_builder.build_command_with_argfile()?;
file = Some(argfile);
error = command.exec() error = command.exec()
} else { } else {
let mut command = process_builder.build_command(); let mut command = process_builder.build_command();
error = command.exec(); error = command.exec();
if process_builder.should_retry_with_argfile(&error) { if process_builder.should_retry_with_argfile(&error) {
let (mut command, _argfile) = process_builder.build_command_with_argfile()?; let (mut command, argfile) = process_builder.build_command_with_argfile()?;
file = Some(argfile);
error = command.exec() error = command.exec()
} }
} }
if let Some(file) = file {
close_tempfile_and_log_error(file);
}
Err(anyhow::Error::from(error).context(ProcessError::new( Err(anyhow::Error::from(error).context(ProcessError::new(
&format!("could not execute process {}", process_builder), &format!("could not execute process {}", process_builder),