1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright 2022 Oxide Computer Company 14 */ 15 16 #include <stdio.h> 17 #include <unistd.h> 18 #include <stdlib.h> 19 #include <fcntl.h> 20 #include <port.h> 21 #include <err.h> 22 #include <assert.h> 23 #include <sys/types.h> 24 #include <sys/stat.h> 25 #include <sys/param.h> 26 #include <sys/poll.h> 27 #include <stdbool.h> 28 29 static bool 30 has_event(int pfd) 31 { 32 port_event_t ev = { 0 }; 33 timespec_t ts = { 0 }; 34 35 /* Because of illumos 14912, more care needs to be taken here */ 36 int res = port_get(pfd, &ev, &ts); 37 if (res != 0 || ev.portev_source == 0) { 38 return (false); 39 } else { 40 return (true); 41 } 42 } 43 44 int 45 main(int argc, char *argv[]) 46 { 47 int res; 48 int pipes[2]; 49 50 res = pipe2(pipes, 0); 51 assert(res == 0); 52 53 int pfd = port_create(); 54 assert(pfd >= 0); 55 56 res = port_associate(pfd, PORT_SOURCE_FD, (uintptr_t)pipes[1], POLLIN, 57 NULL); 58 assert(res == 0); 59 60 if (has_event(pfd)) { 61 errx(EXIT_FAILURE, "FAIL - unexpected early event"); 62 } 63 64 char port_path[MAXPATHLEN]; 65 (void) sprintf(port_path, "/proc/%d/fd/%d", getpid(), pfd); 66 67 /* incur the procfs FDINFO access */ 68 struct stat sbuf; 69 res = lstat(port_path, &sbuf); 70 assert(res == 0); 71 72 /* write a byte to wake up the pipe */ 73 (void) write(pipes[0], port_path, 1); 74 75 /* 76 * Check to see that the FDINFO access did not detach our registration 77 * for the event port. 78 */ 79 if (!has_event(pfd)) { 80 errx(EXIT_FAILURE, "FAIL - no event found"); 81 } 82 83 (void) printf("PASS\n"); 84 return (EXIT_SUCCESS); 85 } 86