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