Skip to content

Commit 515e741

Browse files
committed
csplit: detect and report write errors
1 parent 3162c21 commit 515e741

File tree

1 file changed

+24
-11
lines changed

1 file changed

+24
-11
lines changed

src/uu/csplit/src/csplit.rs

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ where
127127
let ret = do_csplit(&mut split_writer, patterns_vec, &mut input_iter);
128128

129129
// consume the rest, unless there was an error
130-
if ret.is_ok() {
130+
let ret = if ret.is_ok() {
131131
input_iter.rewind_buffer();
132132
if let Some((_, line)) = input_iter.next() {
133133
// There is remaining input: create a final split and copy remainder
@@ -136,14 +136,18 @@ where
136136
for (_, line) in input_iter {
137137
split_writer.writeln(&line?)?;
138138
}
139-
split_writer.finish_split();
139+
split_writer.finish_split()
140140
} else if all_up_to_line && options.suppress_matched {
141141
// GNU semantics for integer patterns with --suppress-matched:
142142
// even if no remaining input, create a final (possibly empty) split
143143
split_writer.new_writer()?;
144-
split_writer.finish_split();
144+
split_writer.finish_split()
145+
} else {
146+
Ok(())
145147
}
146-
}
148+
} else {
149+
ret
150+
};
147151
// delete files on error by default
148152
if ret.is_err() && !options.keep_files {
149153
split_writer.delete_all_splits()?;
@@ -305,15 +309,24 @@ impl SplitWriter<'_> {
305309
///
306310
/// # Errors
307311
///
308-
/// Some [`io::Error`] if the split could not be removed in case it should be elided.
309-
fn finish_split(&mut self) {
312+
/// Some [`CsplitError::WriteError`] if flushing the writer fails.
313+
fn finish_split(&mut self) -> Result<(), CsplitError> {
310314
if !self.dev_null {
315+
// Flush the writer to ensure all data is written and errors are detected
316+
if let Some(ref mut writer) = self.current_writer {
317+
let file_name = self.options.split_name.get(self.counter - 1);
318+
writer
319+
.flush()
320+
.map_err_context(|| file_name.clone())
321+
.map_err(CsplitError::from)?;
322+
}
311323
if self.options.elide_empty_files && self.size == 0 {
312324
self.counter -= 1;
313325
} else if !self.options.quiet {
314326
println!("{}", self.size);
315327
}
316328
}
329+
Ok(())
317330
}
318331

319332
/// Removes all the split files that were created.
@@ -379,7 +392,7 @@ impl SplitWriter<'_> {
379392
}
380393
self.writeln(&line)?;
381394
}
382-
self.finish_split();
395+
self.finish_split()?;
383396
ret
384397
}
385398

@@ -446,15 +459,15 @@ impl SplitWriter<'_> {
446459
self.writeln(&line?)?;
447460
}
448461
None => {
449-
self.finish_split();
462+
self.finish_split()?;
450463
return Err(CsplitError::LineOutOfRange(
451464
pattern_as_str.to_string(),
452465
));
453466
}
454467
}
455468
offset -= 1;
456469
}
457-
self.finish_split();
470+
self.finish_split()?;
458471

459472
// if we have to suppress one line after we take the next and do nothing
460473
if next_line_suppress_matched {
@@ -495,7 +508,7 @@ impl SplitWriter<'_> {
495508
);
496509
}
497510

498-
self.finish_split();
511+
self.finish_split()?;
499512
if input_iter.buffer_len() < offset_usize {
500513
return Err(CsplitError::LineOutOfRange(pattern_as_str.to_string()));
501514
}
@@ -511,7 +524,7 @@ impl SplitWriter<'_> {
511524
}
512525
}
513526

514-
self.finish_split();
527+
self.finish_split()?;
515528
Err(CsplitError::MatchNotFound(pattern_as_str.to_string()))
516529
}
517530
}

0 commit comments

Comments
 (0)