From 8e2cd16fb83ff0789444173ddfd06fd6ad45af4d Mon Sep 17 00:00:00 2001 From: ru Date: Fri, 1 Oct 1999 07:53:40 +0000 Subject: Let sleep(1) handle fractions of a second (up to nanosecond). This is a conservative change. It does the same thing in weird cases like the old one. For example, 'sleep abcd' still sleeps for zero seconds. `sleep 10.a' and `sleep 10.05aa' do the best and not abort (ie: 10.a == 10 seconds, 10.05a == 10.05 seconds). --- bin/sleep/sleep.1 | 24 ++++++++++++++-------- bin/sleep/sleep.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 72 insertions(+), 12 deletions(-) (limited to 'bin/sleep') diff --git a/bin/sleep/sleep.1 b/bin/sleep/sleep.1 index 237b574..1c5e682 100644 --- a/bin/sleep/sleep.1 +++ b/bin/sleep/sleep.1 @@ -42,7 +42,7 @@ .Nm sleep .Nd suspend execution for an interval of time .Sh SYNOPSIS -.Nm sleep +.Nm .Ar seconds .Sh DESCRIPTION The @@ -50,17 +50,27 @@ The command suspends execution for a minimum of .Ar seconds . -.Nm Sleep -is used to schedule the execution of other commands (see -.Sx EXAMPLES -below). .Pp If the .Nm command receives a signal, it takes the standard action. +.Sh IMPLEMENTATION NOTES The .Dv SIGALRM signal is not handled specially by this implementation. +.Pp +The +.Nm +command will accept and honor a non-integer number of specified seconds +.Po +with a +.Ql \&. +character as a decimal point +.Pc . +.Bf Sy +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 DIAGNOSTICS The .Nm @@ -110,9 +120,7 @@ when the file is found, then another portion processing is done courteously by sleeping for 70 seconds in between each awk job. .Sh SEE ALSO -.Xr at 1 , -.Xr nanosleep 2 , -.Xr sleep 3 +.Xr nanosleep 2 .Sh STANDARDS The .Nm diff --git a/bin/sleep/sleep.c b/bin/sleep/sleep.c index 74242c9..0083987 100644 --- a/bin/sleep/sleep.c +++ b/bin/sleep/sleep.c @@ -45,8 +45,11 @@ static const char rcsid[] = "$FreeBSD$"; #endif /* not lint */ +#include +#include #include #include +#include #include void usage __P((void)); @@ -56,22 +59,71 @@ main(argc, argv) int argc; char *argv[]; { - int ch, secs; + struct timespec time_to_sleep; + long l; + int ch, neg; + char *p; while ((ch = getopt(argc, argv, "")) != -1) switch(ch) { case '?': default: usage(); + /* NOTREACHED */ } argc -= optind; argv += optind; - if (argc != 1) + if (argc != 1) { usage(); + /* NOTREACHED */ + } + + p = argv[0]; + + /* Skip over leading whitespaces. */ + while (isspace((unsigned char)*p)) + ++p; + + /* Check for optional `+' or `-' sign. */ + neg = 0; + if (*p == '-') { + neg = 1; + ++p; + } + 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; + } while (l /= 10); + } + + if (!neg && (time_to_sleep.tv_sec > 0 || time_to_sleep.tv_nsec > 0)) + (void)nanosleep(&time_to_sleep, (struct timespec *)NULL); - if ((secs = atoi(*argv)) > 0) - (void)sleep(secs); exit(0); } -- cgit v1.1