subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2008 Vijay Kumar B. <vijaykumar@bravegnu.org> |
| 3 | * |
| 4 | * Based on testcases/kernel/syscalls/waitpid/waitpid01.c |
| 5 | * Original copyright message: |
| 6 | * |
| 7 | * Copyright (c) International Business Machines Corp., 2001 |
| 8 | * |
| 9 | * This program is free software; you can redistribute it and/or modify |
| 10 | * it under the terms of the GNU General Public License as published by |
| 11 | * the Free Software Foundation; either version 2 of the License, or |
| 12 | * (at your option) any later version. |
| 13 | * |
| 14 | * This program is distributed in the hope that it will be useful, |
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See |
| 17 | * the GNU General Public License for more details. |
| 18 | * |
| 19 | * You should have received a copy of the GNU General Public License |
| 20 | * along with this program; if not, write to the Free Software |
Wanlong Gao | 4548c6c | 2012-10-19 18:03:36 +0800 | [diff] [blame] | 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 22 | */ |
| 23 | |
| 24 | /* |
| 25 | * NAME |
| 26 | * eventfd01.c |
| 27 | * |
| 28 | * DESCRIPTION |
| 29 | * Test cases for eventfd syscall. |
| 30 | * |
| 31 | * USAGE: <for command-line> |
| 32 | * eventfd01 [-c n] [-i n] [-I x] [-P x] [-t] |
| 33 | * where, -c n : Run n copies concurrently. |
| 34 | * -i n : Execute test n times. |
| 35 | * -I x : Execute test for x seconds. |
| 36 | * -P x : Pause for x seconds between iterations. |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 37 | * |
| 38 | * History |
| 39 | * 07/2008 Vijay Kumar |
| 40 | * Initial Version. |
| 41 | * |
| 42 | * Restrictions |
| 43 | * None |
| 44 | */ |
| 45 | |
subrata_modak | 4fc9f54 | 2009-01-16 09:03:14 +0000 | [diff] [blame] | 46 | #include "config.h" |
| 47 | |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 48 | #include <sys/types.h> |
Garrett Cooper | 02d739b | 2010-12-21 10:44:52 -0800 | [diff] [blame] | 49 | #include <sys/select.h> |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 50 | #include <sys/wait.h> |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 51 | #include <errno.h> |
Garrett Cooper | 02d739b | 2010-12-21 10:44:52 -0800 | [diff] [blame] | 52 | #include <fcntl.h> |
vapier | c8b68a4 | 2009-08-28 12:26:07 +0000 | [diff] [blame] | 53 | #include <inttypes.h> |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 54 | #include <poll.h> |
Garrett Cooper | 02d739b | 2010-12-21 10:44:52 -0800 | [diff] [blame] | 55 | #include <signal.h> |
| 56 | #include <stdint.h> |
| 57 | #include <string.h> |
| 58 | #include <unistd.h> |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 59 | |
Garrett Cooper | 02d739b | 2010-12-21 10:44:52 -0800 | [diff] [blame] | 60 | #include "test.h" |
| 61 | #include "usctest.h" |
yaberauneya | 6aa2737 | 2009-12-06 19:54:10 +0000 | [diff] [blame] | 62 | #define CLEANUP cleanup |
| 63 | #include "linux_syscall_numbers.h" |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 64 | |
subrata_modak | 4fc9f54 | 2009-01-16 09:03:14 +0000 | [diff] [blame] | 65 | #ifdef HAVE_LIBAIO_H |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 66 | #include <libaio.h> |
| 67 | #endif |
| 68 | |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 69 | static void setup(void); |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 70 | |
subrata_modak | 4fc9f54 | 2009-01-16 09:03:14 +0000 | [diff] [blame] | 71 | TCID_DEFINE(eventfd01); |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 72 | int TST_TOTAL = 15; |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 73 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 74 | static int myeventfd(unsigned int initval, int flags) |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 75 | { |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 76 | /* eventfd2 uses FLAGS but eventfd doesn't take FLAGS. */ |
Jan Stancek | 359980f | 2013-02-15 10:16:05 +0100 | [diff] [blame^] | 77 | return ltp_syscall(__NR_eventfd, initval); |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 78 | } |
| 79 | |
| 80 | /* |
| 81 | * clear_counter() - clears the counter by performing a dummy read |
| 82 | * @fd: the eventfd |
| 83 | * |
| 84 | * RETURNS: |
| 85 | * 0 on success, and -1 on failure |
| 86 | */ |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 87 | static int clear_counter(int fd) |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 88 | { |
| 89 | uint64_t dummy; |
| 90 | int ret; |
| 91 | |
| 92 | ret = read(fd, &dummy, sizeof(dummy)); |
| 93 | if (ret == -1) { |
| 94 | if (errno != EAGAIN) { |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 95 | tst_resm(TINFO | TERRNO, "error clearing counter"); |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 96 | return -1; |
| 97 | } |
| 98 | } |
| 99 | |
| 100 | return 0; |
| 101 | } |
| 102 | |
| 103 | /* |
| 104 | * set_counter() - sets the count to specified value |
| 105 | * @fd: the eventfd |
| 106 | * @val: the value to be set |
| 107 | * |
| 108 | * Clears the counter and sets the counter to @val. |
| 109 | * |
| 110 | * RETURNS: |
| 111 | * 0 on success, -1 on failure |
| 112 | */ |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 113 | static int set_counter(int fd, uint64_t val) |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 114 | { |
| 115 | int ret; |
| 116 | |
| 117 | ret = clear_counter(fd); |
Garrett Cooper | 80678cf | 2010-12-21 10:49:20 -0800 | [diff] [blame] | 118 | if (ret == -1) |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 119 | return -1; |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 120 | |
| 121 | ret = write(fd, &val, sizeof(val)); |
| 122 | if (ret == -1) { |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 123 | tst_resm(TINFO | TERRNO, "error setting counter value"); |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 124 | return -1; |
| 125 | } |
| 126 | |
| 127 | return 0; |
| 128 | } |
| 129 | |
| 130 | /* |
| 131 | * Test whether the current value of the counter matches @required. |
| 132 | */ |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 133 | static void read_test(int fd, uint64_t required) |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 134 | { |
| 135 | int ret; |
| 136 | uint64_t val; |
| 137 | |
| 138 | ret = read(fd, &val, sizeof(val)); |
| 139 | if (ret == -1) { |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 140 | tst_resm(TBROK | TERRNO, "error reading eventfd"); |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 141 | return; |
| 142 | } |
| 143 | |
| 144 | if (val == required) |
| 145 | tst_resm(TPASS, "counter value matches required"); |
| 146 | else |
| 147 | tst_resm(TFAIL, "counter value mismatch: " |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 148 | "required: %" PRIu64 ", got: %" PRIu64, required, val); |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 149 | } |
| 150 | |
| 151 | /* |
| 152 | * Test whether read returns with error EAGAIN when counter is at 0. |
| 153 | */ |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 154 | static void read_eagain_test(int fd) |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 155 | { |
| 156 | int ret; |
| 157 | uint64_t val; |
| 158 | |
| 159 | ret = clear_counter(fd); |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 160 | if (ret == -1) { |
| 161 | tst_resm(TBROK, "error clearing counter"); |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 162 | return; |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 163 | } |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 164 | |
| 165 | ret = read(fd, &val, sizeof(val)); |
| 166 | if (ret == -1) { |
| 167 | if (errno == EAGAIN) |
| 168 | tst_resm(TPASS, "read failed with EAGAIN as expected"); |
| 169 | else |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 170 | tst_resm(TFAIL | TERRNO, "read failed (wanted EAGAIN)"); |
Garrett Cooper | 80678cf | 2010-12-21 10:49:20 -0800 | [diff] [blame] | 171 | } else |
vapier | c8b68a4 | 2009-08-28 12:26:07 +0000 | [diff] [blame] | 172 | tst_resm(TFAIL, "read returned with %d", ret); |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 173 | } |
| 174 | |
| 175 | /* |
| 176 | * Test whether writing to counter works. |
| 177 | */ |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 178 | static void write_test(int fd) |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 179 | { |
| 180 | int ret; |
| 181 | uint64_t val; |
| 182 | |
| 183 | val = 12; |
| 184 | |
| 185 | ret = set_counter(fd, val); |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 186 | if (ret == -1) { |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 187 | tst_resm(TBROK, "error setting counter value to %" PRIu64, val); |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 188 | return; |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 189 | } |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 190 | |
| 191 | read_test(fd, val); |
| 192 | } |
| 193 | |
| 194 | /* |
| 195 | * Test whether write returns with error EAGAIN when counter is at |
| 196 | * (UINT64_MAX - 1). |
| 197 | */ |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 198 | static void write_eagain_test(int fd) |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 199 | { |
| 200 | int ret; |
| 201 | uint64_t val; |
| 202 | |
| 203 | ret = set_counter(fd, UINT64_MAX - 1); |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 204 | if (ret == -1) { |
| 205 | tst_resm(TBROK, "error setting counter value to UINT64_MAX-1"); |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 206 | return; |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 207 | } |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 208 | |
| 209 | val = 1; |
| 210 | ret = write(fd, &val, sizeof(val)); |
| 211 | if (ret == -1) { |
| 212 | if (errno == EAGAIN) |
vapier | c8b68a4 | 2009-08-28 12:26:07 +0000 | [diff] [blame] | 213 | tst_resm(TPASS, "write failed with EAGAIN as expected"); |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 214 | else |
vapier | c8b68a4 | 2009-08-28 12:26:07 +0000 | [diff] [blame] | 215 | tst_resm(TFAIL, "write failed (wanted EAGAIN)"); |
Garrett Cooper | 80678cf | 2010-12-21 10:49:20 -0800 | [diff] [blame] | 216 | } else |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 217 | tst_resm(TFAIL, "write returned with %d", ret); |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 218 | } |
| 219 | |
| 220 | /* |
| 221 | * Test whether read returns with error EINVAL, if buffer size is less |
| 222 | * than 8 bytes. |
| 223 | */ |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 224 | static void read_einval_test(int fd) |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 225 | { |
| 226 | uint32_t invalid; |
| 227 | int ret; |
| 228 | |
| 229 | ret = read(fd, &invalid, sizeof(invalid)); |
| 230 | if (ret == -1) { |
Garrett Cooper | 80678cf | 2010-12-21 10:49:20 -0800 | [diff] [blame] | 231 | if (errno == EINVAL) |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 232 | tst_resm(TPASS, "read failed with EINVAL as expected"); |
Garrett Cooper | 80678cf | 2010-12-21 10:49:20 -0800 | [diff] [blame] | 233 | else |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 234 | tst_resm(TFAIL | TERRNO, "read failed (wanted EINVAL)"); |
Garrett Cooper | 80678cf | 2010-12-21 10:49:20 -0800 | [diff] [blame] | 235 | } else |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 236 | tst_resm(TFAIL, "read returned with %d", ret); |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 237 | } |
| 238 | |
| 239 | /* |
| 240 | * Test whether write returns with error EINVAL, if buffer size is |
| 241 | * less than 8 bytes. |
| 242 | */ |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 243 | static void write_einval_test(int fd) |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 244 | { |
| 245 | uint32_t invalid; |
| 246 | int ret; |
| 247 | |
| 248 | ret = write(fd, &invalid, sizeof(invalid)); |
| 249 | if (ret == -1) { |
Garrett Cooper | 80678cf | 2010-12-21 10:49:20 -0800 | [diff] [blame] | 250 | if (errno == EINVAL) |
vapier | c8b68a4 | 2009-08-28 12:26:07 +0000 | [diff] [blame] | 251 | tst_resm(TPASS, "write failed with EINVAL as expected"); |
Garrett Cooper | 80678cf | 2010-12-21 10:49:20 -0800 | [diff] [blame] | 252 | else |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 253 | tst_resm(TFAIL | TERRNO, |
| 254 | "write failed (wanted EINVAL)"); |
Garrett Cooper | 80678cf | 2010-12-21 10:49:20 -0800 | [diff] [blame] | 255 | } else |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 256 | tst_resm(TFAIL, "write returned with %d", ret); |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 257 | } |
| 258 | |
| 259 | /* |
| 260 | * Test wheter write returns with error EINVAL, when the written value |
| 261 | * is 0xFFFFFFFFFFFFFFFF. |
| 262 | */ |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 263 | static void write_einval2_test(int fd) |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 264 | { |
| 265 | int ret; |
| 266 | uint64_t val; |
| 267 | |
| 268 | ret = clear_counter(fd); |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 269 | if (ret == -1) { |
| 270 | tst_resm(TBROK, "error clearing counter"); |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 271 | return; |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 272 | } |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 273 | |
| 274 | val = 0xffffffffffffffffLL; |
| 275 | ret = write(fd, &val, sizeof(val)); |
| 276 | if (ret == -1) { |
| 277 | if (errno == EINVAL) |
vapier | c8b68a4 | 2009-08-28 12:26:07 +0000 | [diff] [blame] | 278 | tst_resm(TPASS, "write failed with EINVAL as expected"); |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 279 | else |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 280 | tst_resm(TFAIL | TERRNO, |
| 281 | "write failed (wanted EINVAL)"); |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 282 | } else { |
| 283 | tst_resm(TFAIL, "write returned with %d", ret); |
| 284 | } |
| 285 | } |
| 286 | |
| 287 | /* |
| 288 | * Test whether readfd is set by select when counter value is |
| 289 | * non-zero. |
| 290 | */ |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 291 | static void readfd_set_test(int fd) |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 292 | { |
| 293 | int ret; |
| 294 | fd_set readfds; |
| 295 | struct timeval timeout = { 0, 0 }; |
| 296 | uint64_t non_zero = 10; |
| 297 | |
| 298 | FD_ZERO(&readfds); |
| 299 | FD_SET(fd, &readfds); |
| 300 | |
| 301 | ret = set_counter(fd, non_zero); |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 302 | if (ret == -1) { |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 303 | tst_resm(TBROK, "error setting counter value to %" PRIu64, |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 304 | non_zero); |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 305 | return; |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 306 | } |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 307 | |
| 308 | ret = select(fd + 1, &readfds, NULL, NULL, &timeout); |
| 309 | if (ret == -1) { |
| 310 | /* EINTR cannot occur, since we don't block. */ |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 311 | tst_resm(TBROK | TERRNO, "select() failed"); |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 312 | return; |
| 313 | } |
| 314 | |
| 315 | if (FD_ISSET(fd, &readfds)) |
| 316 | tst_resm(TPASS, "fd is set in readfds"); |
| 317 | else |
| 318 | tst_resm(TFAIL, "fd is not set in readfds"); |
| 319 | } |
| 320 | |
| 321 | /* |
| 322 | * Test whether readfd is not set by select when counter value is |
| 323 | * zero. |
| 324 | */ |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 325 | static void readfd_not_set_test(int fd) |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 326 | { |
| 327 | int ret; |
| 328 | fd_set readfds; |
| 329 | struct timeval timeout = { 0, 0 }; |
| 330 | |
| 331 | FD_ZERO(&readfds); |
| 332 | FD_SET(fd, &readfds); |
| 333 | |
| 334 | ret = clear_counter(fd); |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 335 | if (ret == -1) { |
| 336 | tst_resm(TBROK, "error clearing counter"); |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 337 | return; |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 338 | } |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 339 | |
| 340 | ret = select(fd + 1, &readfds, NULL, NULL, &timeout); |
| 341 | if (ret == -1) { |
| 342 | /* EINTR cannot occur, since we don't block. */ |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 343 | tst_resm(TBROK | TERRNO, "select() failed"); |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 344 | return; |
| 345 | } |
| 346 | |
| 347 | if (!FD_ISSET(fd, &readfds)) |
| 348 | tst_resm(TPASS, "fd is not set in readfds"); |
| 349 | else |
| 350 | tst_resm(TFAIL, "fd is set in readfds"); |
| 351 | } |
| 352 | |
| 353 | /* |
| 354 | * Test whether writefd is set by select when counter value is not the |
| 355 | * maximum counter value. |
| 356 | */ |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 357 | static void writefd_set_test(int fd) |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 358 | { |
| 359 | int ret; |
| 360 | fd_set writefds; |
| 361 | struct timeval timeout = { 0, 0 }; |
| 362 | uint64_t non_max = 10; |
| 363 | |
| 364 | FD_ZERO(&writefds); |
| 365 | FD_SET(fd, &writefds); |
| 366 | |
| 367 | ret = set_counter(fd, non_max); |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 368 | if (ret == -1) { |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 369 | tst_resm(TBROK, "error setting counter value to %" PRIu64, |
| 370 | non_max); |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 371 | return; |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 372 | } |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 373 | |
| 374 | ret = select(fd + 1, NULL, &writefds, NULL, &timeout); |
| 375 | if (ret == -1) { |
| 376 | /* EINTR cannot occur, since we don't block. */ |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 377 | tst_resm(TBROK | TERRNO, "select: error getting fd status"); |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 378 | return; |
| 379 | } |
| 380 | |
| 381 | if (FD_ISSET(fd, &writefds)) |
| 382 | tst_resm(TPASS, "fd is set in writefds"); |
| 383 | else |
| 384 | tst_resm(TFAIL, "fd is not set in writefds"); |
| 385 | } |
| 386 | |
| 387 | /* |
| 388 | * Test whether writefd is not set by select when counter value is at |
| 389 | * (UINT64_MAX - 1). |
| 390 | */ |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 391 | static void writefd_not_set_test(int fd) |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 392 | { |
| 393 | int ret; |
| 394 | fd_set writefds; |
| 395 | struct timeval timeout = { 0, 0 }; |
| 396 | |
| 397 | FD_ZERO(&writefds); |
| 398 | FD_SET(fd, &writefds); |
| 399 | |
| 400 | ret = set_counter(fd, UINT64_MAX - 1); |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 401 | if (ret == -1) { |
| 402 | tst_resm(TBROK, "error setting counter value to UINT64_MAX-1"); |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 403 | return; |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 404 | } |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 405 | |
| 406 | ret = select(fd + 1, NULL, &writefds, NULL, &timeout); |
| 407 | if (ret == -1) { |
| 408 | /* EINTR cannot occur, since we don't block. */ |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 409 | tst_resm(TBROK | TERRNO, "select: error getting fd status"); |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 410 | return; |
| 411 | } |
| 412 | |
| 413 | if (!FD_ISSET(fd, &writefds)) |
| 414 | tst_resm(TPASS, "fd is not set in writefds"); |
| 415 | else |
| 416 | tst_resm(TFAIL, "fd is set in writefds"); |
| 417 | } |
| 418 | |
| 419 | /* |
| 420 | * Test whether counter update in child is reflected in the parent. |
| 421 | */ |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 422 | static void child_inherit_test(int fd) |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 423 | { |
| 424 | uint64_t val; |
| 425 | pid_t cpid; |
| 426 | int ret; |
| 427 | int status; |
| 428 | uint64_t to_parent = 0xdeadbeef; |
| 429 | uint64_t dummy; |
| 430 | |
| 431 | cpid = fork(); |
| 432 | if (cpid == -1) |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 433 | tst_resm(TBROK | TERRNO, "fork failed"); |
Garrett Cooper | 80678cf | 2010-12-21 10:49:20 -0800 | [diff] [blame] | 434 | else if (cpid != 0) { |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 435 | ret = wait(&status); |
| 436 | if (ret == -1) { |
| 437 | tst_resm(TBROK, "error getting child exit status"); |
| 438 | return; |
| 439 | } |
| 440 | |
| 441 | if (WEXITSTATUS(status) == 1) { |
| 442 | tst_resm(TBROK, "counter value write not " |
Garrett Cooper | 80678cf | 2010-12-21 10:49:20 -0800 | [diff] [blame] | 443 | "successful in child"); |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 444 | return; |
| 445 | } |
| 446 | |
| 447 | ret = read(fd, &val, sizeof(val)); |
| 448 | if (ret == -1) { |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 449 | tst_resm(TBROK | TERRNO, "error reading eventfd"); |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 450 | return; |
| 451 | } |
| 452 | |
| 453 | if (val == to_parent) |
| 454 | tst_resm(TPASS, "counter value write from " |
| 455 | "child successful"); |
| 456 | else |
| 457 | tst_resm(TFAIL, "counter value write in child " |
| 458 | "failed"); |
| 459 | } else { |
| 460 | /* Child */ |
| 461 | ret = read(fd, &dummy, sizeof(dummy)); |
| 462 | if (ret == -1 && errno != EAGAIN) { |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 463 | tst_resm(TWARN | TERRNO, "error clearing counter"); |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 464 | exit(1); |
| 465 | } |
| 466 | |
| 467 | ret = write(fd, &to_parent, sizeof(to_parent)); |
| 468 | if (ret == -1) { |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 469 | tst_resm(TWARN | TERRNO, "error writing eventfd"); |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 470 | exit(1); |
| 471 | } |
| 472 | |
| 473 | exit(0); |
| 474 | } |
| 475 | } |
| 476 | |
subrata_modak | 4fc9f54 | 2009-01-16 09:03:14 +0000 | [diff] [blame] | 477 | #ifdef HAVE_IO_SET_EVENTFD |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 478 | /* |
subrata_modak | 4bb656a | 2009-02-26 12:02:09 +0000 | [diff] [blame] | 479 | * Test whether counter overflow is detected and handled correctly. |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 480 | * |
| 481 | * It is not possible to directly overflow the counter using the |
| 482 | * write() syscall. Overflows occur when the counter is incremented |
| 483 | * from kernel space, in an irq context, when it is not possible to |
| 484 | * block the calling thread of execution. |
| 485 | * |
| 486 | * The AIO subsystem internally uses eventfd mechanism for |
| 487 | * notification of completion of read or write requests. In this test |
| 488 | * we trigger a counter overflow, by setting the counter value to the |
| 489 | * max possible value initially. When the AIO subsystem notifies |
| 490 | * through the eventfd counter, the counter overflows. |
| 491 | * |
| 492 | * NOTE: If the the counter starts from an initial value of 0, it will |
| 493 | * take decades for an overflow to occur. But since we set the initial |
| 494 | * value to the max possible counter value, we are able to cause it to |
| 495 | * overflow with a single increment. |
| 496 | * |
| 497 | * When the counter overflows, the following are tested |
| 498 | * 1. Check whether POLLERR event occurs in poll() for the eventfd. |
| 499 | * 2. Check whether readfd_set/writefd_set is set in select() for the |
| 500 | eventfd. |
| 501 | * 3. The counter value is UINT64_MAX. |
| 502 | */ |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 503 | static int trigger_eventfd_overflow(int evfd, int *fd, io_context_t * ctx) |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 504 | { |
| 505 | int ret; |
| 506 | struct iocb iocb; |
| 507 | struct iocb *iocbap[1]; |
| 508 | static char buf[4 * 1024]; |
| 509 | |
| 510 | *ctx = 0; |
| 511 | ret = io_setup(16, ctx); |
| 512 | if (ret < 0) { |
vapier | c8b68a4 | 2009-08-28 12:26:07 +0000 | [diff] [blame] | 513 | errno = -ret; |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 514 | tst_resm(TINFO | TERRNO, "io_setup error"); |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 515 | return -1; |
| 516 | } |
| 517 | |
| 518 | *fd = open("testfile", O_RDWR | O_CREAT, 0644); |
| 519 | if (*fd == -1) { |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 520 | tst_resm(TINFO | TERRNO, "open(testfile) failed"); |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 521 | goto err_io_destroy; |
| 522 | } |
| 523 | |
| 524 | ret = set_counter(evfd, UINT64_MAX - 1); |
| 525 | if (ret == -1) { |
| 526 | tst_resm(TINFO, "error setting counter to UINT64_MAX-1"); |
| 527 | goto err_close_file; |
| 528 | } |
| 529 | |
| 530 | io_prep_pwrite(&iocb, *fd, buf, sizeof(buf), 0); |
| 531 | io_set_eventfd(&iocb, evfd); |
subrata_modak | bdbaec5 | 2009-02-26 12:14:51 +0000 | [diff] [blame] | 532 | |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 533 | iocbap[0] = &iocb; |
| 534 | ret = io_submit(*ctx, 1, iocbap); |
| 535 | if (ret < 0) { |
vapier | c8b68a4 | 2009-08-28 12:26:07 +0000 | [diff] [blame] | 536 | errno = -ret; |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 537 | tst_resm(TINFO | TERRNO, "error submitting iocb"); |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 538 | goto err_close_file; |
| 539 | } |
| 540 | |
| 541 | return 0; |
| 542 | |
yaberauneya | e70b30b | 2009-11-27 07:40:16 +0000 | [diff] [blame] | 543 | err_close_file: |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 544 | close(*fd); |
| 545 | |
yaberauneya | e70b30b | 2009-11-27 07:40:16 +0000 | [diff] [blame] | 546 | err_io_destroy: |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 547 | io_destroy(*ctx); |
| 548 | |
| 549 | return -1; |
| 550 | } |
| 551 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 552 | static void cleanup_overflow(int fd, io_context_t ctx) |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 553 | { |
| 554 | close(fd); |
| 555 | io_destroy(ctx); |
| 556 | } |
| 557 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 558 | static void overflow_select_test(int evfd) |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 559 | { |
| 560 | struct timeval timeout = { 10, 0 }; |
| 561 | fd_set readfds; |
| 562 | int fd; |
| 563 | io_context_t ctx; |
| 564 | int ret; |
| 565 | |
| 566 | ret = trigger_eventfd_overflow(evfd, &fd, &ctx); |
| 567 | if (ret == -1) { |
| 568 | tst_resm(TBROK, "error triggering eventfd overflow"); |
| 569 | return; |
| 570 | } |
subrata_modak | bdbaec5 | 2009-02-26 12:14:51 +0000 | [diff] [blame] | 571 | |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 572 | FD_ZERO(&readfds); |
| 573 | FD_SET(evfd, &readfds); |
| 574 | ret = select(evfd + 1, &readfds, NULL, NULL, &timeout); |
Garrett Cooper | 80678cf | 2010-12-21 10:49:20 -0800 | [diff] [blame] | 575 | if (ret == -1) |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 576 | tst_resm(TBROK | TERRNO, |
| 577 | "error getting evfd status with select"); |
Garrett Cooper | 80678cf | 2010-12-21 10:49:20 -0800 | [diff] [blame] | 578 | else { |
yaberauneya | e70b30b | 2009-11-27 07:40:16 +0000 | [diff] [blame] | 579 | if (FD_ISSET(evfd, &readfds)) |
| 580 | tst_resm(TPASS, "read fd set as expected"); |
| 581 | else |
| 582 | tst_resm(TFAIL, "read fd not set"); |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 583 | } |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 584 | cleanup_overflow(fd, ctx); |
| 585 | } |
| 586 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 587 | static void overflow_poll_test(int evfd) |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 588 | { |
| 589 | struct pollfd pollfd; |
| 590 | int fd; |
| 591 | io_context_t ctx; |
| 592 | int ret; |
| 593 | |
| 594 | ret = trigger_eventfd_overflow(evfd, &fd, &ctx); |
Subrata Modak | f0be8b0 | 2010-05-07 10:33:00 +0530 | [diff] [blame] | 595 | if (ret == -1) { |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 596 | tst_resm(TBROK, "error triggering eventfd overflow"); |
| 597 | return; |
| 598 | } |
| 599 | |
| 600 | pollfd.fd = evfd; |
| 601 | pollfd.events = POLLIN; |
| 602 | pollfd.revents = 0; |
| 603 | ret = poll(&pollfd, 1, 10000); |
Garrett Cooper | 80678cf | 2010-12-21 10:49:20 -0800 | [diff] [blame] | 604 | if (ret == -1) |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 605 | tst_resm(TBROK | TERRNO, "error getting evfd status with poll"); |
Garrett Cooper | 80678cf | 2010-12-21 10:49:20 -0800 | [diff] [blame] | 606 | else { |
yaberauneya | e70b30b | 2009-11-27 07:40:16 +0000 | [diff] [blame] | 607 | if (pollfd.revents & POLLERR) |
| 608 | tst_resm(TPASS, "POLLERR occurred as expected"); |
| 609 | else |
| 610 | tst_resm(TFAIL, "POLLERR did not occur"); |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 611 | } |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 612 | cleanup_overflow(fd, ctx); |
| 613 | } |
| 614 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 615 | static void overflow_read_test(int evfd) |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 616 | { |
| 617 | uint64_t count; |
| 618 | io_context_t ctx; |
| 619 | int fd; |
| 620 | int ret; |
| 621 | |
| 622 | ret = trigger_eventfd_overflow(evfd, &fd, &ctx); |
| 623 | if (ret == -1) { |
| 624 | tst_resm(TBROK, "error triggering eventfd overflow"); |
| 625 | return; |
| 626 | } |
subrata_modak | bdbaec5 | 2009-02-26 12:14:51 +0000 | [diff] [blame] | 627 | |
subrata_modak | 4bb656a | 2009-02-26 12:02:09 +0000 | [diff] [blame] | 628 | ret = read(evfd, &count, sizeof(count)); |
Garrett Cooper | 80678cf | 2010-12-21 10:49:20 -0800 | [diff] [blame] | 629 | if (ret == -1) |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 630 | tst_resm(TBROK | TERRNO, "error reading eventfd"); |
Garrett Cooper | 80678cf | 2010-12-21 10:49:20 -0800 | [diff] [blame] | 631 | else { |
yaberauneya | e70b30b | 2009-11-27 07:40:16 +0000 | [diff] [blame] | 632 | |
| 633 | if (count == UINT64_MAX) |
| 634 | tst_resm(TPASS, "overflow occurred as expected"); |
| 635 | else |
| 636 | tst_resm(TFAIL, "overflow did not occur"); |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 637 | } |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 638 | cleanup_overflow(fd, ctx); |
| 639 | } |
| 640 | #else |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 641 | static void overflow_select_test(int evfd) |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 642 | { |
| 643 | tst_resm(TCONF, "eventfd support is not available in AIO subsystem"); |
| 644 | } |
| 645 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 646 | static void overflow_poll_test(int evfd) |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 647 | { |
| 648 | tst_resm(TCONF, "eventfd support is not available in AIO subsystem"); |
| 649 | } |
| 650 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 651 | static void overflow_read_test(int evfd) |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 652 | { |
| 653 | tst_resm(TCONF, "eventfd support is not available in AIO subsystem"); |
| 654 | } |
| 655 | #endif |
| 656 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 657 | int main(int argc, char **argv) |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 658 | { |
Cyril Hrubis | 89af32a | 2012-10-24 16:39:11 +0200 | [diff] [blame] | 659 | int lc; |
| 660 | char *msg; |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 661 | int fd; |
| 662 | |
Garrett Cooper | 80678cf | 2010-12-21 10:49:20 -0800 | [diff] [blame] | 663 | if ((msg = parse_opts(argc, argv, NULL, NULL)) != NULL) |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 664 | tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 665 | |
| 666 | setup(); |
| 667 | |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 668 | for (lc = 0; TEST_LOOPING(lc); lc++) { |
| 669 | int ret; |
| 670 | uint64_t einit = 10; |
| 671 | |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 672 | Tst_count = 0; |
| 673 | |
| 674 | fd = myeventfd(einit, 0); |
| 675 | if (fd == -1) |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 676 | tst_brkm(TBROK | TERRNO, CLEANUP, |
| 677 | "error creating eventfd"); |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 678 | |
| 679 | ret = fcntl(fd, F_SETFL, O_NONBLOCK); |
| 680 | if (ret == -1) |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 681 | tst_brkm(TBROK | TERRNO, CLEANUP, |
| 682 | "error setting non-block mode"); |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 683 | |
| 684 | read_test(fd, einit); |
| 685 | read_eagain_test(fd); |
| 686 | write_test(fd); |
| 687 | write_eagain_test(fd); |
| 688 | read_einval_test(fd); |
| 689 | write_einval_test(fd); |
| 690 | write_einval2_test(fd); |
| 691 | readfd_set_test(fd); |
| 692 | readfd_not_set_test(fd); |
| 693 | writefd_set_test(fd); |
| 694 | writefd_not_set_test(fd); |
| 695 | child_inherit_test(fd); |
subrata_modak | a5b38e4 | 2008-08-20 11:28:51 +0000 | [diff] [blame] | 696 | overflow_select_test(fd); |
| 697 | overflow_poll_test(fd); |
| 698 | overflow_read_test(fd); |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 699 | |
| 700 | close(fd); |
| 701 | } |
| 702 | |
| 703 | cleanup(); |
Garrett Cooper | 2c28215 | 2010-12-16 00:55:50 -0800 | [diff] [blame] | 704 | |
yaberauneya | e70b30b | 2009-11-27 07:40:16 +0000 | [diff] [blame] | 705 | tst_exit(); |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 706 | } |
| 707 | |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 708 | static void setup(void) |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 709 | { |
Garrett Cooper | 2c28215 | 2010-12-16 00:55:50 -0800 | [diff] [blame] | 710 | |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 711 | tst_sig(FORK, DEF_HANDLER, cleanup); |
| 712 | |
| 713 | if (tst_kvercmp(2, 6, 22) < 0) |
Garrett Cooper | 5374050 | 2010-12-16 00:04:01 -0800 | [diff] [blame] | 714 | tst_brkm(TCONF, NULL, "2.6.22 or greater kernel required"); |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 715 | |
subrata_modak | 94e24dd | 2009-06-25 07:24:49 +0000 | [diff] [blame] | 716 | tst_tmpdir(); |
Garrett Cooper | 80678cf | 2010-12-21 10:49:20 -0800 | [diff] [blame] | 717 | |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 718 | TEST_PAUSE; |
| 719 | } |
| 720 | |
yaberauneya | 6aa2737 | 2009-12-06 19:54:10 +0000 | [diff] [blame] | 721 | static void cleanup(void) |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 722 | { |
subrata_modak | 66b8447 | 2008-08-11 09:56:25 +0000 | [diff] [blame] | 723 | TEST_CLEANUP; |
| 724 | |
subrata_modak | 94e24dd | 2009-06-25 07:24:49 +0000 | [diff] [blame] | 725 | tst_rmdir(); |
Garrett Cooper | 02d739b | 2010-12-21 10:44:52 -0800 | [diff] [blame] | 726 | } |