1 /*
2 *
3 * Copyright (c) International Business Machines Corp., 2001
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13 * the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 *
19 */
20
21 /******************************************************************************
22
23 File: epoll-ltp.c
24
25 Description:
26 Test the epoll_* system calls. This test program attempts to
27 be very thorough in exercising epoll_* system calls. Large
28 combinations of valid and invalid parameters are passed with
29 valid and invalid sequences. Due to the combinatorial nature
30 of this test program the test may take a "long" time to
31 execute.
32
33 Total Tests: 2 (2 system calls are being tested for)
34
35 Test Name: epoll_create, epoll_ctl
36
37 Test Assertion
38 & Strategy: Test a variety of incorrect parameters for epoll_create
39
40 Then run a reasonable epoll_create and get a fd for the epoll
41 set.
42
43 Next run epoll_ctl on that fd (epoll_fd) with a variety of
44 incorrect parameters and a couple correct ones.
45
46 Finally ?How to thoroughly test epoll_wait?
47
48 Author: Matt Helsley <matthltc@us.ibm.com>
49
50 History: Created - May 22 2003 - Matt Helsley <matthltc@us.ibm.com>
51 Added -
52
53 Notes: Currently we assume that the OS will never allocate an fd s.t.
54 fd == INT_MAX and that it will instead choose to allocate fds
55 from the "low" numbers. -MH
56
57 Currently pokes epoll_create several times in 2 + NUM_RAND_ATTEMPTS ways
58 pokes epoll_ctl 27648 - (2 + NUM_RAND_ATTEMPTS) ways
59 does not poke epoll_wait
60
61 TODO: change errno test code to build lists of possible errno values for
62 each erroneous parameter. Check that the errno value is in one
63 of the lists. Currently errno is not checked at all when multiple
64 erroneous parameters are passed in.
65
66 test epoll_ctl with a large number of file descriptor events in the
67 set
68
69 Link against epoll and ltp (-lepoll -lltp)
70
71 *******************************************************************************/
72
73 #ifndef _GNU_SOURCE
74 #define _GNU_SOURCE
75 #endif
76
77 #include <stdio.h>
78 #include <stdlib.h>
79 #include <unistd.h>
80 #include <fcntl.h>
81 #include <stdarg.h>
82 #include <string.h>
83 #include <signal.h>
84 #include <assert.h>
85 #include <limits.h>
86 #include <ctype.h>
87 #include <time.h>
88 #include <errno.h>
89 #include <signal.h>
90 #include <sys/types.h>
91 #include <sys/time.h>
92 #include <sys/file.h>
93 #include <sys/ioctl.h>
94 #include <sys/mman.h>
95 #include <sys/select.h>
96 #include <sys/wait.h>
97
98 #include "config.h"
99 #include "test.h"
100
101 char *TCID = "epoll01";
102 int TST_TOTAL = 1;
103
104 #ifdef HAVE_SYS_EPOLL_H
105
106 #include <sys/epoll.h>
107
108 /* Local Defines */
109 #if !defined(TRUE) && !defined(FALSE)
110 #define TRUE 1
111 #define FALSE 0
112 #endif
113
114 #define NUM_RAND_ATTEMPTS 16
115 #define BACKING_STORE_SIZE_HINT 32
116
117 /*
118 Define the beginning of a "protected region".
119 This is a region where a wide variety of errors
120 could occur or signals could arrive (including
121 SIGSEGV and SIGKILL).
122 $
123 The test program uses this to catch those
124 conditions as best it can and continue testing.
125
126 The region MUST be marked by a corresponding
127 PROTECT_REGION_END.
128
129 DO NOT nest protected regions! i.e. Do not build
130 code of the form:
131
132 PROTECT_REGION_START
133 ...
134 PROTECT_REGION_START
135 ...
136 PROTECT_REGION_END
137 ...
138 PROTECT_REGION_END
139 */
140 #define PROTECT_REGION_START \
141 do { \
142 pid_t kid_pid; \
143 int kid_status; \
144 \
145 tst_old_flush(); \
146 kid_pid = FORK_OR_VFORK(); \
147 if (kid_pid == 0) {
148
149 #define PROTECT_REGION_EXIT(errval) return (errval);
150
151 #define PROTECT_REGION_END(result, errval) \
152 return 0; \
153 } else { \
154 waitpid(kid_pid, &kid_status, 0); \
155 if (WIFEXITED(kid_status)) { \
156 (result) = WEXITSTATUS(kid_status); \
157 } else { /* Must have been signaled */ \
158 (result) = (errval); \
159 if (WIFSIGNALED(kid_status)) \
160 tst_resm(TFAIL, "Protected function test exited due to signal %d (%s)", \
161 WTERMSIG(kid_status), strsignal(WTERMSIG(kid_status))); \
162 } \
163 } \
164 } while (0)
165
166 /*
167 * Call a function in a "protected" context.
168 * This protects the test program proper from segfaults
169 * and allows for the extraction of an integer return
170 * code.
171 *
172 * return only integer results.
173 */
174 #define PROTECT_FUNC(fn, errval, epoll_fd) ( \
175 { \
176 pid_t kid_pid; \
177 int kid_status; \
178 \
179 tst_old_flush(); \
180 kid_pid = FORK_OR_VFORK(); \
181 if (kid_pid == 0) { /* Run the function */ \
182 return fn(epoll_fd); \
183 } else { \
184 waitpid(kid_pid, &kid_status, 0); \
185 if (WIFEXITED(kid_status)) { \
186 kid_status = WEXITSTATUS(kid_status); \
187 } else { /* Must have been signaled */ \
188 kid_status = (errval); \
189 if (WIFSIGNALED(kid_status)) \
190 tst_resm(TFAIL, "Protected function test exited due to signal %d (%s)", \
191 WTERMSIG(kid_status), strsignal(WTERMSIG(kid_status))); \
192 } \
193 } \
194 kid_status = kid_status;})
195
196 /*
197 * Given the number of random size requests to test,
198 * test various boundary cases of epoll_create().
199 *
200 * Return the number of tests that failed. 0 indicates
201 * 100% passed.
202 */
test_epoll_create(unsigned int num_rand_attempts)203 int test_epoll_create(unsigned int num_rand_attempts)
204 {
205 int epoll_fd = -1;
206 int fd_set_size = -1;
207 unsigned int attempt_count;
208 unsigned int num_epoll_create_test_fails = 0;
209 unsigned int num_epoll_create_test_calls = 0;
210
211 /* Negative set sizes */
212 errno = 0;
213 fd_set_size = -1;
214 num_epoll_create_test_calls++;
215 epoll_fd = epoll_create(fd_set_size);
216 if (epoll_fd >= 0) {
217 tst_resm(TFAIL | TERRNO,
218 "epoll_create with negative set size succeeded unexpectedly");
219 num_epoll_create_test_fails++;
220 close(epoll_fd);
221 } else {
222 if (errno != EINVAL) {
223 tst_resm(TFAIL | TERRNO,
224 "epoll_create with negative set size didn't set errno to EINVAL");
225 num_epoll_create_test_fails++;
226 } else {
227 tst_resm(TPASS, "epoll_create with negative set size");
228 }
229 }
230
231 /* Large set sizes -- try several less than or equal to INT_MAX by some
232 small amount (expect num_rand_attempts to be approximately the
233 amount we'd like to go below INT_MAX). */
234 fd_set_size = INT_MAX;
235 for (attempt_count = num_rand_attempts; attempt_count > 0;
236 attempt_count--, fd_set_size--) {
237 num_epoll_create_test_calls++;
238 epoll_fd = epoll_create(fd_set_size);
239 if (epoll_fd == -1) {
240 if (errno != ENOMEM) {
241 tst_resm(TFAIL,
242 "epoll_create with large set size (size = %d)",
243 fd_set_size);
244 num_epoll_create_test_fails++;
245 } else {
246 tst_resm(TPASS,
247 "epoll_create with large set size (size = %d)",
248 fd_set_size);
249 }
250 } else {
251 tst_resm(TPASS,
252 "epoll_create with large set size (size = %d)",
253 fd_set_size);
254 close(epoll_fd);
255 }
256 }
257
258 /* Random large set sizes */
259 for (attempt_count = num_rand_attempts; attempt_count > 0;
260 attempt_count--) {
261 fd_set_size = abs(rand() + SHRT_MAX) % INT_MAX;
262 errno = 0;
263 num_epoll_create_test_calls++;
264 epoll_fd = epoll_create(fd_set_size);
265 if (epoll_fd < 0) {
266 if (errno != ENOMEM) {
267 tst_resm(TFAIL,
268 "epoll_create with random random large set size (size = %d)",
269 fd_set_size);
270 num_epoll_create_test_fails++;
271 } else {
272 tst_resm(TPASS,
273 "epoll_create with random random large set size (size = %d)",
274 fd_set_size);
275 }
276 } else {
277 tst_resm(TPASS,
278 "epoll_create with random large set size (size = %d)",
279 fd_set_size);
280 close(epoll_fd);
281 }
282 }
283
284 tst_resm(TINFO,
285 "Summary: Of %d tests, epoll_create failed %d (%3.0f%% passed).",
286 num_epoll_create_test_calls, num_epoll_create_test_fails,
287 ((float)
288 (num_epoll_create_test_calls - num_epoll_create_test_fails)
289 * 100.0f / (float)
290 num_epoll_create_test_calls));
291 /* Return 0 on success. */
292
293 return num_epoll_create_test_fails;
294 }
295
296 /* RES_PASS indicates a PASS result */
297 #define RES_PASS 0
298
299 /*
300 * RES_FAIL_* indicates a FAIL result
301 * In brief, there are two things that can go wrong in a
302 * failiure. The return value (result = epoll_ctl(...)) and
303 * the errno value may not match expectations. In this notation,
304 * MIS -> mismatch, MAT -> match, BAD -> bad, and IGN -> ignored.
305 *
306 * RETV_MIS_* indicates the return value was either 0 or 1, but did
307 * not match the expected return value
308 *
309 * _RETV_MAT_* indicates that the return value was 0 xor 1 and did
310 * match the expected value
311 *
312 *_RETV_BAD_* the return value was neither 0 nor 1.
313 *_ERRNO_MAT the error number matched the expected number
314 *_ERRNO_MIS the error number did not match the expected number
315 *_ERRNO_IGN no error number was expected and so errno was ignored
316 *
317 * Keep these values below 256 as only 1 byte gets passed as a
318 * return value for the process. Note that RES_PASS is 0 which
319 * LTP interprets as a PASS.
320 */
321
322 /* Did not get the expected return value, but errno value was expected */
323 #define RES_FAIL_RETV_MIS_ERRNO_MAT 1
324 /* Did not get the expected return value, but errno value was expected */
325 #define RES_FAIL_RETV_BAD_ERRNO_MAT 2
326 /* Did get the expected return value, and errno value was not expected */
327 #define RES_FAIL_RETV_MAT_ERRNO_MIS 3
328 /* Return value was neither 0 nor -1. Mismatch in value of errno */
329 #define RES_FAIL_RETV_BAD_ERRNO_MIS 4
330 /* Did not get the expected return value and errno is irrelevant */
331 #define RES_FAIL_RETV_MIS_ERRNO_IGN 5
332 /* Return value was neither 0 nor -1. value of errno is irrelevant */
333 #define RES_FAIL_RETV_BAD_ERRNO_IGN 6
334 /* We expected multiple errors so we were unable to check errno for conformance */
335 #define RES_PASS_RETV_MAT_ERRNO_IGN 7
336
337 static const char *result_strings[] = {
338 "Passed",
339 "Return value mismatched yet errno matched.",
340 "Return value was bad yet errno matched.",
341 "Return value matched yet errno mismatched.",
342 "Return value was bad and errno mismatched.",
343 "Return value mismatched so errno ignored.",
344 "Return value was bad so errno ignored.",
345 "Return value matched but errno ignored. (multiple errors expected)"
346 };
347
348 /****************************************************************************************/
349 /* This macro helps keep the code below understandable. It prints out the
350 failiure message passed to it plus the parameters to the system call. */
351 #define EPOLL_CTL_TEST_RESULTS_SHOW_PARAMS 1
352 #if EPOLL_CTL_TEST_RESULTS_SHOW_PARAMS
353 #define EPOLL_CTL_TEST_FAIL(msg , ...) \
354 ({ \
355 if (ev_ptr != NULL) { \
356 tst_resm(TFAIL, ( "(epoll_ctl(%d,%08x,%d,%p = {%08x,%08d}) returned %d:%s)" ) , ##__VA_ARGS__ , \
357 epoll_fds[epfd_index], epoll_ctl_ops[op_index], \
358 epoll_fds[fd_index], ev_ptr, ev_ptr->events, ev_ptr->data.fd, errno, \
359 strerror(errno)); \
360 } else { \
361 tst_resm(TFAIL, ( "(epoll_ctl(%d,%08x,%d,%p) returned %d:%s)" ) , ##__VA_ARGS__ , \
362 epoll_fds[epfd_index], epoll_ctl_ops[op_index], \
363 epoll_fds[fd_index], ev_ptr, errno, strerror(errno)); \
364 } \
365 })
366
367 #define EPOLL_CTL_TEST_PASS(msg , ...) \
368 ({ \
369 if (ev_ptr != NULL) { \
370 tst_resm(TPASS, ( "(epoll_ctl(%d,%08x,%d,%p = {%08x,%08d}) returned %d:%s)" ) , ##__VA_ARGS__ , \
371 epoll_fds[epfd_index], epoll_ctl_ops[op_index], \
372 epoll_fds[fd_index], ev_ptr, ev_ptr->events, ev_ptr->data.fd, errno, \
373 strerror(errno)); \
374 } else { \
375 tst_resm(TPASS, ( "(epoll_ctl(%d,%08x,%d,%p) returned %d:%s)" ) , ##__VA_ARGS__ , \
376 epoll_fds[epfd_index], epoll_ctl_ops[op_index], \
377 epoll_fds[fd_index], ev_ptr, errno, strerror(errno)); \
378 } \
379 })
380 #else
381 #define EPOLL_CTL_TEST_FAIL(msg , ...) tst_resm(TFAIL, msg , ##__VA_ARGS__)
382 #define EPOLL_CTL_TEST_PASS(msg , ...) tst_resm(TPASS, msg , ##__VA_ARGS__)
383 #endif
384
385 /****************************************************************************************/
386
test_epoll_ctl(int epoll_fd)387 int test_epoll_ctl(int epoll_fd)
388 {
389 int fds[] = { -1, INT_MAX };
390 int epoll_fds[] = { 0, -1, 0, INT_MAX };
391 int epoll_events[64];
392 /* The list of operations to try AND THE ORDER THEY ARE TRIED IN */
393 int epoll_ctl_ops[] =
394 { EPOLL_CTL_DEL, EPOLL_CTL_MOD, EPOLL_CTL_ADD, EPOLL_CTL_MOD,
395 EPOLL_CTL_DEL, EPOLL_CTL_MOD, EPOLL_CTL_DEL, INT_MAX, -1
396 };
397 struct epoll_event event;
398 char event_mem[sizeof(struct epoll_event) * 2];
399 struct epoll_event *unaligned_event_ptr;
400
401 /* Indices into lists */
402 int index = 0; /* multi-use index. First uses are to initialize
403 lists. Second use is to iterate over the implicit
404 list of structs to pass in */
405 unsigned int epfd_index; /* index into fd list for the epfd parameter */
406 unsigned int event_index; /* index into event list for the events field of the
407 struct epoll_event parameter */
408 unsigned int fd_index; /* index into fd list for the fd parameter */
409 unsigned int op_index; /* index into the list of operations for the op
410 parameter */
411 unsigned int num_epoll_ctl_test_fails = 0;
412 unsigned int num_epoll_ctl_test_calls = 0;
413
414 /* Generate all possible combinations of events (2^6 == 64)
415 Assume we know nothing about the EPOLL event types _except_
416 that they describe bits in a set. */
417 for (index = 0; index < 64; index++) {
418 epoll_events[index] = ((EPOLLIN * ((index & 0x01) >> 0)) |
419 (EPOLLOUT * ((index & 0x02) >> 1)) |
420 (EPOLLPRI * ((index & 0x04) >> 2)) |
421 (EPOLLERR * ((index & 0x08) >> 3)) |
422 (EPOLLHUP * ((index & 0x10) >> 4)) |
423 (EPOLLET * ((index & 0x20) >> 5)));
424 }
425
426 /* Get a pointer to an unaligned struct epoll_event */
427 {
428 char *unalign_ptr = event_mem;
429
430 unalign_ptr =
431 unalign_ptr + (((unsigned long)unalign_ptr & 1) ? 0 : 1);
432 unaligned_event_ptr = (struct epoll_event *)unalign_ptr;
433 }
434
435 /* One of the fds we want to test is the valid one */
436 epoll_fds[0] = epoll_fd;
437
438 /* Test out all of the interesting combinations. This is going to
439 take a while (in compute cycles). It took less than 1 minute to
440 run on a PIII 500 without checking the results. */
441 for (index = 0; index < 3; index++) {
442 struct epoll_event *ev_ptr = NULL;
443
444 switch (index) {
445 case 0: /* Pass aligned struct */
446 event.data.u64 = 0;
447 ev_ptr = &event;
448 break;
449 case 1: /* Pass unaligned struct */
450 unaligned_event_ptr->data.u64 = 0;
451 ev_ptr = unaligned_event_ptr;
452 break;
453 case 2:
454 default: /* Pass NULL ptr */
455 ev_ptr = NULL;
456 break;
457 }
458
459 for (epfd_index = 0;
460 epfd_index < (sizeof(epoll_fds) / sizeof(int));
461 epfd_index++) {
462 for (event_index = 0;
463 event_index < (sizeof(epoll_events) / sizeof(int));
464 event_index++) {
465 for (fd_index = 0;
466 fd_index < (sizeof(fds) / sizeof(int));
467 fd_index++) {
468 /* Now epoll_fd is a descriptor that references the set of
469 file descriptors we are interested in. Next we test epoll_ctl */
470 for (op_index = 0;
471 op_index <
472 (sizeof(epoll_ctl_ops) /
473 sizeof(int)); op_index++) {
474 int result;
475 int expected_errno = 0;
476 int num_errors_expected = 0;
477
478 if (ev_ptr != NULL)
479 ev_ptr->events =
480 epoll_events
481 [event_index];
482
483 /* Perform the call itself. Put it in a protected region which
484 returns -1 in the variable result if a protection violation
485 occurs (see PROTECT_REGION_END for the result) */
486 PROTECT_REGION_START errno = 0;
487
488 /* NOTE that we are assuming that epoll will operate across
489 a fork() call such that a subsequent fork() in the parent
490 will also manipulate the same set */
491 result =
492 epoll_ctl(epoll_fds
493 [epfd_index],
494 epoll_ctl_ops
495 [op_index],
496 fds[fd_index],
497 ev_ptr);
498
499 /* We can't test errno resulting from the epoll_ctl call outside of
500 the PROTECT_REGION hence we do not have a PROTECT_REGION_END
501 here */
502
503 /*
504 Test the results. Look for appropriate error conditions
505 */
506
507 /* Check the epfd */
508 if (epoll_fds[epfd_index] !=
509 epoll_fd) {
510 /* Expect an error */
511 if (epoll_fds
512 [epfd_index] == 0)
513 expected_errno =
514 EINVAL;
515 else /* epfd is not a valid file descriptor since it is
516 neither epoll_fd nor stdin */
517 expected_errno =
518 EBADF;
519 num_errors_expected++;
520 }
521
522 switch (epoll_ctl_ops[op_index]) {
523 case EPOLL_CTL_ADD:
524 case EPOLL_CTL_MOD:
525 case EPOLL_CTL_DEL:
526 break;
527 default: /* Expect an error */
528 expected_errno = EINVAL;
529 num_errors_expected++;
530 break;
531 }
532
533 expected_errno = EPERM;
534 num_errors_expected++;
535
536 if (ev_ptr == NULL) {
537 expected_errno = EINVAL;
538 num_errors_expected++;
539 } else if ((ev_ptr == &event)
540 || (ev_ptr ==
541 unaligned_event_ptr))
542 {
543 if (ev_ptr->events == 0) {
544 expected_errno =
545 EINVAL;
546 num_errors_expected++;
547 }
548
549 for (index = 1;
550 index < 64;
551 index++) {
552 if (ev_ptr->events != epoll_events[index]) {
553 expected_errno
554 =
555 EINVAL;
556 num_errors_expected++;
557 }
558 }
559 } else {
560 /* Do not expect an error */
561 }
562
563 if (num_errors_expected == 0) {
564 /* We did not expect an error */
565 if (result == 0) {
566 /* We didn't get an error. Think of this as RES_PASS_RETV_MAT_ERRNO_IGN */
567 return RES_PASS;
568 } else if (result == -1) { /* The return value is -1, so it's not bad */
569 return
570 RES_FAIL_RETV_MIS_ERRNO_IGN;
571 } else {
572 return
573 RES_FAIL_RETV_BAD_ERRNO_IGN;
574 }
575 } else if (num_errors_expected
576 == 1) {
577 /* We expected an error */
578 if (result == 0) {
579 return RES_FAIL_RETV_MIS_ERRNO_IGN; /* Unexpected success */
580 } else if (result == -1) {
581 /* We got an error. Check errno */
582 if (errno ==
583 expected_errno)
584 {
585 return RES_PASS; /* think of this as RETV_MAT_ERRNO_MAT */
586 } else {
587 return
588 RES_FAIL_RETV_MAT_ERRNO_MIS;
589 }
590 } else {
591 /* We got a bad return code! Interpret this as
592 getting an error and check errno. */
593 if (errno ==
594 expected_errno)
595 return
596 RES_FAIL_RETV_BAD_ERRNO_MAT;
597 else
598 return
599 RES_FAIL_RETV_BAD_ERRNO_MIS;
600 }
601 } else if (num_errors_expected >
602 1) {
603 /* We expected multiple errors */
604 if (result == 0) {
605 return RES_FAIL_RETV_MIS_ERRNO_IGN; /* Unexpected success */
606 } else if (result == -1) {
607 /* We got an error. Check errno */
608 if (errno ==
609 expected_errno)
610 {
611 return RES_PASS; /* think of this as RETV_MAT_ERRNO_MAT */
612 } else {
613 /* Ignore errno because the desired value is unknowable
614 without looking at the structure of the code. */
615 return
616 RES_PASS_RETV_MAT_ERRNO_IGN;
617 }
618 } else {
619 /* We got a bad return code! Interpret this as
620 getting an error and check errno. */
621 if (errno ==
622 expected_errno)
623 /* Don't Ignore errno because the desired value
624 happened to match what we expected. */
625 return
626 RES_FAIL_RETV_BAD_ERRNO_MAT;
627 else
628 /* Ignore errno because the desired value is unknowable
629 without looking at the structure of the code. */
630 return
631 RES_FAIL_RETV_BAD_ERRNO_IGN;
632 }
633 }
634
635 /* All "return"s between PROTECT_REGION_BEGIN
636 and PROTECT_REGION_END place their value in
637 the result parameter. If the region caused
638 a protection violation (segfault or otherwise)
639 then the result is set to the second parameter's
640 value (-1 in this case). */
641 PROTECT_REGION_END(result, -1);
642
643 /* Count the number of tests run */
644 num_epoll_ctl_test_calls++;
645
646 /* Now test the result */
647 if (!((result == RES_PASS)
648 || (result ==
649 RES_PASS_RETV_MAT_ERRNO_IGN)))
650 {
651 if (result >
652 (sizeof
653 (result_strings) /
654 sizeof(const char
655 *))) {
656 /* Returned a result which has no corresponding text description */
657 EPOLL_CTL_TEST_FAIL
658 ("FIXME FIX ME BUG in Test Program itself!");
659 } else {
660 if (result == -1) /* Segfault during epoll_ctl call */
661 EPOLL_CTL_TEST_FAIL
662 ("Test arguments caused abnormal exit.");
663 else /* The 'normal' failiure */
664 EPOLL_CTL_TEST_FAIL
665 ((result_strings[result]));
666 }
667 num_epoll_ctl_test_fails++;
668 #ifdef DEBUG
669 } else /* The call of epoll_ctl behaved as expected */
670 EPOLL_CTL_TEST_PASS((result_strings[result]));
671 #else
672 }
673 #endif
674 }
675 }
676 }
677 }
678 close(epoll_fd);
679 }
680
681 tst_resm(TINFO,
682 "Summary: Of %d tests, epoll_ctl failed %d (%3.0f%% passed).",
683 num_epoll_ctl_test_calls, num_epoll_ctl_test_fails,
684 ((float)(num_epoll_ctl_test_calls - num_epoll_ctl_test_fails) *
685 100.0f / (float)num_epoll_ctl_test_calls));
686 return (num_epoll_ctl_test_fails / num_epoll_ctl_test_calls);
687 }
688
main(int argc,char ** argv)689 int main(int argc, char **argv)
690 {
691 int epoll_fd;
692 struct timeval tv;
693 int last_result;
694
695 tst_resm(TINFO, "testing if epoll() system call works");
696
697 /* Get the current time */
698 if (gettimeofday(&tv, NULL) != 0) {
699 tst_brkm(TBROK | TERRNO, NULL, "gettimeofday failed");
700 } else {
701 tst_resm(TINFO, "gettimeofday() works");
702 }
703
704 /* Set up RNG */
705 srand(tv.tv_usec);
706 tst_resm(TINFO,
707 "random number seeded with gettimeofday() [seed = %ld] works",
708 tv.tv_usec);
709
710 tst_resm(TINFO, "Testing epoll_create");
711 /* Testing epoll_create with some different sizes */
712 last_result = PROTECT_FUNC(test_epoll_create, -1, NUM_RAND_ATTEMPTS);
713 if (last_result != 0) {
714 /* create test(s) failed */
715 }
716
717 /* Create an epoll_fd for testing epoll_ctl */
718 epoll_fd = epoll_create(BACKING_STORE_SIZE_HINT);
719 if (epoll_fd < 0) {
720 tst_brkm(TFAIL | TERRNO, NULL, "epoll_create failed");
721 }
722
723 tst_resm(TINFO, "Testing epoll_ctl");
724 last_result = PROTECT_FUNC(test_epoll_ctl, -1, epoll_fd);
725 if (last_result != 0) {
726 /* ctl test(s) failed */
727 }
728
729 tst_exit();
730 }
731
732 #else
733
main(void)734 int main(void)
735 {
736 tst_brkm(TCONF, NULL, "No epoll support found.");
737 }
738
739 #endif
740