[libc-commits] [libc] 215c9fa - [libc] Re-enable functions from signal.h and re-enable abort.

Siva Chandra Reddy via libc-commits libc-commits at lists.llvm.org
Fri Sep 30 00:32:33 PDT 2022


Author: Siva Chandra Reddy
Date: 2022-09-30T07:31:50Z
New Revision: 215c9fa4deac9ec6b4e504843830551f03b60620

URL: https://github.com/llvm/llvm-project/commit/215c9fa4deac9ec6b4e504843830551f03b60620
DIFF: https://github.com/llvm/llvm-project/commit/215c9fa4deac9ec6b4e504843830551f03b60620.diff

LOG: [libc] Re-enable functions from signal.h and re-enable abort.

They were disabled because we were including linux/signal.h from our
signal.h. Linux's signal.h is not designed to be included from user
programs as it causes a lot of non-standard name pollution. Also, it is
not self-contained. This change defines types and macros relevant for
signal related syscalls within libc's headers and removes inclusion of
Linux headers.

This patch enables the funtions only for x86_64. They will be enabled
for aarch64 also in a follow up patch after testing.

Reviewed By: abrachet, lntue

Differential Revision: https://reviews.llvm.org/D134567

Added: 
    libc/include/llvm-libc-macros/linux/signal-macros.h
    libc/include/llvm-libc-macros/signal-macros.h
    libc/include/llvm-libc-types/siginfo_t.h
    libc/include/llvm-libc-types/sigset_t.h
    libc/include/llvm-libc-types/union_sigval.h
    libc/src/signal/linux/signal_utils.h

Modified: 
    libc/config/linux/api.td
    libc/config/linux/x86_64/entrypoints.txt
    libc/include/CMakeLists.txt
    libc/include/llvm-libc-macros/CMakeLists.txt
    libc/include/llvm-libc-macros/linux/CMakeLists.txt
    libc/include/llvm-libc-types/CMakeLists.txt
    libc/include/llvm-libc-types/struct_sigaction.h
    libc/include/signal.h.def
    libc/spec/posix.td
    libc/src/CMakeLists.txt
    libc/src/signal/linux/CMakeLists.txt
    libc/src/signal/linux/raise.cpp
    libc/src/signal/linux/sigaction.cpp
    libc/src/signal/linux/sigaddset.cpp
    libc/src/signal/linux/sigdelset.cpp
    libc/src/signal/linux/sigemptyset.cpp
    libc/src/signal/linux/sigfillset.cpp
    libc/src/signal/linux/signal.cpp
    libc/src/signal/linux/sigprocmask.cpp
    libc/src/signal/sigaction.h
    libc/src/signal/sigaddset.h
    libc/src/stdlib/CMakeLists.txt
    libc/src/stdlib/linux/CMakeLists.txt
    libc/test/src/CMakeLists.txt
    libc/test/src/signal/sigaction_test.cpp
    libc/test/src/stdlib/CMakeLists.txt

Removed: 
    libc/src/signal/linux/signal.h


