Serenity Operating System
at master 107 lines 4.2 kB view raw
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}