master
c 289 lines 6.27 KB
Raw
1 /*++
2
3 Copyright (c) Microsoft. All rights reserved.
4
5 Module Name:
6
7 Template.c
8
9 Abstract:
10
11 This file is the poll.
12
13 --*/
14
15 #include "lxtcommon.h"
16 #include "unittests.h"
17 #include <poll.h>
18 #include <signal.h>
19 #include <sys/stat.h>
20 #include <sys/time.h>
21 #include <sys/types.h>
22 #include <unistd.h>
23 #include <fcntl.h>
24 #include <errno.h>
25
26 #define LXT_NAME "Poll"
27
28 int PollVariation0(PLXT_ARGS Args);
29
30 //
31 // Global constants
32 //
33
34 static const LXT_VARIATION g_LxtVariations[] = {{"Poll0", PollVariation0}};
35
36 int PollTestEntry(int Argc, char* Argv[])
37
38 /*++
39 --*/
40
41 {
42
43 LXT_ARGS Args;
44 int Result;
45
46 LxtCheckResult(LxtInitialize(Argc, Argv, &Args, LXT_NAME));
47 LxtCheckResult(LxtRunVariations(&Args, g_LxtVariations, LXT_COUNT_OF(g_LxtVariations)));
48
49 ErrorExit:
50 LxtUninitialize();
51 return !LXT_SUCCESS(Result);
52 }
53
54 int CountFilledDescriptors(struct pollfd* PollDescriptors, int Count)
55 {
56 int NumberFilled;
57 int Index;
58
59 NumberFilled = 0;
60
61 for (Index = 0; Index < Count; Index += 1)
62 {
63
64 if (PollDescriptors[Index].revents != 0)
65 {
66 NumberFilled += 1;
67 }
68 }
69
70 return NumberFilled;
71 }
72
73 int PollVariation0(PLXT_ARGS Args)
74 {
75 int Result;
76 int FileDescriptor1;
77 int FileDescriptor2;
78 struct pollfd PollDescriptors[3];
79 int NumberFilled;
80
81 //
82 // Initialize locals.
83 //
84
85 FileDescriptor1 = -1;
86 FileDescriptor2 = -1;
87
88 //
89 // Open a file that will be used for select.
90 //
91
92 FileDescriptor1 = open("/data/test/poll_test.bin", O_RDWR | O_CREAT, S_IRWXU);
93
94 if (FileDescriptor1 == -1)
95 {
96 Result = errno;
97 LxtLogError("Could not create test file! %d", Result);
98 goto cleanup;
99 }
100
101 FileDescriptor2 = open("/data/test/poll_test.bin", O_RDWR | O_CREAT, S_IRWXU);
102
103 if (FileDescriptor2 == -1)
104 {
105 Result = errno;
106 LxtLogError("Could not create test file! %d", Result);
107 goto cleanup;
108 }
109
110 //
111 // Fill the poll descriptors.
112 //
113
114 PollDescriptors[0].fd = FileDescriptor1;
115 PollDescriptors[0].events = POLLIN;
116 PollDescriptors[0].revents = -1;
117
118 PollDescriptors[1].fd = FileDescriptor2;
119 PollDescriptors[1].events = POLLRDHUP;
120 PollDescriptors[1].revents = -1;
121
122 PollDescriptors[2].fd = 100;
123 PollDescriptors[2].events = POLLOUT;
124 PollDescriptors[2].revents = -1;
125
126 Result = poll(PollDescriptors, 3, 60001);
127
128 if (Result == -1)
129 {
130 Result = errno;
131 LxtLogError("Waiting on poll failed! %d", Result);
132 goto cleanup;
133 }
134
135 if (Result != 2)
136 {
137 LxtLogError("Waiting on poll returned more than 2 events! %d", Result);
138 Result = -1;
139 goto cleanup;
140 }
141
142 NumberFilled = CountFilledDescriptors(PollDescriptors, 3);
143
144 if (NumberFilled != Result)
145 {
146 LxtLogError("Poll returned %d events but filled %d!", Result, NumberFilled);
147 Result = -1;
148 goto cleanup;
149 }
150
151 if (PollDescriptors[2].revents != POLLNVAL)
152 {
153 LxtLogError("Poll descriptor 3 was filled incorrectly!");
154 Result = -1;
155 goto cleanup;
156 }
157
158 NumberFilled = CountFilledDescriptors(PollDescriptors, 3);
159
160 if (NumberFilled != Result)
161 {
162 LxtLogError("Poll returned %d events but filled %d!", Result, NumberFilled);
163 Result = -1;
164 goto cleanup;
165 }
166
167 //
168 // Poll with zero descriptors and it should time out.
169 //
170
171 LxtLogInfo("Wait for 1s for poll to timeout...");
172
173 Result = poll(PollDescriptors, 0, 1000);
174
175 if (Result == -1)
176 {
177 Result = errno;
178 LxtLogError("Waiting on poll failed! %d", Result);
179 goto cleanup;
180 }
181
182 if (Result != 0)
183 {
184 LxtLogError("Waiting on poll returned data but should have timed out! %d", Result);
185 Result = -1;
186 goto cleanup;
187 }
188
189 //
190 // Poll for read/write but get notified of error.
191 //
192
193 read(FileDescriptor2, NULL, 111);
194
195 PollDescriptors[1].fd = FileDescriptor2;
196 PollDescriptors[1].events = POLLIN | POLLOUT;
197 PollDescriptors[1].revents = -1;
198
199 PollDescriptors[2].fd = -FileDescriptor2;
200 PollDescriptors[2].events = POLLIN | POLLOUT;
201 PollDescriptors[2].revents = -1;
202
203 Result = poll(PollDescriptors, 3, -2);
204
205 if (Result == -1)
206 {
207 Result = errno;
208 LxtLogError("Waiting on poll failed! %d", Result);
209 goto cleanup;
210 }
211
212 if (Result != 2)
213 {
214 LxtLogError("Waiting on poll returned more than 2 events! %d", Result);
215 Result = -1;
216 goto cleanup;
217 }
218
219 NumberFilled = CountFilledDescriptors(PollDescriptors, 3);
220
221 if (NumberFilled != Result)
222 {
223 LxtLogError("Poll returned %d events but filled %d!", Result, NumberFilled);
224 Result = -1;
225 goto cleanup;
226 }
227
228 //
229 // Poll for nothing but still got notified of error.
230 //
231
232 PollDescriptors[1].fd = FileDescriptor2;
233 PollDescriptors[1].events = 0;
234 PollDescriptors[1].revents = -1;
235
236 PollDescriptors[2].fd = -FileDescriptor2;
237 PollDescriptors[2].events = POLLIN | POLLOUT;
238 PollDescriptors[2].revents = -1;
239
240 Result = poll(PollDescriptors, 3, -2);
241
242 if (Result == -1)
243 {
244 Result = errno;
245 LxtLogError("Waiting on poll failed! %d", Result);
246 goto cleanup;
247 }
248
249 if (Result != 1)
250 {
251 LxtLogError("Waiting on poll returned more than 1 events! %d", Result);
252 Result = -1;
253 goto cleanup;
254 }
255
256 NumberFilled = CountFilledDescriptors(PollDescriptors, 3);
257
258 if (NumberFilled != Result)
259 {
260 LxtLogError("Poll returned %d events but filled %d!", Result, NumberFilled);
261 Result = -1;
262 goto cleanup;
263 }
264
265 NumberFilled = CountFilledDescriptors(PollDescriptors, 1);
266
267 if (NumberFilled != Result)
268 {
269 LxtLogError("Poll returned %d events but filled %d!", Result, NumberFilled);
270 Result = -1;
271 goto cleanup;
272 }
273
274 Result = LXT_RESULT_SUCCESS;
275
276 cleanup:
277
278 if (FileDescriptor1 != -1)
279 {
280 close(FileDescriptor1);
281 }
282
283 if (FileDescriptor2 != -1)
284 {
285 close(FileDescriptor2);
286 }
287
288 return Result;
289 }