Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions src/uu/csplit/src/csplit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,10 +268,12 @@ impl SplitWriter<'_> {
///
/// # Errors
///
/// The creation of the split file may fail with some [`io::Error`].
fn new_writer(&mut self) -> io::Result<()> {
/// Returns an error if creating the split file fails.
fn new_writer(&mut self) -> Result<(), CsplitError> {
let file_name = self.options.split_name.get(self.counter);
let file = File::create(file_name)?;
let file = File::create(&file_name)
.map_err_context(|| file_name.clone())
.map_err(CsplitError::from)?;
self.current_writer = Some(BufWriter::new(file));
self.counter += 1;
self.size = 0;
Expand Down
20 changes: 18 additions & 2 deletions src/uu/csplit/src/csplit_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
use std::io;
use thiserror::Error;
use uucore::display::Quotable;
use uucore::error::UError;
use uucore::error::{UError, strip_errno};
use uucore::translate;

/// Errors thrown by the csplit command
#[derive(Debug, Error)]
pub enum CsplitError {
#[error("IO error: {}", _0)]
#[error("{}", strip_errno(_0))]
IoError(#[from] io::Error),
#[error("{}", translate!("csplit-error-line-out-of-range", "pattern" => _0.quote()))]
LineOutOfRange(String),
Expand Down Expand Up @@ -54,3 +54,19 @@ impl UError for CsplitError {
}
}
}

#[cfg(test)]
mod tests {
use super::CsplitError;

#[cfg(unix)]
#[test]
fn io_error_display_is_clean() {
// GNU does not print "IO error:" nor the raw "(os error N)" suffix.
let err = CsplitError::IoError(std::io::Error::from_raw_os_error(13));
let msg = err.to_string();
assert_eq!(msg, "Permission denied");
assert!(!msg.contains("IO error:"));
assert!(!msg.contains("os error"));
}
}
19 changes: 19 additions & 0 deletions tests/by-util/test_csplit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1582,3 +1582,22 @@ fn test_write_error_dev_full_keep_files() {
assert!(at.file_exists("xx00"));
assert_eq!(at.read("xx00"), "1\n");
}

/// Test that a failed split-file creation reports the filename.
#[test]
#[cfg(unix)]
fn test_create_error_reports_filename() {
// Root can open a mode-000 file for writing, so File::create would not fail.
if rustix::process::geteuid().is_root() {
return;
}
let (at, mut ucmd) = at_and_ucmd!();
at.write("input", "a\nb\nc\n");
// Pre-create the first split with no write permission so File::create fails.
at.touch("xx00");
at.set_mode("xx00", 0o000);

ucmd.args(&["input", "2"])
.fails()
.stderr_is("csplit: xx00: Permission denied\n");
}
Loading