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