/* Handle signals in whatever os specific way is necessary.
   Basically, we really want to use polling.  In order to do this
   signal_poll_flag is set to TRUE when a signal comes in, and is
   checked and reset by the bytecode emulator at frequent intervals
   when it is safe to field an interrupt. */

#include <stdio.h>
#include "config.h"

#ifdef SIGNALS


#ifdef __STDC__
volatile int signal_poll_flag = 0;
#else
int signal_poll_flag = 0;
#endif


#ifdef unix

#include <signal.h>

static struct sigvec signal_trap_vec = {0,0,0};

/*ARGSUSED*/
static intr_proc(sig,code,scp)
     int sig, code;
     struct sigcontext *scp;
{
  signal_poll_flag += 1;
}

void enable_signal_polling()
{
  signal_poll_flag = 0;
  signal_trap_vec.sv_handler = intr_proc;
  if (sigvec(SIGINT, &signal_trap_vec, (struct sigvec *)NULL) != 0)
    fprintf(stderr, "Unable to enable signal polling.\n");
}

void disable_signal_polling()
{
  signal_poll_flag = 0;
  signal_trap_vec.sv_handler=SIG_DFL;
  if (sigvec(SIGINT, &signal_trap_vec, (struct sigvec *)NULL) != 0)
    fprintf(stderr, "Unable to disable signal polling.\n");
}

void clear_signal()
{
  signal_poll_flag = 0;
}

#endif /* unix */

#ifdef AMIGA

#include <exec/types.h>
#include <libraries/dos.h>
#include <exec/tasks.h>
#include <proto/exec.h>
#define BREAKFLAGS	(SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D)

static ULONG old_signals;
static APTR old_data;
static APTR old_code;
static struct Task *me = NULL;
  
static __interrupt __asm intr_proc(register __d0 sig, register __a1 *data)
{
  SetSignal(0L, BREAKFLAGS);
  *data = 1;
  return BREAKFLAGS;
}

void clear_signal()
{
  SetSignal(0L, BREAKFLAGS);
  signal_poll_flag = 0;
}

void disable_signal_polling()
{
  SetExcept(0, ~1);
  me->tc_ExceptData = old_data;
  me->tc_ExceptCode = old_code;
  SetExcept(old_signals, ~1);
  clear_signal();
}

void enable_signal_polling()
{
  signal_poll_flag = 0;
  if (me == NULL) {
    onexit(disable_signal_polling);
    me = FindTask(NULL);
    old_data = me->tc_ExceptData;
    old_code = me->tc_ExceptCode;
  }
  old_signals = SetExcept(0L, ~1);
  me->tc_ExceptData = &signal_poll_flag;
  me->tc_ExceptCode = (APTR) intr_proc;
  SetExcept(BREAKFLAGS, ~1);
}

#endif /* AMIGA */

#endif /* SIGNALS */
