Welcome to The Fiwix Project
A UNIX-like kernel for the i386 architecture
1 /* 2 * fiwix/kernel/syscalls/signal.c 3 * 4 * Copyright 2018-2021, Jordi Sanfeliu. All rights reserved. 5 * Distributed under the terms of the Fiwix License. 6 */ 7 8 #include <fiwix/syscalls.h> 9 #include <fiwix/signal.h> 10 #include <fiwix/process.h> 11 #include <fiwix/errno.h> 12 #include <fiwix/string.h> 13 14 #ifdef __DEBUG__ 15 #include <fiwix/stdio.h> 16 #endif /*__DEBUG__ */ 17 18 unsigned int sys_signal(__sigset_t signum, void(* sighandler)(int)) 19 { 20 struct sigaction s; 21 int errno; 22 23 #ifdef __DEBUG__ 24 printk("(pid %d) sys_signal()\n", current->pid); 25 #endif /*__DEBUG__ */ 26 27 if(signum < 1 || signum > NSIG) { 28 return -EINVAL; 29 } 30 if(signum == SIGKILL || signum == SIGSTOP) { 31 return -EINVAL; 32 } 33 if(sighandler != SIG_DFL && sighandler != SIG_IGN) { 34 if((errno = check_user_area(VERIFY_READ, sighandler, sizeof(unsigned int)))) { 35 return errno; 36 } 37 } 38 39 memset_b(&s, 0, sizeof(struct sigaction)); 40 s.sa_handler = sighandler; 41 s.sa_mask = 0; 42 s.sa_flags = SA_RESETHAND; 43 sighandler = current->sigaction[signum - 1].sa_handler; 44 current->sigaction[signum - 1] = s; 45 if(current->sigaction[signum - 1].sa_handler == SIG_IGN) { 46 if(signum != SIGCHLD) { 47 current->sigpending &= SIG_MASK(signum); 48 } 49 } 50 if(current->sigaction[signum - 1].sa_handler == SIG_DFL) { 51 if(signum != SIGCHLD) { 52 current->sigpending &= SIG_MASK(signum); 53 } 54 } 55 return (unsigned int)sighandler; 56 }