Wait() for children to terminate
[eleutheria.git] / kqueue / kqdir.c
blob52bb1bfae8c3ecf68a2c4e5573160f22eb3ea416
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 if (strlen(argv[1] + strlen(pdent->d_name) + 1) > 256) {
62 fprintf(stderr,"Max path length exceeded\n");
63 goto CLEANUP_AND_EXIT;
65 strcpy(fullpath, argv[1]);
66 strcat(fullpath, "/");
67 strcat(fullpath, pdent->d_name);
69 /* open directory entry */
70 if ((fdlist[cnt] = open(fullpath, O_RDONLY)) == -1) {
71 perror("open");
72 goto CLEANUP_AND_EXIT;
75 /* initialise kevent structure */
76 EV_SET(&chlist[cnt], fdlist[cnt], EVFILT_VNODE,
77 EV_ADD | EV_ENABLE | EV_ONESHOT,
78 NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_ATTRIB,
79 0, 0);
81 cnt++;
84 /* loop forever */
85 for (;;) {
86 nev = kevent(kq, chlist, cnt, evlist, cnt, NULL);
87 if (nev == -1)
88 perror("kevent");
90 else if (nev > 0) {
91 for (i = 0; i < nev; i++) {
92 if (evlist[i].flags & EV_ERROR) {
93 fprintf(stderr, "EV_ERROR: %s\n", strerror(evlist[i].data));
94 goto CLEANUP_AND_EXIT;
97 if (evlist[i].fflags & NOTE_DELETE) {
98 printf("fd: %d Deleted\n", evlist[i].ident);
100 else if (evlist[i].fflags & NOTE_EXTEND ||
101 evlist[i].fflags & NOTE_WRITE) {
102 printf("fd: %d Modified\n", evlist[i].ident);
104 else if (evlist[i].fflags & NOTE_ATTRIB) {
105 printf("fd: %d Attributes modified\n", evlist[i].ident);
111 /* close open file descriptors, directory stream and kqueue */
112 CLEANUP_AND_EXIT:;
113 for (i = 0; i < cnt; i++)
114 close(fdlist[i]);
115 closedir(pdir);
116 close(kq);
118 return EXIT_SUCCESS;
121 void diep(const char *s)
123 perror(s);
124 exit(EXIT_FAILURE);