summaryrefslogtreecommitdiffstats
path: root/bin/sleep
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2010-08-02 10:57:56 +0000
committerkib <kib@FreeBSD.org>2010-08-02 10:57:56 +0000
commit58f67b3672cdcd81547cb431205e5ca12e1208a1 (patch)
tree7a64f036b0de6246990c0eb79f9be475ff9bfe57 /bin/sleep
parent7ff57057ce887665c7a957a467c441ceb4cffb85 (diff)
downloadFreeBSD-src-58f67b3672cdcd81547cb431205e5ca12e1208a1.zip
FreeBSD-src-58f67b3672cdcd81547cb431205e5ca12e1208a1.tar.gz
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. Submitted by: bde MFC after: 3 weeks
Diffstat (limited to 'bin/sleep')
-rw-r--r--bin/sleep/sleep.c91
1 files changed, 19 insertions, 72 deletions
diff --git a/bin/sleep/sleep.c b/bin/sleep/sleep.c
index f711a3f..fa7deb2 100644
--- a/bin/sleep/sleep.c
+++ b/bin/sleep/sleep.c
@@ -49,7 +49,6 @@ __FBSDID("$FreeBSD$");
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
-#include <unistd.h>
static void usage(void);
@@ -65,91 +64,39 @@ int
main(int argc, char *argv[])
{
struct timespec time_to_sleep;
- long l, original;
- int neg;
- char *p;
+ double d;
+ time_t original;
+ char buf[2];
if (argc != 2)
usage();
- 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();
- }
- else if (*p == '+')
- ++p;
-
- /* Calculate seconds. */
- if (isdigit((unsigned char)*p)) {
- l = strtol(p, &p, 10);
-
- /*
- * 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;
-
- /* 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);
- }
-
- /* Skip over the trailing whitespace. */
- while (isspace((unsigned char)*p))
- ++p;
- if (*p != '\0')
+ 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);
- 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 %jd second(s) left"
- " out of the original %jd",
- (intmax_t)time_to_sleep.tv_sec,
- (intmax_t)original);
- report_requested = 0;
- } else
- break;
- }
+ 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;
}
-
return (0);
}
static void
usage(void)
{
- static const char msg[] = "usage: sleep seconds\n";
- write(STDERR_FILENO, msg, sizeof(msg) - 1);
+ fprintf(stderr, "usage: sleep seconds\n");
exit(1);
}
OpenPOWER on IntegriCloud