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 2023 Oxide Computer Company 14 */ 15 16 17 #include <stdlib.h> 18 #include <unistd.h> 19 #include <fcntl.h> 20 21 #include "common.h" 22 23 int 24 main(void) 25 { 26 int err; 27 ssize_t sz; 28 signalfd_siginfo_t info[3]; 29 30 const int fd = test_basic_prep(0); 31 32 /* A too-small read should yield EINVAL */ 33 sz = read(fd, info, sizeof (signalfd_siginfo_t) - 1); 34 err = errno; 35 if (sz != -1 || errno != EINVAL) { 36 test_fail("expected EINVAL for too-small read, " 37 "found res=%ld errno=%d", sz, err); 38 } 39 40 const int pid = getpid(); 41 42 /* simple single read */ 43 assert(kill(pid, SIGUSR1) == 0); 44 sz = read(fd, info, sizeof (signalfd_siginfo_t)); 45 err = errno; 46 if (sz != sizeof (signalfd_siginfo_t)) { 47 test_fail("bad read result, found sz=%ld errno=%d", sz, err); 48 } 49 if (info[0].ssi_signo != SIGUSR1) { 50 test_fail("bad ssi_signo %d != %d", info[0].ssi_signo, SIGUSR1); 51 } 52 53 struct sigevent sigev = { 54 .sigev_notify = SIGEV_SIGNAL, 55 .sigev_signo = SIGALRM, 56 }; 57 timer_t tid; 58 struct itimerspec its_1ms = { 59 .it_value = { 60 .tv_sec = 0, 61 .tv_nsec = MSEC2NSEC(1), 62 } 63 }; 64 65 /* block for a single read: a SIGALRM 1ms in the future */ 66 assert(timer_create(CLOCK_HIGHRES, &sigev, &tid) == 0); 67 assert(timer_settime(tid, 0, &its_1ms, NULL) == 0); 68 sz = read(fd, info, sizeof (signalfd_siginfo_t)); 69 err = errno; 70 if (sz != sizeof (signalfd_siginfo_t)) { 71 test_fail("bad read result, found sz=%ld errno=%d", sz, err); 72 } 73 if (info[0].ssi_signo != SIGALRM) { 74 test_fail("bad ssi_signo %d != %d", info[0].ssi_signo, SIGALRM); 75 } 76 77 /* 78 * If we get a result during a read, we should not block until the 79 * entire buffer is full, but rather return what we have. 80 */ 81 assert(kill(pid, SIGUSR1) == 0); 82 assert(kill(pid, SIGUSR2) == 0); 83 sz = read(fd, info, sizeof (info)); 84 err = errno; 85 if (sz != (2 * sizeof (signalfd_siginfo_t))) { 86 test_fail("bad read result, found sz=%ld errno=%d", sz, err); 87 } 88 if (info[0].ssi_signo != SIGUSR1) { 89 test_fail("bad ssi_signo %d != %d", info[0].ssi_signo, SIGUSR1); 90 } 91 if (info[1].ssi_signo != SIGUSR2) { 92 test_fail("bad ssi_signo %d != %d", info[1].ssi_signo, SIGUSR2); 93 } 94 95 test_pass(); 96 } 97