forked from OSchip/llvm-project
[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
This commit is contained in:
parent
6886f094e8
commit
215c9fa4de
|
@ -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"> {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -33,3 +33,9 @@ add_header(
|
|||
HDR
|
||||
unistd-macros.h
|
||||
)
|
||||
|
||||
add_header(
|
||||
signal_macros
|
||||
HDR
|
||||
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
|
|
@ -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
|
|
@ -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(
|
||||
|
|
|
@ -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__
|
|
@ -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 different 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__
|
|
@ -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__
|
||||
|
|
|
@ -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__
|
|
@ -14,7 +14,7 @@
|
|||
#define __need_size_t
|
||||
#include <stddef.h>
|
||||
|
||||
%%include_file(${platform_signal})
|
||||
#include <llvm-libc-macros/signal-macros.h>
|
||||
|
||||
%%public_api()
|
||||
|
||||
|
|
|
@ -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
|
||||
[
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 different 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
|
|
@ -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 differ 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
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue