mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 19:47:45 +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:
parent
7b3cfcf708
commit
fe5b537f56
2 changed files with 77 additions and 1 deletions
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue