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?

--
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);
 }
 

Reply via email to