truncate: eliminate duplicate stat() syscall#9527
Conversation
src/uu/truncate/src/truncate.rs
Outdated
| Self::RoundDown(size) => fsize.checked_rem(*size).map(|remainder| fsize - remainder), | ||
| Self::RoundUp(size) => fsize.checked_rem(*size).map(|remainder| fsize + remainder), |
There was a problem hiding this comment.
As previously stated, calling this method when rounding to 0 resulted in a panic. Following the guideline of avoiding panicking code, use checked_rem() method.
There was a problem hiding this comment.
The remainder calculation seems to be wrong for RoundUp - should be (fsize + size - 1) / size * size to properly round up
no?
There was a problem hiding this comment.
The formula is indeed wrong. Should I fix it in this PR or in a separate PR?
There was a problem hiding this comment.
checked_next_multiple_of() depuis la bibliothèque standard est maintenant utilisé pour calculer le prochain multiple de size. Un test unitaire a également été ajouté.
There was a problem hiding this comment.
please don't use french in the comment ;)
| fn is_absolute(&self) -> bool { | ||
| matches!(self, Self::Absolute(_)) | ||
| } |
There was a problem hiding this comment.
Tiny helper function to determine if self is absolute. Useful when checking if an absolute mode was provided with a reference file.
| #[cfg(unix)] | ||
| if let Ok(metadata) = metadata(path) { | ||
| if metadata.file_type().is_fifo() { | ||
| return Err(USimpleError::new( | ||
| 1, | ||
| translate!("truncate-error-cannot-open-no-device", "filename" => filename.to_string_lossy().quote()), | ||
| )); | ||
| } | ||
| } |
There was a problem hiding this comment.
This check was moved to line 212.
| let file_size = match metadata(path) { | ||
| Ok(metadata) => { | ||
| #[cfg(unix)] | ||
| if metadata.file_type().is_fifo() { | ||
| return Err(USimpleError::new( | ||
| 1, | ||
| translate!("truncate-error-cannot-open-no-device", "filename" => filename.to_string_lossy().quote()), | ||
| )); | ||
| } | ||
| metadata.len() | ||
| } | ||
| Ok(m) => m, | ||
| Err(_) => 0, | ||
| }; |
There was a problem hiding this comment.
Retrieve the size of the file, while checking if it is a pipe. One single stat() syscall required.
There was a problem hiding this comment.
maybe add this as a comment in the code?
There was a problem hiding this comment.
Added comments.
| // Omitting the mode is equivalent to extending a file by 0 bytes. | ||
| let mode = match size_string { | ||
| Some(string) => match parse_mode_and_size(string) { | ||
| Err(error) => { | ||
| return Err(USimpleError::new( | ||
| 1, | ||
| translate!("truncate-error-invalid-number", "error" => error), | ||
| )); | ||
| } | ||
| Ok(mode) => mode, | ||
| }, | ||
| None => TruncateMode::Extend(0), | ||
| }; |
There was a problem hiding this comment.
Specifying no mode implies TruncateMode::Extend(0).
There was a problem hiding this comment.
same, better in the code as comment :)
There was a problem hiding this comment.
There is a comment. Look carefully at line 263. Est-ce que j'aurais dû l'écrire en français pour qu'il soit plus clair ? :)
| Self::Reduce(size) => { | ||
| if *size > fsize { | ||
| 0 | ||
| } else { | ||
| fsize - size | ||
| } | ||
| } |
There was a problem hiding this comment.
The standard library provides saturating_sub(). No need to implement its logic by ourselves.
|
GNU testsuite comparison: |
Signed-off-by: Jean-Christian CÎRSTEA <jean-christian.cirstea@tuta.com>
1. The documentation for parse_mode_and_size() has been updated. 2. Added documentation for TruncateMode::is_absolute(). Signed-off-by: Jean-Christian CÎRSTEA <jean-christian.cirstea@tuta.com>
a5efbf3 to
abcae00
Compare
|
GNU testsuite comparison: |
Signed-off-by: Jean-Christian CÎRSTEA <jean-christian.cirstea@tuta.com>
|
GNU testsuite comparison: |
|
@sylvestre Any outstanding issues with this PR? |
When no reference file is given,
truncateperforms twostat()syscalls:This commit fixes this issue by restructuring the code. The main change resides in the elimination of the initial match performed at the top level to select between different scenarios. Instead, the new implementation:
TruncateMode::Extend(0)is implied.ftruncate()to resize the file.