mirror of
https://github.com/BurntSushi/ripgrep.git
synced 2025-06-14 22:15:13 +02:00
cli: fix process leak
If ripgrep was called in a way where the entire contents of a file aren't read (like --files-with-matches, among other methods), and if the file was read through an external process, then ripgrep would never reap that process. We fix this by introducing an explicit 'close' method, which we now call when using decompression or preprocessor searches. The implementation of 'close' is a little hokey. In particular, when we close stdout, this usually results in a broken pipe, and, consequently, a non-zero code returned once the child process is reaped. This is "situation normal," so we invent a (hopefully portable) heuristic for detecting it. Fixes #1766, Closes #1767
This commit is contained in:
committed by
Andrew Gallant
parent
3f33a83a5f
commit
5af7707a35
@ -366,6 +366,30 @@ impl DecompressionReader {
|
||||
let file = File::open(path)?;
|
||||
Ok(DecompressionReader { rdr: Err(file) })
|
||||
}
|
||||
|
||||
/// Closes this reader, freeing any resources used by its underlying child
|
||||
/// process, if one was used. If the child process exits with a nonzero
|
||||
/// exit code, the returned Err value will include its stderr.
|
||||
///
|
||||
/// `close` is idempotent, meaning it can be safely called multiple times.
|
||||
/// The first call closes the CommandReader and any subsequent calls do
|
||||
/// nothing.
|
||||
///
|
||||
/// This method should be called after partially reading a file to prevent
|
||||
/// resource leakage. However there is no need to call `close` explicitly
|
||||
/// if your code always calls `read` to EOF, as `read` takes care of
|
||||
/// calling `close` in this case.
|
||||
///
|
||||
/// `close` is also called in `drop` as a last line of defense against
|
||||
/// resource leakage. Any error from the child process is then printed as a
|
||||
/// warning to stderr. This can be avoided by explictly calling `close`
|
||||
/// before the CommandReader is dropped.
|
||||
pub fn close(&mut self) -> io::Result<()> {
|
||||
match self.rdr {
|
||||
Ok(ref mut rdr) => rdr.close(),
|
||||
Err(_) => Ok(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl io::Read for DecompressionReader {
|
||||
|
Reference in New Issue
Block a user