[libc][signal] cleanup sigaction implementation (#189512)
This commit is contained in:
parent
e7483770c7
commit
5a89da7d13
@ -79,6 +79,14 @@ add_proxy_header_library(
|
||||
libc.include.llvm-libc-types.sigset_t
|
||||
)
|
||||
|
||||
add_proxy_header_library(
|
||||
siginfo_t
|
||||
HDRS
|
||||
siginfo_t.h
|
||||
FULL_BUILD_DEPENDS
|
||||
libc.include.llvm-libc-types.siginfo_t
|
||||
)
|
||||
|
||||
add_proxy_header_library(
|
||||
struct_epoll_event
|
||||
HDRS
|
||||
|
||||
21
libc/hdr/types/siginfo_t.h
Normal file
21
libc/hdr/types/siginfo_t.h
Normal file
@ -0,0 +1,21 @@
|
||||
//===-- Proxy for siginfo_t -----------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef LLVM_LIBC_HDR_TYPES_SIGINFO_T_H
|
||||
#define LLVM_LIBC_HDR_TYPES_SIGINFO_T_H
|
||||
|
||||
#ifdef LIBC_FULL_BUILD
|
||||
|
||||
#include "include/llvm-libc-types/siginfo_t.h"
|
||||
|
||||
#else
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#endif // LIBC_FULL_BUILD
|
||||
|
||||
#endif // LLVM_LIBC_HDR_TYPES_SIGINFO_T_H
|
||||
@ -3,10 +3,14 @@ add_header_library(
|
||||
HDRS
|
||||
signal_utils.h
|
||||
DEPENDS
|
||||
libc.hdr.types.siginfo_t
|
||||
libc.hdr.types.sigset_t
|
||||
libc.include.signal
|
||||
libc.hdr.types.size_t
|
||||
libc.hdr.types.struct_sigaction
|
||||
libc.include.sys_syscall
|
||||
libc.src.__support.OSUtil.linux.vdso
|
||||
libc.src.__support.OSUtil.osutil
|
||||
libc.src.__support.error_or
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
@ -57,10 +61,7 @@ add_entrypoint_object(
|
||||
../sigaction.h
|
||||
DEPENDS
|
||||
.__restore
|
||||
libc.hdr.types.sigset_t
|
||||
libc.hdr.types.struct_sigaction
|
||||
libc.include.sys_syscall
|
||||
libc.src.__support.OSUtil.osutil
|
||||
.signal_utils
|
||||
libc.src.errno.errno
|
||||
)
|
||||
|
||||
|
||||
@ -8,7 +8,6 @@
|
||||
|
||||
#include "src/signal/sigaction.h"
|
||||
|
||||
#include "hdr/types/sigset_t.h"
|
||||
#include "src/__support/common.h"
|
||||
#include "src/__support/libc_errno.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
@ -16,35 +15,15 @@
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
// TOOD: Some architectures will have their signal trampoline functions in the
|
||||
// vdso, use those when available.
|
||||
|
||||
extern "C" void __restore_rt();
|
||||
|
||||
LLVM_LIBC_FUNCTION(int, sigaction,
|
||||
(int signal, const struct sigaction *__restrict libc_new,
|
||||
struct sigaction *__restrict libc_old)) {
|
||||
KernelSigaction kernel_new;
|
||||
if (libc_new) {
|
||||
kernel_new = *libc_new;
|
||||
if (!(kernel_new.sa_flags & SA_RESTORER)) {
|
||||
kernel_new.sa_flags |= SA_RESTORER;
|
||||
kernel_new.sa_restorer = __restore_rt;
|
||||
}
|
||||
}
|
||||
ErrorOr<int> ret = do_sigaction(signal, libc_new, libc_old);
|
||||
if (ret)
|
||||
return ret.value();
|
||||
|
||||
KernelSigaction kernel_old;
|
||||
int ret = LIBC_NAMESPACE::syscall_impl<int>(
|
||||
SYS_rt_sigaction, signal, libc_new ? &kernel_new : nullptr,
|
||||
libc_old ? &kernel_old : nullptr, sizeof(sigset_t));
|
||||
if (ret) {
|
||||
libc_errno = -ret;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (libc_old)
|
||||
*libc_old = kernel_old;
|
||||
return 0;
|
||||
libc_errno = ret.error();
|
||||
return -1;
|
||||
}
|
||||
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
||||
@ -9,17 +9,23 @@
|
||||
#ifndef LLVM_LIBC_SRC_SIGNAL_LINUX_SIGNAL_UTILS_H
|
||||
#define LLVM_LIBC_SRC_SIGNAL_LINUX_SIGNAL_UTILS_H
|
||||
|
||||
#include "hdr/signal_macros.h"
|
||||
#include "hdr/types/siginfo_t.h"
|
||||
#include "hdr/types/sigset_t.h"
|
||||
#include "hdr/types/size_t.h"
|
||||
#include "hdr/types/struct_sigaction.h"
|
||||
#include "src/__support/OSUtil/linux/vdso.h"
|
||||
#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
|
||||
#include "src/__support/common.h"
|
||||
#include "src/__support/error_or.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
|
||||
#include <signal.h> // sigaction
|
||||
#include <stddef.h>
|
||||
#include <sys/syscall.h> // For syscall numbers.
|
||||
#include <sys/syscall.h> // For syscall numbers.
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
extern "C" void __restore_rt();
|
||||
|
||||
// The POSIX definition of struct sigaction and the sigaction data structure
|
||||
// expected by the rt_sigaction syscall differ in their definition. So, we
|
||||
// define the equivalent of the what the kernel expects to help with making
|
||||
@ -107,6 +113,31 @@ LIBC_INLINE int restore_signals(const sigset_t &set) {
|
||||
&set, nullptr, sizeof(sigset_t));
|
||||
}
|
||||
|
||||
LIBC_INLINE ErrorOr<int>
|
||||
do_sigaction(int signal, const struct sigaction *__restrict libc_new,
|
||||
struct sigaction *__restrict libc_old) {
|
||||
vdso::TypedSymbol<vdso::VDSOSym::RTSigReturn> rt_sigreturn;
|
||||
KernelSigaction kernel_new;
|
||||
if (libc_new) {
|
||||
kernel_new = *libc_new;
|
||||
if (!(kernel_new.sa_flags & SA_RESTORER)) {
|
||||
kernel_new.sa_flags |= SA_RESTORER;
|
||||
kernel_new.sa_restorer = rt_sigreturn ? rt_sigreturn : __restore_rt;
|
||||
}
|
||||
}
|
||||
|
||||
KernelSigaction kernel_old;
|
||||
int ret = LIBC_NAMESPACE::syscall_impl<int>(
|
||||
SYS_rt_sigaction, signal, libc_new ? &kernel_new : nullptr,
|
||||
libc_old ? &kernel_old : nullptr, sizeof(sigset_t));
|
||||
if (ret)
|
||||
return Error(-ret);
|
||||
|
||||
if (libc_old)
|
||||
*libc_old = kernel_old;
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
||||
#endif // LLVM_LIBC_SRC_SIGNAL_LINUX_SIGNAL_UTILS_H
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user