#include #include #include #include #include #include #define FD 27 #define MAXFILES 100 #define MAXFD 127 /* FD + MAXFILES */ int main(int argc, char *argv[]) { char *filenames[MAXFD]; int fd, i, kq, n; struct kevent evs[MAXFILES]; struct kevent ev[MAXFILES]; /* parse arguments */ if(argc-1 == 0) goto usage; if(argv[1][0] == '-'){ 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(argc-1 == 0) goto usage; if(argc-1 > MAXFILES) errx(1, "more than %d files", MAXFILES); /* disable buffering even non-interactively */ setbuf(stdout, NULL); /* initialize kqueue */ if((kq = kqueue()) == -1) err(1, "kqueue"); /* 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]; EV_SET(ev+i-1, fd, EVFILT_VNODE, EV_ADD|EV_CLEAR, NOTE_WRITE|NOTE_DELETE, 0, 0); } /* register events to watch for */ if(kevent(kq, ev, argc-1, NULL, 0, NULL) == -1) err(1, "kevent"); for (;;){ 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); } } } usage: fprintf(stderr, "usage: %s [-i] file\n", argv[0]); return 1; }