Created
March 24, 2026 11:21
-
-
Save vegarsti/2fca3bc234839b1ccb3bc33ff03e535d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <sys/event.h> | |
| #include <sys/time.h> | |
| #include <fcntl.h> | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <unistd.h> | |
| // Watches files for changes and prints which file changed | |
| int main(int argc, char *argv[]) { | |
| if (argc < 2) { | |
| fprintf(stderr, "Usage: %s <file1> [file2] ...\n", argv[0]); | |
| exit(1); | |
| } | |
| int nfiles = argc - 1; | |
| // Create the kqueue | |
| int kq = kqueue(); | |
| if (kq == -1) { | |
| perror("kqueue"); | |
| exit(1); | |
| } | |
| // Open all files and set up change events | |
| int *fds = malloc(nfiles * sizeof(int)); | |
| struct kevent *changes = malloc(nfiles * sizeof(struct kevent)); | |
| if (!fds || !changes) { | |
| perror("malloc"); | |
| exit(1); | |
| } | |
| for (int i = 0; i < nfiles; i++) { | |
| fds[i] = open(argv[i + 1], O_RDONLY | O_EVTONLY); | |
| if (fds[i] == -1) { | |
| fprintf(stderr, "open(%s): ", argv[i + 1]); | |
| perror(NULL); | |
| exit(1); | |
| } | |
| printf("Monitoring '%s' (fd %d)\n", argv[i + 1], fds[i]); | |
| EV_SET( | |
| &changes[i], | |
| fds[i], | |
| EVFILT_VNODE, | |
| EV_ADD | EV_CLEAR, | |
| NOTE_WRITE, | |
| 0, | |
| // Store the filename as udata so we can identify it later | |
| (void *)argv[i + 1] | |
| ); | |
| } | |
| // Register all events at once | |
| if (kevent(kq, changes, nfiles, NULL, 0, NULL) == -1) { | |
| perror("kevent register"); | |
| exit(1); | |
| } | |
| printf("Waiting for changes...\n"); | |
| struct kevent event; | |
| while (1) { | |
| // Wait for one event at a time | |
| int n = kevent(kq, NULL, 0, &event, 1, NULL); | |
| if (n == -1) { | |
| perror("kevent wait"); | |
| break; | |
| } | |
| if (event.fflags & NOTE_WRITE) { | |
| const char *name = (const char *)event.udata; | |
| printf("[%s] written\n", name); | |
| } | |
| } | |
| // Cleanup | |
| for (int i = 0; i < nfiles; i++) | |
| close(fds[i]); | |
| free(fds); | |
| free(changes); | |
| close(kq); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment