1200483Srwatson/* 2200483Srwatson * Copyright (c) 2009 Mark Heily <mark@heily.com> 3200483Srwatson * 4200483Srwatson * Permission to use, copy, modify, and distribute this software for any 5200483Srwatson * purpose with or without fee is hereby granted, provided that the above 6200483Srwatson * copyright notice and this permission notice appear in all copies. 7200483Srwatson * 8200483Srwatson * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9200483Srwatson * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10200483Srwatson * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11200483Srwatson * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12200483Srwatson * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13200483Srwatson * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14200483Srwatson * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15200483Srwatson * 16200483Srwatson * $FreeBSD: stable/10/tests/sys/kqueue/libkqueue/read.c 305467 2016-09-06 08:45:29Z ngie $ 17200483Srwatson */ 18200483Srwatson 19200483Srwatson#include "common.h" 20200483Srwatson 21200483Srwatsonint kqfd; 22200483Srwatsonint sockfd[2]; 23200483Srwatson 24200483Srwatsonstatic void 25200483Srwatsonkevent_socket_drain(void) 26200483Srwatson{ 27200483Srwatson char buf[1]; 28200483Srwatson 29200483Srwatson /* Drain the read buffer, then make sure there are no more events. */ 30200483Srwatson puts("draining the read buffer"); 31200483Srwatson if (read(sockfd[0], &buf[0], 1) < 1) 32200483Srwatson err(1, "read(2)"); 33200483Srwatson} 34200483Srwatson 35200483Srwatsonstatic void 36200483Srwatsonkevent_socket_fill(void) 37200483Srwatson{ 38200483Srwatson puts("filling the read buffer"); 39200483Srwatson if (write(sockfd[1], ".", 1) < 1) 40200483Srwatson err(1, "write(2)"); 41200483Srwatson} 42200483Srwatson 43200483Srwatson 44200483Srwatsonvoid 45200483Srwatsontest_kevent_socket_add(void) 46200483Srwatson{ 47200483Srwatson const char *test_id = "kevent(EVFILT_READ, EV_ADD)"; 48200483Srwatson struct kevent kev; 49200483Srwatson 50200483Srwatson test_begin(test_id); 51200483Srwatson EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD, 0, 0, &sockfd[0]); 52200483Srwatson if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 53200483Srwatson err(1, "%s", test_id); 54200483Srwatson 55200483Srwatson success(); 56200483Srwatson} 57200483Srwatson 58200483Srwatsonvoid 59200483Srwatsontest_kevent_socket_get(void) 60200483Srwatson{ 61200483Srwatson const char *test_id = "kevent(EVFILT_READ) wait"; 62200483Srwatson struct kevent kev; 63200483Srwatson 64200483Srwatson test_begin(test_id); 65200483Srwatson 66200483Srwatson EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD, 0, 0, &sockfd[0]); 67200483Srwatson if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 68200483Srwatson err(1, "%s", test_id); 69200483Srwatson 70200483Srwatson kevent_socket_fill(); 71200483Srwatson 72200483Srwatson kev.data = 1; 73200483Srwatson kevent_cmp(&kev, kevent_get(kqfd)); 74200483Srwatson 75200483Srwatson kevent_socket_drain(); 76200483Srwatson test_no_kevents(); 77200483Srwatson 78200483Srwatson kev.flags = EV_DELETE; 79200483Srwatson if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 80200483Srwatson err(1, "%s", test_id); 81200483Srwatson 82200483Srwatson success(); 83200483Srwatson} 84200483Srwatson 85200483Srwatsonvoid 86200483Srwatsontest_kevent_socket_clear(void) 87200483Srwatson{ 88200483Srwatson const char *test_id = "kevent(EVFILT_READ, EV_CLEAR)"; 89200483Srwatson struct kevent kev; 90200483Srwatson 91200483Srwatson test_begin(test_id); 92200483Srwatson 93200483Srwatson test_no_kevents(); 94200483Srwatson 95200483Srwatson EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, &sockfd[0]); 96200483Srwatson if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 97200483Srwatson err(1, "%s", test_id); 98200483Srwatson 99200483Srwatson kevent_socket_fill(); 100200483Srwatson kevent_socket_fill(); 101200483Srwatson 102200483Srwatson kev.data = 2; 103200483Srwatson kevent_cmp(&kev, kevent_get(kqfd)); 104200483Srwatson 105200483Srwatson /* We filled twice, but drain once. Edge-triggered would not generate 106200483Srwatson additional events. 107200483Srwatson */ 108200483Srwatson kevent_socket_drain(); 109200483Srwatson test_no_kevents(); 110200483Srwatson 111200483Srwatson kevent_socket_drain(); 112200483Srwatson EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DELETE, 0, 0, &sockfd[0]); 113200483Srwatson if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 114200483Srwatson err(1, "%s", test_id); 115200483Srwatson 116200483Srwatson success(); 117200483Srwatson} 118200483Srwatson 119200483Srwatsonvoid 120200483Srwatsontest_kevent_socket_disable_and_enable(void) 121200483Srwatson{ 122200483Srwatson const char *test_id = "kevent(EVFILT_READ, EV_DISABLE)"; 123200483Srwatson struct kevent kev; 124200483Srwatson 125200483Srwatson test_begin(test_id); 126200483Srwatson 127295786Smarkj /* 128295786Smarkj * Write to the socket before adding the event. This way we can verify that 129295786Smarkj * enabling a triggered kevent causes the event to be returned immediately. 130295786Smarkj */ 131295786Smarkj kevent_socket_fill(); 132295786Smarkj 133295786Smarkj /* Add a disabled event. */ 134295786Smarkj EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD | EV_DISABLE, 0, 0, &sockfd[0]); 135200483Srwatson if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 136200483Srwatson err(1, "%s", test_id); 137200483Srwatson 138200483Srwatson test_no_kevents(); 139200483Srwatson 140200483Srwatson /* Re-enable the knote, then see if an event is generated */ 141200483Srwatson kev.flags = EV_ENABLE; 142200483Srwatson if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 143200483Srwatson err(1, "%s", test_id); 144200483Srwatson kev.flags = EV_ADD; 145200483Srwatson kev.data = 1; 146200483Srwatson kevent_cmp(&kev, kevent_get(kqfd)); 147200483Srwatson 148200483Srwatson kevent_socket_drain(); 149200483Srwatson 150200483Srwatson kev.flags = EV_DELETE; 151200483Srwatson if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 152200483Srwatson err(1, "%s", test_id); 153200483Srwatson 154200483Srwatson success(); 155200483Srwatson} 156200483Srwatson 157200483Srwatsonvoid 158200483Srwatsontest_kevent_socket_del(void) 159200483Srwatson{ 160200483Srwatson const char *test_id = "kevent(EVFILT_READ, EV_DELETE)"; 161200483Srwatson struct kevent kev; 162200483Srwatson 163200483Srwatson test_begin(test_id); 164200483Srwatson 165200483Srwatson EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DELETE, 0, 0, &sockfd[0]); 166200483Srwatson if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 167200483Srwatson err(1, "%s", test_id); 168200483Srwatson 169200483Srwatson kevent_socket_fill(); 170200483Srwatson test_no_kevents(); 171200483Srwatson kevent_socket_drain(); 172200483Srwatson 173200483Srwatson success(); 174200483Srwatson} 175200483Srwatson 176200483Srwatsonvoid 177200483Srwatsontest_kevent_socket_oneshot(void) 178200483Srwatson{ 179200483Srwatson const char *test_id = "kevent(EVFILT_READ, EV_ONESHOT)"; 180200483Srwatson struct kevent kev; 181200483Srwatson 182200483Srwatson test_begin(test_id); 183200483Srwatson 184200483Srwatson /* Re-add the watch and make sure no events are pending */ 185200483Srwatson puts("-- re-adding knote"); 186200483Srwatson EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD | EV_ONESHOT, 0, 0, &sockfd[0]); 187200483Srwatson if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 188200483Srwatson err(1, "%s", test_id); 189200483Srwatson test_no_kevents(); 190200483Srwatson 191200483Srwatson puts("-- getting one event"); 192200483Srwatson kevent_socket_fill(); 193200483Srwatson kev.data = 1; 194200483Srwatson kevent_cmp(&kev, kevent_get(kqfd)); 195200483Srwatson 196200483Srwatson puts("-- checking knote disabled"); 197200483Srwatson test_no_kevents(); 198200483Srwatson 199200483Srwatson /* Try to delete the knote, it should already be deleted */ 200200483Srwatson EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DELETE, 0, 0, &sockfd[0]); 201200483Srwatson if (kevent(kqfd, &kev, 1, NULL, 0, NULL) == 0) 202200483Srwatson err(1, "%s", test_id); 203200483Srwatson 204200483Srwatson kevent_socket_drain(); 205200483Srwatson 206200483Srwatson success(); 207200483Srwatson} 208200483Srwatson 209200483Srwatson 210200483Srwatson#if HAVE_EV_DISPATCH 211200483Srwatsonvoid 212200483Srwatsontest_kevent_socket_dispatch(void) 213200483Srwatson{ 214200483Srwatson const char *test_id = "kevent(EVFILT_READ, EV_DISPATCH)"; 215200483Srwatson 216200483Srwatson test_begin(test_id); 217200483Srwatson 218200483Srwatson struct kevent kev; 219200483Srwatson 220200483Srwatson /* Re-add the watch and make sure no events are pending */ 221200483Srwatson puts("-- re-adding knote"); 222200483Srwatson EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD | EV_DISPATCH, 0, 0, &sockfd[0]); 223200483Srwatson if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 224200483Srwatson err(1, "%s", test_id); 225200483Srwatson test_no_kevents(); 226200483Srwatson 227200483Srwatson /* The event will occur only once, even though EV_CLEAR is not 228200483Srwatson specified. */ 229200483Srwatson kevent_socket_fill(); 230200483Srwatson kev.data = 1; 231200483Srwatson kevent_cmp(&kev, kevent_get(kqfd)); 232200483Srwatson test_no_kevents(); 233200483Srwatson 234200483Srwatson /* Since the knote is disabled, the EV_DELETE operation succeeds. */ 235200483Srwatson EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DELETE, 0, 0, &sockfd[0]); 236200483Srwatson if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 237200483Srwatson err(1, "%s", test_id); 238200483Srwatson 239200483Srwatson kevent_socket_drain(); 240200483Srwatson 241200483Srwatson success(); 242200483Srwatson} 243200483Srwatson#endif /* HAVE_EV_DISPATCH */ 244200483Srwatson 245200483Srwatson#if BROKEN 246200483Srwatsonvoid 247200483Srwatsontest_kevent_socket_lowat(void) 248200483Srwatson{ 249200483Srwatson const char *test_id = "kevent(EVFILT_READ, NOTE_LOWAT)"; 250200483Srwatson struct kevent kev; 251200483Srwatson 252200483Srwatson test_begin(test_id); 253200483Srwatson 254200483Srwatson /* Re-add the watch and make sure no events are pending */ 255200483Srwatson puts("-- re-adding knote, setting low watermark to 2 bytes"); 256200483Srwatson EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD | EV_ONESHOT, NOTE_LOWAT, 2, &sockfd[0]); 257200483Srwatson if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 258200483Srwatson err(1, "%s", test_id); 259200483Srwatson test_no_kevents(); 260200483Srwatson 261200483Srwatson puts("-- checking that one byte does not trigger an event.."); 262200483Srwatson kevent_socket_fill(); 263200483Srwatson test_no_kevents(); 264200483Srwatson 265200483Srwatson puts("-- checking that two bytes triggers an event.."); 266200483Srwatson kevent_socket_fill(); 267200483Srwatson if (kevent(kqfd, NULL, 0, &kev, 1, NULL) != 1) 268200483Srwatson err(1, "%s", test_id); 269200483Srwatson KEV_CMP(kev, sockfd[0], EVFILT_READ, 0); 270200483Srwatson test_no_kevents(); 271200483Srwatson 272200483Srwatson kevent_socket_drain(); 273200483Srwatson kevent_socket_drain(); 274200483Srwatson 275200483Srwatson success(); 276200483Srwatson} 277200483Srwatson#endif 278200483Srwatson 279200483Srwatsonvoid 280200483Srwatsontest_kevent_socket_eof(void) 281200483Srwatson{ 282200483Srwatson const char *test_id = "kevent(EVFILT_READ, EV_EOF)"; 283200483Srwatson struct kevent kev; 284200483Srwatson 285200483Srwatson test_begin(test_id); 286200483Srwatson 287200483Srwatson /* Re-add the watch and make sure no events are pending */ 288200483Srwatson EV_SET(&kev, sockfd[0], EVFILT_READ, EV_ADD, 0, 0, &sockfd[0]); 289200483Srwatson if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 290200483Srwatson err(1, "%s", test_id); 291200483Srwatson test_no_kevents(); 292200483Srwatson 293200483Srwatson if (close(sockfd[1]) < 0) 294200483Srwatson err(1, "close(2)"); 295200483Srwatson 296200483Srwatson kev.flags |= EV_EOF; 297200483Srwatson kevent_cmp(&kev, kevent_get(kqfd)); 298200483Srwatson 299200483Srwatson /* Delete the watch */ 300200483Srwatson EV_SET(&kev, sockfd[0], EVFILT_READ, EV_DELETE, 0, 0, &sockfd[0]); 301200483Srwatson if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 302200483Srwatson err(1, "%s", test_id); 303200483Srwatson 304200483Srwatson success(); 305200483Srwatson} 306200483Srwatson 307200483Srwatsonvoid 308200483Srwatsontest_evfilt_read() 309200483Srwatson{ 310200483Srwatson /* Create a connected pair of full-duplex sockets for testing socket events */ 311200483Srwatson if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd) < 0) 312200483Srwatson abort(); 313200483Srwatson 314200483Srwatson kqfd = kqueue(); 315200483Srwatson test_kevent_socket_add(); 316200483Srwatson test_kevent_socket_del(); 317200483Srwatson test_kevent_socket_get(); 318200483Srwatson test_kevent_socket_disable_and_enable(); 319200483Srwatson test_kevent_socket_oneshot(); 320200483Srwatson test_kevent_socket_clear(); 321200483Srwatson#if HAVE_EV_DISPATCH 322200483Srwatson test_kevent_socket_dispatch(); 323200483Srwatson#endif 324200483Srwatson test_kevent_socket_eof(); 325200483Srwatson close(kqfd); 326200483Srwatson} 327