[libc-commits] [libc] 5a89da7 - [libc][signal] cleanup sigaction implementation (#189512)

via libc-commits libc-commits at lists.llvm.org
Tue Mar 31 06:44:00 PDT 2026


Author: Schrodinger ZHU Yifan
Date: 2026-03-31T09:43:50-04:00
New Revision: 5a89da7d13e1e9e428db35c28e49c31df8f10996

URL: https://github.com/llvm/llvm-project/commit/5a89da7d13e1e9e428db35c28e49c31df8f10996
DIFF: https://github.com/llvm/llvm-project/commit/5a89da7d13e1e9e428db35c28e49c31df8f10996.diff

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

Added: 
    libc/hdr/types/siginfo_t.h

Modified: 
    libc/hdr/types/CMakeLists.txt
    libc/src/signal/linux/CMakeLists.txt
    libc/src/signal/linux/sigaction.cpp
    libc/src/signal/linux/signal_utils.h

Removed: 
    


################################################################################
diff  --git a/libc/hdr/types/CMakeLists.txt b/libc/hdr/types/CMakeLists.txt
index 76307b0b57330..7e1a8974fa486 100644
--- a/libc/hdr/types/CMakeLists.txt
+++ b/libc/hdr/types/CMakeLists.txt
@@ -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

diff  --git a/libc/hdr/types/siginfo_t.h b/libc/hdr/types/siginfo_t.h
new file mode 100644
index 0000000000000..469738c94167e
--- /dev/null
+++ b/libc/hdr/types/siginfo_t.h
@@ -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

diff  --git a/libc/src/signal/linux/CMakeLists.txt b/libc/src/signal/linux/CMakeLists.txt
index c8a7d95a4f22d..44c41737b89b0 100644
--- a/libc/src/signal/linux/CMakeLists.txt
+++ b/libc/src/signal/linux/CMakeLists.txt
@@ -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
 )
 

diff  --git a/libc/src/signal/linux/sigaction.cpp b/libc/src/signal/linux/sigaction.cpp
index 43a3e195474e5..9e76c188ed440 100644
--- a/libc/src/signal/linux/sigaction.cpp
+++ b/libc/src/signal/linux/sigaction.cpp
@@ -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;
-    }
-  }
-
-  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;
-  }
+  ErrorOr<int> ret = do_sigaction(signal, libc_new, libc_old);
+  if (ret)
+    return ret.value();
 
-  if (libc_old)
-    *libc_old = kernel_old;
-  return 0;
+  libc_errno = ret.error();
+  return -1;
 }
 
 } // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/signal/linux/signal_utils.h b/libc/src/signal/linux/signal_utils.h
index 81021276d784c..be4501c27dba5 100644
--- a/libc/src/signal/linux/signal_utils.h
+++ b/libc/src/signal/linux/signal_utils.h
@@ -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 
diff er 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


        


More information about the libc-commits mailing list