summaryrefslogtreecommitdiffstats
path: root/bin/sleep
diff options
context:
space:
mode:
authorru <ru@FreeBSD.org>1999-10-01 07:53:40 +0000
committerru <ru@FreeBSD.org>1999-10-01 07:53:40 +0000
commit8e2cd16fb83ff0789444173ddfd06fd6ad45af4d (patch)
treee7e3e4d5c4ff94408802afa3d5836113453bd6f2 /bin/sleep
parent69ca82a991ea4825453bf9299c313eb4c4f4a897 (diff)
downloadFreeBSD-src-8e2cd16fb83ff0789444173ddfd06fd6ad45af4d.zip
FreeBSD-src-8e2cd16fb83ff0789444173ddfd06fd6ad45af4d.tar.gz
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).
Diffstat (limited to 'bin/sleep')
-rw-r--r--bin/sleep/sleep.124
-rw-r--r--bin/sleep/sleep.c60
2 files changed, 72 insertions, 12 deletions
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 <ctype.h>
+#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
+#include <time.h>
#include <unistd.h>
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);
}
OpenPOWER on IntegriCloud