mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-15 01:13:30 +00:00
The configure checks for sigcontext (aka sigcontext_struct) have failed
for a long time without anyone noticing. The MR_GET_FAULT_ADDR macro
that is also needed for the sigcontext code paths was only ever defined
for __i386__ and __mc68000__.
According to the sigaction(2) man page, the struct sigcontext
argument was obsoleted by the introduction of the SA_SIGINFO flag
(which we also have code for, though also not working either).
configure.ac:
Delete checks related to struct sigcontext.
Delete check for asm/sigcontext.h
runtime/mercury_conf.h.in:
Delete macros that are no longer defined.
runtime/mercury_memory_handlers.c:
runtime/mercury_signal.c:
runtime/mercury_signal.h:
Delete code for using signal handlers that take a sigcontext argument.
Add XXX where native GC casts a context parameter to
struct sigcontext * when it should be a ucontext_t *.
Possibly never tested.
runtime/mercury_faultaddr.h:
Delete this file containing only the MR_GET_FAULT_ADDR macro which is
no longer used.
runtime/RESERVED_MACRO_NAMES:
ssdb/RESERVED_MACRO_NAMES:
trace/RESERVED_MACRO_NAMES:
Delete macros that are no longer defined.
tools/configure_mingw_cross:
Don't need to set variables mercury_cv_sigcontext_struct_2arg and
mercury_cv_sigcontext_struct_3arg any more.
192 lines
4.3 KiB
C
192 lines
4.3 KiB
C
// vim: ts=4 sw=4 expandtab ft=c
|
|
|
|
// Copyright (C) 1998,2000,2002, 2006, 2010 The University of Melbourne.
|
|
// Copyright (C) 2015-2016, 2018, 2020 The Mercury team.
|
|
// This file is distributed under the terms specified in COPYING.LIB.
|
|
|
|
// This module defines functions for setting up signal handlers.
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "mercury_imp.h"
|
|
#include "mercury_signal.h"
|
|
|
|
#ifdef MR_HAVE_UNISTD_H
|
|
#include <unistd.h>
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
|
|
#include "mercury_signal.h"
|
|
|
|
#ifdef MR_HAVE_SYS_SIGINFO_H
|
|
#include <sys/siginfo.h>
|
|
#endif
|
|
|
|
#ifdef MR_HAVE_MPROTECT
|
|
#include <sys/mman.h>
|
|
#endif
|
|
|
|
#ifdef MR_HAVE_UCONTEXT_H
|
|
#include <ucontext.h>
|
|
#endif
|
|
|
|
#ifdef MR_HAVE_SYS_UCONTEXT_H
|
|
#include <sys/ucontext.h>
|
|
#endif
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
// If we don't have SA_RESTART or SA_SIGINFO, defined them as 0.
|
|
// It would be nice to have them, but it is still better to use
|
|
// sigaction without SA_RESTART or SA_SIGINFO than to use signal.
|
|
|
|
#if !defined(SA_RESTART)
|
|
#define SA_RESTART 0
|
|
#endif
|
|
|
|
#if !defined(SA_SIGINFO)
|
|
#define SA_SIGINFO 0
|
|
#endif
|
|
|
|
static void MR_do_setup_signal(int sig, MR_Code *handler, MR_bool need_info,
|
|
MR_bool restart, const char *error_message);
|
|
|
|
void
|
|
MR_setup_signal(int sig, MR_Code *handler, MR_bool need_info,
|
|
const char *error_message)
|
|
{
|
|
MR_do_setup_signal(sig, handler, need_info, MR_TRUE, error_message);
|
|
}
|
|
|
|
void
|
|
MR_setup_signal_no_restart(int sig, MR_Code *handler, MR_bool need_info,
|
|
const char *error_message)
|
|
{
|
|
MR_do_setup_signal(sig, handler, need_info, MR_FALSE, error_message);
|
|
}
|
|
|
|
void
|
|
MR_do_setup_signal(int sig, MR_Code *handler, MR_bool need_info,
|
|
MR_bool restart, const char *error_message)
|
|
{
|
|
MR_signal_action act;
|
|
|
|
MR_init_signal_action(&act, handler, need_info, restart);
|
|
MR_set_signal_action(sig, &act, error_message);
|
|
}
|
|
|
|
void
|
|
MR_reset_signal(int sig)
|
|
{
|
|
MR_signal_action act;
|
|
|
|
#ifdef MR_HAVE_SIGACTION
|
|
if (sigemptyset(&(act.sa_mask)) != 0) {
|
|
MR_perror("cannot set clear signal mask");
|
|
exit(1);
|
|
}
|
|
errno = 0;
|
|
|
|
act.sa_flags = 0;
|
|
act.sa_handler = SIG_DFL;
|
|
#else
|
|
act = SIG_DFL;
|
|
#endif
|
|
MR_set_signal_action(sig, &act, "Couldn't reset signal");
|
|
}
|
|
|
|
void
|
|
MR_init_signal_action(MR_signal_action *act, MR_Code *handler,
|
|
MR_bool need_info, MR_bool restart)
|
|
{
|
|
#ifdef MR_HAVE_SIGACTION
|
|
|
|
act->sa_flags = (restart ? SA_RESTART : 0);
|
|
|
|
if (need_info) {
|
|
#ifdef MR_HAVE_SIGINFO_T
|
|
act->sa_flags |= SA_SIGINFO;
|
|
#endif
|
|
}
|
|
|
|
if (sigemptyset(&(act->sa_mask)) != 0) {
|
|
MR_perror("cannot set clear signal mask");
|
|
exit(1);
|
|
}
|
|
errno = 0;
|
|
|
|
act->MR_SIGACTION_FIELD = handler;
|
|
|
|
#else // not MR_HAVE_SIGACTION
|
|
|
|
*act = handler;
|
|
|
|
#endif // not MR_HAVE_SIGACTION
|
|
}
|
|
|
|
void
|
|
MR_get_signal_action(int sig, MR_signal_action *act, const char *error_message)
|
|
{
|
|
#ifdef MR_HAVE_SIGACTION
|
|
if (sigaction(sig, NULL, act) != 0) {
|
|
MR_perror(error_message);
|
|
exit(1);
|
|
}
|
|
#else // not MR_HAVE_SIGACTION
|
|
*act = signal(sig, NULL);
|
|
if (*act == SIG_ERR) {
|
|
MR_perror(error_message);
|
|
exit(1);
|
|
}
|
|
#endif // not MR_HAVE_SIGACTION
|
|
}
|
|
|
|
void
|
|
MR_set_signal_action(int sig, MR_signal_action *act,
|
|
const char *error_message)
|
|
{
|
|
#ifdef MR_HAVE_SIGACTION
|
|
if (sigaction(sig, act, NULL) != 0) {
|
|
MR_perror(error_message);
|
|
exit(1);
|
|
}
|
|
#else // not MR_HAVE_SIGACTION
|
|
if (signal(sig, *act) == SIG_ERR) {
|
|
MR_perror(error_message);
|
|
exit(1);
|
|
}
|
|
#endif // not MR_HAVE_SIGACTION
|
|
}
|
|
|
|
void
|
|
MR_signal_should_restart(int sig, MR_bool restart)
|
|
{
|
|
#if defined(MR_HAVE_SIGACTION)
|
|
struct sigaction act;
|
|
|
|
if (sigaction(sig, NULL, &act) != 0) {
|
|
MR_perror("error setting signal system call behaviour");
|
|
exit(1);
|
|
}
|
|
|
|
if (restart) {
|
|
act.sa_flags |= SA_RESTART;
|
|
} else {
|
|
act.sa_flags &= ~SA_RESTART;
|
|
}
|
|
|
|
if (sigaction(sig, &act, NULL) != 0) {
|
|
MR_perror("error setting signal system call behaviour");
|
|
exit(1);
|
|
}
|
|
#elif defined(MR_HAVE_SIGINTERRUPT)
|
|
if (siginterrupt(sig, !restart) != 0) {
|
|
MR_perror("error setting signal system call behaviour");
|
|
exit(1);
|
|
}
|
|
#endif
|
|
}
|