1*5e989a96SDavid Höppner /*
2*5e989a96SDavid Höppner  * This file and its contents are supplied under the terms of the
3*5e989a96SDavid Höppner  * Common Development and Distribution License ("CDDL"), version 1.0.
4*5e989a96SDavid Höppner  * You may only use this file in accordance with the terms of version
5*5e989a96SDavid Höppner  * 1.0 of the CDDL.
6*5e989a96SDavid Höppner  *
7*5e989a96SDavid Höppner  * A full copy of the text of the CDDL should have accompanied this
8*5e989a96SDavid Höppner  * source.  A copy of the CDDL is also available via the Internet at
9*5e989a96SDavid Höppner  * http://www.illumos.org/license/CDDL.
10*5e989a96SDavid Höppner  */
11*5e989a96SDavid Höppner 
12*5e989a96SDavid Höppner /*
13*5e989a96SDavid Höppner  * Copyright 2013 David Hoeppner.  All rights reserved.
14*5e989a96SDavid Höppner  */
15*5e989a96SDavid Höppner 
16*5e989a96SDavid Höppner /*
17*5e989a96SDavid Höppner  * Queue maximum number of signals and test if we can queue more signals then
18*5e989a96SDavid Höppner  * allowed.
19*5e989a96SDavid Höppner  */
20*5e989a96SDavid Höppner 
21*5e989a96SDavid Höppner #include <sys/types.h>
22*5e989a96SDavid Höppner #include <stdarg.h>
23*5e989a96SDavid Höppner #include <stdio.h>
24*5e989a96SDavid Höppner #include <stdlib.h>
25*5e989a96SDavid Höppner #include <unistd.h>
26*5e989a96SDavid Höppner #include <signal.h>
27*5e989a96SDavid Höppner 
28*5e989a96SDavid Höppner #define	SIGQUEUE_SIGNAL		SIGRTMIN	/* Signal used for testing */
29*5e989a96SDavid Höppner 
30*5e989a96SDavid Höppner int nreceived = 0;
31*5e989a96SDavid Höppner 
32*5e989a96SDavid Höppner static void
test_start(const char * test_name,const char * format,...)33*5e989a96SDavid Höppner test_start(const char *test_name, const char *format, ...)
34*5e989a96SDavid Höppner {
35*5e989a96SDavid Höppner 	va_list args;
36*5e989a96SDavid Höppner 
37*5e989a96SDavid Höppner 	(void) printf("TEST STARTING %s: ", test_name);
38*5e989a96SDavid Höppner 
39*5e989a96SDavid Höppner 	va_start(args, format);
40*5e989a96SDavid Höppner 	(void) vprintf(format, args);
41*5e989a96SDavid Höppner 	va_end(args);
42*5e989a96SDavid Höppner 	(void) fflush(stdout);
43*5e989a96SDavid Höppner }
44*5e989a96SDavid Höppner 
45*5e989a96SDavid Höppner static void
test_failed(const char * test_name,const char * format,...)46*5e989a96SDavid Höppner test_failed(const char *test_name, const char *format, ...)
47*5e989a96SDavid Höppner {
48*5e989a96SDavid Höppner 	va_list args;
49*5e989a96SDavid Höppner 
50*5e989a96SDavid Höppner 	(void) printf("TEST FAILED %s: ", test_name);
51*5e989a96SDavid Höppner 
52*5e989a96SDavid Höppner 	va_start(args, format);
53*5e989a96SDavid Höppner 	(void) vprintf(format, args);
54*5e989a96SDavid Höppner 	va_end(args);
55*5e989a96SDavid Höppner 
56*5e989a96SDavid Höppner 	(void) exit(-1);
57*5e989a96SDavid Höppner }
58*5e989a96SDavid Höppner 
59*5e989a96SDavid Höppner static void
test_passed(const char * test_name)60*5e989a96SDavid Höppner test_passed(const char *test_name)
61*5e989a96SDavid Höppner {
62*5e989a96SDavid Höppner 	(void) printf("TEST PASS: %s\n", test_name);
63*5e989a96SDavid Höppner 	(void) fflush(stdout);
64*5e989a96SDavid Höppner }
65*5e989a96SDavid Höppner 
66*5e989a96SDavid Höppner /* ARGSUSED */
67*5e989a96SDavid Höppner static void
maximum_test_handler(int signal,siginfo_t * siginfo,void * context)68*5e989a96SDavid Höppner maximum_test_handler(int signal, siginfo_t *siginfo, void *context)
69*5e989a96SDavid Höppner {
70*5e989a96SDavid Höppner 	nreceived++;
71*5e989a96SDavid Höppner }
72*5e989a96SDavid Höppner 
73*5e989a96SDavid Höppner static void
sigqueue_maximum_test(void)74*5e989a96SDavid Höppner sigqueue_maximum_test(void)
75*5e989a96SDavid Höppner {
76*5e989a96SDavid Höppner 	const char *test_name = __func__;
77*5e989a96SDavid Höppner 	struct sigaction action;
78*5e989a96SDavid Höppner 	long sigqueue_max, i;
79*5e989a96SDavid Höppner 	pid_t pid;
80*5e989a96SDavid Höppner 	union sigval value;
81*5e989a96SDavid Höppner 	int error;
82*5e989a96SDavid Höppner 
83*5e989a96SDavid Höppner 	test_start(test_name, "queue maximum number of signals\n");
84*5e989a96SDavid Höppner 
85*5e989a96SDavid Höppner 	/*
86*5e989a96SDavid Höppner 	 * Get the maximum size of the queue.
87*5e989a96SDavid Höppner 	 */
88*5e989a96SDavid Höppner 	sigqueue_max = sysconf(_SC_SIGQUEUE_MAX);
89*5e989a96SDavid Höppner 	if (sigqueue_max == -1) {
90*5e989a96SDavid Höppner 		test_failed(test_name, "sysconf\n");
91*5e989a96SDavid Höppner 	}
92*5e989a96SDavid Höppner 
93*5e989a96SDavid Höppner 	/*
94*5e989a96SDavid Höppner 	 * Put the signal on hold.
95*5e989a96SDavid Höppner 	 */
96*5e989a96SDavid Höppner 	error = sighold(SIGQUEUE_SIGNAL);
97*5e989a96SDavid Höppner 	if (error == -1) {
98*5e989a96SDavid Höppner 		test_failed(test_name, "sighold\n");
99*5e989a96SDavid Höppner 	}
100*5e989a96SDavid Höppner 
101*5e989a96SDavid Höppner 	pid = getpid();
102*5e989a96SDavid Höppner 	value.sival_int = 0;
103*5e989a96SDavid Höppner 
104*5e989a96SDavid Höppner 	action.sa_flags = SA_SIGINFO;
105*5e989a96SDavid Höppner 	action.sa_sigaction = maximum_test_handler;
106*5e989a96SDavid Höppner 
107*5e989a96SDavid Höppner 	error = sigemptyset(&action.sa_mask);
108*5e989a96SDavid Höppner 	if (error == -1) {
109*5e989a96SDavid Höppner 		test_failed(test_name, "sigemptyset\n");
110*5e989a96SDavid Höppner 	}
111*5e989a96SDavid Höppner 
112*5e989a96SDavid Höppner 	/*
113*5e989a96SDavid Höppner 	 * Set signal handler.
114*5e989a96SDavid Höppner 	 */
115*5e989a96SDavid Höppner 	error = sigaction(SIGQUEUE_SIGNAL, &action, 0);
116*5e989a96SDavid Höppner 	if (error == -1) {
117*5e989a96SDavid Höppner 		test_failed(test_name, "sigaction\n");
118*5e989a96SDavid Höppner 	}
119*5e989a96SDavid Höppner 
120*5e989a96SDavid Höppner 	/*
121*5e989a96SDavid Höppner 	 * Fill the signal queue to the maximum.
122*5e989a96SDavid Höppner 	 */
123*5e989a96SDavid Höppner 	for (i = 0; i < sigqueue_max; i++) {
124*5e989a96SDavid Höppner 		error = sigqueue(pid, SIGQUEUE_SIGNAL, value);
125*5e989a96SDavid Höppner 		if (error == -1) {
126*5e989a96SDavid Höppner 			test_failed(test_name, "sigqueue\n");
127*5e989a96SDavid Höppner 		}
128*5e989a96SDavid Höppner 	}
129*5e989a96SDavid Höppner 
130*5e989a96SDavid Höppner 	/*
131*5e989a96SDavid Höppner 	 * Send a further signal and test if we get the expected
132*5e989a96SDavid Höppner 	 * error.
133*5e989a96SDavid Höppner 	 */
134*5e989a96SDavid Höppner 	error = sigqueue(pid, SIGQUEUE_SIGNAL, value);
135*5e989a96SDavid Höppner 	if (error != -1) {
136*5e989a96SDavid Höppner 		test_failed(test_name, "sigqueue\n");
137*5e989a96SDavid Höppner 	}
138*5e989a96SDavid Höppner 
139*5e989a96SDavid Höppner 	/*
140*5e989a96SDavid Höppner 	 * Unblock the signals and check if we received all messages
141*5e989a96SDavid Höppner 	 * from the signal queue.
142*5e989a96SDavid Höppner 	 */
143*5e989a96SDavid Höppner 	error = sigrelse(SIGQUEUE_SIGNAL);
144*5e989a96SDavid Höppner 	if (error == -1) {
145*5e989a96SDavid Höppner 		test_failed(test_name, "sigrelse\n");
146*5e989a96SDavid Höppner 	}
147*5e989a96SDavid Höppner 
148*5e989a96SDavid Höppner 	if (nreceived != sigqueue_max) {
149*5e989a96SDavid Höppner 		test_failed(test_name, "nreceived != sigqueue_max\n");
150*5e989a96SDavid Höppner 	}
151*5e989a96SDavid Höppner 
152*5e989a96SDavid Höppner 	test_passed(test_name);
153*5e989a96SDavid Höppner }
154*5e989a96SDavid Höppner 
155*5e989a96SDavid Höppner static void
run_tests(void)156*5e989a96SDavid Höppner run_tests(void)
157*5e989a96SDavid Höppner {
158*5e989a96SDavid Höppner 	sigqueue_maximum_test();
159*5e989a96SDavid Höppner }
160*5e989a96SDavid Höppner 
161*5e989a96SDavid Höppner /* ARGSUSED */
162*5e989a96SDavid Höppner int
main(int argc,char * argv[])163*5e989a96SDavid Höppner main(int argc, char *argv[])
164*5e989a96SDavid Höppner {
165*5e989a96SDavid Höppner 	run_tests();
166*5e989a96SDavid Höppner 
167*5e989a96SDavid Höppner 	return (EXIT_SUCCESS);
168*5e989a96SDavid Höppner }
169