Annotation of fam/test/test.c++, Revision 1.1.1.1
1.1 trev 1: #include <sys/types.h>
2: #include <sys/time.h>
3: #include <stdio.h>
4: #include <string.h>
5: #include <unistd.h>
6: #include <stdlib.h>
7: #include <signal.h>
8: #include <errno.h>
9: #include <stdarg.h>
10: //#include <fcntl.h>
11: #include "fam.h"
12: //#include "Boolean.h"
13: /*
14:
15: FILE test.c - simple fam test program
16:
17: Usage: test [-r] [-f <file>] [-d <directory>]
18: ex. test -f /etc/hosts -d /tmp
19:
20: -r includes request IDs in output (if you use this, put it first)
21: -f [file] monitors the given file
22: -d [dir] monitors the given directory
23:
24: */
25:
26:
27: void processDirEvents(FAMEvent* fe);
28:
29: bool suspend = false;
30: bool cont = false;
31: bool intr = false;
32: bool usr1 = false;
33: bool usr2 = false;
34: bool showReqIDs = false;
35: //int lockfd = -1;
36: //FILE *fout;
37:
38: void handle_stop(int) {
39: printf("Suspended!\n");
40: suspend = true;
41: }
42:
43: void handle_cont(int) {
44: printf("Resumed!\n");
45: signal(SIGCONT, handle_cont);
46: cont = true;
47: }
48:
49: void handle_int(int)
50: {
51: printf("Interupted!\n");
52: signal(SIGINT, handle_int);
53: intr = true;
54: }
55:
56: void handle_usr1(int)
57: {
58: printf("Got USR1!\n");
59: signal(SIGUSR1, handle_usr1);
60: usr1 = true;
61: }
62:
63: void handle_usr2(int)
64: {
65: printf("Got USR2!\n");
66: signal(SIGUSR2, handle_usr2);
67: usr2 = true;
68: }
69:
70: struct TestRequest
71: {
72: FAMRequest fr;
73: char path[PATH_MAX];
74: char userData[PATH_MAX];
75: bool isDir;
76: };
77:
78: void sendRequests(FAMConnection &fc, TestRequest tr[], int trlen)
79: {
80: for (int ii = 0; ii < trlen; ++ii) {
81: if (tr[ii].isDir) {
82: printf("FAMMonitorDirectory(\"%s\")\n", tr[ii].path);
83: if (FAMMonitorDirectory(&fc, tr[ii].path, &(tr[ii].fr), tr[ii].userData) < 0) {
84: fprintf(stderr, "FAMMonitorDirectory error\n");
85: exit(1);
86: }
87: if (showReqIDs) printf("req %d: ", tr[ii].fr.reqnum);
88: printf("FAMMonitorDirectory(\"%s\")\n", tr[ii].path);
89: } else {
90: printf("FAMMonitorFile(\"%s\")\n", tr[ii].path);
91: if (FAMMonitorFile(&fc, tr[ii].path, &(tr[ii].fr), tr[ii].userData) < 0) {
92: fprintf(stderr, "FAMMonitorFile error\n");
93: exit(1);
94: }
95: if (showReqIDs) printf("req %d: ", tr[ii].fr.reqnum);
96: printf("FAMMonitorFile(\"%s\")\n", tr[ii].path);
97: }
98: }
99: }
100:
101: //int lprintf(const char *fmt, ...) {
102: // int rv;
103: // va_list args;
104: // int lockfd = fileno(fout);
105: //
106: // if (lockfd > 2) {
107: //fprintf(stderr, "locking fd %d...\n", lockfd);
108: //fflush(stderr);
109: // lockf(lockfd, F_LOCK, 0);
110: // lseek(lockfd, 0, SEEK_END);
111: //fprintf(stderr, " locked!\n");
112: //fflush(stderr);
113: // }
114: // va_start(args, fmt);
115: // rv = vfprintf(fout, fmt, args);
116: // va_end(args);
117: // fflush(fout);
118: // if (lockfd > 2) {
119: // lockf(lockfd, F_ULOCK, 0);
120: // }
121: // return rv;
122: //}
123:
124: int
125: main(int argc, char **argv)
126: {
127: /* Create fam test */
128: // fout = stdout;
129: FAMConnection fc;
130: TestRequest tr[100];
131: int requests = 0;
132: FAMEvent fe;
133: fd_set readfds;
134: fd_set readfdscpy;
135: setbuf(stdout, NULL);
136:
137: if (argc < 2 /*|| (argc %2 != 1)*/ ) {
138: printf("usage: %s [-r] [-f <filename>] [-d <dirname>]\n", argv[0]);
139: exit(1);
140: }
141: int arg;
142: extern char *optarg;
143: extern int optind;
144:
145: if(FAMOpen(&fc) < 0)
146: {
147: fprintf(stderr, "FAMOpen failed!\n");
148: exit(1);
149: }
150: FD_ZERO(&readfds);
151: FD_SET(fc.fd, &readfds);
152: //fcntl(STDIN_FILENO, F_SETFL, FNONBLK);
153: //FD_SET(STDIN_FILENO, &readfds);
154: while ((arg = getopt(argc, argv, "f:d:r")) != -1)
155: {
156: switch (arg)
157: {
158: case 'd':
159: case 'f':
160: snprintf(tr[requests].userData, PATH_MAX, "%s %s: ",
161: (arg == 'd') ? "DIR " : "FILE", optarg);
162: snprintf(tr[requests].path, PATH_MAX, "%s", optarg);
163: tr[requests].isDir = (arg == 'd');
164: ++requests; // just don't use more than 100, OK?
165: break;
166: case 'r':
167: showReqIDs = true;
168: break;
169: }
170: }
171:
172: signal(SIGTSTP, handle_stop);
173: signal(SIGCONT, handle_cont);
174: signal(SIGINT, handle_int);
175: signal(SIGUSR1, handle_usr1);
176: signal(SIGUSR2, handle_usr2);
177:
178: sendRequests(fc, tr, requests);
179:
180: while (1) {
181: if (suspend) {
182: for (int ii = 0; ii < requests; ii++)
183: {
184: FAMSuspendMonitor(&fc, &(tr[ii].fr));
185: printf("Suspended monitoring of request %i\n", ii);
186: }
187: fflush(stdout);
188: suspend = false;
189: kill(getpid(),SIGTSTP);
190: signal(SIGTSTP, handle_stop);
191: }
192: if (cont) {
193: for (int ii = 0; ii < requests; ii++)
194: {
195: FAMResumeMonitor(&fc, &(tr[ii].fr));
196: printf("Resumed monitoring of request %i\n", ii);
197: }
198: fflush(stdout);
199: cont = false;
200: }
201: if (intr) {
202: // Cancel monitoring of every other request. This makes
203: // sure fam can handle the case where the connection goes
204: // down with requests outstanding.
205: for (int ii = 0; ii < requests ; ii++)
206: {
207: if (ii % 2 == 0) continue;
208: FAMCancelMonitor(&fc, &(tr[ii].fr));
209: printf("Canceled monitoring of request %i\n", ii);
210: }
211: FAMClose(&fc);
212: exit(0);
213: }
214: if (usr1) {
215: // Cancel all requests, close the connection, and reopen it.
216: // This makes sure long-lived clients can connect, monitor, and
217: // disconnect repeatedly without leaking.
218: usr1 = false;
219: int sleeptime = 1;
220: for (int ii = 0; ii < requests ; ii++)
221: {
222: FAMCancelMonitor(&fc, &(tr[ii].fr));
223: printf("Canceled monitoring of request %i\n", ii);
224: }
225: FAMClose(&fc);
226: printf("Closed connection, sleeping %d...\n", sleeptime);
227: sleep(sleeptime);
228:
229: // Now reconnect and resend the requests.
230: if(FAMOpen(&fc) < 0)
231: {
232: fprintf(stderr, "FAMOpen failed!\n");
233: exit(1);
234: }
235: FD_ZERO(&readfds);
236: FD_SET(fc.fd, &readfds);
237: sendRequests(fc, tr, requests);
238: }
239: if (usr2) {
240: // Clean things up like a well-behaved client and exit.
241: for (int ii = 0; ii < requests ; ii++)
242: {
243: FAMCancelMonitor(&fc, &(tr[ii].fr));
244: printf("Canceled monitoring of request %i\n", ii);
245: }
246: FAMClose(&fc);
247: printf("Closed connection\n");
248: exit(0);
249: }
250:
251: readfdscpy = readfds;
252: if (select(FD_SETSIZE, &readfdscpy, NULL, NULL, NULL) < 0) {
253: if (errno == EINTR)
254: {
255: continue;
256: }
257: break;
258: }
259: // while (FAMPending(&fc) > 0) {
260: for (; FAMPending(&fc); ) {
261: if (FAMNextEvent(&fc, &fe) < 0) {
262: printf("Gahh, FAMNextEvent() returned < 0!\n");
263: exit(1);
264: }
265: processDirEvents(&fe);
266: fflush(stdout);
267: }
268: // if (FD_ISSET(STDIN_FILENO, &readfdscpy)) {
269: //fprintf(stderr, "reading on stdin...\n");
270: //fflush(stderr);
271: // int readlen;
272: // char buf[PATH_MAX];
273: // while ((readlen = read(STDIN_FILENO, buf, PATH_MAX - 1)) > 0) {
274: //fprintf(stderr, " readlen == %d\n", readlen);
275: //fflush(stderr);
276: // buf[readlen] = '\0';
277: // printf("%s", buf);
278: // }
279: //fprintf(stderr, " readlen == %d, errno == %d%s\n", readlen, errno, errno == EAGAIN ? " (EAGAIN)" : "");
280: //fflush(stderr);
281: // }
282: }
283: return(EXIT_SUCCESS);
284: }
285:
286:
287:
288: void
289: processDirEvents(FAMEvent* fe)
290: {
291: if (fe->userdata) printf("%s ", (char *)fe->userdata);
292: if (showReqIDs) printf("req %d: ", fe->fr.reqnum);
293: switch (fe->code) {
294: case FAMExists:
295: printf("%s Exists\n", fe->filename);
296: break;
297: case FAMEndExist:
298: printf("%s EndExist\n", fe->filename);
299: break;
300: case FAMChanged:
301: printf("%s Changed\n", fe->filename);
302: break;
303: case FAMDeleted:
304: printf("%s was deleted\n", fe->filename);
305: break;
306: case FAMStartExecuting:
307: printf("%s started executing\n", fe->filename);
308: break;
309: case FAMStopExecuting:
310: printf("%s stopped executing\n", fe->filename);
311: break;
312: case FAMCreated:
313: printf("%s was created\n", fe->filename);
314: break;
315: case FAMMoved:
316: printf("%s was moved\n", fe->filename);
317: break;
318: default:
319: printf("(unknown event %d on %s)\n", fe->code, fe->filename);
320: }
321: }
322:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>