1 /* 2 * Copyright (c) 2006-2018, RT-Thread Development Team 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 * 6 * Change Logs: 7 * Date Author Notes 8 * 2017/10/1 Bernard The first version 9 */ 10 #include <rthw.h> 11 #include <rtthread.h> 12 13 #include <time.h> 14 15 #include "posix_signal.h" 16 #define sig_valid(sig_no) (sig_no >= 0 && sig_no < RT_SIG_MAX) 17 18 void (*signal(int sig, void (*func)(int))) (int) 19 { 20 return rt_signal_install(sig, func); 21 } 22 23 int sigprocmask (int how, const sigset_t *set, sigset_t *oset) 24 { 25 rt_base_t level; 26 rt_thread_t tid; 27 28 tid = rt_thread_self(); 29 30 level = rt_hw_interrupt_disable(); 31 if (oset) *oset = tid->sig_mask; 32 33 if (set) 34 { 35 switch(how) 36 { 37 case SIG_BLOCK: 38 tid->sig_mask |= *set; 39 break; 40 case SIG_UNBLOCK: 41 tid->sig_mask &= ~*set; 42 break; 43 case SIG_SETMASK: 44 tid->sig_mask = *set; 45 break; 46 default: 47 break; 48 } 49 } 50 rt_hw_interrupt_enable(level); 51 52 return 0; 53 } 54 55 int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact) 56 { 57 rt_sighandler_t old = RT_NULL; 58 59 if (!sig_valid(signum)) return -RT_ERROR; 60 61 if (act) 62 old = rt_signal_install(signum, act->sa_handler); 63 else 64 { 65 old = rt_signal_install(signum, RT_NULL); 66 rt_signal_install(signum, old); 67 } 68 69 if (oldact) 70 oldact->sa_handler = old; 71 72 return 0; 73 } 74 75 int sigtimedwait(const sigset_t *set, siginfo_t *info, 76 const struct timespec *timeout) 77 { 78 int ret = 0; 79 int tick = RT_WAITING_FOREVER; 80 81 #ifdef RT_USING_PTHREADS 82 if (timeout) 83 { 84 extern int clock_time_to_tick(const struct timespec *time); 85 tick = clock_time_to_tick(timeout); 86 } 87 #endif 88 89 ret = rt_signal_wait(set, info, tick); 90 if (ret == 0) return 0; 91 92 errno = ret; 93 return -1; 94 } 95 96 int sigwait(const sigset_t *set, int *sig) 97 { 98 siginfo_t si; 99 if (sigtimedwait(set, &si, 0) < 0) 100 return -1; 101 102 *sig = si.si_signo; 103 return 0; 104 } 105 106 int sigwaitinfo(const sigset_t *set, siginfo_t *info) 107 { 108 return sigtimedwait(set, info, NULL); 109 } 110 111 int raise(int sig) 112 { 113 rt_thread_kill(rt_thread_self(), sig); 114 return 0; 115 } 116 117