Fix possible memory leak when malloc() fails
[eleutheria.git] / kqdir.c
blob31c0a557ed63d47359aa2ddff6e731b59adac544
1 #include <dirent.h>
2 #include <fcntl.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h> /* for strerror () */
6 #include <unistd.h>
7 #include <sys/event.h>
9 #define MAX_ENTRIES 256
11 /* function prototypes */
12 void diep(const char *s);
14 int main(int argc, char *argv[])
16 struct kevent evlist[MAX_ENTRIES]; /* events we want to monitor */
17 struct kevent chlist[MAX_ENTRIES]; /* events that were triggered */
18 struct dirent *pdent;
19 DIR *pdir;
20 char fullpath[256];
21 int fdlist[MAX_ENTRIES], cnt, i, kq, nev;
23 /* check argument count */
24 if (argc != 2) {
25 fprintf(stderr, "Usage: %s directory\n", argv[0]);
26 exit(EXIT_FAILURE);
29 /* create a new kernel event queue */
30 if ((kq = kqueue()) == -1)
31 diep("kqueue");
33 /* open directory named by argv[1], associate a directory stream
34 with it and return a pointer to it
36 if ((pdir = opendir(argv[1])) == NULL)
37 diep("opendir");
39 /* skip . and .. entries */
40 cnt = 0;
41 while((pdent = readdir(pdir)) != NULL && cnt++ < 2)
44 /* get all directory entries and for each one of them,
45 initialise a kevent structure
47 cnt = 0;
48 while((pdent = readdir(pdir)) != NULL) {
49 /* check whether we have exceeded the max number of
50 entries that we can monitor
52 if (cnt > MAX_ENTRIES - 1) {
53 fprintf(stderr, "Max number of entries exceeded\n");
54 goto CLEANUP_AND_EXIT;
57 /* check path length */
58 if (strlen(argv[1] + strlen(pdent->d_name) + 1) > 256) {
59 fprintf(stderr,"Max path length exceeded\n");
60 goto CLEANUP_AND_EXIT;
62 strcpy(fullpath, argv[1]);
63 strcat(fullpath, "/");
64 strcat(fullpath, pdent->d_name);
66 /* open directory entry */
67 if ((fdlist[cnt] = open(fullpath, O_RDONLY)) == -1) {
68 perror("open");
69 goto CLEANUP_AND_EXIT;
72 /* initialise kevent structure */
73 EV_SET(&chlist[cnt], fdlist[cnt], EVFILT_VNODE,
74 EV_ADD | EV_ENABLE | EV_ONESHOT,
75 NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_ATTRIB,
76 0, 0);
78 cnt++;
81 /* loop forever */
82 for (;;) {
83 nev = kevent(kq, chlist, cnt, evlist, cnt, NULL);
84 if (nev == -1)
85 perror("kevent");
87 else if (nev > 0) {
88 for (i = 0; i < nev; i++) {
89 if (evlist[i].flags & EV_ERROR) {
90 fprintf(stderr, "EV_ERROR: %s\n", strerror(evlist[i].data));
91 goto CLEANUP_AND_EXIT;
94 if (evlist[i].fflags & NOTE_DELETE) {
95 printf("fd: %d Deleted\n", evlist[i].ident);
97 else if (evlist[i].fflags & NOTE_EXTEND ||
98 evlist[i].fflags & NOTE_WRITE) {
99 printf("fd: %d Modified\n", evlist[i].ident);
101 else if (evlist[i].fflags & NOTE_ATTRIB) {
102 printf("fd: %d Attributes modified\n", evlist[i].ident);
108 /* close open file descriptors, directory stream and kqueue */
109 CLEANUP_AND_EXIT:;
110 for (i = 0; i < cnt; i++)
111 close(fdlist[i]);
112 closedir(pdir);
113 close(kq);
115 return EXIT_SUCCESS;
118 void diep(const char *s)
120 perror(s);
121 exit(EXIT_FAILURE);