1 //===-- Linux implementation of sigaction ---------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #define __LLVM_LIBC_INTERNAL_SIGACTION 10 #include "src/signal/sigaction.h" 11 #include "src/errno/llvmlibc_errno.h" 12 #include "src/signal/linux/signal.h" 13 14 #include "src/__support/common.h" 15 16 namespace __llvm_libc { 17 18 // TOOD: Some architectures will have their signal trampoline functions in the 19 // vdso, use those when available. 20 21 extern "C" void __restore_rt(); 22 23 template <typename T, typename V> 24 static void copy_sigaction(T &dest, const V &source) { 25 dest.sa_handler = source.sa_handler; 26 dest.sa_mask = source.sa_mask; 27 dest.sa_flags = source.sa_flags; 28 dest.sa_restorer = source.sa_restorer; 29 } 30 31 LLVM_LIBC_FUNCTION(int, sigaction, 32 (int signal, const struct __sigaction *__restrict libc_new, 33 struct __sigaction *__restrict libc_old)) { 34 struct sigaction kernel_new; 35 if (libc_new) { 36 copy_sigaction(kernel_new, *libc_new); 37 if (!(kernel_new.sa_flags & SA_RESTORER)) { 38 kernel_new.sa_flags |= SA_RESTORER; 39 kernel_new.sa_restorer = __restore_rt; 40 } 41 } 42 43 struct sigaction kernel_old; 44 int ret = syscall(SYS_rt_sigaction, signal, libc_new ? &kernel_new : nullptr, 45 libc_old ? &kernel_old : nullptr, sizeof(sigset_t)); 46 if (ret) { 47 llvmlibc_errno = -ret; 48 return -1; 49 } 50 51 if (libc_old) 52 copy_sigaction(*libc_old, kernel_old); 53 return 0; 54 } 55 56 } // namespace __llvm_libc 57