subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 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 |
Wanlong Gao | 4548c6c | 2012-10-19 18:03:36 +0800 | [diff] [blame] | 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 18 | * |
| 19 | */ |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 20 | |
| 21 | /****************************************************************************** |
| 22 | |
| 23 | File: epoll-ltp.c |
| 24 | |
| 25 | Description: |
| 26 | Test the epoll_* system calls. This test program attempts to |
subrata_modak | 4bb656a | 2009-02-26 12:02:09 +0000 | [diff] [blame] | 27 | be very thorough in exercising epoll_* system calls. Large |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 28 | combinations of valid and invalid parameters are passed with |
| 29 | valid and invalid sequences. Due to the combinatorial nature |
subrata_modak | 4bb656a | 2009-02-26 12:02:09 +0000 | [diff] [blame] | 30 | of this test program the test may take a "long" time to |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 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> |
subrata_modak | 4bb656a | 2009-02-26 12:02:09 +0000 | [diff] [blame] | 51 | Added - |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 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 | *******************************************************************************/ |
vapier | 7f40cfd | 2006-08-21 06:47:15 +0000 | [diff] [blame] | 72 | |
| 73 | #ifndef _GNU_SOURCE |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 74 | #define _GNU_SOURCE |
vapier | 7f40cfd | 2006-08-21 06:47:15 +0000 | [diff] [blame] | 75 | #endif |
| 76 | |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 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 | |
subrata_modak | c81d7b9 | 2009-09-09 17:48:08 +0000 | [diff] [blame] | 98 | #include "config.h" |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 99 | #include "test.h" |
subrata_modak | c81d7b9 | 2009-09-09 17:48:08 +0000 | [diff] [blame] | 100 | |
czhang@redhat.com | f8df4b5 | 2011-03-30 22:32:35 +0800 | [diff] [blame] | 101 | char *TCID = "epoll01"; |
| 102 | int TST_TOTAL = 1; |
subrata_modak | c81d7b9 | 2009-09-09 17:48:08 +0000 | [diff] [blame] | 103 | |
| 104 | #ifdef HAVE_SYS_EPOLL_H |
| 105 | |
| 106 | #include <sys/epoll.h> |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 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 | |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 117 | /* |
| 118 | Define the beginning of a "protected region". |
| 119 | This is a region where a wide variety of errors |
subrata_modak | 4bb656a | 2009-02-26 12:02:09 +0000 | [diff] [blame] | 120 | could occur or signals could arrive (including |
| 121 | SIGSEGV and SIGKILL). |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 122 | $ |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 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 |
subrata_modak | 4bb656a | 2009-02-26 12:02:09 +0000 | [diff] [blame] | 127 | PROTECT_REGION_END. |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 128 | |
| 129 | DO NOT nest protected regions! i.e. Do not build |
| 130 | code of the form: |
| 131 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 132 | PROTECT_REGION_START |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 133 | ... |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 134 | PROTECT_REGION_START |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 135 | ... |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 136 | PROTECT_REGION_END |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 137 | ... |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 138 | PROTECT_REGION_END |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 139 | */ |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 140 | #define PROTECT_REGION_START \ |
| 141 | do { \ |
| 142 | pid_t kid_pid; \ |
| 143 | int kid_status; \ |
| 144 | \ |
| 145 | tst_flush(); \ |
| 146 | kid_pid = FORK_OR_VFORK(); \ |
| 147 | if (kid_pid == 0) { |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 148 | |
| 149 | #define PROTECT_REGION_EXIT(errval) return (errval); |
| 150 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 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 exitted due to signal %d (%s)", \ |
| 161 | WTERMSIG(kid_status), strsignal(WTERMSIG(kid_status))); \ |
| 162 | } \ |
| 163 | } \ |
Garrett Cooper | df3eb16 | 2010-11-28 22:44:32 -0800 | [diff] [blame] | 164 | } while (0) |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 165 | |
| 166 | /* |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 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. |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 173 | */ |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 174 | #define PROTECT_FUNC(fn, errval, epoll_fd) ( \ |
| 175 | { \ |
| 176 | pid_t kid_pid; \ |
| 177 | int kid_status; \ |
| 178 | \ |
| 179 | tst_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 exitted due to signal %d (%s)", \ |
| 191 | WTERMSIG(kid_status), strsignal(WTERMSIG(kid_status))); \ |
| 192 | } \ |
| 193 | } \ |
| 194 | kid_status = kid_status;}) |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 195 | |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 196 | /* |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 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. |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 202 | */ |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 203 | int test_epoll_create(unsigned int num_rand_attempts) |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 204 | { |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 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; |
mridge | 98988cb | 2004-08-11 19:06:57 +0000 | [diff] [blame] | 210 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 211 | /* Negative set sizes */ |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 212 | errno = 0; |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 213 | fd_set_size = -1; |
mridge | 98988cb | 2004-08-11 19:06:57 +0000 | [diff] [blame] | 214 | num_epoll_create_test_calls++; |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 215 | epoll_fd = epoll_create(fd_set_size); |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 216 | if (epoll_fd >= 0) { |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 217 | tst_resm(TFAIL | TERRNO, |
Garrett Cooper | 5374050 | 2010-12-16 00:04:01 -0800 | [diff] [blame] | 218 | "epoll_create with negative set size succeeded unexpectedly"); |
mridge | 98988cb | 2004-08-11 19:06:57 +0000 | [diff] [blame] | 219 | num_epoll_create_test_fails++; |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 220 | close(epoll_fd); |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 221 | } else { |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 222 | if (errno != EINVAL) { |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 223 | tst_resm(TFAIL | TERRNO, |
Garrett Cooper | 5374050 | 2010-12-16 00:04:01 -0800 | [diff] [blame] | 224 | "epoll_create with negative set size didn't set errno to EINVAL"); |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 225 | num_epoll_create_test_fails++; |
| 226 | } else { |
| 227 | tst_resm(TPASS, "epoll_create with negative set size"); |
| 228 | } |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 229 | } |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 230 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 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; |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 235 | for (attempt_count = num_rand_attempts; attempt_count > 0; |
| 236 | attempt_count--, fd_set_size--) { |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 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, |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 252 | "epoll_create with large set size (size = %d)", |
| 253 | fd_set_size); |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 254 | close(epoll_fd); |
| 255 | } |
| 256 | } |
mridge | 98988cb | 2004-08-11 19:06:57 +0000 | [diff] [blame] | 257 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 258 | /* Random large set sizes */ |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 259 | for (attempt_count = num_rand_attempts; attempt_count > 0; |
| 260 | attempt_count--) { |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 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).", |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 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)); |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 291 | /* Return 0 on success. */ |
| 292 | |
| 293 | return num_epoll_create_test_fails; |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 294 | } |
| 295 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 296 | /* RES_PASS indicates a PASS result */ |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 297 | #define RES_PASS 0 |
| 298 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 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 | */ |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 321 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 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 |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 336 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 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)" |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 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 , ...) \ |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 354 | ({ \ |
Garrett Cooper | df3eb16 | 2010-11-28 22:44:32 -0800 | [diff] [blame] | 355 | if (ev_ptr != NULL) { \ |
vapier | df90996 | 2009-08-28 12:19:26 +0000 | [diff] [blame] | 356 | tst_resm(TFAIL, ( "(epoll_ctl(%d,%08x,%d,%p = {%08x,%08d}) returned %d:%s)" ) , ##__VA_ARGS__ , \ |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 357 | epoll_fds[epfd_index], epoll_ctl_ops[op_index], \ |
subrata_modak | c81d7b9 | 2009-09-09 17:48:08 +0000 | [diff] [blame] | 358 | epoll_fds[fd_index], ev_ptr, ev_ptr->events, ev_ptr->data.fd, errno, \ |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 359 | strerror(errno)); \ |
| 360 | } else { \ |
vapier | df90996 | 2009-08-28 12:19:26 +0000 | [diff] [blame] | 361 | tst_resm(TFAIL, ( "(epoll_ctl(%d,%08x,%d,%p) returned %d:%s)" ) , ##__VA_ARGS__ , \ |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 362 | epoll_fds[epfd_index], epoll_ctl_ops[op_index], \ |
| 363 | epoll_fds[fd_index], ev_ptr, errno, strerror(errno)); \ |
| 364 | } \ |
| 365 | }) |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 366 | |
| 367 | #define EPOLL_CTL_TEST_PASS(msg , ...) \ |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 368 | ({ \ |
Garrett Cooper | df3eb16 | 2010-11-28 22:44:32 -0800 | [diff] [blame] | 369 | if (ev_ptr != NULL) { \ |
vapier | df90996 | 2009-08-28 12:19:26 +0000 | [diff] [blame] | 370 | tst_resm(TPASS, ( "(epoll_ctl(%d,%08x,%d,%p = {%08x,%08d}) returned %d:%s)" ) , ##__VA_ARGS__ , \ |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 371 | epoll_fds[epfd_index], epoll_ctl_ops[op_index], \ |
subrata_modak | c81d7b9 | 2009-09-09 17:48:08 +0000 | [diff] [blame] | 372 | epoll_fds[fd_index], ev_ptr, ev_ptr->events, ev_ptr->data.fd, errno, \ |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 373 | strerror(errno)); \ |
| 374 | } else { \ |
vapier | df90996 | 2009-08-28 12:19:26 +0000 | [diff] [blame] | 375 | tst_resm(TPASS, ( "(epoll_ctl(%d,%08x,%d,%p) returned %d:%s)" ) , ##__VA_ARGS__ , \ |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 376 | epoll_fds[epfd_index], epoll_ctl_ops[op_index], \ |
| 377 | epoll_fds[fd_index], ev_ptr, errno, strerror(errno)); \ |
| 378 | } \ |
| 379 | }) |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 380 | #else |
subrata_modak | c81d7b9 | 2009-09-09 17:48:08 +0000 | [diff] [blame] | 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__) |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 383 | #endif |
| 384 | |
| 385 | /****************************************************************************************/ |
mridge | 98988cb | 2004-08-11 19:06:57 +0000 | [diff] [blame] | 386 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 387 | int test_epoll_ctl(int epoll_fd) |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 388 | { |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 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 */ |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 393 | int epoll_ctl_ops[] = |
| 394 | { EPOLL_CTL_DEL, EPOLL_CTL_MOD, EPOLL_CTL_ADD, EPOLL_CTL_MOD, |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 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; |
mridge | 98988cb | 2004-08-11 19:06:57 +0000 | [diff] [blame] | 400 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 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; |
vapier | 7f40cfd | 2006-08-21 06:47:15 +0000 | [diff] [blame] | 413 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 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))); |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 424 | } |
subrata_modak | bdbaec5 | 2009-02-26 12:14:51 +0000 | [diff] [blame] | 425 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 426 | /* Get a pointer to an unaligned struct epoll_event */ |
| 427 | { |
| 428 | char *unalign_ptr = event_mem; |
subrata_modak | bdbaec5 | 2009-02-26 12:14:51 +0000 | [diff] [blame] | 429 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 430 | unalign_ptr = |
| 431 | unalign_ptr + (((unsigned long)unalign_ptr & 1) ? 0 : 1); |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 432 | unaligned_event_ptr = (struct epoll_event *)unalign_ptr; |
| 433 | } |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 434 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 435 | /* One of the fds we want to test is the valid one */ |
| 436 | epoll_fds[0] = epoll_fd; |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 437 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 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; |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 443 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 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 | } |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 458 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 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++) { |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 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 < |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 472 | (sizeof(epoll_ctl_ops) / |
| 473 | sizeof(int)); op_index++) { |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 474 | int result; |
| 475 | int expected_errno = 0; |
| 476 | int num_errors_expected = 0; |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 477 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 478 | if (ev_ptr != NULL) |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 479 | ev_ptr->events = |
| 480 | epoll_events |
| 481 | [event_index]; |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 482 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 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; |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 487 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 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 |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 495 | [op_index], |
| 496 | fds[fd_index], |
| 497 | ev_ptr); |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 498 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 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 */ |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 502 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 503 | /* |
| 504 | Test the results. Look for appropriate error conditions |
| 505 | */ |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 506 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 507 | /* Check the epfd */ |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 508 | if (epoll_fds[epfd_index] != |
| 509 | epoll_fd) { |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 510 | /* Expect an error */ |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 511 | if (epoll_fds |
| 512 | [epfd_index] == 0) |
| 513 | expected_errno = |
| 514 | EINVAL; |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 515 | else /* epfd is not a valid file descriptor since it is |
| 516 | neither epoll_fd nor stdin */ |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 517 | expected_errno = |
| 518 | EBADF; |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 519 | num_errors_expected++; |
| 520 | } |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 521 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 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 | } |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 532 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 533 | expected_errno = EPERM; |
| 534 | num_errors_expected++; |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 535 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 536 | if (ev_ptr == NULL) { |
| 537 | expected_errno = EINVAL; |
| 538 | num_errors_expected++; |
| 539 | } else if ((ev_ptr == &event) |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 540 | || (ev_ptr == |
| 541 | unaligned_event_ptr)) |
| 542 | { |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 543 | if (ev_ptr->events == 0) { |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 544 | expected_errno = |
| 545 | EINVAL; |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 546 | num_errors_expected++; |
| 547 | } |
| 548 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 549 | for (index = 1; |
| 550 | index < 64; |
| 551 | index++) { |
| 552 | if (ev_ptr->events != epoll_events[index]) { |
| 553 | expected_errno |
| 554 | = |
| 555 | EINVAL; |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 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) { |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 566 | /* We didn't get an error. Think of this as RES_PASS_RETV_MAT_ERRNO_IGN */ |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 567 | return RES_PASS; |
| 568 | } else if (result == -1) { /* The return value is -1, so it's not bad */ |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 569 | return |
| 570 | RES_FAIL_RETV_MIS_ERRNO_IGN; |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 571 | } else { |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 572 | return |
| 573 | RES_FAIL_RETV_BAD_ERRNO_IGN; |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 574 | } |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 575 | } else if (num_errors_expected |
| 576 | == 1) { |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 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 */ |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 582 | if (errno == |
| 583 | expected_errno) |
| 584 | { |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 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. */ |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 593 | if (errno == |
| 594 | expected_errno) |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 595 | return |
| 596 | RES_FAIL_RETV_BAD_ERRNO_MAT; |
| 597 | else |
| 598 | return |
| 599 | RES_FAIL_RETV_BAD_ERRNO_MIS; |
| 600 | } |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 601 | } else if (num_errors_expected > |
| 602 | 1) { |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 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 */ |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 608 | if (errno == |
| 609 | expected_errno) |
| 610 | { |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 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. */ |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 621 | if (errno == |
| 622 | expected_errno) |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 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) |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 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 */ |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 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 |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 665 | ((result_strings[result])); |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 666 | } |
| 667 | num_epoll_ctl_test_fails++; |
czhang@redhat.com | f8df4b5 | 2011-03-30 22:32:35 +0800 | [diff] [blame] | 668 | #ifdef DEBUG |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 669 | } else /* The call of epoll_ctl behaved as expected */ |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 670 | EPOLL_CTL_TEST_PASS((result_strings[result])); |
czhang@redhat.com | f8df4b5 | 2011-03-30 22:32:35 +0800 | [diff] [blame] | 671 | #else |
| 672 | } |
| 673 | #endif |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 674 | } |
| 675 | } |
| 676 | } |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 677 | } |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 678 | close(epoll_fd); |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 679 | } |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 680 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 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); |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 687 | } |
| 688 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 689 | int main(int argc, char **argv) |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 690 | { |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 691 | int epoll_fd; |
| 692 | struct timeval tv; |
| 693 | int last_result; |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 694 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 695 | tst_resm(TINFO, "testing if epoll() system call works"); |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 696 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 697 | /* Get the current time */ |
| 698 | if (gettimeofday(&tv, NULL) != 0) { |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 699 | tst_brkm(TBROK | TERRNO, NULL, "gettimeofday failed"); |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 700 | } else { |
| 701 | tst_resm(TINFO, "gettimeofday() works"); |
| 702 | } |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 703 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 704 | /* Set up RNG */ |
| 705 | srand(tv.tv_usec); |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 706 | tst_resm(TINFO, |
| 707 | "random number seeded with gettimeofday() [seed = %ld] works", |
| 708 | tv.tv_usec); |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 709 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 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 | } |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 716 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 717 | /* Create an epoll_fd for testing epoll_ctl */ |
| 718 | epoll_fd = epoll_create(BACKING_STORE_SIZE_HINT); |
| 719 | if (epoll_fd < 0) { |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 720 | tst_brkm(TFAIL | TERRNO, NULL, "epoll_create failed"); |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 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 | |
Garrett Cooper | 5374050 | 2010-12-16 00:04:01 -0800 | [diff] [blame] | 729 | tst_exit(); |
mridge | b0a63b6 | 2004-03-03 21:36:28 +0000 | [diff] [blame] | 730 | } |
subrata_modak | c81d7b9 | 2009-09-09 17:48:08 +0000 | [diff] [blame] | 731 | |
| 732 | #else |
| 733 | |
| 734 | int main(void) |
| 735 | { |
Garrett Cooper | 5374050 | 2010-12-16 00:04:01 -0800 | [diff] [blame] | 736 | tst_brkm(TCONF, NULL, "No epoll support found."); |
subrata_modak | c81d7b9 | 2009-09-09 17:48:08 +0000 | [diff] [blame] | 737 | } |
| 738 | |
czhang@redhat.com | f8df4b5 | 2011-03-30 22:32:35 +0800 | [diff] [blame] | 739 | #endif |