aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Ankarstrom <john@ankarstrom.se>2021-07-03 15:16:27 +0200
committerJohn Ankarstrom <john@ankarstrom.se>2021-07-03 15:16:27 +0200
commitc939da849d2e047534bf21813ed09e08e754522d (patch)
tree6ad3649139b9034b97ef2234c155ddb6640ca72e
parent77c8cfb2cb9331372d8c01c835fcec5be8ca302e (diff)
downloadwhen-c939da849d2e047534bf21813ed09e08e754522d.tar.gz
Re-organize source code
-rw-r--r--watch.c113
1 files changed, 42 insertions, 71 deletions
diff --git a/watch.c b/watch.c
index 0cfc5c9..7e3d256 100644
--- a/watch.c
+++ b/watch.c
@@ -1,4 +1,3 @@
-#define _OPENBSD_SOURCE
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
@@ -10,96 +9,68 @@
#include <sys/types.h>
#include <unistd.h>
-#define LIMIT 256
-
-/* print one initial line at startup */
-int initial = 0;
+#define FD 27
+#define LIMIT 100
int
-main(int argc, char *argv[]) {
- char **filenames;
- int fd, first_file_index, i, kq, n;
- size_t file_count;
- struct kevent changes[LIMIT];
- struct kevent events[LIMIT];
- struct rlimit rlp;
-
- file_count = argc - 1;
- first_file_index = 1; /* index of first file argument */
-
- /* disable buffering even non-interactively */
- setbuf(stdout, NULL);
-
- if (argc < 2) goto usage; /* quit if no arguments */
+main(int argc, char *argv[argc]) {
+ char *filenames[LIMIT+FD];
+ int fd, i, kq, n;
+ struct kevent evs[LIMIT];
+ struct kevent ev[LIMIT];
+
+ /* parse arguments */
+ if (argc-1 == 0) goto usage;
if (argv[1][0] == '-') {
- if (argc < 3) goto usage; /* quit if no filenames */
-
- /* adjust indices */
- file_count = argc - 2;
- first_file_index = 2;
-
- if (strcmp(argv[1], "-i") == 0)
- initial = 1;
- else
- goto usage;
+ if (argv[1][1] == 'i')
+ for (i = 2; i < argc; i++)
+ printf("%s\n", argv[i]);
+ else if (argv[1][1] == '-') ;
+ else goto usage;
+ argv++; argc--;
}
-
- if (file_count > LIMIT)
+ if (argc-1 == 0) goto usage;
+ if (argc-1 > LIMIT)
errx(1, "more than %d files", LIMIT);
- if ((kq = kqueue()) == -1) err(1, "kqueue");
+ /* disable buffering even non-interactively */
+ setbuf(stdout, NULL);
- /* save filenames by file descriptor */
- if (getrlimit(RLIMIT_NOFILE, &rlp) == -1)
- err(1, "getrlimit");
- if ((filenames = reallocarray(NULL, rlp.rlim_max, sizeof(char **))) == NULL)
- err(1, "reallocarray");
+ /* initialize kqueue */
+ if ((kq = kqueue()) == -1)
+ err(1, "kqueue");
- /* add each file to change list */
- for (i = first_file_index; i < argc; i++) {
+ /* process each file */
+ for (i = 1; i < argc; i++) {
if ((fd = open(argv[i], O_RDONLY)) == -1)
err(1, "%s", argv[i]);
filenames[fd] = argv[i];
-
- if (initial)
- printf("%s\n", argv[i]);
-
- /* specify watched events */
- struct kevent change = {
- .ident = fd,
- .filter = EVFILT_VNODE,
- .flags = EV_ADD | EV_CLEAR,
- .fflags = NOTE_WRITE | NOTE_DELETE,
- .data = 0,
- .udata = 0
- };
-
- changes[i - first_file_index] = change;
+ EV_SET(ev+i-1, fd, EVFILT_VNODE, EV_ADD|EV_CLEAR,
+ NOTE_WRITE|NOTE_DELETE, 0, 0);
}
-#ifdef __OpenBSD__
- if (pledge("stdio", NULL) == -1) err(1, "pledge");
-#endif
+ /* register events to watch for */
+ if (kevent(kq, ev, argc-1, NULL, 0, NULL) == -1)
+ err(1, "kevent");
for (;;) {
- /* register changes and wait for events */
- if ((n = kevent(kq, changes, file_count, events, file_count, NULL)) == -1)
- err(1, "kevent wait");
- if (n > 0) {
- for (i = 0; i < n; i++) {
- if (events[i].flags & EV_ERROR)
- errx(1, "event error: %s", strerror(events[i].data));
- if (events[i].fflags & NOTE_WRITE)
- printf("%s\n", filenames[events[i].ident]);
- if (events[i].fflags & NOTE_DELETE)
- errx(1, "%s was deleted", filenames[events[i].ident]);
+ if ((n = kevent(kq, NULL, 0, evs, argc-1, NULL)) == -1)
+ err(1, "kevent");
+ for (i = 0; i < n; i++) {
+ if (evs[i].fflags & NOTE_WRITE)
+ printf("%s\n", filenames[evs[i].ident]);
+ if (evs[i].flags & EV_ERROR)
+ fprintf(stderr, "event error: %s\n",
+ strerror(evs[i].data));
+ if (evs[i].fflags & NOTE_DELETE) {
+ fprintf(stderr, "%s deleted\n",
+ filenames[evs[i].ident]);
+ close(evs[i].ident);
}
}
}
- return 0; /* assume that the kernel closes the file descriptors */
-
usage:
fprintf(stderr, "usage: %s [-i] file\n", argv[0]);
return 1;