Serenity Operating System
1/*
2 * Copyright (c) 2022, Tim Schumacher <timschumi@serenityos.org>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include <LibTest/TestCase.h>
8#include <signal.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <sys/wait.h>
12#include <unistd.h>
13
14static void signal_handler(int)
15{
16 VERIFY_NOT_REACHED();
17}
18
19TEST_CASE(default_handlers)
20{
21 struct sigaction current_action { };
22
23 int rc = sigaction(SIGUSR2, nullptr, ¤t_action);
24
25 EXPECT_EQ(rc, 0);
26 EXPECT_EQ(current_action.sa_handler, SIG_DFL);
27}
28
29TEST_CASE(handlers_after_fork)
30{
31 struct sigaction new_action {
32 { signal_handler }, 0, 0
33 };
34 int rc = sigaction(SIGUSR2, &new_action, nullptr);
35 EXPECT_EQ(rc, 0);
36
37 pid_t pid = fork();
38
39 if (pid == 0) {
40 struct sigaction current_action { };
41 rc = sigaction(SIGUSR2, nullptr, ¤t_action);
42 EXPECT_EQ(rc, 0);
43 EXPECT_EQ(current_action.sa_handler, signal_handler);
44 exit(rc == 0 && current_action.sa_handler == signal_handler ? EXIT_SUCCESS : EXIT_FAILURE);
45 } else {
46 int exit_status = 0;
47 rc = waitpid(pid, &exit_status, 0);
48 EXPECT_EQ(rc, pid);
49 EXPECT(WIFEXITED(exit_status));
50 EXPECT_EQ(WEXITSTATUS(exit_status), 0);
51 }
52}
53
54TEST_CASE(handlers_after_exec)
55{
56 struct sigaction new_action {
57 { signal_handler }, 0, 0
58 };
59 int rc = sigaction(SIGUSR2, &new_action, nullptr);
60 EXPECT_EQ(rc, 0);
61
62 pid_t pid = fork();
63
64 if (pid == 0) {
65 // Hide the confusing "Running 1 cases out of 3" output.
66 freopen("/dev/null", "w", stdout);
67
68 // This runs the 'default_handlers' test in this binary again, but after exec.
69 execl("/proc/self/exe", "TestSigHandler", "default_handlers", nullptr);
70 FAIL("Failed to exec.");
71 } else {
72 int exit_status = 0;
73 rc = waitpid(pid, &exit_status, 0);
74 EXPECT_EQ(rc, pid);
75 EXPECT(WIFEXITED(exit_status));
76 EXPECT_EQ(WEXITSTATUS(exit_status), 0);
77 }
78}