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

Reply via email to