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