1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 11:37:44 +00:00

truncate: error when trying to truncate a fifo

Terminate the `truncate` program with an error message when trying to
truncate a named pipe (also known as a fifo).
This commit is contained in:
Jeffrey Finkelstein 2022-01-28 22:24:07 -05:00
parent 7b3cfcf708
commit fe5b537f56
2 changed files with 77 additions and 1 deletions

View file

@ -10,6 +10,8 @@ use clap::{crate_version, App, AppSettings, Arg};
use std::convert::TryFrom;
use std::fs::{metadata, OpenOptions};
use std::io::ErrorKind;
#[cfg(unix)]
use std::os::unix::fs::FileTypeExt;
use std::path::Path;
use uucore::display::Quotable;
use uucore::error::{FromIo, UResult, USimpleError, UUsageError};
@ -207,6 +209,8 @@ fn file_truncate(filename: &str, create: bool, size: usize) -> std::io::Result<(
///
/// If the any file could not be opened, or there was a problem setting
/// the size of at least one file.
///
/// If at least one file is a named pipe (also known as a fifo).
fn truncate_reference_and_size(
rfilename: &str,
size_string: &str,
@ -239,6 +243,17 @@ fn truncate_reference_and_size(
let fsize = metadata.len() as usize;
let tsize = mode.to_size(fsize);
for filename in filenames {
#[cfg(unix)]
if std::fs::metadata(filename)?.file_type().is_fifo() {
return Err(USimpleError::new(
1,
format!(
"cannot open {} for writing: No such device or address",
filename.quote()
),
));
}
file_truncate(filename, create, tsize)
.map_err_context(|| format!("cannot open {} for writing", filename.quote()))?;
}
@ -256,6 +271,8 @@ fn truncate_reference_and_size(
///
/// If the any file could not be opened, or there was a problem setting
/// the size of at least one file.
///
/// If at least one file is a named pipe (also known as a fifo).
fn truncate_reference_file_only(
rfilename: &str,
filenames: &[String],
@ -273,6 +290,16 @@ fn truncate_reference_file_only(
})?;
let tsize = metadata.len() as usize;
for filename in filenames {
#[cfg(unix)]
if std::fs::metadata(filename)?.file_type().is_fifo() {
return Err(USimpleError::new(
1,
format!(
"cannot open {} for writing: No such device or address",
filename.quote()
),
));
}
file_truncate(filename, create, tsize)
.map_err_context(|| format!("cannot open {} for writing", filename.quote()))?;
}
@ -294,6 +321,8 @@ fn truncate_reference_file_only(
///
/// If the any file could not be opened, or there was a problem setting
/// the size of at least one file.
///
/// If at least one file is a named pipe (also known as a fifo).
fn truncate_size_only(size_string: &str, filenames: &[String], create: bool) -> UResult<()> {
let mode = parse_mode_and_size(size_string)
.map_err(|e| USimpleError::new(1, format!("Invalid number: {}", e)))?;
@ -302,7 +331,19 @@ fn truncate_size_only(size_string: &str, filenames: &[String], create: bool) ->
}
for filename in filenames {
let fsize = match metadata(filename) {
Ok(m) => m.len(),
Ok(m) => {
#[cfg(unix)]
if m.file_type().is_fifo() {
return Err(USimpleError::new(
1,
format!(
"cannot open {} for writing: No such device or address",
filename.quote()
),
));
}
m.len()
}
Err(_) => 0,
};
let tsize = mode.to_size(fsize as usize);

View file

@ -398,3 +398,38 @@ fn test_underflow_relative_size() {
assert!(at.file_exists(FILE1));
assert!(at.read_bytes(FILE1).is_empty());
}
#[cfg(not(windows))]
#[test]
fn test_fifo_error_size_only() {
let (at, mut ucmd) = at_and_ucmd!();
at.mkfifo("fifo");
ucmd.args(&["-s", "0", "fifo"])
.fails()
.no_stdout()
.stderr_contains("cannot open 'fifo' for writing: No such device or address");
}
#[cfg(not(windows))]
#[test]
fn test_fifo_error_reference_file_only() {
let (at, mut ucmd) = at_and_ucmd!();
at.mkfifo("fifo");
at.make_file("reference_file");
ucmd.args(&["-r", "reference_file", "fifo"])
.fails()
.no_stdout()
.stderr_contains("cannot open 'fifo' for writing: No such device or address");
}
#[cfg(not(windows))]
#[test]
fn test_fifo_error_reference_and_size() {
let (at, mut ucmd) = at_and_ucmd!();
at.mkfifo("fifo");
at.make_file("reference_file");
ucmd.args(&["-r", "reference_file", "-s", "+0", "fifo"])
.fails()
.no_stdout()
.stderr_contains("cannot open 'fifo' for writing: No such device or address");
}