[hackers] [sbase][PATCH] Improvements to sleep(1):

From: Mattias Andrée <maandree_AT_kth.se>
Date: Sat, 26 Mar 2016 18:31:57 +0100

- Add support for floating pointer numbers,
  which you will find in other implementations.

- Add support for suffixes [s|m|h|d], as
  found in GNU sleep, which is very useful.

- Add support for multiple arguments. Not
  really necessary, but brings compatibility
  at barely any cost.

Signed-off-by: Mattias Andrée <maandree_AT_kth.se>
---
 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.3
Received 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