]> git.saurik.com Git - apple/launchd.git/blob - launchd/testing/missed-EVFILT_READ.c
launchd-258.1.tar.gz
[apple/launchd.git] / launchd / testing / missed-EVFILT_READ.c
1 /*
2 * <rdar://problem/4437060> EVFILT_READ doesn't fire reliably
3 */
4
5 #include <sys/types.h>
6 #include <sys/time.h>
7 #include <sys/event.h>
8 #include <sys/socket.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <unistd.h>
12 #include <fcntl.h>
13 #include <string.h>
14 #include <errno.h>
15
16 static void do_parent(int thefd);
17 static void do_child(int thefd);
18
19 int main(void)
20 {
21 int sp[2];
22
23 if (-1 == socketpair(AF_UNIX, SOCK_STREAM, 0, sp)) {
24 fprintf(stderr, "socketpair(): %s\n", strerror(errno));
25 exit(EXIT_FAILURE);
26 }
27
28 switch (fork()) {
29 case -1:
30 fprintf(stderr, "fork(): %s\n", strerror(errno));
31 exit(EXIT_FAILURE);
32 case 0:
33 close(sp[0]);
34 do_child(sp[1]);
35 break;
36 default:
37 close(sp[1]);
38 do_parent(sp[0]);
39 break;
40 }
41
42 exit(EXIT_SUCCESS);
43 }
44
45 void
46 do_child(int thefd)
47 {
48 char junk = '\0';
49
50 for (;;) {
51 if (-1 == write(thefd, &junk, sizeof(junk))) {
52 fprintf(stderr, "%d: write(): %s\n", __LINE__, strerror(errno));
53 exit(EXIT_FAILURE);
54 }
55 if (-1 == read(thefd, &junk, sizeof(junk))) {
56 fprintf(stderr, "%d: read(): %s\n", __LINE__, strerror(errno));
57 exit(EXIT_FAILURE);
58 }
59 }
60 }
61
62 void
63 do_parent(int thefd)
64 {
65 struct timespec timeout = { 5, 0 };
66 int iter = 0, kq;
67 struct kevent kev;
68 char junk = '\0';
69
70 if (-1 == (kq = kqueue())) {
71 fprintf(stderr, "kqueue(): %s\n", strerror(errno));
72 exit(EXIT_FAILURE);
73 }
74
75 EV_SET(&kev, thefd, EVFILT_READ, EV_ADD, 0, 0, NULL);
76
77 if (-1 == kevent(kq, &kev, 1, NULL, 0, NULL)) {
78 fprintf(stderr, "%d: kevent(): %s\n", __LINE__, strerror(errno));
79 exit(EXIT_FAILURE);
80 }
81
82 for (;;) {
83 switch (kevent(kq, NULL, 0, &kev, 1, &timeout)) {
84 case -1:
85 fprintf(stderr, "%d: kevent(): %s\n", __LINE__, strerror(errno));
86 exit(EXIT_FAILURE);
87 case 0:
88 fprintf(stderr, "After %d iterations, 4437060 still exists!\n", iter);
89 exit(EXIT_FAILURE);
90 case 1:
91 break;
92 default:
93 fprintf(stderr, "kevent should only return -1, 0 or 1 for this case!\n");
94 exit(EXIT_FAILURE);
95 }
96
97 if (kev.filter != EVFILT_READ) {
98 fprintf(stderr, "kevent should return EVFILT_READ!\n");
99 exit(EXIT_FAILURE);
100 }
101
102 if (-1 == read(thefd, &junk, sizeof(junk))) {
103 fprintf(stderr, "read(): %s\n", strerror(errno));
104 exit(EXIT_FAILURE);
105 }
106 if (-1 == write(thefd, &junk, sizeof(junk))) {
107 fprintf(stderr, "%d: write(): %s\n", __LINE__, strerror(errno));
108 exit(EXIT_FAILURE);
109 }
110 iter++;
111 }
112 }