Author: kib
Date: Sat Aug 21 08:49:53 2010
New Revision: 211536
URL: http://svn.freebsd.org/changeset/base/211536

Log:
  MFC r210679:
  Report the time left for the sleep on SIGINFO.
  Be stricter in the checking of interval specification.
  
  MFC r210696:
  Deal with proper format for printing time_t.
  
  MFC r210749:
  Simplify argument parser by using sscanf(); simplify usage() by not
  refusing to use stdio.
  Reduce nesting level in the sleep loop by returning earlier for negative
  timeouts.
  Limit the maximum timeout to INT_MAX seconds.
  
  MFC r210750:
  Document the new argument parser for sleep(1) and SIGINFO behaviour.
  Remove higlight for the unportability notice.

Modified:
  stable/8/bin/sleep/sleep.1
  stable/8/bin/sleep/sleep.c
Directory Properties:
  stable/8/bin/sleep/   (props changed)

Modified: stable/8/bin/sleep/sleep.1
==============================================================================
--- stable/8/bin/sleep/sleep.1  Sat Aug 21 04:04:46 2010        (r211535)
+++ stable/8/bin/sleep/sleep.1  Sat Aug 21 08:49:53 2010        (r211536)
@@ -51,6 +51,10 @@ suspends execution for a minimum of
 If the
 .Nm
 command receives a signal, it takes the standard action.
+When the
+.Dv SIGINFO
+signal is received, the estimate of the amount of seconds left to
+sleep is printed on the standard output.
 .Sh IMPLEMENTATION NOTES
 The
 .Dv SIGALRM
@@ -58,14 +62,11 @@ signal is not handled specially by this 
 .Pp
 The
 .Nm
-command will accept and honor a non-integer number of specified seconds
-(with a
-.Ql .\&
-character as a decimal point).
-.Bf Sy
+command allows and honors a non-integer number of seconds to sleep
+in any form acceptable by
+.Xr strtod 3 .
 This is a non-portable extension, and its use will nearly guarantee that
 a shell script will not execute properly on another system.
-.Ef
 .Sh EXIT STATUS
 .Ex -std
 .Sh EXAMPLES

Modified: stable/8/bin/sleep/sleep.c
==============================================================================
--- stable/8/bin/sleep/sleep.c  Sat Aug 21 04:04:46 2010        (r211535)
+++ stable/8/bin/sleep/sleep.c  Sat Aug 21 08:49:53 2010        (r211536)
@@ -42,84 +42,61 @@ static char sccsid[] = "@(#)sleep.c 8.3 
 __FBSDID("$FreeBSD$");
 
 #include <ctype.h>
+#include <err.h>
 #include <limits.h>
+#include <signal.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <time.h>
-#include <unistd.h>
 
-void usage(void);
+static void usage(void);
+
+static volatile sig_atomic_t report_requested;
+static void
+report_request(int signo __unused)
+{
+
+       report_requested = 1;
+}
 
 int
 main(int argc, char *argv[])
 {
        struct timespec time_to_sleep;
-       long l;
-       int neg;
-       char *p;
+       double d;
+       time_t original;
+       char buf[2];
 
-       if (argc != 2) {
+       if (argc != 2)
                usage();
-               return(1);
-       }
-
-       p = argv[1];
 
-       /* Skip over leading whitespaces. */
-       while (isspace((unsigned char)*p))
-               ++p;
-
-       /* Check for optional `+' or `-' sign. */
-       neg = 0;
-       if (*p == '-') {
-               neg = 1;
-               ++p;
-               if (!isdigit((unsigned char)*p) && *p != '.') {
-                       usage();
-                       return(1);
-               }
-       }
-       else if (*p == '+')
-               ++p;
-
-       /* Calculate seconds. */
-       if (isdigit((unsigned char)*p)) {
-               l = strtol(p, &p, 10);
-               if (l > INT_MAX) {
-                       /*
-                        * Avoid overflow when `seconds' is huge.  This assumes
-                        * that the maximum value for a time_t is <= INT_MAX.
-                        */
-                       l = INT_MAX;
-               }
-       } else
-               l = 0;
-       time_to_sleep.tv_sec = (time_t)l;
-
-       /* Calculate nanoseconds. */
-       time_to_sleep.tv_nsec = 0;
-
-       if (*p == '.') {                /* Decimal point. */
-               l = 100000000L;
-               do {
-                       if (isdigit((unsigned char)*++p))
-                               time_to_sleep.tv_nsec += (*p - '0') * l;
-                       else
-                               break;
-                       l /= 10;
-               } while (l);
+       if (sscanf(argv[1], "%lf%1s", &d, buf) != 1)
+               usage();
+       if (d > INT_MAX)
+               usage();
+       if (d <= 0)
+               return (0);
+       original = time_to_sleep.tv_sec = (time_t)d;
+       time_to_sleep.tv_nsec = 1e9 * (d - time_to_sleep.tv_sec);
+
+       signal(SIGINFO, report_request);
+       while (nanosleep(&time_to_sleep, &time_to_sleep) != 0) {
+               if (report_requested) {
+                       /* Reporting does not bother with nanoseconds. */
+                       warnx("about %d second(s) left out of the original %d",
+                           (int)time_to_sleep.tv_sec, (int)original);
+                       report_requested = 0;
+               } else
+                       break;
        }
-
-       if (!neg && (time_to_sleep.tv_sec > 0 || time_to_sleep.tv_nsec > 0))
-               (void)nanosleep(&time_to_sleep, (struct timespec *)NULL);
-
-       return(0);
+       return (0);
 }
 
-void
+static void
 usage(void)
 {
-       const char msg[] = "usage: sleep seconds\n";
 
-       write(STDERR_FILENO, msg, sizeof(msg) - 1);
+       fprintf(stderr, "usage: sleep seconds\n");
+       exit(1);
 }
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to