1*374858d2SPatrick Mooney /*
2*374858d2SPatrick Mooney  * This file and its contents are supplied under the terms of the
3*374858d2SPatrick Mooney  * Common Development and Distribution License ("CDDL"), version 1.0.
4*374858d2SPatrick Mooney  * You may only use this file in accordance with the terms of version
5*374858d2SPatrick Mooney  * 1.0 of the CDDL.
6*374858d2SPatrick Mooney  *
7*374858d2SPatrick Mooney  * A full copy of the text of the CDDL should have accompanied this
8*374858d2SPatrick Mooney  * source.  A copy of the CDDL is also available via the Internet at
9*374858d2SPatrick Mooney  * http://www.illumos.org/license/CDDL.
10*374858d2SPatrick Mooney  */
11*374858d2SPatrick Mooney 
12*374858d2SPatrick Mooney /*
13*374858d2SPatrick Mooney  * Copyright 2023 Oxide Computer Company
14*374858d2SPatrick Mooney  */
15*374858d2SPatrick Mooney 
16*374858d2SPatrick Mooney 
17*374858d2SPatrick Mooney #include <stdlib.h>
18*374858d2SPatrick Mooney #include <unistd.h>
19*374858d2SPatrick Mooney #include <fcntl.h>
20*374858d2SPatrick Mooney 
21*374858d2SPatrick Mooney #include "common.h"
22*374858d2SPatrick Mooney 
23*374858d2SPatrick Mooney int
main(void)24*374858d2SPatrick Mooney main(void)
25*374858d2SPatrick Mooney {
26*374858d2SPatrick Mooney 	int err;
27*374858d2SPatrick Mooney 	ssize_t sz;
28*374858d2SPatrick Mooney 	signalfd_siginfo_t info[3];
29*374858d2SPatrick Mooney 
30*374858d2SPatrick Mooney 	const int fd = test_basic_prep(0);
31*374858d2SPatrick Mooney 
32*374858d2SPatrick Mooney 	/* A too-small read should yield EINVAL */
33*374858d2SPatrick Mooney 	sz = read(fd, info, sizeof (signalfd_siginfo_t) - 1);
34*374858d2SPatrick Mooney 	err = errno;
35*374858d2SPatrick Mooney 	if (sz != -1 || errno != EINVAL) {
36*374858d2SPatrick Mooney 		test_fail("expected EINVAL for too-small read, "
37*374858d2SPatrick Mooney 		    "found res=%ld errno=%d", sz, err);
38*374858d2SPatrick Mooney 	}
39*374858d2SPatrick Mooney 
40*374858d2SPatrick Mooney 	const int pid = getpid();
41*374858d2SPatrick Mooney 
42*374858d2SPatrick Mooney 	/* simple single read */
43*374858d2SPatrick Mooney 	assert(kill(pid, SIGUSR1) == 0);
44*374858d2SPatrick Mooney 	sz = read(fd, info, sizeof (signalfd_siginfo_t));
45*374858d2SPatrick Mooney 	err = errno;
46*374858d2SPatrick Mooney 	if (sz != sizeof (signalfd_siginfo_t)) {
47*374858d2SPatrick Mooney 		test_fail("bad read result, found sz=%ld errno=%d", sz, err);
48*374858d2SPatrick Mooney 	}
49*374858d2SPatrick Mooney 	if (info[0].ssi_signo != SIGUSR1) {
50*374858d2SPatrick Mooney 		test_fail("bad ssi_signo %d != %d", info[0].ssi_signo, SIGUSR1);
51*374858d2SPatrick Mooney 	}
52*374858d2SPatrick Mooney 
53*374858d2SPatrick Mooney 	struct sigevent sigev = {
54*374858d2SPatrick Mooney 		.sigev_notify = SIGEV_SIGNAL,
55*374858d2SPatrick Mooney 		.sigev_signo = SIGALRM,
56*374858d2SPatrick Mooney 	};
57*374858d2SPatrick Mooney 	timer_t tid;
58*374858d2SPatrick Mooney 	struct itimerspec its_1ms = {
59*374858d2SPatrick Mooney 		.it_value = {
60*374858d2SPatrick Mooney 			.tv_sec = 0,
61*374858d2SPatrick Mooney 			.tv_nsec = MSEC2NSEC(1),
62*374858d2SPatrick Mooney 		}
63*374858d2SPatrick Mooney 	};
64*374858d2SPatrick Mooney 
65*374858d2SPatrick Mooney 	/* block for a single read: a SIGALRM 1ms in the future */
66*374858d2SPatrick Mooney 	assert(timer_create(CLOCK_HIGHRES, &sigev, &tid) == 0);
67*374858d2SPatrick Mooney 	assert(timer_settime(tid, 0, &its_1ms, NULL) == 0);
68*374858d2SPatrick Mooney 	sz = read(fd, info, sizeof (signalfd_siginfo_t));
69*374858d2SPatrick Mooney 	err = errno;
70*374858d2SPatrick Mooney 	if (sz != sizeof (signalfd_siginfo_t)) {
71*374858d2SPatrick Mooney 		test_fail("bad read result, found sz=%ld errno=%d", sz, err);
72*374858d2SPatrick Mooney 	}
73*374858d2SPatrick Mooney 	if (info[0].ssi_signo != SIGALRM) {
74*374858d2SPatrick Mooney 		test_fail("bad ssi_signo %d != %d", info[0].ssi_signo, SIGALRM);
75*374858d2SPatrick Mooney 	}
76*374858d2SPatrick Mooney 
77*374858d2SPatrick Mooney 	/*
78*374858d2SPatrick Mooney 	 * If we get a result during a read, we should not block until the
79*374858d2SPatrick Mooney 	 * entire buffer is full, but rather return what we have.
80*374858d2SPatrick Mooney 	 */
81*374858d2SPatrick Mooney 	assert(kill(pid, SIGUSR1) == 0);
82*374858d2SPatrick Mooney 	assert(kill(pid, SIGUSR2) == 0);
83*374858d2SPatrick Mooney 	sz = read(fd, info, sizeof (info));
84*374858d2SPatrick Mooney 	err = errno;
85*374858d2SPatrick Mooney 	if (sz != (2 * sizeof (signalfd_siginfo_t))) {
86*374858d2SPatrick Mooney 		test_fail("bad read result, found sz=%ld errno=%d", sz, err);
87*374858d2SPatrick Mooney 	}
88*374858d2SPatrick Mooney 	if (info[0].ssi_signo != SIGUSR1) {
89*374858d2SPatrick Mooney 		test_fail("bad ssi_signo %d != %d", info[0].ssi_signo, SIGUSR1);
90*374858d2SPatrick Mooney 	}
91*374858d2SPatrick Mooney 	if (info[1].ssi_signo != SIGUSR2) {
92*374858d2SPatrick Mooney 		test_fail("bad ssi_signo %d != %d", info[1].ssi_signo, SIGUSR2);
93*374858d2SPatrick Mooney 	}
94*374858d2SPatrick Mooney 
95*374858d2SPatrick Mooney 	test_pass();
96*374858d2SPatrick Mooney }
97