Author: kib
Date: Sat Jul 31 14:30:11 2010
New Revision: 210679
URL: http://svn.freebsd.org/changeset/base/210679

Log:
  Report the time left for the sleep on SIGINFO.
  Be stricter in the checking of interval specification.
  
  PR:   bin/139345
  MFC after:    3 weeks

Modified:
  head/bin/sleep/sleep.c

Modified: head/bin/sleep/sleep.c
==============================================================================
--- head/bin/sleep/sleep.c      Sat Jul 31 14:26:10 2010        (r210678)
+++ head/bin/sleep/sleep.c      Sat Jul 31 14:30:11 2010        (r210679)
@@ -42,26 +42,34 @@ static char sccsid[] = "@(#)sleep.c 8.3 
 __FBSDID("$FreeBSD$");
 
 #include <ctype.h>
+#include <err.h>
 #include <limits.h>
+#include <signal.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;
+       long l, original;
        int neg;
        char *p;
 
-       if (argc != 2) {
+       if (argc != 2)
                usage();
-               return(1);
-       }
 
        p = argv[1];
 
@@ -74,10 +82,8 @@ main(int argc, char *argv[])
        if (*p == '-') {
                neg = 1;
                ++p;
-               if (!isdigit((unsigned char)*p) && *p != '.') {
+               if (!isdigit((unsigned char)*p) && *p != '.')
                        usage();
-                       return(1);
-               }
        }
        else if (*p == '+')
                ++p;
@@ -85,13 +91,13 @@ main(int argc, char *argv[])
        /* 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.
-                        */
+
+               /*
+                * Avoid overflow when `seconds' is huge.  This assumes
+                * that the maximum value for a time_t is <= INT_MAX.
+                */
+               if (l > INT_MAX)
                        l = INT_MAX;
-               }
        } else
                l = 0;
        time_to_sleep.tv_sec = (time_t)l;
@@ -110,16 +116,38 @@ main(int argc, char *argv[])
                } while (l);
        }
 
-       if (!neg && (time_to_sleep.tv_sec > 0 || time_to_sleep.tv_nsec > 0))
-               (void)nanosleep(&time_to_sleep, (struct timespec *)NULL);
+       /* Skip over the trailing whitespace. */
+       while (isspace((unsigned char)*p))
+               ++p;
+       if (*p != '\0')
+               usage();
+
+       signal(SIGINFO, report_request);
+       if (!neg && (time_to_sleep.tv_sec > 0 || time_to_sleep.tv_nsec > 0)) {
+               original = time_to_sleep.tv_sec;
+               while (nanosleep(&time_to_sleep, &time_to_sleep) != 0) {
+                       if (report_requested) {
+                               /*
+                                * Reporting does not bother with
+                                * fractions of a second...
+                                */
+                               warnx("about %ld second(s) left"
+                                   " out of the original %ld",
+                                   time_to_sleep.tv_sec, original);
+                               report_requested = 0;
+                       } else
+                               break;
+               }
+       }
 
-       return(0);
+       return (0);
 }
 
-void
+static void
 usage(void)
 {
-       const char msg[] = "usage: sleep seconds\n";
+       static const char msg[] = "usage: sleep seconds\n";
 
        write(STDERR_FILENO, msg, sizeof(msg) - 1);
+       exit(1);
 }
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to