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
101char *TCID = "epoll01";
102int 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		\
141do {					\
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}										\
194kid_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 */
203int 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 * failure. 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
337static 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   failure 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
387int 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 ((int)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							   (int)(sizeof(result_strings) /
653							     sizeof(const char
654								    *))) {
655								/* Returned a result which has no corresponding text description */
656								EPOLL_CTL_TEST_FAIL
657								    ("FIXME FIX ME BUG in Test Program itself!");
658							} else {
659								if (result == -1)	/* Segfault during epoll_ctl call */
660									EPOLL_CTL_TEST_FAIL
661									    ("Test arguments caused abnormal exit.");
662								else	/* The 'normal' failure */
663									EPOLL_CTL_TEST_FAIL
664									    ((result_strings[result]));
665							}
666							num_epoll_ctl_test_fails++;
667#ifdef DEBUG
668						} else	/* The call of epoll_ctl behaved as expected */
669							EPOLL_CTL_TEST_PASS((result_strings[result]));
670#else
671						}
672#endif
673					}
674				}
675			}
676		}
677		close(epoll_fd);
678	}
679
680	tst_resm(TINFO,
681		 "Summary: Of %d tests, epoll_ctl failed %d (%3.0f%% passed).",
682		 num_epoll_ctl_test_calls, num_epoll_ctl_test_fails,
683		 ((float)(num_epoll_ctl_test_calls - num_epoll_ctl_test_fails) *
684		  100.0f / (float)num_epoll_ctl_test_calls));
685	return (num_epoll_ctl_test_fails / num_epoll_ctl_test_calls);
686}
687
688int main(void)
689{
690	int epoll_fd;
691	struct timeval tv;
692	int last_result;
693
694	tst_resm(TINFO, "testing if epoll() system call works");
695
696	/* Get the current time */
697	if (gettimeofday(&tv, NULL) != 0) {
698		tst_brkm(TBROK | TERRNO, NULL, "gettimeofday failed");
699	} else {
700		tst_resm(TINFO, "gettimeofday() works");
701	}
702
703	/* Set up RNG */
704	srand(tv.tv_usec);
705	tst_resm(TINFO,
706		 "random number seeded with gettimeofday() [seed = %ld] works",
707		 tv.tv_usec);
708
709	tst_resm(TINFO, "Testing epoll_create");
710	/* Testing epoll_create with some different sizes */
711	last_result = PROTECT_FUNC(test_epoll_create, -1, NUM_RAND_ATTEMPTS);
712	if (last_result != 0) {
713		/* create test(s) failed */
714	}
715
716	/* Create an epoll_fd for testing epoll_ctl */
717	epoll_fd = epoll_create(BACKING_STORE_SIZE_HINT);
718	if (epoll_fd < 0) {
719		tst_brkm(TFAIL | TERRNO, NULL, "epoll_create failed");
720	}
721
722	tst_resm(TINFO, "Testing epoll_ctl");
723	last_result = PROTECT_FUNC(test_epoll_ctl, -1, epoll_fd);
724	if (last_result != 0) {
725		/* ctl test(s) failed */
726	}
727
728	tst_exit();
729}
730
731#else
732
733int main(void)
734{
735	tst_brkm(TCONF, NULL, "No epoll support found.");
736}
737
738#endif
739