1#include <string.h>
2#include <errno.h>
3#include <pwd.h>
4#include <stdarg.h>
5#include <stdio.h>
6#include <stdlib.h>
7#include <unistd.h>
8#include <fcntl.h>
9#include <pthread.h>
10#include <poll.h>
11#include <sys/types.h>
12#include <sys/event.h>
13#include <sys/time.h>
14#include <sys/stat.h>
15#include <sys/mman.h>
16#include <sys/xattr.h>
17
18#define DIR1 	"dir1"
19#define DOTDOT 	".."
20#define DIR2 	"dir2"
21#define FILE1	"file1"
22#define FILE2 	"file2"
23
24#define KEY	"somekey"
25#define VAL	"someval"
26
27#define NOSLEEP		0
28#define SLEEP		1
29#define NO_EVENT	0
30#define YES_EVENT	1
31
32
33#define OUTPUT_LEVEL 	2
34#define RESULT_LEVEL	3
35
36#define TEST_STRING	"Some text!!! Yes indeed, some of that very structure which has passed on man's knowledge for generations."
37#define HELLO_WORLD	"Hello, World!"
38#define SLEEP_TIME	2
39#define WAIT_TIME	(4l)
40#define LENGTHEN_SIZE	500
41#define FIFO_SPACE	8192	/* FIFOS have 8K of buffer space */
42
43/*
44 * Types of actions for setup, cleanup, and execution of tests
45 */
46typedef enum {CREAT, MKDIR, READ, WRITE, WRITEFD, FILLFD, UNLINK, LSKEE, RMDIR, MKFIFO, LENGTHEN, TRUNC,
47	SYMLINK, CHMOD, CHOWN, EXCHANGEDATA, RENAME, LSEEK, OPEN, MMAP, NOTHING,
48	SETXATTR, UTIMES, STAT, HARDLINK, REVOKE} action_id_t;
49
50/*
51 * Directs an action as mentioned above
52 */
53typedef struct _action {
54	int 		act_dosleep;
55	action_id_t 	act_id;
56	void 		*act_args[5];
57	int		act_fd;
58} action_t;
59
60/*
61 * A test case.  Specifies setup, an event to look for, an action to take to
62 * cause (or not cause) that event, and cleanup.
63 */
64typedef struct _test {
65	char *t_testname;
66
67	/* Test kevent() or poll() */
68	int 	t_is_poll_test;
69
70	/* Actions for setting up test */
71	int 	 t_n_prep_actions;
72	action_t t_prep_actions[5];
73
74	/* Actions for cleaning up test */
75	int 	 t_n_cleanup_actions;
76	action_t t_cleanup_actions[5];
77
78	/* Action for thred to take while we wait */
79	action_t t_helpthreadact;
80
81	/* File to look for event on */
82	char 	 *t_watchfile; 	/* set event ident IN TEST (can't know fd beforehand)*/
83	int	 t_file_is_fifo;/* FIFOs are handled in a special manner */
84
85	/* Different parameters for poll() vs kevent() */
86	union {
87		struct kevent	tu_kev;
88		short		tu_pollevents;
89	} t_union;
90
91	/* Do we expect results? */
92	int	 t_want_event;
93
94	/* Not always used--how much data should we find (EVFILT_{READ,WRITE}) */
95	int	 t_nbytes;
96
97	/* Hacks for FILT_READ and pipes */
98	int 	 t_read_to_end_first; 	/* Consume all data in file before waiting for event */
99	int 	 t_write_some_data; 	/* Write some data to file before waiting for event (FIFO hack) */
100	int	 t_extra_sleep_hack;	/* Sleep before waiting, to let a fifo fill up with data */
101} test_t;
102
103/*
104 * Extra logging infrastructure so we can filter some out
105 */
106void LOG(int level, FILE *f, const char *fmt, ...) {
107	va_list ap;
108	va_start(ap, fmt);
109	if (level >= OUTPUT_LEVEL) {
110		/* Indent for ease of reading */
111		if (level < RESULT_LEVEL) {
112			fprintf(f, "\t");
113		}
114		vfprintf(f, fmt, ap);
115	}
116
117	va_end(ap);
118}
119
120/*
121 * Initialize an action struct.  Whether to sleep, what action to take,
122 * and arguments for that action.
123 */
124void
125init_action(action_t *act, int sleep, action_id_t call, int nargs, ...)
126{
127	int i;
128	va_list ap;
129	va_start(ap, nargs);
130	act->act_dosleep = sleep;
131	act->act_id = call;
132
133	for (i = 0; i < nargs; i++)
134	{
135		act->act_args[i] = va_arg(ap, void*);
136	}
137
138	va_end(ap);
139
140}
141
142/*
143 * Opening a fifo is complicated: need to open both sides at once
144 */
145void*
146open_fifo_readside(void *arg)
147{
148	return (void*)open((char*)arg, O_RDONLY);
149}
150
151/*
152 * Open a fifo, setting read and write descriptors.  Return 0 for success, -1 for failure.
153 * Only set FD args upon success; they will be unmodified on failure.
154 */
155int
156open_fifo(const char *path, int *readfd, int *writefd)
157{
158	pthread_t thread;
159	int waitres;
160	int res;
161	int tmpreadfd, tmpwritefd;
162
163	res = pthread_create(&thread, 0, open_fifo_readside, (void*)path);
164	if (res == 0) {
165		tmpwritefd = open(path, O_WRONLY);
166		waitres = pthread_join(thread, (void**) &tmpreadfd);
167
168		fcntl(tmpwritefd, F_SETFL, O_WRONLY | O_NONBLOCK);
169
170		if ((waitres == 0) && (tmpwritefd >= 0) && (tmpreadfd >= 0)) {
171			*readfd = tmpreadfd;
172			*writefd = tmpwritefd;
173		} else {
174			res = -1;
175		}
176	}
177
178	return res;
179}
180
181/*
182 * Just concatenate a directory and a filename, sticking a "/" betwixt them
183 */
184void
185makepath(char *buf, const char *dir, const char *file)
186{
187	strcpy(buf, dir);
188	strcat(buf, "/");
189	strcat(buf, file);
190}
191
192
193/* Execute a prep, cleanup, or test action; specific tricky notes below.
194 *
195 * CREAT: 	comes to life and given length 1
196 * READ: 	try to read one char
197 * WRITE:	try to write TEST_STRING to file
198 * LENGTHEN:	make longer by LENGTHEN_SIZE
199 * MMAP:	mmap first 20 bytes of file, write HELLO_WORLD in
200 * SETXATTR:	set the KEY attribute to value VAL
201 * WRITEFD:	instead of opening fresh, take an FD in the action struct (FIFOs)
202 * FILLFD:	write a file until you can no longer.  for filling FIFOS.
203 *
204 * * Several of these have hard-coded sizes.
205 */
206void*
207execute_action(void *actionptr)
208{
209	action_t *act = (action_t*)actionptr;
210	void **args = act->act_args;
211	char c;
212	int res = -1, tmpfd, tmpfd2;
213	static int lastfd;
214	void *addr;
215	struct timeval tv;
216	struct stat sstat;
217
218	LOG(1, stderr, "Beginning action of type %d\n", act->act_id);
219
220	/* Let other thread get into kevent() sleep */
221	if(SLEEP == act->act_dosleep) {
222		sleep(SLEEP_TIME);
223	}
224	switch(act->act_id) {
225		case NOTHING:
226			res = 0;
227			break;
228		case CREAT:
229			tmpfd = creat((char*)args[0], 0755);
230			ftruncate(tmpfd, 1); /* So that mmap() doesn't fool us */
231			if (tmpfd >= 0) {
232				close(tmpfd);
233				res = 0;
234			}
235			break;
236		case MKDIR:
237			res = mkdir((char*)args[0], 0755);
238			break;
239		case READ:
240			tmpfd = open((char*)args[0], O_RDONLY);
241			if (tmpfd >= 0) {
242				res = read(tmpfd, &c, 1);
243				res = (res == 1 ? 0 : -1);
244			}
245			close(tmpfd);
246			break;
247		case WRITE:
248			tmpfd = open((char*)args[0], O_RDWR);
249			if (tmpfd >= 0) {
250				res = write(tmpfd, TEST_STRING, strlen(TEST_STRING));
251				if (res == strlen(TEST_STRING)) {
252					res = 0;
253				} else {
254					res = -1;
255				}
256
257				close(tmpfd);
258			}
259			break;
260		case WRITEFD:
261			res = write((int)act->act_fd, TEST_STRING, strlen(TEST_STRING));
262			if (res == strlen(TEST_STRING)) {
263				res = 0;
264			} else {
265				res = -1;
266			}
267			break;
268		case FILLFD:
269			while (write((int)act->act_fd, "a", 1) > 0);
270			res = 0;
271			break;
272		case UNLINK:
273			res = unlink((char*)args[0]);
274			break;
275		case LSEEK:
276			res = lseek((int)act->act_fd, (int)args[0], SEEK_SET);
277			res = (res == (int)args[0] ? 0 : -1);
278			break;
279		case RMDIR:
280			res = rmdir((char*)args[0]);
281			break;
282		case MKFIFO:
283			res = mkfifo((char*)args[0], 0755);
284			break;
285		case LENGTHEN:
286			res = truncate((char*)args[0], LENGTHEN_SIZE);
287			break;
288		case TRUNC:
289			res = truncate((char*)args[0], 0);
290			break;
291		case SYMLINK:
292			res = symlink((char*)args[0], (char*)args[1]);
293			break;
294		case CHMOD:
295			res = chmod((char*)args[0], (int)args[1]);
296			break;
297		case CHOWN:
298			/* path, uid, gid */
299			res = chown((char*)args[0], (int) args[1], (int) args[2]);
300			break;
301		case EXCHANGEDATA:
302			res = exchangedata((char*)args[0], (char*)args[1], 0);
303			break;
304		case RENAME:
305			res = rename((char*)args[0], (char*)args[1]);
306			break;
307		case OPEN:
308			tmpfd = open((char*)args[0], O_RDONLY | O_CREAT);
309			res = close(tmpfd);
310			break;
311		case MMAP:
312			/* It had best already exist with nonzero size */
313			tmpfd = open((char*)args[0], O_RDWR);
314			addr = mmap(0, 20, PROT_WRITE | PROT_READ, MAP_FILE | MAP_SHARED, tmpfd, 0);
315			if (addr != ((void*)-1)) {
316				res = 0;
317				if ((int)args[1]) {
318					strcpy((char*)addr, HELLO_WORLD);
319					msync(addr, 20, MS_SYNC);
320				}
321			}
322			close(tmpfd);
323			munmap(addr, 20);
324			break;
325		case SETXATTR:
326			res = setxattr((char*)args[0], KEY, (void*)VAL, strlen(VAL),
327						   0, 0);
328			break;
329		case UTIMES:
330			tv.tv_sec = time(NULL);
331			tv.tv_usec = 0;
332			res = utimes((char*)args[0], &tv);
333			break;
334		case STAT:
335			res = lstat((char*)args[0], &sstat);
336			break;
337		case HARDLINK:
338			res = link((char*)args[0], (char*)args[1]);
339			break;
340		case REVOKE:
341			tmpfd = open((char*)args[0], O_RDONLY);
342			res = revoke((char*)args[0]);
343			close(tmpfd);
344			break;
345		default:
346			res = -1;
347			break;
348	}
349
350	return (void*)res;
351
352}
353
354/*
355 * Read until the end of a file, for EVFILT_READ purposes (considers file position)
356 */
357void
358read_to_end(int fd)
359{
360	char buf[50];
361	while (read(fd, buf, sizeof(buf)) > 0);
362}
363
364/*
365 * Helper for setup and cleanup; just execute every action in an array
366 * of actions.  "failout" parameter indicates whether to stop if one fails.
367 */
368int
369execute_action_list(action_t *actions, int nactions, int failout)
370{
371	int i, res;
372	for (i = 0, res = 0; (0 == res || (!failout)) && (i < nactions); i++) {
373		LOG(1, stderr, "Starting prep action %d\n", i);
374		res = (int) execute_action(&(actions[i]));
375		if(res != 0) {
376			LOG(2, stderr, "Action list failed on step %d.\n", i);
377		} else {
378			LOG(1, stderr, "Action list work succeeded on step %d.\n", i);
379		}
380	}
381
382	return res;
383}
384
385/*
386 * Execute a full test, return success value.
387 */
388int
389execute_test(test_t *test)
390{
391	int i, kqfd, filefd = -1, res2, res, cnt, status, writefd = -1;
392	int retval = -1;
393	pthread_t thr;
394	struct kevent evlist;
395	struct timespec ts = {WAIT_TIME, 0l};
396
397	memset(&evlist, 0, sizeof(evlist));
398
399	LOG(1, stderr, "Test %s starting.\n", test->t_testname);
400	LOG(1, stderr, test->t_want_event ? "Expecting an event.\n" : "Not expecting events.\n");
401
402	res = execute_action_list(test->t_prep_actions, test->t_n_prep_actions, 1);
403
404	/* If prep succeeded */
405	if (0 == res) {
406		/* Create kqueue for kqueue tests*/
407		if (!test->t_is_poll_test) {
408			kqfd = kqueue();
409		}
410
411		if ((test->t_is_poll_test) || kqfd >= 0) {
412			LOG(1, stderr, "Opened kqueue.\n");
413
414			/* Open the file we're to monitor.  Fifos get special handling */
415			if (test->t_file_is_fifo) {
416				filefd = -1;
417				open_fifo(test->t_watchfile, &filefd, &writefd);
418			} else {
419				filefd = open(test->t_watchfile, O_RDONLY | O_SYMLINK);
420			}
421
422			if (filefd >= 0) {
423				LOG(1, stderr, "Opened file to monitor.\n");
424
425				/*
426				 * Fill in the fd to monitor once you know it
427				 * If it's a fifo test, then the helper is definitely going to want the write end.
428				 */
429				test->t_helpthreadact.act_fd = (writefd >= 0 ? writefd : filefd);
430
431				if (test->t_read_to_end_first) {
432					read_to_end(filefd);
433				} else if (test->t_write_some_data) {
434					action_t dowr;
435					init_action(&dowr, NOSLEEP, WRITEFD, 0);
436					dowr.act_fd = writefd;
437					execute_action(&dowr);
438				}
439
440				/* Helper modifies the file that we're listening on (sleeps first, in general) */
441				res = pthread_create(&thr, NULL, execute_action, (void*) &test->t_helpthreadact);
442				if (0 == res) {
443					LOG(1, stderr, "Created helper thread.\n");
444
445					/* This is ugly business to hack on filling up a FIFO */
446					if (test->t_extra_sleep_hack) {
447						sleep(5);
448					}
449
450					if (test->t_is_poll_test) {
451						struct pollfd pl;
452						pl.fd = filefd;
453						pl.events = test->t_union.tu_pollevents;
454						cnt = poll(&pl, 1, WAIT_TIME);
455						LOG(1, stderr, "Finished poll() call.\n");
456
457						if ((cnt < 0)) {
458							LOG(2, stderr, "error is in errno, %s\n", strerror(errno));
459							res = cnt;
460						}
461					} else {
462						test->t_union.tu_kev.ident = filefd;
463						cnt = kevent(kqfd, &test->t_union.tu_kev, 1, &evlist, 1,  &ts);
464						LOG(1, stderr, "Finished kevent() call.\n");
465
466						if ((cnt < 0) || (evlist.flags & EV_ERROR))  {
467							LOG(2, stderr, "kevent() call failed.\n");
468							if (cnt < 0) {
469								LOG(2, stderr, "error is in errno, %s\n", strerror(errno));
470							} else {
471								LOG(2, stderr, "error is in data, %s\n", strerror(evlist.data));
472							}
473							res = cnt;
474						}
475					}
476
477					/* Success only if you've succeeded to this point AND joined AND other thread is happy*/
478					status = 0;
479					res2 = pthread_join(thr, (void**)&status);
480					if (res2 < 0) {
481						LOG(2, stderr, "Couldn't join helper thread.\n");
482					} else if (status) {
483						LOG(2, stderr, "Helper action had result %d\n", (int)status);
484					}
485					res = ((res == 0) && (res2 == 0) && (status == 0)) ? 0 : -1;
486				} else {
487					LOG(2, stderr, "Couldn't start thread.\n");
488				}
489
490				close(filefd);
491				if (test->t_file_is_fifo) {
492					close(writefd);
493				}
494			} else {
495				LOG(2, stderr, "Couldn't open test file %s to monitor.\n", test->t_watchfile);
496				res = -1;
497			}
498			close(kqfd);
499		} else {
500			LOG(2, stderr, "Couldn't open kqueue.\n");
501			res = -1;
502		}
503	}
504
505	/* Cleanup work */
506	execute_action_list(test->t_cleanup_actions, test->t_n_cleanup_actions, 0);
507
508	/* Success if nothing failed and we either received or did not receive event,
509	 * as expected
510	 */
511	if (0 == res) {
512		LOG(1, stderr, cnt > 0 ? "Got an event.\n" : "Did not get an event.\n");
513		if (((cnt > 0) && (test->t_want_event)) || ((cnt == 0) && (!test->t_want_event))) {
514			if ((!test->t_is_poll_test) && (test->t_union.tu_kev.filter == EVFILT_READ || test->t_union.tu_kev.filter == EVFILT_WRITE)
515				&& (test->t_nbytes) && (test->t_nbytes != evlist.data)) {
516				LOG(2, stderr, "Read wrong number of bytes available.  Wanted %d, got %d\n", test->t_nbytes, evlist.data);
517				retval = -1;
518			} else {
519				retval = 0;
520			}
521
522		} else {
523			LOG(2, stderr, "Got unexpected event or lack thereof.\n");
524			retval = -1;
525		}
526	} else {
527		LOG(2, stderr, "Failed to execute test.\n");
528		retval = -1;
529	}
530
531	LOG(3, stdout, "Test %s done with result %d.\n", test->t_testname, retval);
532}
533
534void
535init_test_common(test_t *tst, char *testname, char *watchfile, int nprep, int nclean, int event, int want, int ispoll)
536{
537	memset(tst, 0, sizeof(test_t));
538	tst->t_testname = testname;
539	tst->t_watchfile = watchfile;
540	tst->t_n_prep_actions = nprep;
541	tst->t_n_cleanup_actions = nclean;
542	tst->t_want_event = (want > 0);
543
544	if (ispoll) {
545		tst->t_is_poll_test = 1;
546		tst->t_union.tu_pollevents = (short)event;
547	} else {
548		/* Can do this because filter is negative, notes are positive */
549		if (event == EVFILT_READ || event == EVFILT_WRITE) {
550			EV_SET(&tst->t_union.tu_kev, 0, event, EV_ADD | EV_ENABLE, 0, 0, NULL);
551			tst->t_nbytes = want;
552		} else {
553			EV_SET(&tst->t_union.tu_kev, 0, EVFILT_VNODE, EV_ADD | EV_ENABLE, event, 0, NULL);
554		}
555	}
556}
557
558/*
559 * Initialize a test case, not including its actions.  Meaning: a name for it, what filename to watch,
560 * counts of prep and cleanup actions, what event to watch for, and whether you want an event/how many bytes read.
561 *
562 * "want" does double duty as whether you want an event and how many bytes you might want to read
563 * "event" is either an event flag (e.g. NOTE_WRITE) or EVFILT_READ
564 */
565void
566init_test(test_t *tst, char *testname, char *watchfile, int nprep, int nclean, int event, int want)
567{
568	init_test_common(tst, testname, watchfile, nprep, nclean, event, want, 0);
569}
570
571/*
572 * Same as above, but for a poll() test
573 */
574void
575init_poll_test(test_t *tst, char *testname, char *watchfile, int nprep, int nclean, int event, int want)
576{
577	init_test_common(tst, testname, watchfile, nprep, nclean, event, want, 1);
578}
579
580void
581run_note_delete_tests()
582{
583	test_t test;
584
585	init_test(&test, "1.1.2: unlink a file", FILE1, 1, 0, NOTE_DELETE, YES_EVENT);
586	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
587	init_action(&test.t_helpthreadact, SLEEP, UNLINK, 2, (void*)FILE1, NULL);
588	execute_test(&test);
589
590	init_test(&test, "1.1.3: rmdir a dir", DIR1, 1, 0, NOTE_DELETE, YES_EVENT);
591	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
592	init_action(&test.t_helpthreadact, SLEEP, RMDIR, 2, (void*)DIR1, NULL);
593	execute_test(&test);
594
595	init_test(&test, "1.1.4: rename one file over another", FILE2, 2, 1, NOTE_DELETE, YES_EVENT);
596	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
597	init_action(&(test.t_prep_actions[1]), NOSLEEP, CREAT, 2, (void*)FILE2, (void*)NULL);
598	init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)FILE1, (void*)FILE2);
599	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE2, NULL);
600	execute_test(&test);
601
602	init_test(&test, "1.1.5: rename one dir over another", DIR2, 2, 1, NOTE_DELETE, YES_EVENT);
603	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
604	init_action(&(test.t_prep_actions[1]), NOSLEEP, MKDIR, 2, (void*)DIR2, (void*)NULL);
605	init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)DIR1, (void*)DIR2);
606	init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR2, NULL);
607	execute_test(&test);
608
609	/* Do FIFO stuff here */
610	init_test(&test, "1.1.6: make a fifo, unlink it", FILE1, 1, 0, NOTE_DELETE, YES_EVENT);
611	test.t_file_is_fifo = 1;
612	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKFIFO, 2, (void*)FILE1, (void*)NULL);
613	init_action(&test.t_helpthreadact, SLEEP, UNLINK, 1, (void*)FILE1);
614	execute_test(&test);
615
616	init_test(&test, "1.1.7: rename a file over a fifo", FILE1, 2, 1, NOTE_DELETE, YES_EVENT);
617	test.t_file_is_fifo = 1;
618	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKFIFO, 2, (void*)FILE1, (void*)NULL);
619	init_action(&(test.t_prep_actions[1]), NOSLEEP, CREAT, 2, (void*)FILE2, (void*)NULL);
620	init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)FILE2, (void*)FILE1);
621	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
622	execute_test(&test);
623
624	init_test(&test, "1.1.8: unlink a symlink to a file", FILE2, 2, 1, NOTE_DELETE, YES_EVENT);
625	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
626	init_action(&(test.t_prep_actions[1]), NOSLEEP, SYMLINK, 2, (void*)FILE1, (void*)FILE2);
627	init_action(&test.t_helpthreadact, SLEEP, UNLINK, 2, (void*)FILE2, NULL);
628	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
629	execute_test(&test);
630
631	/* ================= */
632
633	init_test(&test, "1.2.1: Straight-up rename file", FILE1, 1, 1, NOTE_DELETE, NO_EVENT);
634	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
635	init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)FILE1, (void*)FILE2);
636	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE2, (void*)NULL);
637	execute_test(&test);
638
639	init_test(&test, "1.2.2: Straight-up rename dir", DIR1, 1, 1, NOTE_DELETE, NO_EVENT);
640	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
641	init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)DIR1, (void*)DIR2);
642	init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR2, (void*)NULL);
643	execute_test(&test);
644
645	init_test(&test, "1.2.3: Null action on file", FILE1, 1, 1, NOTE_DELETE, NO_EVENT);
646	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
647	init_action(&test.t_helpthreadact, SLEEP, NOTHING, 2, NULL, NULL); /* The null action */
648	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
649	execute_test(&test);
650
651	init_test(&test, "1.2.4: Rename one file over another: watch the file that lives", FILE1, 2, 1, NOTE_DELETE, NO_EVENT);
652	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
653	init_action(&(test.t_prep_actions[1]), NOSLEEP, CREAT, 2, (void*)FILE2, (void*)NULL);
654	init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)FILE1, (void*)FILE2);
655	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE2, NULL);
656	execute_test(&test);
657
658	init_test(&test, "1.2.5: Rename one dir over another, watch the dir that lives", DIR1, 2, 1, NOTE_DELETE, NO_EVENT);
659	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
660	init_action(&(test.t_prep_actions[1]), NOSLEEP, MKDIR, 2, (void*)DIR2, (void*)NULL);
661	init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)DIR1, (void*)DIR2);
662	init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR2, NULL);
663}
664
665void
666run_note_write_tests()
667{
668	char pathbuf[50];
669	char otherpathbuf[50];
670
671	test_t test;
672
673	init_test(&test, "2.1.1: Straight-up write to a file", FILE1, 1, 1, NOTE_WRITE, YES_EVENT);
674	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
675	init_action(&test.t_helpthreadact, SLEEP, WRITE, 2, (void*)FILE1, NULL);
676	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
677	execute_test(&test);
678
679
680	makepath(pathbuf, DIR1, FILE1);
681	init_test(&test, "2.1.2: creat() file inside a dir", DIR1, 1, 2, NOTE_WRITE, YES_EVENT);
682	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
683	init_action(&test.t_helpthreadact, SLEEP, CREAT, 2, (void*)pathbuf, NULL);
684	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)pathbuf, (void*)NULL);
685	init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
686	execute_test(&test);
687
688	makepath(pathbuf, DIR1, FILE1);
689	init_test(&test, "2.1.3: open() file inside a dir", DIR1, 1, 2, NOTE_WRITE, YES_EVENT);
690	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
691	init_action(&test.t_helpthreadact, SLEEP, OPEN, 2, (void*)pathbuf, NULL);
692	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)pathbuf, (void*)NULL);
693	init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
694	execute_test(&test);
695
696	makepath(pathbuf, DIR1, FILE1);
697	init_test(&test, "2.1.3: unlink a file from a dir", DIR1, 2, 1, NOTE_WRITE, YES_EVENT);
698	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
699	init_action(&(test.t_prep_actions[1]), NOSLEEP, CREAT, 2, (void*)pathbuf, (void*)NULL);
700	init_action(&test.t_helpthreadact, SLEEP, UNLINK, 2, (void*)pathbuf, NULL);
701	init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
702	execute_test(&test);
703
704	makepath(pathbuf, DIR1, FILE1);
705	makepath(otherpathbuf, DIR1, FILE2);
706	init_test(&test, "2.1.5: rename a file in a dir", DIR1, 2, 2, NOTE_WRITE, YES_EVENT);
707	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
708	init_action(&(test.t_prep_actions[1]), NOSLEEP, CREAT, 2, (void*)pathbuf, (void*)NULL);
709	init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)pathbuf, (void*)otherpathbuf);
710	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)otherpathbuf, (void*)NULL);
711	init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
712	execute_test(&test);
713
714	makepath(pathbuf, DIR1, FILE1);
715	init_test(&test, "2.1.6: rename a file to outside of a dir", DIR1, 2, 2, NOTE_WRITE, YES_EVENT);
716	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
717	init_action(&(test.t_prep_actions[1]), NOSLEEP, CREAT, 2, (void*)pathbuf, (void*)NULL);
718	init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)pathbuf, (void*)FILE1);
719	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
720	init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
721	execute_test(&test);
722
723	makepath(pathbuf, DIR1, FILE1);
724	init_test(&test, "2.1.7: rename a file into a dir", DIR1, 2, 2, NOTE_WRITE, YES_EVENT);
725	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
726	init_action(&(test.t_prep_actions[1]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
727	init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)FILE1, (void*)pathbuf);
728	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)pathbuf, (void*)NULL);
729	init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
730	execute_test(&test);
731
732	makepath(pathbuf, DIR1, FILE1);
733	init_test(&test, "2.1.9: unlink a fifo from a dir", DIR1, 2, 1, NOTE_WRITE, YES_EVENT);
734	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
735	init_action(&(test.t_prep_actions[1]), NOSLEEP, MKFIFO, 2, (void*)pathbuf, (void*)NULL);
736	init_action(&test.t_helpthreadact, SLEEP, UNLINK, 2, (void*)pathbuf, NULL);
737	init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
738	execute_test(&test);
739
740	makepath(pathbuf, DIR1, FILE1);
741	init_test(&test, "2.1.10: make symlink in a dir", DIR1, 1, 2, NOTE_WRITE, YES_EVENT);
742	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
743	init_action(&test.t_helpthreadact, SLEEP, SYMLINK, 2, (void*)DOTDOT, (void*)pathbuf);
744	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)pathbuf, (void*)NULL);
745	init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
746	execute_test(&test);
747
748	init_test(&test, "2.1.12: write to a FIFO", FILE1, 1, 1, NOTE_WRITE, YES_EVENT);
749	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKFIFO, 2, (void*)FILE1, (void*)NULL);
750	test.t_file_is_fifo = 1;
751	init_action(&test.t_helpthreadact, SLEEP, WRITEFD, 0);
752	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
753	execute_test(&test);
754
755
756	makepath(pathbuf, DIR1, FILE1);
757	init_test(&test, "2.1.13: delete a symlink in a dir", DIR1, 2, 1, NOTE_WRITE, YES_EVENT);
758	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
759	init_action(&(test.t_prep_actions[1]), NOSLEEP, SYMLINK, 2, (void*)DOTDOT, (void*)pathbuf);
760	init_action(&test.t_helpthreadact, SLEEP, UNLINK, 2, (void*)pathbuf, (void*)FILE1);
761	init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
762	execute_test(&test);
763
764	/* This actually should not generate an event, though it's in this section */
765	makepath(pathbuf, DIR1, FILE1);
766	makepath(otherpathbuf, DIR1, FILE2);
767	init_test(&test, "2.1.14: exchangedata two files in a dir", DIR1, 3, 3, NOTE_WRITE, NO_EVENT);
768	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
769	init_action(&(test.t_prep_actions[1]), NOSLEEP, CREAT, 2, (void*)pathbuf, (void*)NULL);
770	init_action(&(test.t_prep_actions[2]), NOSLEEP, CREAT, 2, (void*)otherpathbuf, (void*)NULL);
771	init_action(&test.t_helpthreadact, SLEEP, EXCHANGEDATA, 2, (void*)pathbuf, (void*)otherpathbuf);
772	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)pathbuf, (void*)NULL);
773	init_action(&test.t_cleanup_actions[1], NOSLEEP, UNLINK, 2, (void*)otherpathbuf, (void*)NULL);
774	init_action(&test.t_cleanup_actions[2], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
775	execute_test(&test);
776
777	LOG(1, stderr, "MMAP test should fail on HFS.\n");
778	init_test(&test, "2.1.15: Change a file with mmap()", FILE1, 1, 1, NOTE_WRITE, YES_EVENT);
779	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
780	init_action(&test.t_helpthreadact, SLEEP, MMAP, 2, (void*)FILE1, (void*)1); /* 1 -> "modify it"*/
781	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
782	execute_test(&test);
783
784	/*================= no-event tests ==================*/
785	init_test(&test, "2.2.1: just open and close existing file", FILE1, 1, 1, NOTE_WRITE, NO_EVENT);
786	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
787	init_action(&test.t_helpthreadact, SLEEP, OPEN, 2, (void*)FILE1, NULL);
788	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
789	execute_test(&test);
790
791	init_test(&test, "2.2.2: read from existing file", FILE1, 1, 1, NOTE_WRITE, NO_EVENT);
792	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
793	init_action(&test.t_helpthreadact, SLEEP, READ, 2, (void*)FILE1, NULL);
794	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
795	execute_test(&test);
796
797	init_test(&test, "2.2.3: rename existing file", FILE1, 1, 1, NOTE_WRITE, NO_EVENT);
798	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
799	init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)FILE1, (void*)FILE2);
800	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE2, (void*)NULL);
801	execute_test(&test);
802
803	init_test(&test, "2.2.4: just open and close dir", DIR1, 1, 1, NOTE_WRITE, NO_EVENT);
804	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
805	init_action(&test.t_helpthreadact, SLEEP, OPEN, 2, (void*)DIR1, (void*)NULL);
806	init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
807	execute_test(&test);
808
809	/* There are no tests 2.2.5 or 2.2.6 */
810
811	init_test(&test, "2.2.7: rename a dir", DIR1, 1, 1, NOTE_WRITE, NO_EVENT);
812	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
813	init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)DIR1, (void*)DIR2);
814	init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR2, (void*)NULL);
815	execute_test(&test);
816
817	init_test(&test, "2.2.8: rename a fifo", FILE1, 1, 1, NOTE_WRITE, NO_EVENT);
818	test.t_file_is_fifo = 1;
819	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKFIFO, 2, (void*)FILE1, (void*)NULL);
820	init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)FILE1, (void*)FILE2);
821	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE2, (void*)NULL);
822	execute_test(&test);
823
824	init_test(&test, "2.2.9: unlink a fifo", FILE1, 1, 0, NOTE_WRITE, NO_EVENT);
825	test.t_file_is_fifo = 1;
826	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKFIFO, 2, (void*)FILE1, (void*)NULL);
827	init_action(&test.t_helpthreadact, SLEEP, UNLINK,1, (void*)FILE1);
828	execute_test(&test);
829
830	init_test(&test, "2.2.10: chmod a file", FILE1, 1, 1, NOTE_WRITE, NO_EVENT);
831	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
832	init_action(&test.t_helpthreadact, SLEEP, CHMOD, 2, (void*)FILE1, (void*)0700);
833	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
834	execute_test(&test);
835
836	struct passwd *pwd = getpwnam("local");
837	int uid = pwd->pw_uid;
838	int gid = pwd->pw_gid;
839
840	init_test(&test, "2.2.11: chown a file", FILE1, 2, 1, NOTE_WRITE, NO_EVENT);
841	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
842	init_action(&test.t_prep_actions[1], NOSLEEP, CHOWN, 3, (void*)FILE1, (void*)uid, (void*)gid);
843	init_action(&test.t_helpthreadact, SLEEP, CHOWN, 3, (void*)FILE1, (void*)getuid(), (void*)getgid());
844	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
845	execute_test(&test);
846
847
848	init_test(&test, "2.2.12: chmod a dir", DIR1, 1, 1, NOTE_WRITE, NO_EVENT);
849	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
850	init_action(&test.t_helpthreadact, SLEEP, CHMOD, 2, (void*)DIR1, (void*)0700);
851	init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
852	execute_test(&test);
853
854	init_test(&test, "2.2.13: chown a dir", DIR1, 2, 1, NOTE_WRITE, NO_EVENT);
855	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
856	init_action(&test.t_prep_actions[1], NOSLEEP, CHOWN, 3, (void*)DIR1, (void*)uid, (void*)gid);
857	init_action(&test.t_helpthreadact, SLEEP, CHOWN, 3, (void*)DIR1, (void*)getuid(), (void*)getgid());
858	init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
859	execute_test(&test);
860
861
862
863	LOG(1, stderr, "MMAP will never give a notification on HFS.\n");
864	init_test(&test, "2.1.14: mmap() a file but do not change it", FILE1, 1, 1, NOTE_WRITE, NO_EVENT);
865	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
866	init_action(&test.t_helpthreadact, SLEEP, MMAP, 2, (void*)FILE1, (void*)0);
867	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
868	execute_test(&test);
869}
870
871void
872run_note_extend_tests()
873{
874	test_t test;
875	char pathbuf[50];
876
877	LOG(1, stderr, "THESE TESTS WILL FAIL ON HFS!\n");
878
879	init_test(&test, "3.1.1: write beyond the end of a file", FILE1, 1, 1, NOTE_EXTEND, YES_EVENT);
880	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
881	init_action(&test.t_helpthreadact, SLEEP, WRITE, 2, (void*)FILE1, (void*)NULL);
882	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
883	execute_test(&test);
884
885	/*
886	 * We won't concern ourselves with lengthening directories: commenting these out
887	 *
888
889	 makepath(pathbuf, DIR1, FILE1);
890	 init_test(&test, "3.1.2: add a file to a directory with creat()", DIR1, 1, 2, NOTE_EXTEND, YES_EVENT);
891	 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
892	 init_action(&test.t_helpthreadact, SLEEP, CREAT, 2, (void*)pathbuf, (void*)NULL);
893	 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)pathbuf, (void*)NULL);
894	 init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
895	 execute_test(&test);
896
897	 makepath(pathbuf, DIR1, FILE1);
898	 init_test(&test, "3.1.3: add a file to a directory with open()", DIR1, 1, 2, NOTE_EXTEND, YES_EVENT);
899	 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
900	 init_action(&test.t_helpthreadact, SLEEP, CREAT, 2, (void*)pathbuf, (void*)NULL);
901	 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)pathbuf, (void*)NULL);
902	 init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
903	 execute_test(&test);
904
905	 makepath(pathbuf, DIR1, FILE1);
906	 init_test(&test, "3.1.4: add a file to a directory with rename()", DIR1, 2, 2, NOTE_EXTEND, YES_EVENT);
907	 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
908	 init_action(&(test.t_prep_actions[1]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
909	 init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)FILE1, (void*)pathbuf);
910	 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)pathbuf, (void*)NULL);
911	 init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
912	 execute_test(&test);
913	 */
914
915	/* 3.1.5: a placeholder for a potential kernel test */
916	/*
917	 makepath(pathbuf, DIR1, DIR2);
918	 init_test(&test, "3.1.6: add a file to a directory with mkdir()", DIR1, 1, 2, NOTE_EXTEND, YES_EVENT);
919	 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
920	 init_action(&test.t_helpthreadact, SLEEP, MKDIR, 2, (void*)pathbuf, (void*)NULL);
921	 init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)pathbuf, (void*)NULL);
922	 init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
923	 execute_test(&test);
924	 */
925	init_test(&test, "3.1.7: lengthen a file with truncate()", FILE1, 1, 1, NOTE_EXTEND, YES_EVENT);
926	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
927	init_action(&test.t_helpthreadact, SLEEP, LENGTHEN, 2, FILE1, (void*)NULL);
928	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
929	execute_test(&test);
930
931
932	/** ========== NO EVENT SECTION ============== **/
933	init_test(&test, "3.2.1: setxattr() a file", FILE1, 1, 1, NOTE_EXTEND, NO_EVENT);
934	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
935	init_action(&test.t_helpthreadact, SLEEP, SETXATTR, 2, FILE1, (void*)NULL);
936	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
937	execute_test(&test);
938
939	init_test(&test, "3.2.2: chmod a file", FILE1, 1, 1, NOTE_EXTEND, NO_EVENT);
940	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
941	init_action(&test.t_helpthreadact, SLEEP, CHMOD, 2, (void*)FILE1, (void*)0700);
942	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
943	execute_test(&test);
944
945	struct passwd *pwd = getpwnam("local");
946	if (!pwd) {
947		LOG(2, stderr, "Couldn't getpwnam for local.\n");
948		exit(1);
949	}
950	int uid = pwd->pw_uid;
951	int gid = pwd->pw_gid;
952
953	init_test(&test, "3.2.3: chown a file", FILE1, 2, 1, NOTE_EXTEND, NO_EVENT);
954	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
955	init_action(&test.t_prep_actions[1], NOSLEEP, CHOWN, 3, (void*)FILE1, (void*)uid, (void*)gid);
956	init_action(&test.t_helpthreadact, SLEEP, CHOWN, 3, (void*)FILE1, (void*)getuid(), (void*)getgid());
957	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
958	execute_test(&test);
959
960
961	init_test(&test, "3.2.4: chmod a dir", DIR1, 1, 1, NOTE_EXTEND, NO_EVENT);
962	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
963	init_action(&test.t_helpthreadact, SLEEP, CHMOD, 2, (void*)DIR1, (void*)0700);
964	init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
965	execute_test(&test);
966
967	init_test(&test, "3.2.5: chown a dir", DIR1, 2, 1, NOTE_EXTEND, NO_EVENT);
968	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
969	init_action(&test.t_prep_actions[1], NOSLEEP, CHOWN, 3, (void*)DIR1, (void*)uid, (void*)gid);
970	init_action(&test.t_helpthreadact, SLEEP, CHOWN, 3, (void*)DIR1, (void*)getuid(), (void*)getgid());
971	init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
972	execute_test(&test);
973
974	init_test(&test, "3.2.6: TRUNC a file with truncate()", FILE1, 1, 1, NOTE_EXTEND, NO_EVENT);
975	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
976	init_action(&test.t_helpthreadact, SLEEP, TRUNC, 2, FILE1, (void*)NULL);
977	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
978	execute_test(&test);
979}
980
981void
982run_note_attrib_tests()
983{
984	test_t test;
985	char pathbuf[50];
986
987	init_test(&test, "4.1.1: chmod a file", FILE1, 1, 1, NOTE_ATTRIB, YES_EVENT);
988	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
989	init_action(&test.t_helpthreadact, SLEEP, CHMOD, 2, FILE1, (void*)0700);
990	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
991	execute_test(&test);
992
993	struct passwd *pwd = getpwnam("local");
994	int uid = pwd->pw_uid;
995	int gid = pwd->pw_gid;
996
997	init_test(&test, "4.1.2: chown a file", FILE1, 2, 1, NOTE_ATTRIB, YES_EVENT);
998	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
999	init_action(&(test.t_prep_actions[1]), NOSLEEP, CHOWN, 3, (void*)FILE1, (void*)uid, (void*)gid);
1000	init_action(&test.t_helpthreadact, SLEEP, CHOWN, 3, FILE1, (void*)getuid(), (void*)gid);
1001	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
1002	execute_test(&test);
1003
1004	init_test(&test, "4.1.3: chmod a dir", DIR1, 1, 1, NOTE_ATTRIB, YES_EVENT);
1005	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1006	init_action(&(test.t_helpthreadact), SLEEP, CHMOD, 2, (void*)DIR1, (void*)0700);
1007	init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
1008	execute_test(&test);
1009
1010	init_test(&test, "4.1.4: chown a dir", DIR1, 2, 1, NOTE_ATTRIB, YES_EVENT);
1011	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1012	init_action(&(test.t_prep_actions[1]), NOSLEEP, CHOWN, 3, (void*)DIR1, (void*) uid, (void*)gid);
1013	init_action(&test.t_helpthreadact, SLEEP, CHOWN, 3, DIR1, (void*)getuid(), (void*)getgid());
1014	init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
1015	execute_test(&test);
1016
1017	init_test(&test, "4.1.5: setxattr on a file", FILE1, 1, 1, NOTE_ATTRIB, YES_EVENT);
1018	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1019	init_action(&test.t_helpthreadact, SLEEP, SETXATTR, 2, (void*)FILE1, (void*)NULL);
1020	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
1021	execute_test(&test);
1022
1023	init_test(&test, "4.1.6: setxattr on a dir", DIR1, 1, 1, NOTE_ATTRIB, YES_EVENT);
1024	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1025	init_action(&test.t_helpthreadact, SLEEP, SETXATTR, 2, (void*)DIR1, (void*)NULL);
1026	init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
1027	execute_test(&test);
1028
1029
1030	init_test(&test, "4.1.7: exchangedata", FILE1, 2, 2, NOTE_ATTRIB, YES_EVENT);
1031	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1032	init_action(&(test.t_prep_actions[1]), NOSLEEP, CREAT, 2, (void*)FILE2, (void*)NULL);
1033	init_action(&test.t_helpthreadact, SLEEP, EXCHANGEDATA, 2, (void*)FILE1, (void*)FILE2);
1034	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
1035	init_action(&test.t_cleanup_actions[1], NOSLEEP, UNLINK, 2, (void*)FILE2, (void*)NULL);
1036	execute_test(&test);
1037
1038
1039	init_test(&test, "4.1.8: utimes on a file", FILE1, 1, 1, NOTE_ATTRIB, YES_EVENT);
1040	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1041	init_action(&test.t_helpthreadact, SLEEP, UTIMES, 2, (void*)FILE1, (void*)NULL);
1042	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
1043	execute_test(&test);
1044
1045	init_test(&test, "4.1.9: utimes on a dir", DIR1, 1, 1, NOTE_ATTRIB, YES_EVENT);
1046	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1047	init_action(&test.t_helpthreadact, SLEEP, UTIMES, 2, (void*)DIR1, (void*)NULL);
1048	init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
1049	execute_test(&test);
1050
1051
1052	/* ====== NO EVENT TESTS ========== */
1053
1054	init_test(&test, "4.2.1: rename a file", FILE1, 1, 1, NOTE_ATTRIB, NO_EVENT);
1055	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1056	init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)FILE1, (void*)FILE2);
1057	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE2, NULL);
1058	execute_test(&test);
1059
1060	init_test(&test, "4.2.2: open (do not change) a file", FILE1, 1, 1, NOTE_ATTRIB, NO_EVENT);
1061	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1062	init_action(&test.t_helpthreadact, SLEEP, OPEN, 2, (void*)FILE1, NULL);
1063	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1064	execute_test(&test);
1065
1066	init_test(&test, "4.2.3: stat a file", FILE1, 1, 1, NOTE_ATTRIB, NO_EVENT);
1067	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1068	init_action(&test.t_helpthreadact, SLEEP, STAT, 2, (void*)FILE1, NULL);
1069	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1070	execute_test(&test);
1071
1072	init_test(&test, "4.2.4: unlink a file", FILE1, 1, 0, NOTE_ATTRIB, NO_EVENT);
1073	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1074	init_action(&test.t_helpthreadact, SLEEP, UNLINK, 2, (void*)FILE1, NULL);
1075	execute_test(&test);
1076
1077	init_test(&test, "4.2.5: write to a file", FILE1, 1, 1, NOTE_ATTRIB, NO_EVENT);
1078	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1079	init_action(&test.t_helpthreadact, SLEEP, WRITE, 2, (void*)FILE1, (void*)NULL);
1080	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
1081	execute_test(&test);
1082
1083	LOG(1, stderr, "EXPECT SPURIOUS NOTE_ATTRIB EVENTS FROM DIRECTORY OPERATIONS on HFS.\n");
1084	init_test(&test, "4.2.6: add a file to a directory with creat()", DIR1, 1, 2, NOTE_ATTRIB, NO_EVENT);
1085	makepath(pathbuf, DIR1, FILE1);
1086	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1087	init_action(&test.t_helpthreadact, SLEEP, CREAT, 2, (void*)pathbuf, (void*)NULL);
1088	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)pathbuf, (void*)NULL);
1089	init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
1090	execute_test(&test);
1091
1092	init_test(&test, "4.2.7: mkdir in a dir", DIR1, 1, 2, NOTE_ATTRIB, NO_EVENT);
1093	makepath(pathbuf, DIR1, DIR2);
1094	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1095	init_action(&test.t_helpthreadact, SLEEP, MKDIR, 2, (void*)pathbuf, (void*)NULL);
1096	init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)pathbuf, (void*)NULL);
1097	init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
1098	execute_test(&test);
1099
1100	init_test(&test, "4.2.8: add a symlink to a directory", DIR1, 1, 2, NOTE_ATTRIB, NO_EVENT);
1101	makepath(pathbuf, DIR1, FILE1);
1102	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1103	init_action(&test.t_helpthreadact, SLEEP, SYMLINK, 2, (void*)DOTDOT, (void*)pathbuf);
1104	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)pathbuf, (void*)NULL);
1105	init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
1106	execute_test(&test);
1107
1108	init_test(&test, "4.2.9: rename into a dir()", DIR1, 2, 2, NOTE_ATTRIB, NO_EVENT);
1109	makepath(pathbuf, DIR1, FILE1);
1110	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1111	init_action(&(test.t_prep_actions[1]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1112	init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)FILE1, (void*)pathbuf);
1113	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)pathbuf, (void*)NULL);
1114	init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
1115	execute_test(&test);
1116
1117	init_test(&test, "4.2.10: unlink() file from dir", DIR1, 2, 1, NOTE_ATTRIB, NO_EVENT);
1118	makepath(pathbuf, DIR1, FILE1);
1119	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1120	init_action(&(test.t_prep_actions[1]), NOSLEEP, CREAT, 2, (void*)pathbuf, (void*)NULL);
1121	init_action(&test.t_helpthreadact, SLEEP, UNLINK, 2, (void*)pathbuf, (void*)NULL);
1122	init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
1123	execute_test(&test);
1124
1125	init_test(&test, "4.2.11: mkfifo in a directory", DIR1, 1, 2, NOTE_ATTRIB, NO_EVENT);
1126	makepath(pathbuf, DIR1, FILE1);
1127	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1128	init_action(&test.t_helpthreadact, SLEEP, MKFIFO, 1, (void*)pathbuf);
1129	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)pathbuf, (void*)NULL);
1130	init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
1131	execute_test(&test);
1132
1133
1134}
1135
1136
1137void
1138run_note_link_tests()
1139{
1140	test_t test;
1141	char pathbuf[50];
1142	char otherpathbuf[50];
1143
1144	LOG(1, stderr, "HFS DOES NOT HANDLE UNLINK CORRECTLY...\n");
1145	init_test(&test, "5.1.1: unlink() a file", FILE1, 1, 0, NOTE_LINK, YES_EVENT);
1146	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1147	init_action(&test.t_helpthreadact, SLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
1148	execute_test(&test);
1149
1150
1151	init_test(&test, "5.1.1.5: link A to B, watch A, remove B", FILE1, 2, 1, NOTE_LINK, YES_EVENT);
1152	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1153	init_action(&(test.t_prep_actions[1]), NOSLEEP, HARDLINK, 2, (void*)FILE1, (void*)FILE2);
1154	init_action(&test.t_helpthreadact, SLEEP, UNLINK, 2, (void*)FILE2, (void*)NULL);
1155	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1156	execute_test(&test);
1157
1158	init_test(&test, "5.1.2: link() to a file", FILE1, 1, 2, NOTE_LINK, YES_EVENT);
1159	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1160	init_action(&test.t_helpthreadact, SLEEP, HARDLINK, 2, (void*)FILE1, (void*)FILE2);
1161	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1162	init_action(&test.t_cleanup_actions[1], NOSLEEP, UNLINK, 2, (void*)FILE2, NULL);
1163	execute_test(&test);
1164
1165	makepath(pathbuf, DIR1, DIR2);
1166	init_test(&test, "5.1.3: make one dir in another", DIR1, 1, 2, NOTE_LINK, YES_EVENT);
1167	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1168	init_action(&test.t_helpthreadact, SLEEP, MKDIR, 2, (void*)pathbuf, (void*)NULL);
1169	init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)pathbuf, NULL);
1170	init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, NULL);
1171	execute_test(&test);
1172
1173	makepath(pathbuf, DIR1, DIR2);
1174	init_test(&test, "5.1.4: rmdir a dir from within another", DIR1, 2, 1, NOTE_LINK, YES_EVENT);
1175	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1176	init_action(&(test.t_prep_actions[1]), NOSLEEP, MKDIR, 2, (void*)pathbuf, (void*)NULL);
1177	init_action(&test.t_helpthreadact, SLEEP, RMDIR, 2, (void*)pathbuf, (void*)NULL);
1178	init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR1, NULL);
1179	execute_test(&test);
1180
1181	makepath(pathbuf, DIR1, DIR2);
1182	makepath(otherpathbuf, DIR1, DIR1);
1183	init_test(&test, "5.1.5: rename dir A over dir B inside dir C", DIR1, 3, 2, NOTE_LINK, YES_EVENT);
1184	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1185	init_action(&(test.t_prep_actions[1]), NOSLEEP, MKDIR, 2, (void*)pathbuf, (void*)NULL);
1186	init_action(&(test.t_prep_actions[2]), NOSLEEP, MKDIR, 2, (void*)otherpathbuf, (void*)NULL);
1187	init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)pathbuf, (void*)otherpathbuf);
1188	init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)otherpathbuf, NULL);
1189	init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, NULL);
1190	execute_test(&test);
1191
1192	LOG(1, stderr, "HFS bypasses hfs_makenode to create in target, so misses knote.\n");
1193	makepath(pathbuf, DIR1, DIR2);
1194	init_test(&test, "5.1.6: rename one dir into another", DIR1, 2, 2, NOTE_LINK, YES_EVENT);
1195	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1196	init_action(&(test.t_prep_actions[1]), NOSLEEP, MKDIR, 2, (void*)DIR2, (void*)NULL);
1197	init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)DIR2, (void*)pathbuf);
1198	init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)pathbuf, NULL);
1199	init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, NULL);
1200	execute_test(&test);
1201
1202	LOG(1, stderr, "HFS bypasses hfs_removedir to remove from source, so misses knote.\n");
1203	makepath(pathbuf, DIR1, DIR2);
1204	init_test(&test, "5.1.7: rename one dir out of another", DIR1, 2, 2, NOTE_LINK, YES_EVENT);
1205	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1206	init_action(&(test.t_prep_actions[1]), NOSLEEP, MKDIR, 2, (void*)pathbuf, (void*)NULL);
1207	init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)pathbuf, (void*)DIR2);
1208	init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR2, NULL);
1209	init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, NULL);
1210	execute_test(&test);
1211
1212	init_test(&test, "5.1.8: rmdir a dir", DIR1, 1, 0, NOTE_LINK, YES_EVENT);
1213	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1214	init_action(&test.t_helpthreadact, SLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
1215	execute_test(&test);
1216
1217	/* ============= NO EVENT SECTION ============== */
1218	makepath(pathbuf, DIR1, FILE1);
1219	init_test(&test, "5.2.1: make a file in a dir", DIR1, 1, 2, NOTE_LINK, NO_EVENT);
1220	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1221	init_action(&test.t_helpthreadact, SLEEP, CREAT, 2, (void*)pathbuf, (void*)NULL);
1222	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)pathbuf, NULL);
1223	init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, NULL);
1224	execute_test(&test);
1225
1226	makepath(pathbuf, DIR1, FILE1);
1227	init_test(&test, "5.2.2: unlink a file in a dir", DIR1, 2, 1, NOTE_LINK, NO_EVENT);
1228	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1229	init_action(&(test.t_prep_actions[1]), NOSLEEP, CREAT, 2, (void*)pathbuf, (void*)NULL);
1230	init_action(&test.t_helpthreadact, SLEEP, UNLINK, 2, (void*)pathbuf, (void*)NULL);
1231	init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR1, NULL);
1232	execute_test(&test);
1233
1234	makepath(pathbuf, DIR1, FILE1);
1235	makepath(otherpathbuf, DIR1, FILE2);
1236	init_test(&test, "5.2.3: rename a file within a dir", DIR1, 2, 2, NOTE_LINK, NO_EVENT);
1237	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1238	init_action(&(test.t_prep_actions[1]), NOSLEEP, CREAT, 2, (void*)pathbuf, (void*)NULL);
1239	init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)pathbuf, (void*)otherpathbuf);
1240	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)otherpathbuf, NULL);
1241	init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, NULL);
1242	execute_test(&test);
1243
1244	makepath(pathbuf, DIR1, FILE1);
1245	init_test(&test, "5.2.4: rename a file into a dir", DIR1, 2, 2, NOTE_LINK, NO_EVENT);
1246	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1247	init_action(&(test.t_prep_actions[1]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1248	init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)FILE1, (void*)pathbuf);
1249	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)pathbuf, NULL);
1250	init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, NULL);
1251	execute_test(&test);
1252
1253	makepath(pathbuf, DIR1, FILE1);
1254	init_test(&test, "5.2.5: make a symlink in a dir", DIR1, 1, 2, NOTE_LINK, NO_EVENT);
1255	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1256	init_action(&test.t_helpthreadact, SLEEP, SYMLINK, 2, (void*)DOTDOT, (void*)pathbuf);
1257	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)pathbuf, NULL);
1258	init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, NULL);
1259	execute_test(&test);
1260
1261	init_test(&test, "5.2.6: make a symlink to a dir", DIR1, 1, 2, NOTE_LINK, NO_EVENT);
1262	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1263	init_action(&test.t_helpthreadact, SLEEP, SYMLINK, 2, (void*)DIR1, (void*)FILE1);
1264	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1265	init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, NULL);
1266	execute_test(&test);
1267
1268	init_test(&test, "5.2.7: make a symlink to a file", FILE1, 1, 2, NOTE_LINK, NO_EVENT);
1269	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1270	init_action(&test.t_helpthreadact, SLEEP, SYMLINK, 2, (void*)FILE1, (void*)FILE2);
1271	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE2, NULL);
1272	init_action(&test.t_cleanup_actions[1], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1273	execute_test(&test);
1274}
1275
1276void
1277run_note_rename_tests()
1278{
1279	test_t test;
1280
1281	init_test(&test, "6.1.1: rename a file", FILE1, 1, 1, NOTE_RENAME, YES_EVENT);
1282	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1283	init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)FILE1, (void*)FILE2);
1284	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE2, NULL);
1285	execute_test(&test);
1286
1287	init_test(&test, "6.1.2: rename a dir", DIR1, 1, 1, NOTE_RENAME, YES_EVENT);
1288	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1289	init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)DIR1, (void*)DIR2);
1290	init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR2, NULL);
1291	execute_test(&test);
1292
1293	init_test(&test, "6.1.2: rename one file over another", FILE1, 2, 1, NOTE_RENAME, YES_EVENT);
1294	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1295	init_action(&(test.t_prep_actions[1]), NOSLEEP, CREAT, 2, (void*)FILE2, (void*)NULL);
1296	init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)FILE1, (void*)FILE2);
1297	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE2, NULL);
1298	execute_test(&test);
1299
1300	init_test(&test, "6.1.3: rename one dir over another", DIR1, 2, 1, NOTE_RENAME, YES_EVENT);
1301	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1302	init_action(&(test.t_prep_actions[1]), NOSLEEP, MKDIR, 2, (void*)DIR2, (void*)NULL);
1303	init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)DIR1, (void*)DIR2);
1304	init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR2, NULL);
1305	execute_test(&test);
1306
1307	/* ========= NO EVENT SECTION =========== */
1308
1309	init_test(&test, "6.2.1: unlink a file", FILE1, 1, 0, NOTE_RENAME, NO_EVENT);
1310	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1311	init_action(&test.t_helpthreadact, SLEEP, UNLINK, 2, (void*)FILE1, NULL);
1312	execute_test(&test);
1313
1314	init_test(&test, "6.2.2: rmdir a dir", DIR1, 1, 0, NOTE_RENAME, NO_EVENT);
1315	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1316	init_action(&test.t_helpthreadact, SLEEP, RMDIR, 2, (void*)DIR1, NULL);
1317	execute_test(&test);
1318
1319	init_test(&test, "6.2.3: link() to a file", FILE1, 1, 2, NOTE_RENAME, NO_EVENT);
1320	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1321	init_action(&test.t_helpthreadact, SLEEP, HARDLINK, 2, (void*)FILE1, (void*)FILE2);
1322	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1323	init_action(&test.t_cleanup_actions[1], NOSLEEP, UNLINK, 2, (void*)FILE2, NULL);
1324	execute_test(&test);
1325
1326	init_test(&test, "6.2.4: rename one file over another: watch deceased",
1327			  FILE2, 2, 1, NOTE_RENAME, NO_EVENT);
1328	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1329	init_action(&(test.t_prep_actions[1]), NOSLEEP, CREAT, 2, (void*)FILE2, (void*)NULL);
1330	init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)FILE1, (void*)FILE2);
1331	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE2, NULL);
1332	execute_test(&test);
1333
1334	init_test(&test, "6.2.5: rename one dir over another: watch deceased",
1335			  DIR2, 2, 1, NOTE_RENAME, NO_EVENT);
1336	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1337	init_action(&(test.t_prep_actions[1]), NOSLEEP, MKDIR, 2, (void*)DIR2, (void*)NULL);
1338	init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)DIR1, (void*)DIR2);
1339	init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR2, NULL);
1340	execute_test(&test);
1341
1342	init_test(&test, "6.2.6: rename a file to itself", FILE1, 1, 1, NOTE_RENAME, NO_EVENT);
1343	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1344	init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)FILE1, (void*)FILE1);
1345	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1346	execute_test(&test);
1347
1348	init_test(&test, "6.2.7: rename a dir to itself", DIR1, 1, 1, NOTE_RENAME, NO_EVENT);
1349	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1350	init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)DIR1, (void*)DIR1);
1351	init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR1, NULL);
1352	execute_test(&test);
1353}
1354
1355void
1356run_note_revoke_tests()
1357{
1358	test_t test;
1359	init_test(&test, "7.1.1: revoke file", FILE1, 1, 1, NOTE_REVOKE, YES_EVENT);
1360	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 1, (void*)FILE1);
1361	init_action(&test.t_helpthreadact, SLEEP, REVOKE, 1, (void*)FILE1);
1362	init_action(&(test.t_cleanup_actions[0]), NOSLEEP, UNLINK, 1, (void*)FILE1);
1363	execute_test(&test);
1364
1365	init_test(&test, "7.2.1: delete file", FILE1, 1, 0, NOTE_REVOKE, NO_EVENT);
1366	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 1, (void*)FILE1);
1367	init_action(&test.t_helpthreadact, SLEEP, UNLINK, 1, (void*)FILE1);
1368	execute_test(&test);
1369}
1370
1371
1372void
1373run_evfilt_read_tests()
1374{
1375	test_t test;
1376	init_test(&test, "8.1.1: how much data in file of length LENGTHEN_SIZE?", FILE1, 2, 1, EVFILT_READ, LENGTHEN_SIZE);
1377	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1378	init_action(&(test.t_prep_actions[1]), NOSLEEP, LENGTHEN, 2, (void*)FILE1, (void*)NULL);
1379	init_action(&test.t_helpthreadact, SLEEP, NOTHING, 0);
1380	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1381	execute_test(&test);
1382
1383	init_test(&test, "8.1.2: block, then write to file", FILE1, 2, 1, EVFILT_READ, strlen(TEST_STRING));
1384	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 1, (void*)FILE1);
1385	init_action(&(test.t_prep_actions[1]), NOSLEEP, TRUNC, 1, (void*)FILE1);
1386	init_action(&test.t_helpthreadact, SLEEP, WRITE, 1, (void*)FILE1);
1387	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1388	execute_test(&test);
1389
1390	init_test(&test, "8.1.3: block, then extend", FILE1, 2, 1, EVFILT_READ, LENGTHEN_SIZE);
1391	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 1, (void*)FILE1);
1392	init_action(&(test.t_prep_actions[1]), NOSLEEP, TRUNC, 1, (void*)FILE1);
1393	init_action(&test.t_helpthreadact, SLEEP, LENGTHEN, 1, (void*)FILE1);
1394	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1395	execute_test(&test);
1396
1397	init_test(&test, "8.1.4: block, then seek to beginning", FILE1, 2, 1, EVFILT_READ, strlen(TEST_STRING));
1398	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 1, (void*)FILE1);
1399	init_action(&(test.t_prep_actions[1]), NOSLEEP, WRITE, 1, (void*)FILE1);
1400	test.t_read_to_end_first = 1; /* hack means that we've gotten to EOF before we block */
1401	init_action(&test.t_helpthreadact, SLEEP, LSEEK, 1, (void*)0);
1402	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1403	execute_test(&test);
1404
1405
1406	init_test(&test, "8.1.5: block, then write to fifo", FILE1, 1, 1, EVFILT_READ, strlen(TEST_STRING));
1407	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKFIFO, 1, (void*)FILE1);
1408	test.t_file_is_fifo = 1;
1409	init_action(&test.t_helpthreadact, SLEEP, WRITE, 1, (void*)FILE1);
1410	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1411	execute_test(&test);
1412
1413	/* No result section... */
1414	init_test(&test, "8.2.1: just rename", FILE1, 2, 1, EVFILT_READ, NO_EVENT);
1415	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 1, (void*)FILE1);
1416	init_action(&(test.t_prep_actions[1]), NOSLEEP, TRUNC, 1, (void*)FILE1);
1417	init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)FILE1, (void*)FILE2);
1418	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE2, NULL);
1419	execute_test(&test);
1420
1421	init_test(&test, "8.2.2: delete file", FILE1, 2, 0, EVFILT_READ, NO_EVENT);
1422	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 1, (void*)FILE1);
1423	init_action(&(test.t_prep_actions[1]), NOSLEEP, TRUNC, 1, (void*)FILE1);
1424	init_action(&test.t_helpthreadact, SLEEP, UNLINK, 1, (void*)FILE1);
1425	execute_test(&test);
1426
1427	init_test(&test, "8.2.3: write to beginning", FILE1, 2, 1, EVFILT_READ, NO_EVENT);
1428	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 1, (void*)FILE1);
1429	init_action(&(test.t_prep_actions[1]), NOSLEEP, WRITE, 1, (void*)FILE1);
1430	test.t_read_to_end_first = 1; /* hack means that we've gotten to EOF before we block */
1431	init_action(&test.t_helpthreadact, SLEEP, WRITE, 1, (void*)FILE1);
1432	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 1, (void*)FILE1);
1433	execute_test(&test);
1434
1435	init_test(&test, "8.1.4: block, then seek to current location", FILE1, 2, 1, EVFILT_READ, 0);
1436	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 1, (void*)FILE1);
1437	init_action(&(test.t_prep_actions[1]), NOSLEEP, WRITE, 1, (void*)FILE1);
1438	test.t_read_to_end_first = 1; /* hack means that we've gotten to EOF before we block */
1439	init_action(&test.t_helpthreadact, SLEEP, LSEEK, 1, (void*)strlen(TEST_STRING));
1440	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1441	execute_test(&test);
1442
1443	init_test(&test, "8.2.5: trying to read from empty fifo", FILE1, 1, 1, EVFILT_READ, 0);
1444	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKFIFO, 1, (void*)FILE1);
1445	test.t_file_is_fifo = 1;
1446	init_action(&test.t_helpthreadact, SLEEP, NOTHING, 1, (void*)0);
1447	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1448	execute_test(&test);
1449
1450}
1451
1452
1453
1454void*
1455read_from_fd(void *arg)
1456{
1457	char buf[50];
1458	int fd = (int) arg;
1459	sleep(2);
1460	return (void*) read(fd, buf, sizeof(buf));
1461}
1462
1463void*
1464write_to_fd(void *arg)
1465{
1466	char buf[50];
1467	int fd = (int) arg;
1468	sleep(2);
1469	return (void*) write(fd, buf, sizeof(buf));
1470}
1471
1472/*
1473 * We don't (in principle) support EVFILT_WRITE for vnodes; thusly, no tests here
1474 */
1475void
1476run_evfilt_write_tests()
1477{
1478
1479	test_t test;
1480	init_test(&test, "9.1.1: how much space in empty fifo?", FILE1, 1, 1, EVFILT_WRITE, FIFO_SPACE);
1481	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKFIFO, 1, (void*)FILE1, (void*)NULL);
1482	test.t_file_is_fifo = 1;
1483	init_action(&test.t_helpthreadact, SLEEP, NOTHING, 0);
1484	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1485	execute_test(&test);
1486
1487	init_test(&test, "9.1.2: how much space in slightly written fifo?", FILE1, 1, 1, EVFILT_WRITE, FIFO_SPACE - strlen(TEST_STRING));
1488	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKFIFO, 1, (void*)FILE1, (void*)NULL);
1489	test.t_file_is_fifo = 1;
1490	test.t_write_some_data = 1;
1491	init_action(&(test.t_helpthreadact), NOSLEEP, NOTHING, 0);
1492	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1493	execute_test(&test);
1494
1495	init_test(&test, "9.2.1: how much space in a full fifo?", FILE1, 1, 1, EVFILT_WRITE, 0);
1496	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKFIFO, 1, (void*)FILE1, (void*)NULL);
1497	test.t_file_is_fifo = 1;
1498	test.t_extra_sleep_hack = 1;
1499	init_action(&(test.t_helpthreadact), NOSLEEP, FILLFD, 1, (void*)FILE1, (void*)NULL);
1500	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1501	execute_test(&test);
1502}
1503
1504void
1505run_poll_tests()
1506{
1507	test_t test;
1508	init_poll_test(&test, "10.1.1: does poll say I can write a regular file?", FILE1, 1, 1, POLLWRNORM, 1);
1509	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 1, (void*)FILE1, (void*)NULL);
1510	init_action(&test.t_helpthreadact, SLEEP, NOTHING, 0);
1511	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1512	execute_test(&test);
1513
1514	init_poll_test(&test, "10.1.2: does poll say I can write an empty FIFO?", FILE1, 1, 1, POLLWRNORM, 1);
1515	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKFIFO, 1, (void*)FILE1, (void*)NULL);
1516	test.t_file_is_fifo = 1;
1517	init_action(&test.t_helpthreadact, SLEEP, NOTHING, 0);
1518	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1519	execute_test(&test);
1520
1521	init_poll_test(&test, "10.1.3: does poll say I can read a nonempty FIFO?", FILE1, 1, 1, POLLRDNORM, 1);
1522	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKFIFO, 1, (void*)FILE1, (void*)NULL);
1523	test.t_file_is_fifo = 1;
1524	test.t_write_some_data = 1;
1525	init_action(&test.t_helpthreadact, SLEEP, NOTHING, 0);
1526	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1527	execute_test(&test);
1528
1529	init_poll_test(&test, "10.1.4: does poll say I can read a nonempty regular file?", FILE1, 2, 1, POLLRDNORM, 1);
1530	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 1, (void*)FILE1, (void*)NULL);
1531	init_action(&(test.t_prep_actions[1]), NOSLEEP, LENGTHEN, 1, (void*)FILE1, (void*)NULL);
1532	init_action(&test.t_helpthreadact, SLEEP, NOTHING, 0);
1533	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1534	execute_test(&test);
1535
1536	init_poll_test(&test, "10.1.5: does poll say I can read an empty file?", FILE1, 1, 1, POLLRDNORM, 1);
1537	init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 1, (void*)FILE1, (void*)NULL);
1538	init_action(&test.t_helpthreadact, SLEEP, NOTHING, 0);
1539	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1540	execute_test(&test);
1541
1542
1543
1544
1545	init_poll_test(&test, "10.2.2: does poll say I can read an empty FIFO?", FILE1, 1, 1, POLLRDNORM, 0);
1546	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKFIFO, 1, (void*)FILE1, (void*)NULL);
1547	test.t_file_is_fifo = 1;
1548	init_action(&test.t_helpthreadact, SLEEP, NOTHING, 0);
1549	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1550	execute_test(&test);
1551
1552	init_poll_test(&test, "10.2.3: does poll say I can write a full FIFO?", FILE1, 1, 1, POLLWRNORM, 0);
1553	init_action(&(test.t_prep_actions[0]), NOSLEEP, MKFIFO, 1, (void*)FILE1, (void*)NULL);
1554	test.t_file_is_fifo = 1;
1555	test.t_extra_sleep_hack = 1;
1556	init_action(&(test.t_helpthreadact), NOSLEEP, FILLFD, 1, (void*)FILE1, (void*)NULL);
1557	init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1558	execute_test(&test);
1559}
1560
1561void
1562run_all_tests()
1563{
1564	run_note_delete_tests();
1565	run_note_write_tests();
1566	run_note_extend_tests();
1567	run_note_attrib_tests();
1568	run_note_link_tests();
1569	run_note_rename_tests();
1570#if 0
1571	run_note_revoke_tests(); /* Can no longer revoke a regular file--need an unmount test */
1572#endif /* 0 */
1573	run_evfilt_read_tests();
1574	run_evfilt_write_tests();
1575	run_poll_tests();
1576}
1577
1578int
1579main(int argc, char **argv)
1580{
1581	char *which = NULL;
1582	if (argc > 1) {
1583		which = argv[1];
1584	}
1585
1586	if ((!which) || (strcmp(which, "all") == 0))
1587		run_all_tests();
1588	else if (strcmp(which, "delete") == 0)
1589		run_note_delete_tests();
1590	else if (strcmp(which, "write") == 0)
1591		run_note_write_tests();
1592	else if (strcmp(which, "extend") == 0)
1593		run_note_extend_tests();
1594	else if (strcmp(which, "attrib") == 0)
1595		run_note_attrib_tests();
1596	else if (strcmp(which, "link") == 0)
1597		run_note_link_tests();
1598	else if (strcmp(which, "rename") == 0)
1599		run_note_rename_tests();
1600	else if (strcmp(which, "revoke") == 0)
1601		run_note_revoke_tests();
1602	else if (strcmp(which, "evfiltread") == 0)
1603		run_evfilt_read_tests();
1604	else if (strcmp(which, "evfiltwrite") == 0)
1605		run_evfilt_write_tests();
1606	else if (strcmp(which, "poll") == 0)
1607		run_poll_tests();
1608	else {
1609		fprintf(stderr, "Valid options are:\n\tdelete, write, extend,"
1610				"attrib, link, rename, revoke, evfiltread, fifo, all, evfiltwrite<none>\n");
1611		exit(1);
1612	}
1613	return 0;
1614}
1615
1616