[libc-commits] [libc] ca04d0c - [libc] Add signal
Alex Brachet via libc-commits
libc-commits at lists.llvm.org
Sun Mar 22 11:15:54 PDT 2020
Author: Alex Brachet
Date: 2020-03-22T14:15:47-04:00
New Revision: ca04d0c8fd269978be1c13fe1241172cdfe6a6ea
URL: https://github.com/llvm/llvm-project/commit/ca04d0c8fd269978be1c13fe1241172cdfe6a6ea
DIFF: https://github.com/llvm/llvm-project/commit/ca04d0c8fd269978be1c13fe1241172cdfe6a6ea.diff
LOG: [libc] Add signal
Summary:
This patch adds a Linux implementation for `signal`
It also fixes `ASSERT|EXPECT_THAT` macros
Reviewers: sivachandra, PaulkaToast, MaskRay
Reviewed By: sivachandra
Subscribers: mgorny, tschuett, libc-commits
Differential Revision: https://reviews.llvm.org/D76536
Added:
libc/src/signal/linux/signal.cpp
libc/src/signal/signal.h
libc/test/src/signal/signal_test.cpp
Modified:
libc/config/linux/api.td
libc/lib/CMakeLists.txt
libc/spec/stdc.td
libc/src/signal/linux/CMakeLists.txt
libc/test/src/signal/CMakeLists.txt
libc/utils/UnitTest/Test.h
Removed:
################################################################################
diff --git a/libc/config/linux/api.td b/libc/config/linux/api.td
index e9391cb52feb..d9c2470b6e52 100644
--- a/libc/config/linux/api.td
+++ b/libc/config/linux/api.td
@@ -194,9 +194,16 @@ def StructSigactionDefn : TypeDecl<"struct sigaction"> {
}];
}
+def SighandlerTDefn : TypeDecl<"__sighandler_t"> {
+ let Decl = [{
+ typedef void(*__sighandler_t)(int);
+ }];
+}
+
def SignalAPI : PublicAPI<"signal.h"> {
let TypeDeclarations = [
StructSigactionDefn,
+ SighandlerTDefn,
];
let Functions = [
@@ -205,6 +212,7 @@ def SignalAPI : PublicAPI<"signal.h"> {
"sigprocmask",
"sigemptyset",
"sigaddset",
+ "signal",
];
}
diff --git a/libc/lib/CMakeLists.txt b/libc/lib/CMakeLists.txt
index b234c91704a9..748dac161043 100644
--- a/libc/lib/CMakeLists.txt
+++ b/libc/lib/CMakeLists.txt
@@ -23,6 +23,7 @@ add_entrypoint_library(
sigaddset
sigemptyset
sigprocmask
+ signal
# stdlib.h entrypoints
_Exit
diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index dfac8ebed3c7..8505b70c7eee 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -16,6 +16,8 @@ def StdC : StandardSpec<"stdc"> {
PtrType IntPtr = PtrType<IntType>;
+ NamedType SigHandlerT = NamedType<"__sighandler_t">;
+
HeaderSpec Assert = HeaderSpec<
"assert.h",
[
@@ -226,10 +228,16 @@ def StdC : StandardSpec<"stdc"> {
],
[
SizeTType,
+ SigHandlerT,
],
[], // Enumerations
[
FunctionSpec<"raise", RetValSpec<IntType>, [ArgSpec<IntType>]>,
+ FunctionSpec<
+ "signal",
+ RetValSpec<SigHandlerT>,
+ [ArgSpec<IntType>, ArgSpec<SigHandlerT>]
+ >,
]
>;
diff --git a/libc/src/signal/linux/CMakeLists.txt b/libc/src/signal/linux/CMakeLists.txt
index 1d59b7502f7b..447818e0fd20 100644
--- a/libc/src/signal/linux/CMakeLists.txt
+++ b/libc/src/signal/linux/CMakeLists.txt
@@ -84,3 +84,15 @@ add_entrypoint_object(
errno_h
signal_h
)
+
+add_entrypoint_object(
+ signal
+ SRCS
+ signal.cpp
+ HDRS
+ signal.h
+ ../signal.h
+ DEPENDS
+ sigaction
+ signal_h
+)
diff --git a/libc/src/signal/linux/signal.cpp b/libc/src/signal/linux/signal.cpp
new file mode 100644
index 000000000000..5a7a12d6c842
--- /dev/null
+++ b/libc/src/signal/linux/signal.cpp
@@ -0,0 +1,26 @@
+//===------------------ Linux implementation of signal --------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#define __LLVM_LIBC_INTERNAL_SIGACTION
+#include "src/signal/signal.h"
+#include "src/signal/sigaction.h"
+
+#include "src/__support/common.h"
+
+namespace __llvm_libc {
+
+sighandler_t LLVM_LIBC_ENTRYPOINT(signal)(int signum, sighandler_t handler) {
+ 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.
+ return __llvm_libc::sigaction(signum, &action, &old) == -1 ? SIG_ERR
+ : old.sa_handler;
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/signal/signal.h b/libc/src/signal/signal.h
new file mode 100644
index 000000000000..fb4e12d89ec5
--- /dev/null
+++ b/libc/src/signal/signal.h
@@ -0,0 +1,22 @@
+//===------------- Implementation header for signal ------------*- 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_SIGNAL_H
+#define LLVM_LIBC_SRC_SIGNAL_SIGNAL_H
+
+#include "include/signal.h"
+
+namespace __llvm_libc {
+
+using sighandler_t = __sighandler_t;
+
+sighandler_t signal(int signum, sighandler_t handler);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_SIGNAL_SIGNAL_H
diff --git a/libc/test/src/signal/CMakeLists.txt b/libc/test/src/signal/CMakeLists.txt
index db919b6f5d01..3fc33c3dbecc 100644
--- a/libc/test/src/signal/CMakeLists.txt
+++ b/libc/test/src/signal/CMakeLists.txt
@@ -52,3 +52,18 @@ add_libc_unittest(
signal_h
__errno_location
)
+
+add_libc_unittest(
+ signal_test
+ SUITE
+ libc_signal_unittests
+ SRCS
+ signal_test.cpp
+ DEPENDS
+ signal
+ signal_h
+ sigaction
+ raise
+ __errno_location
+ errno_h
+)
diff --git a/libc/test/src/signal/signal_test.cpp b/libc/test/src/signal/signal_test.cpp
new file mode 100644
index 000000000000..6be38fc27bdc
--- /dev/null
+++ b/libc/test/src/signal/signal_test.cpp
@@ -0,0 +1,41 @@
+//===------------------------ Unittests for signal ------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "include/errno.h"
+#include "include/signal.h"
+#include "src/errno/llvmlibc_errno.h"
+#include "src/signal/raise.h"
+#include "src/signal/signal.h"
+
+#include "utils/UnitTest/ErrnoSetterMatcher.h"
+#include "utils/UnitTest/Test.h"
+
+using __llvm_libc::testing::ErrnoSetterMatcher::Fails;
+using __llvm_libc::testing::ErrnoSetterMatcher::Succeeds;
+
+TEST(Signal, Invalid) {
+ llvmlibc_errno = 0;
+ __llvm_libc::sighandler_t valid = +[](int) {};
+ EXPECT_THAT((void *)__llvm_libc::signal(0, valid),
+ Fails(EINVAL, (void *)SIG_ERR));
+ EXPECT_THAT((void *)__llvm_libc::signal(65, valid),
+ Fails(EINVAL, (void *)SIG_ERR));
+}
+
+static int sum;
+TEST(Signal, Basic) {
+ // In case test get run multiple times.
+ sum = 0;
+ ASSERT_NE(__llvm_libc::signal(SIGUSR1, +[](int) { sum++; }),
+ SIG_ERR);
+ ASSERT_THAT(__llvm_libc::raise(SIGUSR1), Succeeds());
+ EXPECT_EQ(sum, 1);
+ for (int i = 0; i < 10; i++)
+ ASSERT_THAT(__llvm_libc::raise(SIGUSR1), Succeeds());
+ EXPECT_EQ(sum, 11);
+}
diff --git a/libc/utils/UnitTest/Test.h b/libc/utils/UnitTest/Test.h
index 7982cd66a8cc..3c042de4c12d 100644
--- a/libc/utils/UnitTest/Test.h
+++ b/libc/utils/UnitTest/Test.h
@@ -249,13 +249,20 @@ class Test {
#define UNIQUE_VAR(prefix) __CAT(prefix, __LINE__)
#define EXPECT_THAT(MATCH, MATCHER) \
- auto UNIQUE_VAR(__matcher) = (MATCHER); \
- __llvm_libc::testing::Test::testMatch( \
- Ctx, UNIQUE_VAR(__matcher).match((MATCH)), UNIQUE_VAR(__matcher), \
- #MATCH, #MATCHER, __FILE__, __LINE__)
+ do { \
+ auto UNIQUE_VAR(__matcher) = (MATCHER); \
+ __llvm_libc::testing::Test::testMatch( \
+ Ctx, UNIQUE_VAR(__matcher).match((MATCH)), UNIQUE_VAR(__matcher), \
+ #MATCH, #MATCHER, __FILE__, __LINE__); \
+ } while (0)
#define ASSERT_THAT(MATCH, MATCHER) \
- if (!EXPECT_THAT(MATCH, MATCHER)) \
- return
+ do { \
+ auto UNIQUE_VAR(__matcher) = (MATCHER); \
+ if (!__llvm_libc::testing::Test::testMatch( \
+ Ctx, UNIQUE_VAR(__matcher).match((MATCH)), UNIQUE_VAR(__matcher), \
+ #MATCH, #MATCHER, __FILE__, __LINE__)) \
+ return; \
+ } while (0)
#endif // LLVM_LIBC_UTILS_UNITTEST_H
More information about the libc-commits
mailing list