[libc][signal] cleanup sigaction implementation (#189512)

This commit is contained in:
Schrodinger ZHU Yifan 2026-03-31 09:43:50 -04:00 committed by GitHub
parent e7483770c7
commit 5a89da7d13
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 74 additions and 34 deletions

View File

@ -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

View 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

View File

@ -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
)

View File

@ -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

View File

@ -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