Tizen 2.1 base
[platform/upstream/gcd.git] / kqueue-1.0.4 / test / kevent.c
1 /*
2  * Copyright (c) 2009 Mark Heily <mark@heily.com>
3  *
4  * Permission to use, copy, modify, and distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 #include "common.h"
18
19 extern int kqfd;
20
21 /* Checks if any events are pending, which is an error. */
22 void 
23 test_no_kevents(int kqfd)
24 {
25     int nfds;
26     struct timespec timeo;
27     struct kevent kev;
28
29     memset(&timeo, 0, sizeof(timeo));
30     nfds = kevent(kqfd, NULL, 0, &kev, 1, &timeo);
31     if (nfds < 0)
32         die("kevent(2)");
33     if (nfds > 0) {
34         puts("\nUnexpected event:");
35         die(kevent_to_str(&kev));
36     }
37 }
38
39 /* Retrieve a single kevent */
40 struct kevent *
41 kevent_get(int kqfd)
42 {
43     int nfds;
44     static struct kevent __thread kev;
45
46     nfds = kevent(kqfd, NULL, 0, &kev, 1, NULL);
47     if (nfds < 1)
48         die("kevent(2)");
49
50     return (&kev);
51 }
52
53 char *
54 kevent_fflags_dump(struct kevent *kev)
55 {
56     char *buf;
57
58 #define KEVFFL_DUMP(attrib) \
59     if (kev->fflags & attrib) \
60         strncat(buf, #attrib" ", 64);
61
62     if ((buf = calloc(1, 1024)) == NULL)
63         abort();
64
65     /* Not every filter has meaningful fflags */
66     if (kev->filter != EVFILT_VNODE) {
67         snprintf(buf, 1024, "fflags = %d", kev->fflags);
68         return (buf);
69     }
70
71     snprintf(buf, 1024, "fflags = %d (", kev->fflags);
72     KEVFFL_DUMP(NOTE_DELETE);
73     KEVFFL_DUMP(NOTE_WRITE);
74     KEVFFL_DUMP(NOTE_EXTEND);
75 #if HAVE_NOTE_TRUNCATE
76     KEVFFL_DUMP(NOTE_TRUNCATE);
77 #endif
78     KEVFFL_DUMP(NOTE_ATTRIB);
79     KEVFFL_DUMP(NOTE_LINK);
80     KEVFFL_DUMP(NOTE_RENAME);
81 #if HAVE_NOTE_REVOKE
82     KEVFFL_DUMP(NOTE_REVOKE);
83 #endif
84     buf[strlen(buf) - 1] = ')';
85
86     return (buf);
87 }
88
89 char *
90 kevent_flags_dump(struct kevent *kev)
91 {
92     char *buf;
93
94 #define KEVFL_DUMP(attrib) \
95     if (kev->flags & attrib) \
96         strncat(buf, #attrib" ", 64);
97
98     if ((buf = calloc(1, 1024)) == NULL)
99         abort();
100
101     snprintf(buf, 1024, "flags = %d (", kev->flags);
102     KEVFL_DUMP(EV_ADD);
103     KEVFL_DUMP(EV_ENABLE);
104     KEVFL_DUMP(EV_DISABLE);
105     KEVFL_DUMP(EV_DELETE);
106     KEVFL_DUMP(EV_ONESHOT);
107     KEVFL_DUMP(EV_CLEAR);
108     KEVFL_DUMP(EV_EOF);
109     KEVFL_DUMP(EV_ERROR);
110 #if HAVE_EV_DISPATCH
111     KEVFL_DUMP(EV_DISPATCH);
112 #endif
113 #if HAVE_EV_RECEIPT
114     KEVFL_DUMP(EV_RECEIPT);
115 #endif
116     buf[strlen(buf) - 1] = ')';
117
118     return (buf);
119 }
120
121 /* TODO - backport changes from src/common/kevent.c kevent_dump() */
122 const char *
123 kevent_to_str(struct kevent *kev)
124 {
125     char buf[512];
126
127     snprintf(&buf[0], sizeof(buf), 
128             "[ident=%d, filter=%d, %s, %s, data=%d, udata=%p]",
129             (u_int) kev->ident,
130             kev->filter,
131             kevent_flags_dump(kev),
132             kevent_fflags_dump(kev),
133             (int) kev->data,
134             kev->udata);
135
136     return (strdup(buf));
137 }
138
139 void
140 kevent_update(int kqfd, struct kevent *kev)
141 {
142     if (kevent(kqfd, kev, 1, NULL, 0, NULL) < 0) {
143         printf("Unable to add the following kevent:\n%s\n",
144                 kevent_to_str(kev));
145         die("kevent");
146     }
147 }
148
149 void
150 kevent_add(int kqfd, struct kevent *kev, 
151         uintptr_t ident,
152         short     filter,
153         u_short   flags,
154         u_int     fflags,
155         intptr_t  data,
156         void      *udata)
157 {
158     EV_SET(kev, ident, filter, flags, fflags, data, NULL);    
159     if (kevent(kqfd, kev, 1, NULL, 0, NULL) < 0) {
160         printf("Unable to add the following kevent:\n%s\n",
161                 kevent_to_str(kev));
162         die("kevent");
163     }
164 }
165
166 void
167 kevent_cmp(struct kevent *k1, struct kevent *k2)
168 {
169 /* XXX-
170    Workaround for inconsistent implementation of kevent(2) 
171  */
172 #if defined (__FreeBSD_kernel__) || defined (__FreeBSD__) 
173     if (k1->flags & EV_ADD)
174         k2->flags |= EV_ADD;
175 #endif
176     if (memcmp(k1, k2, sizeof(*k1)) != 0) {
177         printf("kevent_cmp: mismatch:\n  expected %s\n  but got  %s\n", 
178               kevent_to_str(k1), kevent_to_str(k2));
179         abort();
180     }
181 }