1*6f58b090SIlya Leoshkevich /*
2*6f58b090SIlya Leoshkevich * Test the lowest and the highest real-time signals.
3*6f58b090SIlya Leoshkevich *
4*6f58b090SIlya Leoshkevich * SPDX-License-Identifier: GPL-2.0-or-later
5*6f58b090SIlya Leoshkevich */
6*6f58b090SIlya Leoshkevich #include <assert.h>
7*6f58b090SIlya Leoshkevich #include <signal.h>
8*6f58b090SIlya Leoshkevich #include <stdbool.h>
9*6f58b090SIlya Leoshkevich #include <stdio.h>
10*6f58b090SIlya Leoshkevich #include <stdlib.h>
11*6f58b090SIlya Leoshkevich #include <string.h>
12*6f58b090SIlya Leoshkevich #include <unistd.h>
13*6f58b090SIlya Leoshkevich
14*6f58b090SIlya Leoshkevich /* For hexagon and microblaze. */
15*6f58b090SIlya Leoshkevich #ifndef __SIGRTMIN
16*6f58b090SIlya Leoshkevich #define __SIGRTMIN 32
17*6f58b090SIlya Leoshkevich #endif
18*6f58b090SIlya Leoshkevich
19*6f58b090SIlya Leoshkevich extern char **environ;
20*6f58b090SIlya Leoshkevich
21*6f58b090SIlya Leoshkevich static bool seen_sigrtmin, seen_sigrtmax;
22*6f58b090SIlya Leoshkevich
handle_signal(int sig)23*6f58b090SIlya Leoshkevich static void handle_signal(int sig)
24*6f58b090SIlya Leoshkevich {
25*6f58b090SIlya Leoshkevich if (sig == SIGRTMIN) {
26*6f58b090SIlya Leoshkevich seen_sigrtmin = true;
27*6f58b090SIlya Leoshkevich } else if (sig == SIGRTMAX) {
28*6f58b090SIlya Leoshkevich seen_sigrtmax = true;
29*6f58b090SIlya Leoshkevich } else {
30*6f58b090SIlya Leoshkevich _exit(1);
31*6f58b090SIlya Leoshkevich }
32*6f58b090SIlya Leoshkevich }
33*6f58b090SIlya Leoshkevich
main(int argc,char ** argv)34*6f58b090SIlya Leoshkevich int main(int argc, char **argv)
35*6f58b090SIlya Leoshkevich {
36*6f58b090SIlya Leoshkevich char *qemu = getenv("QEMU");
37*6f58b090SIlya Leoshkevich struct sigaction act;
38*6f58b090SIlya Leoshkevich
39*6f58b090SIlya Leoshkevich assert(qemu);
40*6f58b090SIlya Leoshkevich
41*6f58b090SIlya Leoshkevich if (!getenv("QEMU_RTSIG_MAP")) {
42*6f58b090SIlya Leoshkevich char **new_argv = malloc((argc + 2) + sizeof(char *));
43*6f58b090SIlya Leoshkevich int tsig1, hsig1, count1, tsig2, hsig2, count2;
44*6f58b090SIlya Leoshkevich char rt_sigmap[64];
45*6f58b090SIlya Leoshkevich
46*6f58b090SIlya Leoshkevich /* Re-exec with a mapping that includes SIGRTMIN and SIGRTMAX. */
47*6f58b090SIlya Leoshkevich new_argv[0] = qemu;
48*6f58b090SIlya Leoshkevich memcpy(&new_argv[1], argv, (argc + 1) * sizeof(char *));
49*6f58b090SIlya Leoshkevich tsig1 = __SIGRTMIN;
50*6f58b090SIlya Leoshkevich /* The host must have a few signals starting from this one. */
51*6f58b090SIlya Leoshkevich hsig1 = 36;
52*6f58b090SIlya Leoshkevich count1 = SIGRTMIN - __SIGRTMIN + 1;
53*6f58b090SIlya Leoshkevich tsig2 = SIGRTMAX;
54*6f58b090SIlya Leoshkevich hsig2 = hsig1 + count1;
55*6f58b090SIlya Leoshkevich count2 = 1;
56*6f58b090SIlya Leoshkevich snprintf(rt_sigmap, sizeof(rt_sigmap), "%d %d %d,%d %d %d",
57*6f58b090SIlya Leoshkevich tsig1, hsig1, count1, tsig2, hsig2, count2);
58*6f58b090SIlya Leoshkevich setenv("QEMU_RTSIG_MAP", rt_sigmap, 0);
59*6f58b090SIlya Leoshkevich assert(execve(new_argv[0], new_argv, environ) == 0);
60*6f58b090SIlya Leoshkevich return EXIT_FAILURE;
61*6f58b090SIlya Leoshkevich }
62*6f58b090SIlya Leoshkevich
63*6f58b090SIlya Leoshkevich memset(&act, 0, sizeof(act));
64*6f58b090SIlya Leoshkevich act.sa_handler = handle_signal;
65*6f58b090SIlya Leoshkevich assert(sigaction(SIGRTMIN, &act, NULL) == 0);
66*6f58b090SIlya Leoshkevich assert(sigaction(SIGRTMAX, &act, NULL) == 0);
67*6f58b090SIlya Leoshkevich
68*6f58b090SIlya Leoshkevich assert(kill(getpid(), SIGRTMIN) == 0);
69*6f58b090SIlya Leoshkevich assert(seen_sigrtmin);
70*6f58b090SIlya Leoshkevich assert(kill(getpid(), SIGRTMAX) == 0);
71*6f58b090SIlya Leoshkevich assert(seen_sigrtmax);
72*6f58b090SIlya Leoshkevich
73*6f58b090SIlya Leoshkevich return EXIT_SUCCESS;
74*6f58b090SIlya Leoshkevich }
75