[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