2 gcc kqdir.c -o kqdir -Wall -W -Wextra -ansi -pedantic
4 The following program will monitor up to MAX_ENTRIES files
5 (in a directory supplied by the user), and will report any
6 delete, write or attributes' change operation.
13 #include <string.h> /* for strerror () */
15 #include <sys/event.h>
17 #define MAX_ENTRIES 256
19 /* function prototypes */
20 void diep(const char *s
);
22 int main(int argc
, char *argv
[])
24 struct kevent evlist
[MAX_ENTRIES
]; /* events we want to monitor */
25 struct kevent chlist
[MAX_ENTRIES
]; /* events that were triggered */
29 int fdlist
[MAX_ENTRIES
], cnt
, i
, kq
, nev
;
31 /* check argument count */
33 fprintf(stderr
, "Usage: %s directory\n", argv
[0]);
37 /* create a new kernel event queue */
38 if ((kq
= kqueue()) == -1)
41 /* open directory named by argv[1], associate a directory stream
42 with it and return a pointer to it
44 if ((pdir
= opendir(argv
[1])) == NULL
)
47 /* skip . and .. entries */
49 while((pdent
= readdir(pdir
)) != NULL
&& cnt
++ < 2)
52 /* get all directory entries and for each one of them,
53 initialise a kevent structure
56 while((pdent
= readdir(pdir
)) != NULL
) {
57 /* check whether we have exceeded the max number of
58 entries that we can monitor
60 if (cnt
> MAX_ENTRIES
- 1) {
61 fprintf(stderr
, "Max number of entries exceeded\n");
62 goto CLEANUP_AND_EXIT
;
66 don't forget +1 for the '\0'
68 if (strlen(argv
[1] + strlen(pdent
->d_name
) + 2) > 256) {
69 fprintf(stderr
,"Max path length exceeded\n");
70 goto CLEANUP_AND_EXIT
;
72 strcpy(fullpath
, argv
[1]);
73 strcat(fullpath
, "/");
74 strcat(fullpath
, pdent
->d_name
);
76 /* open directory entry */
77 if ((fdlist
[cnt
] = open(fullpath
, O_RDONLY
)) == -1) {
79 goto CLEANUP_AND_EXIT
;
82 /* initialise kevent structure */
83 EV_SET(&chlist
[cnt
], fdlist
[cnt
], EVFILT_VNODE
,
84 EV_ADD
| EV_ENABLE
| EV_ONESHOT
,
85 NOTE_DELETE
| NOTE_EXTEND
| NOTE_WRITE
| NOTE_ATTRIB
,
93 nev
= kevent(kq
, chlist
, cnt
, evlist
, cnt
, NULL
);
98 for (i
= 0; i
< nev
; i
++) {
99 if (evlist
[i
].flags
& EV_ERROR
) {
100 fprintf(stderr
, "EV_ERROR: %s\n", strerror(evlist
[i
].data
));
101 goto CLEANUP_AND_EXIT
;
104 if (evlist
[i
].fflags
& NOTE_DELETE
)
105 printf("fd: %d Deleted\n", evlist
[i
].ident
);
107 else if (evlist
[i
].fflags
& NOTE_EXTEND
108 || evlist
[i
].fflags
& NOTE_WRITE
)
109 printf("fd: %d Modified\n", evlist
[i
].ident
);
111 else if (evlist
[i
].fflags
& NOTE_ATTRIB
)
112 printf("fd: %d Attributes modified\n", evlist
[i
].ident
);
117 /* close open file descriptors, directory stream and kqueue */
119 for (i
= 0; i
< cnt
; i
++)
127 void diep(const char *s
)