[libc-commits] [libc] [libc][signal] clean up usage of sighandler_t (PR #125745)

Nick Desaulniers via libc-commits libc-commits at lists.llvm.org
Tue Feb 4 11:04:47 PST 2025


https://github.com/nickdesaulniers created https://github.com/llvm/llvm-project/pull/125745

`man 3 signal`'s declaration has a face _only a mother could love_.

sighandler_t and __sighandler_t are not defined in the C standard, or POSIX.

They are helpful typedefs provided by glibc since working with function
pointers' syntax can be painful. But we should not rely on them; in C++ we have
`auto*` and `using` statements.

Remove the proxy header, and only include typedefs for these two typedefs when
targeting Linux, for compatibility with glibc.

Also, adds a typedef for non-double-underscore-prefixed sighandler_t that we
were missing.

Fixes: #125598


>From 62e8a9c228080a9cc13e5a5c321f037b1dccbbc6 Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Tue, 4 Feb 2025 10:27:44 -0800
Subject: [PATCH 1/4] [libc][signal] clean up sighandler_t declarations

---
 libc/hdr/types/sighandler_t.h                       |  2 --
 libc/include/llvm-libc-macros/gpu/signal-macros.h   |  6 +++---
 libc/include/llvm-libc-macros/linux/signal-macros.h |  6 +++---
 libc/include/llvm-libc-types/__sighandler_t.h       |  1 +
 libc/include/llvm-libc-types/struct_sigaction.h     |  2 --
 libc/include/signal.yaml                            | 11 ++++++-----
 6 files changed, 13 insertions(+), 15 deletions(-)

diff --git a/libc/hdr/types/sighandler_t.h b/libc/hdr/types/sighandler_t.h
index bc40dd8b4c8f4a..8d7e04d6788683 100644
--- a/libc/hdr/types/sighandler_t.h
+++ b/libc/hdr/types/sighandler_t.h
@@ -13,8 +13,6 @@
 
 #include "include/llvm-libc-types/__sighandler_t.h"
 
-using sighandler_t = __sighandler_t;
-
 #else // overlay mode
 
 #include <signal.h>
diff --git a/libc/include/llvm-libc-macros/gpu/signal-macros.h b/libc/include/llvm-libc-macros/gpu/signal-macros.h
index 2d8159240de8bf..f0d49ea34fe0ef 100644
--- a/libc/include/llvm-libc-macros/gpu/signal-macros.h
+++ b/libc/include/llvm-libc-macros/gpu/signal-macros.h
@@ -16,9 +16,9 @@
 #define SIGSEGV 11
 #define SIGTERM 15
 
-#define SIG_DFL ((__sighandler_t)(0))
-#define SIG_IGN ((__sighandler_t)(1))
-#define SIG_ERR ((__sighandler_t)(-1))
+#define SIG_DFL ((void (*)(int))(0))
+#define SIG_IGN ((void (*)(int))(1))
+#define SIG_ERR ((void (*)(int))(-1))
 
 // Max signal number
 #define NSIG 64
diff --git a/libc/include/llvm-libc-macros/linux/signal-macros.h b/libc/include/llvm-libc-macros/linux/signal-macros.h
index 0b7317ebc9b80a..6afa7facd8091f 100644
--- a/libc/include/llvm-libc-macros/linux/signal-macros.h
+++ b/libc/include/llvm-libc-macros/linux/signal-macros.h
@@ -86,9 +86,9 @@
 #error "Signal stack sizes not defined for your platform."
 #endif
 
-#define SIG_DFL ((__sighandler_t)0)
-#define SIG_IGN ((__sighandler_t)1)
-#define SIG_ERR ((__sighandler_t)-1)
+#define SIG_DFL ((void (*)(int))0)
+#define SIG_IGN ((void (*)(int))1)
+#define SIG_ERR ((void (*)(int))-1)
 
 // SIGCHLD si_codes
 #define CLD_EXITED 1    // child has exited
diff --git a/libc/include/llvm-libc-types/__sighandler_t.h b/libc/include/llvm-libc-types/__sighandler_t.h
index 9c1ac997fc4ee0..1b1b40d60384c8 100644
--- a/libc/include/llvm-libc-types/__sighandler_t.h
+++ b/libc/include/llvm-libc-types/__sighandler_t.h
@@ -10,5 +10,6 @@
 #define LLVM_LIBC_TYPES___SIGHANDLER_T_H
 
 typedef void (*__sighandler_t)(int);
+typedef __sighandler_t sighandler_t;
 
 #endif // LLVM_LIBC_TYPES___SIGHANDLER_T_H
diff --git a/libc/include/llvm-libc-types/struct_sigaction.h b/libc/include/llvm-libc-types/struct_sigaction.h
index b4d0c965a4c633..907418b5e0f9a0 100644
--- a/libc/include/llvm-libc-types/struct_sigaction.h
+++ b/libc/include/llvm-libc-types/struct_sigaction.h
@@ -25,6 +25,4 @@ struct sigaction {
 #endif
 };
 
-typedef void (*__sighandler_t)(int);
-
 #endif // LLVM_LIBC_TYPES_STRUCT_SIGACTION_H
diff --git a/libc/include/signal.yaml b/libc/include/signal.yaml
index 576e77576ac740..ad05b9a04df989 100644
--- a/libc/include/signal.yaml
+++ b/libc/include/signal.yaml
@@ -2,13 +2,14 @@ header: signal.h
 header_template: signal.h.def
 macros: []
 types:
+  - type_name: __sighandler_t
   - type_name: pid_t
-  - type_name: stack_t
+  - type_name: sig_atomic_t
   - type_name: siginfo_t
-  - type_name: struct_sigaction
   - type_name: sigset_t
+  - type_name: stack_t
+  - type_name: struct_sigaction
   - type_name: union_sigval
-  - type_name: sig_atomic_t
 enums: []
 objects: []
 functions:
@@ -69,10 +70,10 @@ functions:
   - name: signal
     standards:
       - stdc
-    return_type: __sighandler_t
+    return_type: sighandler_t
     arguments:
       - type: int
-      - type: __sighandler_t
+      - type: sighandler_t
   - name: sigprocmask
     standards:
       - POSIX

>From c84b8f2cf4c2fa6ab5c75856670df8e739336865 Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Tue, 4 Feb 2025 10:46:02 -0800
Subject: [PATCH 2/4] clean up our usage of sighandler_t

---
 libc/hdr/types/CMakeLists.txt          |  9 ---------
 libc/hdr/types/sighandler_t.h          | 22 ----------------------
 libc/src/signal/linux/CMakeLists.txt   |  1 -
 libc/src/signal/linux/signal.cpp       |  6 ++++--
 libc/src/signal/signal.h               |  3 +--
 libc/test/UnitTest/FPExceptMatcher.cpp |  2 +-
 libc/test/src/signal/CMakeLists.txt    |  1 -
 libc/test/src/signal/signal_test.cpp   |  4 +---
 8 files changed, 7 insertions(+), 41 deletions(-)
 delete mode 100644 libc/hdr/types/sighandler_t.h

diff --git a/libc/hdr/types/CMakeLists.txt b/libc/hdr/types/CMakeLists.txt
index 3dfa38a020fad0..83c01fd6aeafef 100644
--- a/libc/hdr/types/CMakeLists.txt
+++ b/libc/hdr/types/CMakeLists.txt
@@ -250,15 +250,6 @@ add_proxy_header_library(
     libc.include.locale
 )
 
-add_proxy_header_library(
-  sighandler_t
-  HDRS
-    sighandler_t.h
-  FULL_BUILD_DEPENDS
-    libc.include.llvm-libc-types.__sighandler_t
-    libc.include.signal
-)
-
 add_proxy_header_library(
   stack_t
   HDRS
diff --git a/libc/hdr/types/sighandler_t.h b/libc/hdr/types/sighandler_t.h
deleted file mode 100644
index 8d7e04d6788683..00000000000000
--- a/libc/hdr/types/sighandler_t.h
+++ /dev/null
@@ -1,22 +0,0 @@
-//===-- Definition of macros from __sighandler_t.h ------------------------===//
-//
-// 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_SIGHANDLER_T_H
-#define LLVM_LIBC_HDR_TYPES_SIGHANDLER_T_H
-
-#ifdef LIBC_FULL_BUILD
-
-#include "include/llvm-libc-types/__sighandler_t.h"
-
-#else // overlay mode
-
-#include <signal.h>
-
-#endif // LLVM_LIBC_FULL_BUILD
-
-#endif // LLVM_LIBC_HDR_TYPES_SIGHANDLER_T_H
diff --git a/libc/src/signal/linux/CMakeLists.txt b/libc/src/signal/linux/CMakeLists.txt
index f7457d31cf4f85..c0dd61e473881b 100644
--- a/libc/src/signal/linux/CMakeLists.txt
+++ b/libc/src/signal/linux/CMakeLists.txt
@@ -127,7 +127,6 @@ add_entrypoint_object(
   DEPENDS
     .sigaction
     libc.hdr.signal_macros
-    libc.hdr.types.sighandler_t
 )
 
 add_entrypoint_object(
diff --git a/libc/src/signal/linux/signal.cpp b/libc/src/signal/linux/signal.cpp
index 1da0ef8c97a206..f196aa52634e47 100644
--- a/libc/src/signal/linux/signal.cpp
+++ b/libc/src/signal/linux/signal.cpp
@@ -8,14 +8,16 @@
 
 #include "src/signal/signal.h"
 #include "hdr/signal_macros.h"
-#include "hdr/types/sighandler_t.h"
 #include "src/__support/common.h"
 #include "src/__support/macros/config.h"
 #include "src/signal/sigaction.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
-LLVM_LIBC_FUNCTION(sighandler_t, signal, (int signum, sighandler_t handler)) {
+// Our LLVM_LIBC_FUNCTION macro doesn't handle function pointer return types.
+using signal_handler = void (*)(int);
+
+LLVM_LIBC_FUNCTION(signal_handler, signal, (int signum, signal_handler handler)) {
   struct sigaction action, old;
   action.sa_handler = handler;
   action.sa_flags = SA_RESTART;
diff --git a/libc/src/signal/signal.h b/libc/src/signal/signal.h
index 06e77e11bf0bd3..e1f31a8e126c58 100644
--- a/libc/src/signal/signal.h
+++ b/libc/src/signal/signal.h
@@ -9,12 +9,11 @@
 #ifndef LLVM_LIBC_SRC_SIGNAL_SIGNAL_H
 #define LLVM_LIBC_SRC_SIGNAL_SIGNAL_H
 
-#include "hdr/types/sighandler_t.h"
 #include "src/__support/macros/config.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
-sighandler_t signal(int signum, sighandler_t handler);
+void (*signal(int signum, void (*handler)(int)))(int);
 
 } // namespace LIBC_NAMESPACE_DECL
 
diff --git a/libc/test/UnitTest/FPExceptMatcher.cpp b/libc/test/UnitTest/FPExceptMatcher.cpp
index 119a06985b8f1c..d66066023984e5 100644
--- a/libc/test/UnitTest/FPExceptMatcher.cpp
+++ b/libc/test/UnitTest/FPExceptMatcher.cpp
@@ -37,7 +37,7 @@ static void sigfpeHandler(int sig) {
 }
 
 FPExceptMatcher::FPExceptMatcher(FunctionCaller *func) {
-  sighandler_t oldSIGFPEHandler = signal(SIGFPE, &sigfpeHandler);
+  auto *oldSIGFPEHandler = signal(SIGFPE, &sigfpeHandler);
 
   caughtExcept = false;
   fenv_t oldEnv;
diff --git a/libc/test/src/signal/CMakeLists.txt b/libc/test/src/signal/CMakeLists.txt
index a27f5b8f1000e9..f86ce2ae96857c 100644
--- a/libc/test/src/signal/CMakeLists.txt
+++ b/libc/test/src/signal/CMakeLists.txt
@@ -74,7 +74,6 @@ add_libc_unittest(
   SRCS
     signal_test.cpp
   DEPENDS
-    libc.hdr.types.sighandler_t
     libc.src.errno.errno
     libc.src.signal.raise
     libc.src.signal.signal
diff --git a/libc/test/src/signal/signal_test.cpp b/libc/test/src/signal/signal_test.cpp
index 4b57311eee2d86..bac9c3b8b68bb2 100644
--- a/libc/test/src/signal/signal_test.cpp
+++ b/libc/test/src/signal/signal_test.cpp
@@ -13,14 +13,12 @@
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
-#include "hdr/types/sighandler_t.h"
-
 using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
 using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
 
 TEST(LlvmLibcSignal, Invalid) {
   LIBC_NAMESPACE::libc_errno = 0;
-  sighandler_t valid = +[](int) {};
+  auto *valid = +[](int) {};
   EXPECT_THAT((void *)LIBC_NAMESPACE::signal(0, valid),
               Fails(EINVAL, (void *)SIG_ERR));
   EXPECT_THAT((void *)LIBC_NAMESPACE::signal(65, valid),

>From 669bb96c3093f596330d745eb1f02852d2c7a9f0 Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Tue, 4 Feb 2025 10:48:55 -0800
Subject: [PATCH 3/4] only include __sighandler_t.h on linux

---
 libc/include/llvm-libc-types/__sighandler_t.h | 4 ++++
 libc/include/signal.h.def                     | 4 ++++
 libc/include/signal.yaml                      | 1 -
 3 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/libc/include/llvm-libc-types/__sighandler_t.h b/libc/include/llvm-libc-types/__sighandler_t.h
index 1b1b40d60384c8..0fa412568a6912 100644
--- a/libc/include/llvm-libc-types/__sighandler_t.h
+++ b/libc/include/llvm-libc-types/__sighandler_t.h
@@ -9,6 +9,10 @@
 #ifndef LLVM_LIBC_TYPES___SIGHANDLER_T_H
 #define LLVM_LIBC_TYPES___SIGHANDLER_T_H
 
+#ifndef __linux__
+#error "sighandler_t only available on linux"
+#endif
+
 typedef void (*__sighandler_t)(int);
 typedef __sighandler_t sighandler_t;
 
diff --git a/libc/include/signal.h.def b/libc/include/signal.h.def
index 50a5f44c7337aa..11e56138879d59 100644
--- a/libc/include/signal.h.def
+++ b/libc/include/signal.h.def
@@ -16,6 +16,10 @@
 
 #include "llvm-libc-macros/signal-macros.h"
 
+#ifdef __linux__
+#include "llvm-libc-types/__sighandler_t.h"
+#endif
+
 %%public_api()
 
 #endif // LLVM_LIBC_SIGNAL_H
diff --git a/libc/include/signal.yaml b/libc/include/signal.yaml
index ad05b9a04df989..91e307e00d21c9 100644
--- a/libc/include/signal.yaml
+++ b/libc/include/signal.yaml
@@ -2,7 +2,6 @@ header: signal.h
 header_template: signal.h.def
 macros: []
 types:
-  - type_name: __sighandler_t
   - type_name: pid_t
   - type_name: sig_atomic_t
   - type_name: siginfo_t

>From 19e518a20a1acae3113efcd22ce87a82c73461b6 Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Tue, 4 Feb 2025 10:56:09 -0800
Subject: [PATCH 4/4] update signal.h hdrgen

---
 libc/include/signal.yaml | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/libc/include/signal.yaml b/libc/include/signal.yaml
index 91e307e00d21c9..5530d63c4bff97 100644
--- a/libc/include/signal.yaml
+++ b/libc/include/signal.yaml
@@ -69,10 +69,15 @@ functions:
   - name: signal
     standards:
       - stdc
-    return_type: sighandler_t
+    # May the Geneva Convention have mercy on my soul... Why this insanity?
+    # Well: signal returns a function pointer to a function with no return
+    # value and which accepts an int. The parameter list appears on the far
+    # right of the declaration. i.e.
+    # void (*signal(int, void (*)(int)))(int);
+    return_type: void (*
     arguments:
       - type: int
-      - type: sighandler_t
+      - type: void (*)(int)))(int
   - name: sigprocmask
     standards:
       - POSIX



More information about the libc-commits mailing list