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