.B mtimeout
.RB [ \-s
.IR signal ]
-.I seconds
+.I time
.I command
.RI [ arguments ...]
.
.SH DESCRIPTION
The
.B mtimeout
-command runs a specified program for at most a given number of
-.IR seconds .
+command runs a specified program for at most a given amount of
+.IR time .
+The
+.I time
+may be fractional (with a decimal point), and may be followed by a unit
+suffix:
+.RB ` s '
+for seconds,
+.RB ` m '
+for minutes,
+.RB ` h '
+for hours, and
+.RB ` d '
+for days.
.PP
It works by running the given command as a separate process group. It
then waits either for the top-level process (only) to exit, or for the
#include <ctype.h>
#include <errno.h>
+#include <math.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
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)
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;
}
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 --- */
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 */