#include <ctype.h>
#include <errno.h>
+#include <math.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
static int namesig(const char *p)
{
const static struct namesig tab[] = {
-/*
- ;;; The signal name table is very boring to type. To make life less awful,
- ;;; put the signal names in this list and evaluate the code to get Emacs to
- ;;; regenerate it. We use @bsearch@ on it, so it's important that it be
- ;;; sorted: Emacs does this for us.
- (let ((signals '(HUP INT QUIT ILL ABRT FPE KILL SEGV PIPE ALRM TERM
- USR1 USR2 CHLD CONT STOP TSTP TTIN TTOU BUS POLL
- PROF SYS TRAP URG VTALRM XCPU XFSZ IOT EMT STKFLT
- IO CLD PWR INFO LOST WINCH)))
- (save-excursion
- (goto-char (point-min))
- (let ((start (search-forward (concat "/" "* SIGLIST *" "/\n")))
- (end (search-forward (concat "/" "* END *" "/\n"))))
- (delete-region start end))
- (dolist (sig (sort (copy-list signals) #'string<))
- (insert (format "#ifdef SIG%s\n { \"%s\", SIG%s },\n#endif\n"
- sig sig sig)))
- (insert (concat "/" "* END *" "/\n"))))
-*/
-
-/* SIGLIST */
+ /*
+ ;;; The signal name table is very boring to type. To make life less
+ ;;; awful, put the signal names in this list and evaluate the code to
+ ;;; get Emacs to regenerate it. We use @bsearch@ on it, so it's
+ ;;; important that it be sorted: Emacs does this for us.
+
+ (let ((signals '(HUP INT QUIT ILL ABRT FPE KILL SEGV PIPE ALRM TERM
+ USR1 USR2 CHLD CONT STOP TSTP TTIN TTOU BUS POLL
+ PROF SYS TRAP URG VTALRM XCPU XFSZ IOT EMT STKFLT
+ IO CLD PWR INFO LOST WINCH)))
+ (save-excursion
+ (goto-char (point-min))
+ (search-forward (concat "***" "BEGIN siglist" "***"))
+ (beginning-of-line 2)
+ (delete-region (point)
+ (progn
+ (search-forward "***END***")
+ (beginning-of-line)
+ (point)))
+ (dolist (sig (sort (copy-list signals) #'string<))
+ (insert (format "#ifdef SIG%s\n { \"%s\", SIG%s },\n#endif\n"
+ sig sig sig)))))
+ */
+
+ /***BEGIN siglist***/
#ifdef SIGABRT
{ "ABRT", SIGABRT },
#endif
#ifdef SIGXFSZ
{ "XFSZ", SIGXFSZ },
#endif
-/* END */
+ /***END***/
};
const struct namesig *ns = bsearch(p, tab, N(tab), sizeof(tab[0]),
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 */