--- sleep.1 | 27 +++++++++++++++++----- sleep.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 92 insertions(+), 14 deletions(-) diff --git a/sleep.1 b/sleep.1 index 2b78bfb..66c71c0 100644 --- a/sleep.1 +++ b/sleep.1 _AT_@ -1,22 +1,37 @@ -.Dd 2015-10-08 +.Dd 2016-03-26 .Dt SLEEP 1 .Os sbase .Sh NAME .Nm sleep -.Nd wait for a number of seconds +.Nd wait for a specified amount of time .Sh SYNOPSIS .Nm -.Ar num +.Ar num[suffix] ... .Sh DESCRIPTION .Nm -waits for +waits for the sum of all +.Ar num[suffix] +to elapse. +.Pp +.Ar suffix +may be either +\fBs\fP for seconds (default), +\fBm\fP for minutes, +\fBh\fP for hours, or +\fBd\fP for days. +.Pp .Ar num -seconds to elapse. +may be a floating point number. .Sh SEE ALSO -.Xr sleep 3 +.Xr sleep 3 , +.Xr nanosleep 3 .Sh STANDARDS The .Nm utility is compliant with the .St -p1003.1-2013 specification. +.Ar suffix , +multiple arguments, and +floatomg point number support +are extension to that standard. diff --git a/sleep.c b/sleep.c index b1028ed..693ce88 100644 --- a/sleep.c +++ b/sleep.c _AT_@ -1,27 +1,90 @@ /* See LICENSE file for copyright and license details. */ -#include <unistd.h> +#include <ctype.h> +#include <string.h> +#include <time.h> #include "util.h" +#ifndef TIME_MAX +# define TIME_MAX ((time_t)~0 ^ ((time_t)1 << (8 * sizeof(time_t) - 1))) +#endif + static void usage(void) { - eprintf("usage: %s num\n", argv0); + eprintf("usage: %s num[s|m|h|d] ...\n", argv0); +} + +static char * +strtotime(char *str, struct timespec *ts) +{ + char *p = str, *suf, c; + char buf[10]; + size_t n; + + while (isdigit(*p)) + p++; + suf = p + (*p == '.'); + while (isdigit(*suf)) + suf++; + + c = *suf; + *suf = *p = '\0'; + + ts->tv_sec = estrtonum(str, 0, TIME_MAX); + + if (p++ != suf) { + n = strlen(p); + n = n < 9 ? n : 9; + memcpy(buf, p, n); + memset(buf + n, '0', 9 - n); + buf[9] = '\0'; + ts->tv_nsec = estrtonum(buf, 0, 999999999L); + } else { + ts->tv_nsec = 0; + } + + *suf = c; + return suf; + +} + +static int +parsesuffix(char *suf) +{ + int n = 1; + if (!strcmp(suf, "m")) + n = 60; + else if (!strcmp(suf, "h")) + n = 60 * 60; + else if (!strcmp(suf, "d")) + n = 60 * 60 * 24; + else if (*suf && strcmp(suf, "s")) + eprintf("%s: invalid suffix\n"); + return n; } int main(int argc, char *argv[]) { - unsigned seconds; + struct timespec dur, rem; + int n; - argv0 = argv[0], argc--, argv++; + ARGBEGIN { + default: + usage(); + } ARGEND - if (argc != 1) + if (!argc) usage(); - seconds = estrtonum(argv[0], 0, UINT_MAX); - while ((seconds = sleep(seconds)) > 0) - ; + for (; argc; argc--, argv++) { + n = parsesuffix(strtotime(*argv, &dur)); + while (n--) { + rem = dur; + while (nanosleep(&rem, &rem) < 0); + } + } return 0; } -- 2.7.3Received on Sat Mar 26 2016 - 18:31:57 CET
This archive was generated by hypermail 2.3.0 : Sat Mar 26 2016 - 18:36:16 CET