[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
This commit is contained in:
parent
b89ae50795
commit
ca04d0c8fd
@ -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",
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@ -23,6 +23,7 @@ add_entrypoint_library(
|
||||
sigaddset
|
||||
sigemptyset
|
||||
sigprocmask
|
||||
signal
|
||||
|
||||
# stdlib.h entrypoints
|
||||
_Exit
|
||||
|
||||
@ -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>]
|
||||
>,
|
||||
]
|
||||
>;
|
||||
|
||||
|
||||
@ -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
|
||||
)
|
||||
|
||||
26
libc/src/signal/linux/signal.cpp
Normal file
26
libc/src/signal/linux/signal.cpp
Normal file
@ -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
|
||||
22
libc/src/signal/signal.h
Normal file
22
libc/src/signal/signal.h
Normal file
@ -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
|
||||
@ -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
|
||||
)
|
||||
|
||||
41
libc/test/src/signal/signal_test.cpp
Normal file
41
libc/test/src/signal/signal_test.cpp
Normal file
@ -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);
|
||||
}
|
||||
@ -249,13 +249,20 @@ private:
|
||||
#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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user