IMPLEMENTATION MODULE Signals;

INLINE
  % #include <assert.h>
  % #include <signal.h>
  % #ifdef YAFL_MICROSOFT
  % #include <float.h>
  % #endif
  % 
  % #ifdef YAFL_ANSI
  % static void sig_handler(int sig)
  % #else
  % static void sig_handler(sig)
  % int sig;
  % #endif
  % {
  %  extern void y_sig_exc();
  %
  %#ifdef YAFL_MICROSOFT
  %  if (sig == SIGFPE)
  %      _fpreset();
  %   else
  %    signal(sig, sig_handler);
  %#else
  %  signal(sig, sig_handler);
  %#endif
  %  y_sig_exc(sig);
  % }
  %
  % static void init_all_signals YPARAMS0
  % {
  % int i;
  %
  % for (i=0; i< 100; i++)
  %   signal(i, sig_handler);
  % return;
  %
  % #ifdef SIGFPE
  %   signal(SIGFPE,sig_handler);
  % #endif  
  % #ifdef SIGINT
  %   signal(SIGINT,sig_handler);
  % #endif
  % #ifdef SIGILL  
  %   signal(SIGILL,sig_handler);
  % #endif
  % #ifdef SIGBUS  
  %   signal(SIGBUS,sig_handler);
  % #endif  
  % #ifdef SIGSEGV
  %   signal(SIGSEGV,sig_handler);
  % #endif  
  % #ifdef SIGTSTP
  %   signal(SIGTSTP,sig_handler);
  % #endif
  % #ifdef SIGTERM  
  %   signal(SIGTERM, sig_handler);
  % #endif
  % #ifdef SIGABRT  
  %   signal(SIGABRT,sig_handler); 
  % #endif
  % #ifdef SIGTTIN  
  %   signal(SIGTTIN, SIG_IGN);
  % #endif
  % #ifdef SIGTTOU  
  %   signal(SIGTTOU, SIG_IGN);
  % #endif  
  % }
  END;

  CLASS SignalHandler;
  
    REDEFINE METHOD CREATE;
      BEGIN
      INLINE
        %  init_all_signals();
        END;
      END CREATE;
  
    METHOD Register;
      BEGIN
      SignalHandlerCreator.SetHandler (THIS);
      END Register;
      
  END SignalHandler;

  ONCE CLASS SignalHandlerCreator;
  
    VAR
      TheHandler: SignalHandler;
      
    PRAGMA
      CallBack (Err, "y_sig_exc");
    
    METHOD Err(Code: INTEGER);
      BEGIN
      TheHandler.Raised (Code);
      END Err;
    
    METHOD SetHandler (Handler: SignalHandler);
      BEGIN
      TheHandler :=  Handler;
      END SetHandler;
      
  END SignalHandlerCreator;
    
END Signals;
