Describe kqclient.c program
[eleutheria.git] / kqueue / kqdir.c
blob869ee72224d797608cb337c4dae9827dd589fb27
1 /* compile with:
2 gcc kqdir.c -o kqdir -Wall -W -Wextra -ansi -pedantic */
4 #include <dirent.h>
5 #include <fcntl.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h> /* for strerror () */
9 #include <unistd.h>
10 #include <sys/event.h>
12 #define MAX_ENTRIES 256
14 /* function prototypes */
15 void diep(const char *s);
17 int main(int argc, char *argv[])
19 struct kevent evlist[MAX_ENTRIES]; /* events we want to monitor */
20 struct kevent chlist[MAX_ENTRIES]; /* events that were triggered */
21 struct dirent *pdent;
22 DIR *pdir;
23 char fullpath[256];
24 int fdlist[MAX_ENTRIES], cnt, i, kq, nev;
26 /* check argument count */
27 if (argc != 2) {
28 fprintf(stderr, "Usage: %s directory\n", argv[0]);
29 exit(EXIT_FAILURE);
32 /* create a new kernel event queue */
33 if ((kq = kqueue()) == -1)
34 diep("kqueue");
36 /* open directory named by argv[1], associate a directory stream
37 with it and return a pointer to it
39 if ((pdir = opendir(argv[1])) == NULL)
40 diep("opendir");
42 /* skip . and .. entries */
43 cnt = 0;
44 while((pdent = readdir(pdir)) != NULL && cnt++ < 2)
47 /* get all directory entries and for each one of them,
48 initialise a kevent structure
50 cnt = 0;
51 while((pdent = readdir(pdir)) != NULL) {
52 /* check whether we have exceeded the max number of
53 entries that we can monitor
55 if (cnt > MAX_ENTRIES - 1) {
56 fprintf(stderr, "Max number of entries exceeded\n");
57 goto CLEANUP_AND_EXIT;
60 /* check path length
61 don't forget +1 for the '\0'
63 if (strlen(argv[1] + strlen(pdent->d_name) + 2) > 256) {
64 fprintf(stderr,"Max path length exceeded\n");
65 goto CLEANUP_AND_EXIT;
67 strcpy(fullpath, argv[1]);
68 strcat(fullpath, "/");
69 strcat(fullpath, pdent->d_name);
71 /* open directory entry */
72 if ((fdlist[cnt] = open(fullpath, O_RDONLY)) == -1) {
73 perror("open");
74 goto CLEANUP_AND_EXIT;
77 /* initialise kevent structure */
78 EV_SET(&chlist[cnt], fdlist[cnt], EVFILT_VNODE,
79 EV_ADD | EV_ENABLE | EV_ONESHOT,
80 NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_ATTRIB,
81 0, 0);
83 cnt++;
86 /* loop forever */
87 for (;;) {
88 nev = kevent(kq, chlist, cnt, evlist, cnt, NULL);
89 if (nev == -1)
90 perror("kevent");
92 else if (nev > 0) {
93 for (i = 0; i < nev; i++) {
94 if (evlist[i].flags & EV_ERROR) {
95 fprintf(stderr, "EV_ERROR: %s\n", strerror(evlist[i].data));
96 goto CLEANUP_AND_EXIT;
99 if (evlist[i].fflags & NOTE_DELETE)
100 printf("fd: %d Deleted\n", evlist[i].ident);
102 else if (evlist[i].fflags & NOTE_EXTEND
103 || evlist[i].fflags & NOTE_WRITE)
104 printf("fd: %d Modified\n", evlist[i].ident);
106 else if (evlist[i].fflags & NOTE_ATTRIB)
107 printf("fd: %d Attributes modified\n", evlist[i].ident);
112 /* close open file descriptors, directory stream and kqueue */
113 CLEANUP_AND_EXIT:;
114 for (i = 0; i < cnt; i++)
115 close(fdlist[i]);
116 closedir(pdir);
117 close(kq);
119 return EXIT_SUCCESS;
122 void diep(const char *s)
124 perror(s);
125 exit(EXIT_FAILURE);