chiark / gitweb /
mtimeout.c: Accept time unit specification on timeout options.
[misc] / mtimeout.c
index 1bb484800f99c99597b63e5cf07641b3b6267da1..38723ae14e8d210a4531ce7b06d75d5eb44c32c1 100644 (file)
@@ -50,6 +50,7 @@
 
 #include <ctype.h>
 #include <errno.h>
+#include <math.h>
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -250,6 +251,39 @@ static int namesig(const char *p)
   else return (-1);
 }
 
+/* --- @strtotime@ --- *
+ *
+ * Arguments:  @const char *p@ = pointer to string
+ *             @struct timeval *tv@ = where to put the result
+ *
+ * Returns:    ---
+ *
+ * Use:                Converts a string representation of a duration into an
+ *             internal version.  Understands various time units.
+ */
+
+static void strtotime(const char *p, struct timeval *tv)
+{
+  char *q = (/*unconst*/ char *)p;
+  double t, i, f;
+
+  while (isspace((unsigned char)*q)) q++;
+  t = strtod(q, &q);
+  while (isspace((unsigned char)*q)) q++;
+  switch (*q) {
+    case 'd': case 'D': t *= 24;
+    case 'h': case 'H': t *= 60;
+    case 'm': case 'M': t *= 60;
+    case 's': case 'S':
+      q++;
+      while (isspace((unsigned char)*q)) q++;
+  }
+  if (*q) die(253, "bad time value `%s'", p);
+  f = modf(t, &i);
+  tv->tv_sec = i;
+  tv->tv_usec = f * 1000000;
+}
+
 /*----- Help functions ----------------------------------------------------*/
 
 static void usage(FILE *fp)
@@ -369,11 +403,9 @@ static void sigpropagate(int sig, void *p)
 
 int main(int argc, char *const argv[])
 {
-  char *p;
-  double t;
   int signo = SIGTERM;
   pid_t kid;
-  struct timeval tv;
+  struct timeval now, tv;
   struct timeout to;
   struct sigchld sc;
   sig sig_CHLD;
@@ -411,12 +443,7 @@ int main(int argc, char *const argv[])
   }
   argc -= optind; argv += optind;
   if ((f & F_BOGUS) || argc < 2) { usage(stderr); exit(253); }
-
-  p = argv[0];
-  while (isspace((unsigned char)*p)) p++;
-  t = strtod(argv[0], &p);
-  while (isspace((unsigned char)*p)) p++;
-  if (*p) die(253, "bad time value `%s'", argv[0]);
+  strtotime(argv[0], &tv);
 
   /* --- Get things set up --- */
 
@@ -452,8 +479,8 @@ int main(int argc, char *const argv[])
   to.kid = kid;
   to.sig = signo;
   to.panic = 0;
-  gettimeofday(&tv, 0);
-  TV_ADDL(&tv, &tv, (time_t)t, ((long)(t * 1000000))%1000000);
+  gettimeofday(&now, 0);
+  TV_ADD(&tv, &now, &tv);
   sel_addtimer(&sel, &to.t, &tv, timeout, &to);
 
   /* --- Main @select@ loop */