fix: write -o targets that are devices or pipes directly
This commit is contained in:
1 parent
7ec2d30bce
commit
2512fdd430
1 file changed
+12
@@ -60,6 +60,12 @@ pub fn encode_png(img: &RgbaImage) -> Result<Vec<u8>> {
|
|||||||
/// Writes via a temp file in the same directory and a rename, so a partial
|
/// Writes via a temp file in the same directory and a rename, so a partial
|
||||||
/// screenshot never appears under the final name.
|
/// screenshot never appears under the final name.
|
||||||
pub fn write_atomic(path: &Path, bytes: &[u8]) -> Result<()> {
|
pub fn write_atomic(path: &Path, bytes: &[u8]) -> Result<()> {
|
||||||
|
// Devices and pipes (`-o /dev/null`, a FIFO) can't be replaced by a
|
||||||
|
// rename, and there is no partial file to protect; write them directly.
|
||||||
|
if fs::metadata(path).is_ok_and(|m| !m.is_file() && !m.is_dir()) {
|
||||||
|
return fs::write(path, bytes)
|
||||||
|
.with_context(|| format!("could not write {}", path.display()));
|
||||||
|
}
|
||||||
// "a.png" has the parent "", which means the current directory.
|
// "a.png" has the parent "", which means the current directory.
|
||||||
let dir = match path.parent() {
|
let dir = match path.parent() {
|
||||||
Some(p) if !p.as_os_str().is_empty() => p,
|
Some(p) if !p.as_os_str().is_empty() => p,
|
||||||
@@ -192,6 +198,12 @@ mod tests {
|
|||||||
assert_eq!(names.len(), 1);
|
assert_eq!(names.len(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn write_atomic_writes_devices_directly() {
|
||||||
|
// No temp file and rename for things that aren't regular files.
|
||||||
|
write_atomic(Path::new("/dev/null"), b"png").unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn write_atomic_reports_unwritable_dir() {
|
fn write_atomic_reports_unwritable_dir() {
|
||||||
let dir = tempfile::tempdir().unwrap();
|
let dir = tempfile::tempdir().unwrap();
|
||||||
|
|||||||
Reference in new issue
Block a user