Pádraig Brady <[email protected]> writes:
> 'stty' again rejects empty speed arguments.
> Previously such arguments were accepted as value 0.
> [bug introduced in coreutils-9.8]
> diff --git a/src/seq.c b/src/seq.c
> index a49a18988..acae21fd0 100644
> --- a/src/seq.c
> +++ b/src/seq.c
> @@ -313,12 +313,22 @@ print_numbers (char const *fmt, struct layout layout,
> write_error ();
> if (out_of_range)
> break;
> + if (i + 1 == i)
> + error (EXIT_FAILURE, EOVERFLOW, _("sequence counter exhausted"));
>
> /* Mathematically equivalent to 'x += step;', and typically
> less subject to rounding error. */
> x = first + i * step;
>
> - out_of_range = (step < 0 ? x < last : last < x);
> + /* If STEP is too small to change X, then X might never pass LAST,
> + so compare the offsets from FIRST, which are not so rounded. */
> + if (x == x0
> + && ! (step < 0
> + ? last - first <= i * step : i * step <= last - first))
> + break;
> +
> + /* Also treat NaN, from "seq -- -inf inf 0", as out of range. */
> + out_of_range = ! (step < 0 ? last <= x : x <= last);
Not entirely related to this change, but regarding these lines in 'seq':
/* Roll our own isfinite/isnan rather than using <math.h>, so that we don't
have to worry about linking -lm just for isfinite. */
#ifndef isfinite
# define isfinite(x) ((x) * 0 == 0)
#endif
#ifndef isnan
# define isnan(x) ((x) != (x))
#endif
I wonder if it is better to use the built-ins, if available. I don't
think those require linking to libm.
> diff --git a/tests/seq/seq-no-progress.sh b/tests/seq/seq-no-progress.sh
> new file mode 100755
> index 000000000..da48dbb85
> --- /dev/null
> +++ b/tests/seq/seq-no-progress.sh
> @@ -0,0 +1,49 @@
> +#!/bin/sh
> +# Ensure seq terminates when floating point arithmetic stops progressing.
> +
> +# Copyright (C) 2026 Free Software Foundation, Inc.
> +
> +# This program is free software: you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation, either version 3 of the License, or
> +# (at your option) any later version.
> +
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +# GNU General Public License for more details.
> +
> +# You should have received a copy of the GNU General Public License
> +# along with this program. If not, see <https://www.gnu.org/licenses/>.
> +
> +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
> +print_ver_ seq
> +
> +# 2**130 is exactly representable in a 64 bit double
> +big=1361129467683753853853498429727072845824
> +test $(timeout 10 seq -f '%.0f' "$big" "$big" "$big") = "$big" ||
> + skip_ 'seq not built with double support'
> +
> +check_seq_ ()
> +{
> + printf '%s\n' "$1" >exp || framework_failure_
> + shift
> +
> + { timeout 10 seq "$@" 2>err; echo $? >status; } | head -n2 >out
> + echo 0 >exp-status || framework_failure_
> + compare exp-status status || fail=1
> + compare /dev/null err || fail=1
> + compare exp out || fail=1
> +}
> +
> +check_seq_ "$big" -w "$big" "$big"
> +check_seq_ "$big" "$big" 201 "$big"
> +check_seq_ "-$big" -- "-$big" "-$big"
> +check_seq_ "-$big" -- "-$big" -1 "-$big"
> +
> +check_seq_ 1.0000000000000000000000000000000000000000 1 1e-40 1
> +check_seq_ -inf -- -inf -inf
> +# Adding opposite infinities produces NaN, which must terminate the loop.
> +check_seq_ -inf -- -inf inf 0
> +
> +Exit $fail
Maybe it is worth adding this test which also triggers the infinite
loop, but should be more portable?
$ eval $(src/getlimits);
$ timeout -v 10 seq -w $LDBL_MAX $LDBL_MAX >/dev/null
timeout: sending signal TERM to command 'seq'
Collin