diff --git a/catsit-watch.1 b/catsit-watch.1 index 892fd18..5e97bdd 100644 --- a/catsit-watch.1 +++ b/catsit-watch.1 @@ -9,6 +9,7 @@ .Sh SYNOPSIS .Nm .Op Fl ai +.Op Fl d Ar delay .Op Fl f Ar file .Ar command ... . @@ -17,7 +18,7 @@ The .Nm utility runs a command each time any of a set of files -are modified. +are written to. If any watched files are removed or if the command exits non-zero, .Nm @@ -31,6 +32,12 @@ Append the path of the modified file to the arguments of .Ar command . +.It Fl d Ar delay +Wait +.Ar delay +milliseconds before running the command. +Any further writes within that time +do not trigger additional runs. .It Fl f Ar file Add .Ar file diff --git a/catsit-watch.c b/catsit-watch.c index ea64155..78d1cb2 100644 --- a/catsit-watch.c +++ b/catsit-watch.c @@ -65,10 +65,12 @@ int main(int argc, char *argv[]) { fcntl(kq, F_SETFD, FD_CLOEXEC); int init = 0; + int delay = 0; int append = 0; - for (int opt; 0 < (opt = getopt(argc, argv, "af:i"));) { + for (int opt; 0 < (opt = getopt(argc, argv, "ad:f:i"));) { switch (opt) { break; case 'a': append = 1; + break; case 'd': delay = strtol(optarg, NULL, 10); break; case 'f': watch(kq, optarg); break; case 'i': init = 1; break; default: return EX_USAGE; @@ -96,9 +98,27 @@ int main(int argc, char *argv[]) { int nevents = kevent(kq, NULL, 0, &event, 1, NULL); if (nevents < 0) err(EX_OSERR, "kevent"); - if (event.fflags & NOTE_DELETE) { + if (delay) { + struct kevent timer; + EV_SET( + &timer, 0, EVFILT_TIMER, EV_ADD | EV_ONESHOT, + 0, delay, event.udata + ); + nevents = kevent(kq, &timer, 1, NULL, 0, NULL); + if (nevents < 0) err(EX_OSERR, "kevent"); + while ( + event.filter != EVFILT_TIMER + && !(event.fflags & NOTE_DELETE) + ) { + nevents = kevent(kq, NULL, 0, &event, 1, NULL); + if (nevents < 0) err(EX_OSERR, "kevent"); + } + } + + if (event.filter == EVFILT_VNODE && event.fflags & NOTE_DELETE) { errx(EX_TEMPFAIL, "%s: file removed", (char *)event.udata); } + if (append) rest[argc] = (char *)event.udata; run(rest); }