• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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