Skip to content

Commit 7146111

Browse files
committed
Close tempfile explicitly after the command to exist
1 parent 5e8827f commit 7146111

File tree

1 file changed

+29
-9
lines changed

1 file changed

+29
-9
lines changed

crates/cargo-util/src/process_builder.rs

+29-9
Original file line numberDiff line numberDiff line change
@@ -226,8 +226,10 @@ impl ProcessBuilder {
226226
Ok(mut child) => return child.wait(),
227227
}
228228
}
229-
let (mut cmd, _argfile) = self.build_command_with_argfile()?;
230-
cmd.spawn()?.wait()
229+
let (mut cmd, argfile) = self.build_command_with_argfile()?;
230+
let status = cmd.spawn()?.wait();
231+
close_tempfile_and_log_error(argfile);
232+
status
231233
}
232234

233235
/// Runs the process, waiting for completion, and mapping non-success exit codes to an error.
@@ -279,8 +281,10 @@ impl ProcessBuilder {
279281
Ok(child) => return child.wait_with_output(),
280282
}
281283
}
282-
let (mut cmd, _argfile) = self.build_command_with_argfile()?;
283-
piped(&mut cmd).spawn()?.wait_with_output()
284+
let (mut cmd, argfile) = self.build_command_with_argfile()?;
285+
let output = piped(&mut cmd).spawn()?.wait_with_output();
286+
close_tempfile_and_log_error(argfile);
287+
output
284288
}
285289

286290
/// Executes the process, returning the stdio output, or an error if non-zero exit status.
@@ -334,7 +338,7 @@ impl ProcessBuilder {
334338

335339
let status = (|| {
336340
let cmd = self.build_command();
337-
let (mut child, _argfile) = spawn(cmd)?;
341+
let (mut child, argfile) = spawn(cmd)?;
338342
let out = child.stdout.take().unwrap();
339343
let err = child.stderr.take().unwrap();
340344
read2(out, err, &mut |is_out, data, eof| {
@@ -380,7 +384,11 @@ impl ProcessBuilder {
380384
data.drain(..idx);
381385
*pos = 0;
382386
})?;
383-
child.wait()
387+
let status = child.wait();
388+
if let Some(argfile) = argfile {
389+
close_tempfile_and_log_error(argfile);
390+
}
391+
status
384392
})()
385393
.with_context(|| ProcessError::could_not_execute(self))?;
386394
let output = Output {
@@ -526,26 +534,38 @@ fn piped(cmd: &mut Command) -> &mut Command {
526534
.stdin(Stdio::null())
527535
}
528536

537+
fn close_tempfile_and_log_error(file: NamedTempFile) {
538+
file.close().unwrap_or_else(|e| {
539+
log::warn!("failed to close temporary file: {e}");
540+
});
541+
}
542+
529543
#[cfg(unix)]
530544
mod imp {
531-
use super::{debug_force_argfile, ProcessBuilder, ProcessError};
545+
use super::{close_tempfile_and_log_error, debug_force_argfile, ProcessBuilder, ProcessError};
532546
use anyhow::Result;
533547
use std::io;
534548
use std::os::unix::process::CommandExt;
535549

536550
pub fn exec_replace(process_builder: &ProcessBuilder) -> Result<()> {
537551
let mut error;
552+
let mut file = None;
538553
if debug_force_argfile(process_builder.retry_with_argfile) {
539-
let (mut command, _argfile) = process_builder.build_command_with_argfile()?;
554+
let (mut command, argfile) = process_builder.build_command_with_argfile()?;
555+
file = Some(argfile);
540556
error = command.exec()
541557
} else {
542558
let mut command = process_builder.build_command();
543559
error = command.exec();
544560
if process_builder.should_retry_with_argfile(&error) {
545-
let (mut command, _argfile) = process_builder.build_command_with_argfile()?;
561+
let (mut command, argfile) = process_builder.build_command_with_argfile()?;
562+
file = Some(argfile);
546563
error = command.exec()
547564
}
548565
}
566+
if let Some(file) = file {
567+
close_tempfile_and_log_error(file);
568+
}
549569

550570
Err(anyhow::Error::from(error).context(ProcessError::new(
551571
&format!("could not execute process {}", process_builder),

0 commit comments

Comments
 (0)