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