csplit: avoid extraenous output files given empty input

* src/csplit.c (get_first_line_in_buffer): Don't exit here
upon empty input, rather indicate no input in the return
to let callers handle in a more consistent fashion.
* NEWS: Mention the bug fix.
* tests/csplit/csplit.sh: Add a test case.
Reported by Daniel Hofstetter.
This commit is contained in:
Pádraig Brady
2025-01-09 19:29:01 +00:00
parent b58e321c8d
commit 8482cb9451
3 changed files with 20 additions and 4 deletions

3
NEWS
View File

@@ -11,6 +11,9 @@ GNU coreutils NEWS -*- outline -*-
cp,mv --update no longer overrides --interactive or --force. cp,mv --update no longer overrides --interactive or --force.
[bug introduced in coreutils-9.3] [bug introduced in coreutils-9.3]
csplit no longer creates empty files given empty input.
[This bug was present in "the beginning".]
ls and printf fix shell quoted output in the edge case of escaped ls and printf fix shell quoted output in the edge case of escaped
first and last characters, and single quotes in the string. first and last characters, and single quotes in the string.
[bug introduced in coreutils-8.26] [bug introduced in coreutils-8.26]

View File

@@ -494,13 +494,14 @@ load_buffer (void)
} }
} }
/* Return the line number of the first line that has not yet been retrieved. */ /* Return the line number of the first line that has not yet been retrieved.
Return 0 if no lines available. */
static intmax_t static intmax_t
get_first_line_in_buffer (void) get_first_line_in_buffer (void)
{ {
if (head == nullptr && !load_buffer ()) if (head == nullptr && !load_buffer ())
error (EXIT_FAILURE, errno, _("input disappeared")); return 0;
return head->first_available; return head->first_available;
} }
@@ -627,7 +628,7 @@ write_to_file (intmax_t last_line, bool ignore, int argnum)
first_line = get_first_line_in_buffer (); first_line = get_first_line_in_buffer ();
if (first_line > last_line) if (! first_line || first_line > last_line)
{ {
error (0, 0, _("%s: line number out of range"), error (0, 0, _("%s: line number out of range"),
quote (global_argv[argnum])); quote (global_argv[argnum]));
@@ -698,7 +699,9 @@ process_line_count (const struct control *p, intmax_t repetition)
if (no_more_lines () && suppress_matched) if (no_more_lines () && suppress_matched)
handle_line_error (p, repetition); handle_line_error (p, repetition);
linenum = get_first_line_in_buffer (); if (!(linenum = get_first_line_in_buffer ()))
handle_line_error (p, repetition);
while (linenum++ < last_line_to_save) while (linenum++ < last_line_to_save)
{ {
struct cstring *line = remove_line (); struct cstring *line = remove_line ();

View File

@@ -100,4 +100,14 @@ printf 'x%8199s\nx\n%8199s\nx\n' x x > in
csplit in '/x\{1\}/' '{*}' > /dev/null || fail=1 csplit in '/x\{1\}/' '{*}' > /dev/null || fail=1
cat xx?? | compare - in || fail=1 cat xx?? | compare - in || fail=1
# Ensure file not created for empty input
# which was the case with coreutils <= 9.5
rm -f xx??
csplit /dev/null 1 >/dev/null 2>err && fail=1
test -f xx00 && fail=1
cat <<\EOF > experr
csplit: '1': line number out of range
EOF
compare experr err || fail=1
Exit $fail Exit $fail