//
// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
//
// The contents of this file are covered under the licence agreement in the
// file "LICENCE" distributed with Cforall.
//
// bits/signal.h -- Helper functions and defines to use signals
//
// Author           : Thierry Delisle
// Created On       : Thu Jan 25 16:06:29 2018
// Last Modified By :
// Last Modified On :
// Update Count     :
//

#pragma once

#include "bits/debug.h"
#include "bits/defs.h"

extern "C" {
#include <errno.h>
#define __USE_GNU
#include <signal.h>
#undef __USE_GNU
#include <stdlib.h>
#include <string.h>
}

// Short hands for signal context information
#define __CFA_SIGCXT__ ucontext_t *
#define __CFA_SIGPARMS__ __attribute__((unused)) int sig, __attribute__((unused)) siginfo_t *sfp, __attribute__((unused)) __CFA_SIGCXT__ cxt

// Sigaction wrapper : register an signal handler
static void __cfaabi_sigaction( int sig, void (*handler)(__CFA_SIGPARMS__), int flags ) {
	struct sigaction act;

	act.sa_sigaction = (void (*)(int, siginfo_t *, void *))handler;
	act.sa_flags = flags;

	if ( sigaction( sig, &act, NULL ) == -1 ) {
		__cfaabi_dbg_print_buffer_decl(
			" __cfaabi_sigaction( sig:%d, handler:%p, flags:%d ), problem installing signal handler, error(%d) %s.\n",
			sig, handler, flags, errno, strerror( errno )
		);
		_exit( EXIT_FAILURE );
	}
}

// Sigaction wrapper : restore default handler
static void __cfaabi_sigdefault( int sig ) {
	struct sigaction act;

	act.sa_handler = SIG_DFL;
	act.sa_flags = 0;
	sigemptyset( &act.sa_mask );

	if ( sigaction( sig, &act, NULL ) == -1 ) {
		__cfaabi_dbg_print_buffer_decl(
			" __cfaabi_sigdefault( sig:%d ), problem reseting signal handler, error(%d) %s.\n",
			sig, errno, strerror( errno )
		);
		_exit( EXIT_FAILURE );
	}
}
