summary refs log tree commit diff stats
path: root/tests/tcg/multiarch/linux/linux-sigrtminmax.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/tcg/multiarch/linux/linux-sigrtminmax.c')
-rw-r--r--tests/tcg/multiarch/linux/linux-sigrtminmax.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/tests/tcg/multiarch/linux/linux-sigrtminmax.c b/tests/tcg/multiarch/linux/linux-sigrtminmax.c
new file mode 100644
index 0000000000..a7059aacd9
--- /dev/null
+++ b/tests/tcg/multiarch/linux/linux-sigrtminmax.c
@@ -0,0 +1,74 @@
+/*
+ * Test the lowest and the highest real-time signals.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#include <assert.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+/* For hexagon and microblaze. */
+#ifndef __SIGRTMIN
+#define __SIGRTMIN 32
+#endif
+
+extern char **environ;
+
+static bool seen_sigrtmin, seen_sigrtmax;
+
+static void handle_signal(int sig)
+{
+    if (sig == SIGRTMIN) {
+        seen_sigrtmin = true;
+    } else if (sig == SIGRTMAX) {
+        seen_sigrtmax = true;
+    } else {
+        _exit(1);
+    }
+}
+
+int main(int argc, char **argv)
+{
+    char *qemu = getenv("QEMU");
+    struct sigaction act;
+
+    assert(qemu);
+
+    if (!getenv("QEMU_RTSIG_MAP")) {
+        char **new_argv = malloc((argc + 2) + sizeof(char *));
+        int tsig1, hsig1, count1, tsig2, hsig2, count2;
+        char rt_sigmap[64];
+
+        /* Re-exec with a mapping that includes SIGRTMIN and SIGRTMAX. */
+        new_argv[0] = qemu;
+        memcpy(&new_argv[1], argv, (argc + 1) * sizeof(char *));
+        tsig1 = __SIGRTMIN;
+        /* The host must have a few signals starting from this one. */
+        hsig1 = 36;
+        count1 = SIGRTMIN - __SIGRTMIN + 1;
+        tsig2 = SIGRTMAX;
+        hsig2 = hsig1 + count1;
+        count2 = 1;
+        snprintf(rt_sigmap, sizeof(rt_sigmap), "%d %d %d,%d %d %d",
+                 tsig1, hsig1, count1, tsig2, hsig2, count2);
+        setenv("QEMU_RTSIG_MAP", rt_sigmap, 0);
+        assert(execve(new_argv[0], new_argv, environ) == 0);
+        return EXIT_FAILURE;
+    }
+
+    memset(&act, 0, sizeof(act));
+    act.sa_handler = handle_signal;
+    assert(sigaction(SIGRTMIN, &act, NULL) == 0);
+    assert(sigaction(SIGRTMAX, &act, NULL) == 0);
+
+    assert(kill(getpid(), SIGRTMIN) == 0);
+    assert(seen_sigrtmin);
+    assert(kill(getpid(), SIGRTMAX) == 0);
+    assert(seen_sigrtmax);
+
+    return EXIT_SUCCESS;
+}