On Thu, Jan 25, 2018 at 09:35:33PM -0600, Scott Cheloha wrote:
> Hi,
>
> This increases the range for sleep(1) from 100 million seconds up to
> 9223372036854775807.
>
> POSIX.1-2001 added a stipulation (which POSIX.1-2008 retains) that sleep(1)
> support inputs of at least 2147483647 seconds. This patch fulfills that
> requirement and brings us into alignment with POSIX.1-2008, which we already
> claim anyway.
>
> FreeBSD supports up to INT_MAX and no further. GNU sleep keeps seconds
> in a double, so they too ought to support at least this minimum... but
> they do something weird that I haven't quite figured out yet, so I'm
> actually not sure what they support.
>
> But anyway I don't see a reason to cap user input (as FreeBSD does) at the
> positive 32-bit limit when we already carefully parse up to the limit of
> time_t and check for overflow. If the end user wants to sleep that long,
> we can just let them. I have a subsequent patch that tells the user that
> their input is too large in the event of overflow. Currently we just exit
> with EINVAL and say nothing, which is both unusual and unhelpful.
>
> Using a loop to extend the input range of the utility seems a bit unclean,
> but this case alone certainly doesn't warrant extending the input range for
> nanosleep(2).
>
> I'm not sure whether the larger range is actually an extension to the
> standard, and if so whether we need to mention it in the manpage, but
> I've included a diff here anyway just in case. If you have ideas about
> the wording I'd love to hear them.
>
> Thoughts? ok?
The diff for sleep.c is ok.
For the manpage part, I have no strong opinion, but I'm not so sure this
is needed/useful. That sleeping for fractions of a second isn't portable
definitely has practical relevance, sleeping longer than 68 years not so
much. I'll leave this for jmc to decide.
>
> --
> Scott Cheloha
>
> Index: bin/sleep/sleep.1
> ===================================================================
> RCS file: /cvs/src/bin/sleep/sleep.1,v
> retrieving revision 1.22
> diff -u -p -r1.22 sleep.1
> --- bin/sleep/sleep.1 16 Aug 2016 18:51:25 -0000 1.22
> +++ bin/sleep/sleep.1 26 Jan 2018 03:22:08 -0000
> @@ -108,8 +108,10 @@ utility is compliant with the
> .St -p1003.1-2008
> specification.
> .Pp
> -The handling of fractional arguments is provided as an extension to that
> -specification.
> +The handling of fractional arguments and the support for values of
> +.Ar seconds
> +greater than 2147483647
> +are extensions to that specification.
> .Sh HISTORY
> A
> .Nm
> Index: bin/sleep/sleep.c
> ===================================================================
> RCS file: /cvs/src/bin/sleep/sleep.c,v
> retrieving revision 1.24
> diff -u -p -r1.24 sleep.c
> --- bin/sleep/sleep.c 11 Oct 2015 20:17:49 -0000 1.24
> +++ bin/sleep/sleep.c 26 Jan 2018 03:22:08 -0000
> @@ -102,12 +102,24 @@ main(int argc, char *argv[])
> }
> }
>
> - rqtp.tv_sec = secs;
> - rqtp.tv_nsec = nsecs;
> -
> - if ((secs > 0) || (nsecs > 0))
> + while (secs > 0 || nsecs > 0) {
> + /*
> + * nanosleep(2) supports a maximum of 100 million
> + * seconds, so we break the nap up into multiple
> + * calls if we have more than that.
> + */
> + if (secs > 100000000) {
> + rqtp.tv_sec = 100000000;
> + rqtp.tv_nsec = 0;
> + } else {
> + rqtp.tv_sec = secs;
> + rqtp.tv_nsec = nsecs;
> + }
> if (nanosleep(&rqtp, NULL))
> err(1, NULL);
> + secs -= rqtp.tv_sec;
> + nsecs -= rqtp.tv_nsec;
> + }
> return (0);
> }
>
>