################################################################################
diff  --git a/libc/config/linux/api.td b/libc/config/linux/api.td
index 414b874b86663..bd60cb1a572fe 100644
--- a/libc/config/linux/api.td
+++ b/libc/config/linux/api.td
@@ -205,7 +205,7 @@ def SysMManAPI : PublicAPI<"sys/mman.h"> {
 }
 
 def SignalAPI : PublicAPI<"signal.h"> {
-  let Types = ["struct sigaction", "__sighandler_t"];
+  let Types = ["sigset_t", "struct sigaction", "union sigval", "siginfo_t"];
 }
 
 def ThreadsAPI : PublicAPI<"threads.h"> {

diff  --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index bf46da228d59b..6745b548b3eae 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -355,20 +355,20 @@ if(LLVM_LIBC_FULL_BUILD)
 
     # stdlib.h entrypoints
     libc.src.stdlib._Exit
+    libc.src.stdlib.abort
     libc.src.stdlib.atexit
     libc.src.stdlib.exit
     libc.src.stdlib.getenv
 
     # signal.h entrypoints
-    # TODO: Enable signal.h entrypoints after fixing signal.h
-    # libc.src.signal.raise
-    # libc.src.signal.sigaction
-    # libc.src.signal.sigdelset
-    # libc.src.signal.sigaddset
-    # libc.src.signal.sigemptyset
-    # libc.src.signal.sigprocmask
-    # libc.src.signal.sigfillset
-    # libc.src.signal.signal
+    libc.src.signal.raise
+    libc.src.signal.sigaction
+    libc.src.signal.sigdelset
+    libc.src.signal.sigaddset
+    libc.src.signal.sigemptyset
+    libc.src.signal.sigprocmask
+    libc.src.signal.sigfillset
+    libc.src.signal.signal
 
     # threads.h entrypoints
     libc.src.threads.call_once

diff  --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index 5cee537c429a0..70bf4d663f70a 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -133,8 +133,10 @@ add_gen_header(
   DATA_FILES
     ../config/${LIBC_TARGET_OS}/signal.h.in
   DEPENDS
+    .llvm-libc-macros.signal_macros
     .llvm-libc-types.struct_sigaction
     .llvm-libc-types.__sighandler_t
+    .llvm-libc-types.sigset_t
 )
 
 add_gen_header(

diff  --git a/libc/include/llvm-libc-macros/CMakeLists.txt b/libc/include/llvm-libc-macros/CMakeLists.txt
index f7490e813ea86..fbf8cef92dcdb 100644
--- a/libc/include/llvm-libc-macros/CMakeLists.txt
+++ b/libc/include/llvm-libc-macros/CMakeLists.txt
@@ -14,6 +14,14 @@ add_header(
     file-seek-macros.h
 )
 
+add_header(
+  signal_macros
+  HDR
+    signal-macros.h
+  DEPENDS
+    .linux.signal_macros
+)
+
 add_header(
   sys_stat_macros
   HDR

diff  --git a/libc/include/llvm-libc-macros/linux/CMakeLists.txt b/libc/include/llvm-libc-macros/linux/CMakeLists.txt
index 2018d041987f7..e0dcb7c9058bc 100644
--- a/libc/include/llvm-libc-macros/linux/CMakeLists.txt
+++ b/libc/include/llvm-libc-macros/linux/CMakeLists.txt
@@ -33,3 +33,9 @@ add_header(
   HDR
     unistd-macros.h
 )
+
+add_header(
+  signal_macros
+  HDR
+    signal-macros.h
+)

diff  --git a/libc/include/llvm-libc-macros/linux/signal-macros.h b/libc/include/llvm-libc-macros/linux/signal-macros.h
new file mode 100644
index 0000000000000..9fe71d1c75d81
--- /dev/null
+++ b/libc/include/llvm-libc-macros/linux/signal-macros.h
@@ -0,0 +1,78 @@
+//===-- Definition of Linux signal number macros --------------------------===//
+//
+// 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_MACROS_LINUX_SIGNUM_MACROS_H
+#define __LLVM_LIBC_MACROS_LINUX_SIGNUM_MACROS_H
+
+#define SIGHUP 1
+#define SIGINT 2
+#define SIGQUIT 3
+#define SIGILL 4
+#define SIGTRAP 5
+#define SIGABRT 6
+#define SIGIOT 6
+#define SIGBUS 7
+#define SIGFPE 8
+#define SIGKILL 9
+#define SIGUSR1 10
+#define SIGSEGV 11
+#define SIGUSR2 12
+#define SIGPIPE 13
+#define SIGALRM 14
+#define SIGTERM 15
+#define SIGSTKFLT 16
+#define SIGCHLD 17
+#define SIGCONT 18
+#define SIGSTOP 19
+#define SIGTSTP 20
+#define SIGTTIN 21
+#define SIGTTOU 22
+#define SIGURG 23
+#define SIGXCPU 24
+#define SIGXFSZ 25
+#define SIGVTALRM 26
+#define SIGPROF 27
+#define SIGWINCH 28
+#define SIGIO 29
+#define SIGPOLL SIGIO
+#define SIGPWR 30
+#define SIGSYS 31
+
+// Max signal number
+#define NSIG 64
+
+// SIGRTMIN is current set to the minimum usable from user mode programs. If
+// the libc itself uses some of these signal numbers for private operations,
+// then it has to be adjusted in future to reflect that.
+#define SIGRTMIN 32
+
+#define SIGRTMAX NSIG
+
+// The kernel sigset is stored as an array of long values. Each bit of this
+// array corresponds to a signal, adjusted by 1. That is, bit 0 corresponds
+// to signal number 1, bit 1 corresponds to signal number 2 and so on. The
+// below macro denotes the size of that array (in number of long words and
+// not bytes).
+#define __NSIGSET_WORDS (NSIG / (sizeof(unsigned long) * 8))
+
+#define SIG_BLOCK 0   // For blocking signals
+#define SIG_UNBLOCK 1 // For unblocking signals
+#define SIG_SETMASK 2 // For setting signal mask
+
+// Flag values to be used for setting sigaction.sa_flags.
+#define SA_NOCLDSTOP 0x00000001
+#define SA_NOCLDWAIT 0x00000002
+#define SA_SIGINFO 0x00000004
+#define SA_RESTART 0x10000000
+#define SA_RESTORER 0x04000000
+
+#define SIG_DFL ((__sighandler_t)0)
+#define SIG_IGN ((__sighandler_t)1)
+#define SIG_ERR ((__sighandler_t)-1)
+
+#endif // __LLVM_LIBC_MACROS_LINUX_SIGNUM_MACROS_H

diff  --git a/libc/include/llvm-libc-macros/signal-macros.h b/libc/include/llvm-libc-macros/signal-macros.h
new file mode 100644
index 0000000000000..525032b3c5b16
--- /dev/null
+++ b/libc/include/llvm-libc-macros/signal-macros.h
@@ -0,0 +1,16 @@
+//===-- Definition of signal number macros --------------------------------===//
+//
+// 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_MACROS_SIGNUM_MACROS_H
+#define __LLVM_LIBC_MACROS_SIGNUM_MACROS_H
+
+#ifdef __linux__
+#include "linux/signal-macros.h"
+#endif
+
+#endif // __LLVM_LIBC_MACROS_SIGNUM_MACROS_H

diff  --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt
index 399fe396594c3..3b367ab5da988 100644
--- a/libc/include/llvm-libc-types/CMakeLists.txt
+++ b/libc/include/llvm-libc-types/CMakeLists.txt
@@ -46,7 +46,10 @@ add_header(rlim_t HDR rlim_t.h)
 add_header(struct_rlimit HDR struct_rlimit.h DEPENDS .rlim_t)
 add_header(ssize_t HDR ssize_t.h)
 add_header(struct_dirent HDR struct_dirent.h DEPENDS .ino_t .off_t)
-add_header(struct_sigaction HDR struct_sigaction.h)
+add_header(union_sigval HDR union_sigval.h)
+add_header(siginfo_t HDR siginfo_t.h DEPENDS .union_sigval .pid_t .uid_t)
+add_header(sigset_t HDR sigset_t.h DEPENDS libc.include.llvm-libc-macros.signal_macros)
+add_header(struct_sigaction HDR struct_sigaction.h DEPENDS .sigset_t .siginfo_t)
 add_header(time_t HDR time_t.h)
 add_header(struct_timespec HDR struct_timespec.h DEPENDS .time_t)
 add_header(

diff  --git a/libc/include/llvm-libc-types/siginfo_t.h b/libc/include/llvm-libc-types/siginfo_t.h
new file mode 100644
index 0000000000000..59d39e046b66c
--- /dev/null
+++ b/libc/include/llvm-libc-types/siginfo_t.h
@@ -0,0 +1,28 @@
+//===-- Definition of siginfo_t type --------------------------------------===//
+//
+// 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_TYPES_SIGINFO_T_H__
+#define __LLVM_LIBC_TYPES_SIGINFO_T_H__
+
+#include <llvm-libc-types/pid_t.h>
+#include <llvm-libc-types/uid_t.h>
+#include <llvm-libc-types/union_sigval.h>
+
+typedef struct {
+  int si_signo;
+  int si_code;
+  int si_errno;
+  pid_t si_pid;
+  uid_t si_uid;
+  void *si_addr;
+  int si_status;
+  long si_band;
+  union sigval si_value;
+} siginfo_t;
+
+#endif // __LLVM_LIBC_TYPES_SIGINFO_T_H__

diff  --git a/libc/include/llvm-libc-types/sigset_t.h b/libc/include/llvm-libc-types/sigset_t.h
new file mode 100644
index 0000000000000..bcfbc29996ae4
--- /dev/null
+++ b/libc/include/llvm-libc-types/sigset_t.h
@@ -0,0 +1,20 @@
+//===-- Definition of sigset_t type ---------------------------------------===//
+//
+// 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_TYPES_SIGSET_T_H__
+#define __LLVM_LIBC_TYPES_SIGSET_T_H__
+
+#include <llvm-libc-macros/signal-macros.h>
+
+// This definition can be adjusted/specialized for 
diff erent targets and
+// platforms as necessary. This definition works for Linux on most targets.
+typedef struct {
+  unsigned long __signals[__NSIGSET_WORDS];
+} sigset_t;
+
+#endif // __LLVM_LIBC_TYPES_SIGSET_T_H__

diff  --git a/libc/include/llvm-libc-types/struct_sigaction.h b/libc/include/llvm-libc-types/struct_sigaction.h
index 1c7243c0e921f..3940f14ffa842 100644
--- a/libc/include/llvm-libc-types/struct_sigaction.h
+++ b/libc/include/llvm-libc-types/struct_sigaction.h
@@ -9,14 +9,22 @@
 #ifndef __LLVM_LIBC_TYPES_SIGACTION_H__
 #define __LLVM_LIBC_TYPES_SIGACTION_H__
 
-struct __sigaction {
+#include <llvm-libc-types/siginfo_t.h>
+#include <llvm-libc-types/sigset_t.h>
+
+struct sigaction {
   union {
     void (*sa_handler)(int);
-    void (*sa_action)(int, siginfo_t *, void *);
+    void (*sa_sigaction)(int, siginfo_t *, void *);
   };
   sigset_t sa_mask;
   int sa_flags;
+#ifdef __linux__
+  // This field is present on linux for most targets.
   void (*sa_restorer)(void);
+#endif
 };
 
+typedef void (*__sighandler_t)(int);
+
 #endif // __LLVM_LIBC_TYPES_SIGACTION_H__

diff  --git a/libc/include/llvm-libc-types/union_sigval.h b/libc/include/llvm-libc-types/union_sigval.h
new file mode 100644
index 0000000000000..ccc9f2e5d0fb2
--- /dev/null
+++ b/libc/include/llvm-libc-types/union_sigval.h
@@ -0,0 +1,17 @@
+//===-- Definition of type union sigval -----------------------------------===//
+//
+// 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_TYPES_UNION_SIGVAL_H__
+#define __LLVM_LIBC_TYPES_UNION_SIGVAL_H__
+
+union sigval {
+  int sival_int;
+  void *sival_ptr;
+};
+
+#endif // __LLVM_LIBC_TYPES_UNION_SIGVAL_H__

diff  --git a/libc/include/signal.h.def b/libc/include/signal.h.def
index 7fecb6383592e..0e70334527157 100644
--- a/libc/include/signal.h.def
+++ b/libc/include/signal.h.def
@@ -14,7 +14,7 @@
 #define __need_size_t
 #include <stddef.h>
 
-%%include_file(${platform_signal})
+#include <llvm-libc-macros/signal-macros.h>
 
 %%public_api()
 

diff  --git a/libc/spec/posix.td b/libc/spec/posix.td
index 28d9813cb37f8..d3464e7d655a5 100644
--- a/libc/spec/posix.td
+++ b/libc/spec/posix.td
@@ -4,6 +4,9 @@ def ConstSigSetPtrType : ConstType<SigSetPtrType>;
 def RestrictedSigSetType : RestrictedPtrType<SigSetType>;
 def ConstRestrictedSigSetType : ConstType<RestrictedSigSetType>;
 
+def SigInfoType : NamedType<"siginfo_t">;
+def UnionSigVal : NamedType<"union sigval">;
+
 def StructSigaction : NamedType<"struct sigaction">;
 def StructSigactionPtr : PtrType<StructSigaction>;
 def ConstStructSigactionPtr : ConstType<StructSigactionPtr>;
@@ -248,8 +251,10 @@ def POSIX : StandardSpec<"POSIX"> {
       "signal.h",
       [], // Macros
       [
+        SigInfoType,
         SigSetType,
         StructSigaction,
+        UnionSigVal,
       ],
       [], // Enumerations
       [

diff  --git a/libc/src/CMakeLists.txt b/libc/src/CMakeLists.txt
index c8f801b03d0be..8c689d2e3935f 100644
--- a/libc/src/CMakeLists.txt
+++ b/libc/src/CMakeLists.txt
@@ -25,6 +25,6 @@ endif()
 # The signal API is currently disabled as signal.h is incorrect.
 # since assert uses the signal API, we disable assert also.
 # add_subdirectory(assert)
-# add_subdirectory(signal)
+add_subdirectory(signal)
 add_subdirectory(threads)
 add_subdirectory(time)

diff  --git a/libc/src/signal/linux/CMakeLists.txt b/libc/src/signal/linux/CMakeLists.txt
index c069c9fa350eb..efe32290529ff 100644
--- a/libc/src/signal/linux/CMakeLists.txt
+++ b/libc/src/signal/linux/CMakeLists.txt
@@ -1,12 +1,20 @@
+add_header_library(
+  signal_utils
+  HDRS
+    signal_utils.h
+  DEPENDS
+    libc.include.sys_syscall
+    libc.src.__support.OSUtil.osutil
+)
 
 add_entrypoint_object(
   raise
   SRCS
     raise.cpp
   HDRS
-    signal.h
     ../raise.h
   DEPENDS
+    .signal_utils
     libc.include.signal
     libc.include.sys_syscall
     libc.src.__support.OSUtil.osutil
@@ -34,7 +42,6 @@ add_entrypoint_object(
   SRCS
     sigaction.cpp
   HDRS
-    signal.h
     ../sigaction.h
   DEPENDS
     .__restore
@@ -49,9 +56,9 @@ add_entrypoint_object(
   SRCS
     sigprocmask.cpp
   HDRS
-    signal.h
     ../sigprocmask.h
   DEPENDS
+    .signal_utils
     libc.include.signal
     libc.include.sys_syscall
     libc.src.__support.OSUtil.osutil
@@ -63,9 +70,9 @@ add_entrypoint_object(
   SRCS
     sigemptyset.cpp
   HDRS
-    signal.h
     ../sigemptyset.h
   DEPENDS
+    .signal_utils
     libc.include.errno
     libc.include.signal
     libc.src.errno.errno
@@ -76,9 +83,9 @@ add_entrypoint_object(
   SRCS
     sigaddset.cpp
   HDRS
-    signal.h
     ../sigaddset.h
   DEPENDS
+    .signal_utils
     libc.include.errno
     libc.include.signal
     libc.src.errno.errno
@@ -89,7 +96,6 @@ add_entrypoint_object(
   SRCS
     signal.cpp
   HDRS
-    signal.h
     ../signal.h
   DEPENDS
     .sigaction
@@ -101,9 +107,9 @@ add_entrypoint_object(
   SRCS
     sigfillset.cpp
   HDRS
-    signal.h
     ../sigfillset.h
   DEPENDS
+    .signal_utils
     libc.include.errno
     libc.include.signal
     libc.src.errno.errno
@@ -114,9 +120,9 @@ add_entrypoint_object(
   SRCS
     sigdelset.cpp
   HDRS
-    signal.h
     ../sigdelset.h
   DEPENDS
+    .signal_utils
     libc.include.errno
     libc.include.signal
     libc.src.errno.errno

diff  --git a/libc/src/signal/linux/raise.cpp b/libc/src/signal/linux/raise.cpp
index eccc4f7c996af..eb880d1bd7057 100644
--- a/libc/src/signal/linux/raise.cpp
+++ b/libc/src/signal/linux/raise.cpp
@@ -7,19 +7,19 @@
 //===----------------------------------------------------------------------===//
 
 #include "src/signal/raise.h"
-#include "src/signal/linux/signal.h"
+#include "src/signal/linux/signal_utils.h"
 
 #include "src/__support/common.h"
 
 namespace __llvm_libc {
 
 LLVM_LIBC_FUNCTION(int, raise, (int sig)) {
-  __llvm_libc::Sigset sigset;
-  __llvm_libc::block_all_signals(sigset);
+  ::sigset_t sigset;
+  block_all_signals(sigset);
   long pid = __llvm_libc::syscall(SYS_getpid);
   long tid = __llvm_libc::syscall(SYS_gettid);
   int ret = __llvm_libc::syscall(SYS_tgkill, pid, tid, sig);
-  __llvm_libc::restore_signals(sigset);
+  restore_signals(sigset);
   return ret;
 }
 

diff  --git a/libc/src/signal/linux/sigaction.cpp b/libc/src/signal/linux/sigaction.cpp
index bd3581ba08587..c6324005a6d1c 100644
--- a/libc/src/signal/linux/sigaction.cpp
+++ b/libc/src/signal/linux/sigaction.cpp
@@ -6,13 +6,14 @@
 //
 //===----------------------------------------------------------------------===//
 
-#define __LLVM_LIBC_INTERNAL_SIGACTION
 #include "src/signal/sigaction.h"
-#include "src/errno/llvmlibc_errno.h"
-#include "src/signal/linux/signal.h"
+#include "src/signal/linux/signal_utils.h"
 
 #include "src/__support/common.h"
 
+#include <errno.h>
+#include <signal.h>
+
 namespace __llvm_libc {
 
 // TOOD: Some architectures will have their signal trampoline functions in the
@@ -20,36 +21,28 @@ namespace __llvm_libc {
 
 extern "C" void __restore_rt();
 
-template <typename T, typename V>
-static void copy_sigaction(T &dest, const V &source) {
-  dest.sa_handler = source.sa_handler;
-  dest.sa_mask = source.sa_mask;
-  dest.sa_flags = source.sa_flags;
-  dest.sa_restorer = source.sa_restorer;
-}
-
 LLVM_LIBC_FUNCTION(int, sigaction,
-                   (int signal, const struct __sigaction *__restrict libc_new,
-                    struct __sigaction *__restrict libc_old)) {
-  struct sigaction kernel_new;
+                   (int signal, const struct sigaction *__restrict libc_new,
+                    struct sigaction *__restrict libc_old)) {
+  KernelSigaction kernel_new;
   if (libc_new) {
-    copy_sigaction(kernel_new, *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;
     }
   }
 
-  struct sigaction kernel_old;
+  KernelSigaction kernel_old;
   int ret = syscall(SYS_rt_sigaction, signal, libc_new ? &kernel_new : nullptr,
                     libc_old ? &kernel_old : nullptr, sizeof(sigset_t));
   if (ret) {
-    llvmlibc_errno = -ret;
+    errno = -ret;
     return -1;
   }
 
   if (libc_old)
-    copy_sigaction(*libc_old, kernel_old);
+    *libc_old = kernel_old;
   return 0;
 }
 

diff  --git a/libc/src/signal/linux/sigaddset.cpp b/libc/src/signal/linux/sigaddset.cpp
index bc51ef67e0b3a..ea79445640e84 100644
--- a/libc/src/signal/linux/sigaddset.cpp
+++ b/libc/src/signal/linux/sigaddset.cpp
@@ -7,22 +7,19 @@
 //===----------------------------------------------------------------------===//
 
 #include "src/signal/sigaddset.h"
-#include "include/errno.h" // For E* macros.
-#include "src/errno/llvmlibc_errno.h"
-#include "src/signal/linux/signal.h"
-
 #include "src/__support/common.h"
+#include "src/signal/linux/signal_utils.h"
+
+#include <errno.h>
+#include <signal.h>
 
 namespace __llvm_libc {
 
 LLVM_LIBC_FUNCTION(int, sigaddset, (sigset_t * set, int signum)) {
-  if (!set || (unsigned)(signum - 1) >= (8 * sizeof(sigset_t))) {
-    llvmlibc_errno = EINVAL;
-    return -1;
-  }
-  auto *sigset = reinterpret_cast<__llvm_libc::Sigset *>(set);
-  sigset->addset(signum);
-  return 0;
+  if (set != nullptr && add_signal(*set, signum))
+    return 0;
+  errno = EINVAL;
+  return -1;
 }
 
 } // namespace __llvm_libc

diff  --git a/libc/src/signal/linux/sigdelset.cpp b/libc/src/signal/linux/sigdelset.cpp
index f870f71560074..2eec258754716 100644
--- a/libc/src/signal/linux/sigdelset.cpp
+++ b/libc/src/signal/linux/sigdelset.cpp
@@ -7,22 +7,19 @@
 //===----------------------------------------------------------------------===//
 
 #include "src/signal/sigdelset.h"
-#include "include/errno.h"
-#include "src/errno/llvmlibc_errno.h"
-#include "src/signal/linux/signal.h"
-
 #include "src/__support/common.h"
+#include "src/signal/linux/signal_utils.h"
+
+#include <errno.h>
+#include <signal.h>
 
 namespace __llvm_libc {
 
 LLVM_LIBC_FUNCTION(int, sigdelset, (sigset_t * set, int signum)) {
-  if (!set || (unsigned)(signum - 1) >= (8 * sizeof(sigset_t))) {
-    llvmlibc_errno = EINVAL;
-    return -1;
-  }
-  auto *sigset = reinterpret_cast<__llvm_libc::Sigset *>(set);
-  sigset->delset(signum);
-  return 0;
+  if (set != nullptr && delete_signal(*set, signum))
+    return 0;
+  errno = EINVAL;
+  return -1;
 }
 
 } // namespace __llvm_libc

diff  --git a/libc/src/signal/linux/sigemptyset.cpp b/libc/src/signal/linux/sigemptyset.cpp
index 9ae8a7330f207..311fcb4bc8e95 100644
--- a/libc/src/signal/linux/sigemptyset.cpp
+++ b/libc/src/signal/linux/sigemptyset.cpp
@@ -7,20 +7,21 @@
 //===----------------------------------------------------------------------===//
 
 #include "src/signal/sigemptyset.h"
-#include "include/errno.h" // For E* macros.
-#include "src/errno/llvmlibc_errno.h"
-#include "src/signal/linux/signal.h"
+#include "src/signal/linux/signal_utils.h"
 
 #include "src/__support/common.h"
 
+#include <errno.h>
+#include <signal.h>
+
 namespace __llvm_libc {
 
 LLVM_LIBC_FUNCTION(int, sigemptyset, (sigset_t * set)) {
   if (!set) {
-    llvmlibc_errno = EINVAL;
+    errno = EINVAL;
     return -1;
   }
-  *set = __llvm_libc::Sigset::empty_set();
+  *set = empty_set();
   return 0;
 }
 

diff  --git a/libc/src/signal/linux/sigfillset.cpp b/libc/src/signal/linux/sigfillset.cpp
index 1b908f1992640..2fb09ede026db 100644
--- a/libc/src/signal/linux/sigfillset.cpp
+++ b/libc/src/signal/linux/sigfillset.cpp
@@ -7,21 +7,20 @@
 //===----------------------------------------------------------------------===//
 
 #include "src/signal/sigfillset.h"
-#include "include/errno.h"
-#include "src/errno/llvmlibc_errno.h"
-#include "src/signal/linux/signal.h"
-
 #include "src/__support/common.h"
+#include "src/signal/linux/signal_utils.h"
+
+#include <errno.h>
+#include <signal.h>
 
 namespace __llvm_libc {
 
 LLVM_LIBC_FUNCTION(int, sigfillset, (sigset_t * set)) {
   if (!set) {
-    llvmlibc_errno = EINVAL;
+    errno = EINVAL;
     return -1;
   }
-  auto *sigset = reinterpret_cast<__llvm_libc::Sigset *>(set);
-  *sigset = __llvm_libc::Sigset::fullset();
+  *set = full_set();
   return 0;
 }
 

diff  --git a/libc/src/signal/linux/signal.cpp b/libc/src/signal/linux/signal.cpp
index fc0487709007b..464a23c297754 100644
--- a/libc/src/signal/linux/signal.cpp
+++ b/libc/src/signal/linux/signal.cpp
@@ -6,16 +6,17 @@
 //
 //===----------------------------------------------------------------------===//
 
-#define __LLVM_LIBC_INTERNAL_SIGACTION
 #include "src/signal/signal.h"
 #include "src/signal/sigaction.h"
 
 #include "src/__support/common.h"
 
+#include <signal.h>
+
 namespace __llvm_libc {
 
 LLVM_LIBC_FUNCTION(sighandler_t, signal, (int signum, sighandler_t handler)) {
-  struct __sigaction action, old;
+  struct sigaction action, old;
   action.sa_handler = handler;
   action.sa_flags = SA_RESTART;
   // Errno will already be set so no need to worry about changing errno here.

diff  --git a/libc/src/signal/linux/signal.h b/libc/src/signal/linux/signal.h
deleted file mode 100644
index fd312d79ed72e..0000000000000
--- a/libc/src/signal/linux/signal.h
+++ /dev/null
@@ -1,55 +0,0 @@
-//===-- Internal header for Linux signals -----------------------*- C++ -*-===//
-//
-// 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_SRC_SIGNAL_LINUX_SIGNAL_H
-#define LLVM_LIBC_SRC_SIGNAL_LINUX_SIGNAL_H
-
-#include "include/sys/syscall.h"          // For syscall numbers.
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
-
-#include "include/signal.h"
-
-static_assert(sizeof(sigset_t) * 8 >= NSIG, "sigset_t cannot hold all signals");
-
-namespace __llvm_libc {
-
-// Using this internally defined type will make it easier in the future to port
-// to 
diff erent architectures.
-struct Sigset {
-  sigset_t native_sigset;
-
-  constexpr static Sigset fullset() { return {-1UL}; }
-  constexpr static Sigset empty_set() { return {0}; }
-
-  constexpr void addset(int signal) { native_sigset |= (1L << (signal - 1)); }
-
-  constexpr void delset(int signal) { native_sigset &= ~(1L << (signal - 1)); }
-
-  operator sigset_t() const { return native_sigset; }
-};
-
-constexpr static Sigset ALL = Sigset::fullset();
-
-static inline int block_all_signals(Sigset &set) {
-  sigset_t native_sigset = ALL;
-  sigset_t old_set = set;
-  int ret = __llvm_libc::syscall(SYS_rt_sigprocmask, SIG_BLOCK, &native_sigset,
-                                 &old_set, sizeof(sigset_t));
-  set = {old_set};
-  return ret;
-}
-
-static inline int restore_signals(const Sigset &set) {
-  sigset_t native_sigset = set;
-  return __llvm_libc::syscall(SYS_rt_sigprocmask, SIG_SETMASK, &native_sigset,
-                              nullptr, sizeof(sigset_t));
-}
-
-} // namespace __llvm_libc
-
-#endif // LLVM_LIBC_SRC_SIGNAL_LINUX_SIGNAL_H

diff  --git a/libc/src/signal/linux/signal_utils.h b/libc/src/signal/linux/signal_utils.h
new file mode 100644
index 0000000000000..8eba593e4e610
--- /dev/null
+++ b/libc/src/signal/linux/signal_utils.h
@@ -0,0 +1,109 @@
+//===-- Internal header for Linux signals -----------------------*- C++ -*-===//
+//
+// 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_SRC_SIGNAL_LINUX_SIGNAL_UTILS_H
+#define LLVM_LIBC_SRC_SIGNAL_LINUX_SIGNAL_UTILS_H
+
+#include "include/sys/syscall.h"          // For syscall numbers.
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+
+#include <signal.h>
+#include <stddef.h>
+
+namespace __llvm_libc {
+
+// 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
+// the rt_sigaction syscall.
+//
+// NOTE: Though the kernel definition does not have a union to include the
+// handler taking siginfo_t * argument, one can set sa_handler to sa_sigaction
+// if SA_SIGINFO is set in sa_flags.
+struct KernelSigaction {
+  using HandlerType = void(int);
+  using SiginfoHandlerType = void(int, siginfo_t *, void *);
+
+  KernelSigaction &operator=(const struct sigaction &sa) {
+    sa_flags = sa.sa_flags;
+    sa_restorer = sa.sa_restorer;
+    sa_mask = sa.sa_mask;
+    if (sa_flags & SA_SIGINFO) {
+      sa_handler = reinterpret_cast<HandlerType *>(sa.sa_sigaction);
+    } else {
+      sa_handler = sa.sa_handler;
+    }
+    return *this;
+  }
+
+  operator struct sigaction() const {
+    struct sigaction sa;
+    sa.sa_flags = sa_flags;
+    sa.sa_mask = sa_mask;
+    sa.sa_restorer = sa_restorer;
+    if (sa_flags & SA_SIGINFO)
+      sa.sa_sigaction = reinterpret_cast<SiginfoHandlerType *>(sa_handler);
+    else
+      sa.sa_handler = sa_handler;
+    return sa;
+  }
+
+  HandlerType *sa_handler;
+  unsigned long sa_flags;
+  void (*sa_restorer)(void);
+  // Our public definition of sigset_t matches that of the kernel's definition.
+  // So, we can use the public sigset_t type here.
+  sigset_t sa_mask;
+};
+
+static constexpr size_t BITS_PER_SIGWORD = sizeof(unsigned long) * 8;
+
+constexpr sigset_t full_set() { return sigset_t{{-1UL}}; }
+
+constexpr sigset_t empty_set() { return sigset_t{{0}}; }
+
+// Set the bit corresponding to |signal| in |set|. Return true on success
+// and false on failure. The function will fail if |signal| is greater than
+// NSIG or negative.
+constexpr inline bool add_signal(sigset_t &set, int signal) {
+  if (signal > NSIG || signal <= 0)
+    return false;
+  size_t n = size_t(signal) - 1;
+  size_t word = n / BITS_PER_SIGWORD;
+  size_t bit = n % BITS_PER_SIGWORD;
+  set.__signals[word] |= (1UL << bit);
+  return true;
+}
+
+// Reset the bit corresponding to |signal| in |set|. Return true on success
+// and false on failure. The function will fail if |signal| is greater than
+// NSIG or negative.
+constexpr inline bool delete_signal(sigset_t &set, int signal) {
+  if (signal > NSIG || signal <= 0)
+    return false;
+  size_t n = size_t(signal) - 1;
+  size_t word = n / BITS_PER_SIGWORD;
+  size_t bit = n % BITS_PER_SIGWORD;
+  set.__signals[word] &= ~(1UL << bit);
+  return true;
+}
+
+static inline int block_all_signals(sigset_t &set) {
+  sigset_t full = full_set();
+  return __llvm_libc::syscall(SYS_rt_sigprocmask, SIG_BLOCK, &full, &set,
+                              sizeof(sigset_t));
+}
+
+static inline int restore_signals(const sigset_t &set) {
+  return __llvm_libc::syscall(SYS_rt_sigprocmask, SIG_SETMASK, &set, nullptr,
+                              sizeof(sigset_t));
+}
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_SIGNAL_LINUX_SIGNAL_UTILS_H

diff  --git a/libc/src/signal/linux/sigprocmask.cpp b/libc/src/signal/linux/sigprocmask.cpp
index e4b101c490944..343fd0f41bc4b 100644
--- a/libc/src/signal/linux/sigprocmask.cpp
+++ b/libc/src/signal/linux/sigprocmask.cpp
@@ -7,11 +7,15 @@
 //===----------------------------------------------------------------------===//
 
 #include "src/signal/sigprocmask.h"
-#include "src/errno/llvmlibc_errno.h"
-#include "src/signal/linux/signal.h"
+#include "include/sys/syscall.h"          // For syscall numbers.
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/signal/linux/signal_utils.h"
 
 #include "src/__support/common.h"
 
+#include <errno.h>
+#include <signal.h>
+
 namespace __llvm_libc {
 
 LLVM_LIBC_FUNCTION(int, sigprocmask,
@@ -22,7 +26,7 @@ LLVM_LIBC_FUNCTION(int, sigprocmask,
   if (!ret)
     return 0;
 
-  llvmlibc_errno = -ret;
+  errno = -ret;
   return -1;
 }
 

diff  --git a/libc/src/signal/sigaction.h b/libc/src/signal/sigaction.h
index 105ab1b250cc6..8315a56bb0166 100644
--- a/libc/src/signal/sigaction.h
+++ b/libc/src/signal/sigaction.h
@@ -9,13 +9,12 @@
 #ifndef LLVM_LIBC_SRC_SIGNAL_SIGACTION_H
 #define LLVM_LIBC_SRC_SIGNAL_SIGACTION_H
 
-#define __LLVM_LIBC_INTERNAL_SIGACTION
-#include "include/signal.h"
+#include <signal.h>
 
 namespace __llvm_libc {
 
-int sigaction(int signal, const struct __sigaction *__restrict libc_new,
-              struct __sigaction *__restrict libc_old);
+int sigaction(int signal, const struct sigaction *__restrict libc_new,
+              struct sigaction *__restrict libc_old);
 
 } // namespace __llvm_libc
 

diff  --git a/libc/src/signal/sigaddset.h b/libc/src/signal/sigaddset.h
index 40cec9f00c647..8d72f7767bbf8 100644
--- a/libc/src/signal/sigaddset.h
+++ b/libc/src/signal/sigaddset.h
@@ -9,7 +9,7 @@
 #ifndef LLVM_LIBC_SRC_SIGNAL_SIGEADDSET_H
 #define LLVM_LIBC_SRC_SIGNAL_SIGEADDSET_H
 
-#include "include/signal.h"
+#include <signal.h>
 
 namespace __llvm_libc {
 

diff  --git a/libc/src/stdlib/CMakeLists.txt b/libc/src/stdlib/CMakeLists.txt
index d3dd5b2068b0c..7daecd92225bc 100644
--- a/libc/src/stdlib/CMakeLists.txt
+++ b/libc/src/stdlib/CMakeLists.txt
@@ -302,9 +302,9 @@ add_entrypoint_object(
     .atexit
 )
 
-# add_entrypoint_object(
-#   abort
-#   ALIAS
-#   DEPENDS
-#     .${LIBC_TARGET_OS}.abort
-# )
+add_entrypoint_object(
+  abort
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.abort
+)

diff  --git a/libc/src/stdlib/linux/CMakeLists.txt b/libc/src/stdlib/linux/CMakeLists.txt
index 637191871e011..7d471e5e95fbf 100644
--- a/libc/src/stdlib/linux/CMakeLists.txt
+++ b/libc/src/stdlib/linux/CMakeLists.txt
@@ -10,14 +10,14 @@ add_entrypoint_object(
     libc.src.__support.OSUtil.osutil
 )
 
-# add_entrypoint_object(
-#   abort
-#   SRCS
-#     abort.cpp
-#   HDRS
-#     ../abort.h
-#   DEPENDS
-#     libc.include.stdlib
-#     libc.src.signal.raise
-#     ._Exit
-# )
+add_entrypoint_object(
+  abort
+  SRCS
+    abort.cpp
+  HDRS
+    ../abort.h
+  DEPENDS
+    libc.include.stdlib
+    libc.src.signal.raise
+    ._Exit
+)

diff  --git a/libc/test/src/CMakeLists.txt b/libc/test/src/CMakeLists.txt
index 18253ec9d9ced..b186e7764b7fa 100644
--- a/libc/test/src/CMakeLists.txt
+++ b/libc/test/src/CMakeLists.txt
@@ -51,7 +51,7 @@ add_subdirectory(dirent)
 # The signal API is currently disabled as signal.h is incorrect.
 # since assert uses the signal API, we disable assert also.
 # add_subdirectory(assert)
-# add_subdirectory(signal)
+add_subdirectory(signal)
 add_subdirectory(time)
 
 if(${LIBC_TARGET_OS} STREQUAL "linux")

diff  --git a/libc/test/src/signal/sigaction_test.cpp b/libc/test/src/signal/sigaction_test.cpp
index 4baf093deadc5..3696694655b5b 100644
--- a/libc/test/src/signal/sigaction_test.cpp
+++ b/libc/test/src/signal/sigaction_test.cpp
@@ -6,15 +6,15 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "include/errno.h"
-#define __LLVM_LIBC_INTERNAL_SIGACTION
-#include "include/signal.h"
 #include "src/signal/raise.h"
 #include "src/signal/sigaction.h"
 
 #include "test/ErrnoSetterMatcher.h"
 #include "utils/UnitTest/Test.h"
 
+#include <errno.h>
+#include <signal.h>
+
 using __llvm_libc::testing::ErrnoSetterMatcher::Fails;
 using __llvm_libc::testing::ErrnoSetterMatcher::Succeeds;
 
@@ -25,7 +25,7 @@ TEST(LlvmLibcSigaction, Invalid) {
 
 // SIGKILL cannot have its action changed, but it can be examined.
 TEST(LlvmLibcSigaction, Sigkill) {
-  struct __sigaction action;
+  struct sigaction action;
   EXPECT_THAT(__llvm_libc::sigaction(SIGKILL, nullptr, &action), Succeeds());
   EXPECT_THAT(__llvm_libc::sigaction(SIGKILL, &action, nullptr), Fails(EINVAL));
 }
@@ -37,7 +37,7 @@ TEST(LlvmLibcSigaction, CustomAction) {
   // Zero this incase tests get run multiple times in the future.
   sigusr1Count = 0;
 
-  struct __sigaction action;
+  struct sigaction action;
   EXPECT_THAT(__llvm_libc::sigaction(SIGUSR1, nullptr, &action), Succeeds());
 
   action.sa_handler = +[](int signal) {
@@ -57,7 +57,7 @@ TEST(LlvmLibcSigaction, CustomAction) {
 }
 
 TEST(LlvmLibcSigaction, Ignore) {
-  struct __sigaction action;
+  struct sigaction action;
   EXPECT_THAT(__llvm_libc::sigaction(SIGUSR1, nullptr, &action), Succeeds());
   action.sa_handler = SIG_IGN;
   EXPECT_THAT(__llvm_libc::sigaction(SIGUSR1, &action, nullptr), Succeeds());

diff  --git a/libc/test/src/stdlib/CMakeLists.txt b/libc/test/src/stdlib/CMakeLists.txt
index 3b3f04f28b799..c31c23c463651 100644
--- a/libc/test/src/stdlib/CMakeLists.txt
+++ b/libc/test/src/stdlib/CMakeLists.txt
@@ -231,18 +231,18 @@ if(LLVM_LIBC_FULL_BUILD)
       libc.src.__support.CPP.utility
   )
 
-  # add_libc_unittest(
-  #   abort_test
-  #   SUITE
-  #     libc_stdlib_unittests
-  #   SRCS
-  #     abort_test.cpp
-  #   DEPENDS
-  #     libc.include.stdlib
-  #     libc.include.signal
-  #     libc.src.stdlib.abort
-  #     libc.src.stdlib._Exit
-  #     libc.src.signal.raise
-  # )
+  add_libc_unittest(
+    abort_test
+    SUITE
+      libc_stdlib_unittests
+    SRCS
+      abort_test.cpp
+    DEPENDS
+      libc.include.stdlib
+      libc.include.signal
+      libc.src.stdlib.abort
+      libc.src.stdlib._Exit
+      libc.src.signal.raise
+  )
 
 endif()


        


More information about the libc-commits mailing list