]> git.saurik.com Git - apple/launchd.git/blame - launchd/testing/missed-EVFILT_READ.c
launchd-392.39.tar.gz
[apple/launchd.git] / launchd / testing / missed-EVFILT_READ.c
CommitLineData
ed34e3c3
A
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
16static void do_parent(int thefd);
17static void do_child(int thefd);
18
19int 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
45void
46do_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
62void
63do_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}