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