Serenity Operating System
1/*
2 * Copyright (c) 2020-2022, the SerenityOS developers.
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include <signal.h>
8#include <stdio.h>
9#include <sys/types.h>
10#include <sys/wait.h>
11#include <unistd.h>
12
13// Supposed to use volatile everywhere here but good lord does C++ make that a pain
14volatile sig_atomic_t saved_signal;
15volatile siginfo_t saved_siginfo;
16volatile ucontext_t saved_ucontext;
17siginfo_t* sig_info_addr;
18ucontext_t* ucontext_addr;
19void* stack_ptr;
20bool volatile signal_was_delivered = false;
21
22static void signal_handler(int sig, siginfo_t* sig_info, void* u_context)
23{
24 stack_ptr = __builtin_frame_address(0);
25 signal_was_delivered = true;
26
27 saved_signal = sig;
28 // grumble grumble, assignment operator on volatile types not a thing
29 // grumble grumble more, can't memcpy voltile either, that casts away volatile
30 // grumble grumble even more, can't std::copy to volatile.
31 // screw it, just write all the fields
32 sig_info_addr = sig_info;
33 saved_siginfo.si_status = sig_info->si_status;
34 saved_siginfo.si_signo = sig_info->si_signo;
35 saved_siginfo.si_code = sig_info->si_code;
36 saved_siginfo.si_pid = sig_info->si_pid;
37 saved_siginfo.si_uid = sig_info->si_uid;
38 saved_siginfo.si_value.sival_int = sig_info->si_value.sival_int;
39 auto user_context = (ucontext_t*)u_context;
40 ucontext_addr = user_context;
41 saved_ucontext.uc_link = user_context->uc_link;
42 saved_ucontext.uc_sigmask = user_context->uc_sigmask;
43 saved_ucontext.uc_stack.ss_sp = user_context->uc_stack.ss_sp;
44 saved_ucontext.uc_stack.ss_size = user_context->uc_stack.ss_size;
45 saved_ucontext.uc_stack.ss_flags = user_context->uc_stack.ss_flags;
46 // saved_ucontext.uc_mcontext = user_context->uc_mcontext;
47}
48
49static int print_signal_results()
50{
51 if (!signal_was_delivered) {
52 fprintf(stderr, "Where was my signal bro?\n");
53 return 2;
54 }
55
56 sig_atomic_t read_the_signal = saved_signal;
57 siginfo_t read_the_siginfo = {};
58 read_the_siginfo.si_status = saved_siginfo.si_status;
59 read_the_siginfo.si_signo = saved_siginfo.si_signo;
60 read_the_siginfo.si_code = saved_siginfo.si_code;
61 read_the_siginfo.si_pid = saved_siginfo.si_pid;
62 read_the_siginfo.si_uid = saved_siginfo.si_uid;
63 read_the_siginfo.si_value.sival_int = saved_siginfo.si_value.sival_int;
64
65 ucontext_t read_the_ucontext = {};
66 read_the_ucontext.uc_link = saved_ucontext.uc_link;
67 read_the_ucontext.uc_sigmask = saved_ucontext.uc_sigmask;
68 read_the_ucontext.uc_stack.ss_sp = saved_ucontext.uc_stack.ss_sp;
69 read_the_ucontext.uc_stack.ss_size = saved_ucontext.uc_stack.ss_size;
70 read_the_ucontext.uc_stack.ss_flags = saved_ucontext.uc_stack.ss_flags;
71 // read_the_ucontext.uc_mcontext = saved_ucontext.uc_mcontext;
72
73 printf("Handled signal: %d\n", read_the_signal);
74 printf("Stack sorta started as %p\n", stack_ptr);
75 printf("Siginfo was stored at %p:\n", sig_info_addr);
76 printf("\tsi_signo: %d\n", read_the_siginfo.si_signo);
77 printf("\tsi_code, %x\n", read_the_siginfo.si_code);
78 printf("\tsi_pid, %d\n", read_the_siginfo.si_pid);
79 printf("\tsi_uid, %d\n", read_the_siginfo.si_uid);
80 printf("\tsi_status, %x\n", read_the_siginfo.si_status);
81 printf("\tsi_value.sival_int, %x\n", read_the_siginfo.si_value.sival_int);
82 printf("ucontext was stored at %p:\n", ucontext_addr);
83 printf("\tuc_link, %p\n", read_the_ucontext.uc_link);
84 printf("\tuc_sigmask, %d\n", read_the_ucontext.uc_sigmask);
85 printf("\tuc_stack.ss_sp, %p\n", read_the_ucontext.uc_stack.ss_sp);
86 printf("\tuc_stack.ss_size, %zu\n", read_the_ucontext.uc_stack.ss_size);
87 printf("\tuc_stack.ss_flags, %d\n", read_the_ucontext.uc_stack.ss_flags);
88 // printf("\tuc_mcontext, %d\n", read_the_ucontext.uc_mcontext);
89
90 return 0;
91}
92
93int main()
94{
95 struct sigaction action = {};
96 action.sa_flags = SA_SIGINFO;
97 sigemptyset(&action.sa_mask);
98 action.sa_sigaction = signal_handler;
99
100 for (size_t i = 0; i < NSIG; ++i)
101 (void)sigaction(i, &action, nullptr);
102
103 printf("Sleeping for a long time waiting for kill -<N> %d\n", getpid());
104
105 sleep(1000);
106 return print_signal_results();
107}