1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2020 Jan Kokemüller 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 #include <sys/cdefs.h> 29 __FBSDID("$FreeBSD$"); 30 31 #include <sys/param.h> 32 #include <sys/event.h> 33 #include <sys/stat.h> 34 35 #include <errno.h> 36 #include <fcntl.h> 37 #include <limits.h> 38 #include <poll.h> 39 #include <stdio.h> 40 #include <stdlib.h> 41 #include <time.h> 42 #include <unistd.h> 43 44 #include <atf-c.h> 45 46 ATF_TC_WITHOUT_HEAD(fifo_kqueue__writes); 47 ATF_TC_BODY(fifo_kqueue__writes, tc) 48 { 49 int p[2] = { -1, -1 }; 50 51 ATF_REQUIRE(mkfifo("testfifo", 0600) == 0); 52 53 ATF_REQUIRE((p[0] = open("testfifo", 54 O_RDONLY | O_CLOEXEC | O_NONBLOCK)) >= 0); 55 ATF_REQUIRE((p[1] = open("testfifo", 56 O_WRONLY | O_CLOEXEC | O_NONBLOCK)) >= 0); 57 58 int kq = kqueue(); 59 ATF_REQUIRE(kq >= 0); 60 61 struct kevent kev[32]; 62 EV_SET(&kev[0], p[1], EVFILT_WRITE, EV_ADD | EV_CLEAR, 0, 0, 0); 63 EV_SET(&kev[1], p[1], EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, 0); 64 65 ATF_REQUIRE(kevent(kq, kev, 2, NULL, 0, NULL) == 0); 66 67 /* A new writer should immediately get a EVFILT_WRITE event. */ 68 69 ATF_REQUIRE(kevent(kq, NULL, 0, kev, nitems(kev), 70 &(struct timespec) { 0, 0 }) == 1); 71 ATF_REQUIRE(kev[0].ident == (uintptr_t)p[1]); 72 ATF_REQUIRE(kev[0].filter == EVFILT_WRITE); 73 ATF_REQUIRE(kev[0].flags == EV_CLEAR); 74 ATF_REQUIRE(kev[0].fflags == 0); 75 ATF_REQUIRE(kev[0].data == 16384); 76 ATF_REQUIRE(kev[0].udata == 0); 77 78 /* Filling up the pipe should make the EVFILT_WRITE disappear. */ 79 80 char c = 0; 81 ssize_t r; 82 while ((r = write(p[1], &c, 1)) == 1) { 83 } 84 ATF_REQUIRE(r < 0); 85 ATF_REQUIRE(errno == EAGAIN || errno == EWOULDBLOCK); 86 87 ATF_REQUIRE(kevent(kq, NULL, 0, kev, nitems(kev), 88 &(struct timespec) { 0, 0 }) == 0); 89 90 /* Reading (PIPE_BUF - 1) bytes will not trigger a EVFILT_WRITE yet. */ 91 92 for (int i = 0; i < PIPE_BUF - 1; ++i) { 93 ATF_REQUIRE(read(p[0], &c, 1) == 1); 94 } 95 96 ATF_REQUIRE(kevent(kq, NULL, 0, kev, nitems(kev), 97 &(struct timespec) { 0, 0 }) == 0); 98 99 /* Reading one additional byte triggers the EVFILT_WRITE. */ 100 101 ATF_REQUIRE(read(p[0], &c, 1) == 1); 102 103 ATF_REQUIRE(kevent(kq, NULL, 0, kev, nitems(kev), 104 &(struct timespec) { 0, 0 }) == 1); 105 ATF_REQUIRE(kev[0].ident == (uintptr_t)p[1]); 106 ATF_REQUIRE(kev[0].filter == EVFILT_WRITE); 107 ATF_REQUIRE(kev[0].flags == EV_CLEAR); 108 ATF_REQUIRE(kev[0].fflags == 0); 109 ATF_REQUIRE(kev[0].data == PIPE_BUF); 110 ATF_REQUIRE(kev[0].udata == 0); 111 112 /* 113 * Reading another byte triggers the EVFILT_WRITE again with a changed 114 * 'data' field. 115 */ 116 117 ATF_REQUIRE(read(p[0], &c, 1) == 1); 118 119 ATF_REQUIRE(kevent(kq, NULL, 0, kev, nitems(kev), 120 &(struct timespec) { 0, 0 }) == 1); 121 ATF_REQUIRE(kev[0].ident == (uintptr_t)p[1]); 122 ATF_REQUIRE(kev[0].filter == EVFILT_WRITE); 123 ATF_REQUIRE(kev[0].flags == EV_CLEAR); 124 ATF_REQUIRE(kev[0].fflags == 0); 125 ATF_REQUIRE(kev[0].data == PIPE_BUF + 1); 126 ATF_REQUIRE(kev[0].udata == 0); 127 128 /* 129 * Closing the read end should make a EV_EOF appear but leave the 'data' 130 * field unchanged. 131 */ 132 133 ATF_REQUIRE(close(p[0]) == 0); 134 135 ATF_REQUIRE(kevent(kq, NULL, 0, kev, nitems(kev), NULL) == 1); 136 ATF_REQUIRE(kev[0].ident == (uintptr_t)p[1]); 137 ATF_REQUIRE(kev[0].filter == EVFILT_WRITE); 138 ATF_REQUIRE(kev[0].flags == (EV_CLEAR | EV_EOF)); 139 ATF_REQUIRE(kev[0].fflags == 0); 140 ATF_REQUIRE(kev[0].data == PIPE_BUF + 1); 141 ATF_REQUIRE(kev[0].udata == 0); 142 143 ATF_REQUIRE(close(kq) == 0); 144 ATF_REQUIRE(close(p[1]) == 0); 145 } 146 147 ATF_TC_WITHOUT_HEAD(fifo_kqueue__connecting_reader); 148 ATF_TC_BODY(fifo_kqueue__connecting_reader, tc) 149 { 150 int p[2] = { -1, -1 }; 151 152 ATF_REQUIRE(mkfifo("testfifo", 0600) == 0); 153 154 ATF_REQUIRE((p[0] = open("testfifo", 155 O_RDONLY | O_CLOEXEC | O_NONBLOCK)) >= 0); 156 ATF_REQUIRE((p[1] = open("testfifo", 157 O_WRONLY | O_CLOEXEC | O_NONBLOCK)) >= 0); 158 159 int kq = kqueue(); 160 ATF_REQUIRE(kq >= 0); 161 162 struct kevent kev[32]; 163 EV_SET(&kev[0], p[1], EVFILT_WRITE, EV_ADD | EV_CLEAR, 0, 0, 0); 164 EV_SET(&kev[1], p[1], EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, 0); 165 166 ATF_REQUIRE(kevent(kq, kev, 2, NULL, 0, NULL) == 0); 167 168 /* A new writer should immediately get a EVFILT_WRITE event. */ 169 170 ATF_REQUIRE(kevent(kq, NULL, 0, kev, nitems(kev), 171 &(struct timespec) { 0, 0 }) == 1); 172 ATF_REQUIRE(kev[0].ident == (uintptr_t)p[1]); 173 ATF_REQUIRE(kev[0].filter == EVFILT_WRITE); 174 ATF_REQUIRE(kevent(kq, NULL, 0, kev, nitems(kev), 175 &(struct timespec) { 0, 0 }) == 0); 176 177 /* 178 * Filling the pipe, reading (PIPE_BUF + 1) bytes, then closing the 179 * read end leads to a EVFILT_WRITE with EV_EOF set. 180 */ 181 182 char c = 0; 183 ssize_t r; 184 while ((r = write(p[1], &c, 1)) == 1) { 185 } 186 ATF_REQUIRE(r < 0); 187 ATF_REQUIRE(errno == EAGAIN || errno == EWOULDBLOCK); 188 189 for (int i = 0; i < PIPE_BUF + 1; ++i) { 190 ATF_REQUIRE(read(p[0], &c, 1) == 1); 191 } 192 193 ATF_REQUIRE(close(p[0]) == 0); 194 195 ATF_REQUIRE(kevent(kq, NULL, 0, kev, nitems(kev), NULL) == 1); 196 ATF_REQUIRE(kev[0].filter == EVFILT_WRITE); 197 ATF_REQUIRE((kev[0].flags & EV_EOF) != 0); 198 ATF_REQUIRE(kevent(kq, NULL, 0, kev, nitems(kev), 199 &(struct timespec) { 0, 0 }) == 0); 200 201 /* Opening the reader again must trigger the EVFILT_WRITE. */ 202 203 ATF_REQUIRE((p[0] = open("testfifo", 204 O_RDONLY | O_CLOEXEC | O_NONBLOCK)) >= 0); 205 206 r = kevent(kq, NULL, 0, kev, nitems(kev), &(struct timespec) { 1, 0 }); 207 ATF_REQUIRE(r == 1); 208 ATF_REQUIRE(kev[0].ident == (uintptr_t)p[1]); 209 ATF_REQUIRE(kev[0].filter == EVFILT_WRITE); 210 ATF_REQUIRE(kev[0].flags == EV_CLEAR); 211 ATF_REQUIRE(kev[0].fflags == 0); 212 ATF_REQUIRE(kev[0].data == PIPE_BUF + 1); 213 ATF_REQUIRE(kev[0].udata == 0); 214 ATF_REQUIRE(kevent(kq, NULL, 0, kev, nitems(kev), 215 &(struct timespec) { 0, 0 }) == 0); 216 217 ATF_REQUIRE(close(kq) == 0); 218 ATF_REQUIRE(close(p[0]) == 0); 219 ATF_REQUIRE(close(p[1]) == 0); 220 } 221 222 /* Check that EVFILT_READ behaves sensibly on a FIFO reader. */ 223 ATF_TC_WITHOUT_HEAD(fifo_kqueue__reads); 224 ATF_TC_BODY(fifo_kqueue__reads, tc) 225 { 226 struct kevent kev[32]; 227 ssize_t bytes, i, n; 228 int kq, p[2]; 229 char c; 230 231 ATF_REQUIRE(mkfifo("testfifo", 0600) == 0); 232 233 ATF_REQUIRE((p[0] = open("testfifo", 234 O_RDONLY | O_CLOEXEC | O_NONBLOCK)) >= 0); 235 ATF_REQUIRE((p[1] = open("testfifo", 236 O_WRONLY | O_CLOEXEC | O_NONBLOCK)) >= 0); 237 238 bytes = 0; 239 c = 0; 240 while ((n = write(p[1], &c, 1)) == 1) 241 bytes++; 242 ATF_REQUIRE(n < 0); 243 ATF_REQUIRE(errno == EAGAIN || errno == EWOULDBLOCK); 244 ATF_REQUIRE(bytes > 1); 245 246 for (i = 0; i < bytes / 2; i++) 247 ATF_REQUIRE(read(p[0], &c, 1) == 1); 248 bytes -= i; 249 250 kq = kqueue(); 251 ATF_REQUIRE(kq >= 0); 252 253 EV_SET(&kev[0], p[0], EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, 0); 254 255 ATF_REQUIRE(kevent(kq, kev, 1, NULL, 0, NULL) == 0); 256 257 ATF_REQUIRE(kevent(kq, NULL, 0, kev, nitems(kev), 258 &(struct timespec){ 0, 0 }) == 1); 259 ATF_REQUIRE(kev[0].ident == (uintptr_t)p[0]); 260 ATF_REQUIRE(kev[0].filter == EVFILT_READ); 261 ATF_REQUIRE(kev[0].flags == EV_CLEAR); 262 ATF_REQUIRE(kev[0].fflags == 0); 263 ATF_REQUIRE(kev[0].data == bytes); 264 ATF_REQUIRE(kev[0].udata == 0); 265 266 while (bytes-- > 0) 267 ATF_REQUIRE(read(p[0], &c, 1) == 1); 268 n = read(p[0], &c, 1); 269 ATF_REQUIRE(n < 0); 270 ATF_REQUIRE(errno == EAGAIN || errno == EWOULDBLOCK); 271 272 ATF_REQUIRE(kevent(kq, NULL, 0, kev, nitems(kev), 273 &(struct timespec) { 0, 0 }) == 0); 274 275 ATF_REQUIRE(close(kq) == 0); 276 ATF_REQUIRE(close(p[0]) == 0); 277 ATF_REQUIRE(close(p[1]) == 0); 278 } 279 280 ATF_TC_WITHOUT_HEAD(fifo_kqueue__read_eof_wakeups); 281 ATF_TC_BODY(fifo_kqueue__read_eof_wakeups, tc) 282 { 283 int p[2] = { -1, -1 }; 284 285 ATF_REQUIRE(mkfifo("testfifo", 0600) == 0); 286 287 ATF_REQUIRE((p[0] = open("testfifo", 288 O_RDONLY | O_CLOEXEC | O_NONBLOCK)) >= 0); 289 ATF_REQUIRE((p[1] = open("testfifo", 290 O_WRONLY | O_CLOEXEC | O_NONBLOCK)) >= 0); 291 292 int kq = kqueue(); 293 ATF_REQUIRE(kq >= 0); 294 295 struct kevent kev[32]; 296 297 EV_SET(&kev[0], p[0], EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, 0); 298 ATF_REQUIRE(kevent(kq, kev, 1, NULL, 0, NULL) == 0); 299 300 ATF_REQUIRE(kevent(kq, NULL, 0, kev, nitems(kev), 301 &(struct timespec) { 0, 0 }) == 0); 302 303 /* 304 * Closing the writer must trigger a EVFILT_READ edge with EV_EOF set. 305 */ 306 307 ATF_REQUIRE(close(p[1]) == 0); 308 309 ATF_REQUIRE(kevent(kq, NULL, 0, kev, nitems(kev), 310 &(struct timespec) { 0, 0 }) == 1); 311 ATF_REQUIRE(kev[0].ident == (uintptr_t)p[0]); 312 ATF_REQUIRE(kev[0].filter == EVFILT_READ); 313 ATF_REQUIRE(kev[0].flags == (EV_EOF | EV_CLEAR)); 314 ATF_REQUIRE(kev[0].fflags == 0); 315 ATF_REQUIRE(kev[0].data == 0); 316 ATF_REQUIRE(kev[0].udata == 0); 317 318 /* 319 * Trying to read from a closed pipe should not trigger EVFILT_READ 320 * edges. 321 */ 322 323 char c; 324 ATF_REQUIRE(read(p[0], &c, 1) == 0); 325 326 ATF_REQUIRE(kevent(kq, NULL, 0, kev, nitems(kev), 327 &(struct timespec) { 0, 0 }) == 0); 328 329 ATF_REQUIRE(close(kq) == 0); 330 ATF_REQUIRE(close(p[0]) == 0); 331 } 332 333 ATF_TC_WITHOUT_HEAD(fifo_kqueue__read_eof_state_when_reconnecting); 334 ATF_TC_BODY(fifo_kqueue__read_eof_state_when_reconnecting, tc) 335 { 336 int p[2] = { -1, -1 }; 337 338 ATF_REQUIRE(mkfifo("testfifo", 0600) == 0); 339 340 ATF_REQUIRE((p[0] = open("testfifo", 341 O_RDONLY | O_CLOEXEC | O_NONBLOCK)) >= 0); 342 ATF_REQUIRE((p[1] = open("testfifo", 343 O_WRONLY | O_CLOEXEC | O_NONBLOCK)) >= 0); 344 345 int kq = kqueue(); 346 ATF_REQUIRE(kq >= 0); 347 348 struct kevent kev[32]; 349 350 EV_SET(&kev[0], p[0], EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, 0); 351 ATF_REQUIRE(kevent(kq, kev, 1, NULL, 0, NULL) == 0); 352 353 ATF_REQUIRE(kevent(kq, NULL, 0, kev, nitems(kev), 354 &(struct timespec) { 0, 0 }) == 0); 355 356 /* 357 * Closing the writer must trigger a EVFILT_READ edge with EV_EOF set. 358 */ 359 360 ATF_REQUIRE(close(p[1]) == 0); 361 362 ATF_REQUIRE(kevent(kq, NULL, 0, kev, nitems(kev), 363 &(struct timespec) { 0, 0 }) == 1); 364 ATF_REQUIRE(kev[0].ident == (uintptr_t)p[0]); 365 ATF_REQUIRE(kev[0].filter == EVFILT_READ); 366 ATF_REQUIRE(kev[0].flags == (EV_EOF | EV_CLEAR)); 367 ATF_REQUIRE(kev[0].fflags == 0); 368 ATF_REQUIRE(kev[0].data == 0); 369 ATF_REQUIRE(kev[0].udata == 0); 370 371 /* A new reader shouldn't see the EOF flag. */ 372 373 { 374 int new_reader; 375 ATF_REQUIRE((new_reader = open("testfifo", 376 O_RDONLY | O_CLOEXEC | O_NONBLOCK)) >= 0); 377 378 int new_kq = kqueue(); 379 ATF_REQUIRE(new_kq >= 0); 380 381 struct kevent new_kev[32]; 382 EV_SET(&new_kev[0], new_reader, EVFILT_READ, EV_ADD | EV_CLEAR, 383 0, 0, 0); 384 ATF_REQUIRE(kevent(new_kq, new_kev, 1, NULL, 0, NULL) == 0); 385 386 ATF_REQUIRE(kevent(new_kq, NULL, 0, new_kev, nitems(new_kev), 387 &(struct timespec) { 0, 0 }) == 0); 388 389 ATF_REQUIRE(close(new_kq) == 0); 390 ATF_REQUIRE(close(new_reader) == 0); 391 } 392 393 /* 394 * Simply reopening the writer does not trigger the EVFILT_READ again -- 395 * EV_EOF should be cleared, but there is no data yet so the filter 396 * does not trigger. 397 */ 398 399 ATF_REQUIRE((p[1] = open("testfifo", 400 O_WRONLY | O_CLOEXEC | O_NONBLOCK)) >= 0); 401 402 ATF_REQUIRE(kevent(kq, NULL, 0, kev, nitems(kev), 403 &(struct timespec) { 0, 0 }) == 0); 404 405 /* Writing a byte should trigger a EVFILT_READ. */ 406 407 char c = 0; 408 ATF_REQUIRE(write(p[1], &c, 1) == 1); 409 410 ATF_REQUIRE(kevent(kq, NULL, 0, kev, nitems(kev), 411 &(struct timespec) { 0, 0 }) == 1); 412 ATF_REQUIRE(kev[0].ident == (uintptr_t)p[0]); 413 ATF_REQUIRE(kev[0].filter == EVFILT_READ); 414 ATF_REQUIRE(kev[0].flags == EV_CLEAR); 415 ATF_REQUIRE(kev[0].fflags == 0); 416 ATF_REQUIRE(kev[0].data == 1); 417 ATF_REQUIRE(kev[0].udata == 0); 418 419 ATF_REQUIRE(close(kq) == 0); 420 ATF_REQUIRE(close(p[0]) == 0); 421 ATF_REQUIRE(close(p[1]) == 0); 422 } 423 424 ATF_TP_ADD_TCS(tp) 425 { 426 ATF_TP_ADD_TC(tp, fifo_kqueue__writes); 427 ATF_TP_ADD_TC(tp, fifo_kqueue__connecting_reader); 428 ATF_TP_ADD_TC(tp, fifo_kqueue__reads); 429 ATF_TP_ADD_TC(tp, fifo_kqueue__read_eof_wakeups); 430 ATF_TP_ADD_TC(tp, fifo_kqueue__read_eof_state_when_reconnecting); 431 432 return atf_no_error(); 433 } 434