#line 1169 "/home/travis/build/felix-lang/felix/src/packages/program.fdoc"
  
  class PosixSignal {
    requires C89_headers::signal_h;
    type signal_t = "int";
    ctor signal_t: int = "$1";
    ctor int: signal_t = "$1";
  
    type sig_t = "sig_t"; // what a pity posix calls the handler sig_t
    gen signal: signal_t * sig_t -> sig_t = "signal($1, $2)";
    instance Eq[signal_t] {
      fun == : signal_t * signal_t ->  bool = "$1==$2";
    }
    inherit Eq[signal_t];
  
    // http://pubs.opengroup.org/onlinepubs/009695399/basedefs/signal.h.html
    const
      SIGABRT, SIGALRM, SIGBUS, SIGCHLD, SIGCONT, SIGFPE, SIGHUP, SIGILL, SIGINT, SIGKILL,
      SIGPIPE, SIGQUIT, SIGSEGV, SIGSTOP, SIGTERM, SIGTSTP, SIGTTN, SIGTTOU, SIGUSR1, SIGUSR2,
      SIGPOLL, SIGPROF, SIGSYS, SIGTRAP, SIGURG, SIGVTALRM, SIGXCPU,SIGXSZ
    : signal_t;
  
    instance Str[signal_t] {
      fun str: signal_t -> string =
      | $(SIGABRT) =>  "SIGABRT"
      | $(SIGALRM) =>  "SIGALRM"
      | $(SIGBUS) =>  "SIGBUS"
      | $(SIGCHLD) =>  "SIGCHLD"
      | $(SIGCONT) =>  "SIGCONT"
      | $(SIGFPE) =>  "SIGFPE"
      | $(SIGHUP) =>  "SIGHUP"
      | $(SIGILL) =>  "SIGILL"
      | $(SIGINT) =>  "SIGINT"
      | $(SIGKILL) =>  "SIGKILL"
      | $(SIGPIPE) =>  "SIGPIPE"
      | $(SIGQUIT) =>  "SIGQUIT"
      | $(SIGSEGV) =>  "SIGSEGV"
      | $(SIGSTOP) =>  "SIGSTOP"
      | $(SIGTERM) =>  "SIGTERM"
      | $(SIGTSTP) =>  "SIGTSTP"
      // | $(SIGTTN) =>  "SIGTTN"  // not in OSX
      | $(SIGTTOU) =>  "SIGTTOU"
      | $(SIGUSR1) =>  "SIGUSR1"
      | $(SIGUSR2) =>  "SIGUSR2"
      // | $(SIGPOLL) =>  "SIGPOLL" // not in OSX
      | $(SIGPROF) =>  "SIGPROF"
      | $(SIGSYS) =>  "SIGSYS"
      | $(SIGTRAP) =>  "SIGTRAP"
      | $(SIGURG) =>  "SIGURG"
      | $(SIGVTALRM) =>  "SIGVTALRM"
      | $(SIGXCPU) =>  "SIGXCPU"
      // | $(SIGXSZ) =>  "SIGXSZ" // not in OSX
      | x => "signal " + x.int.str
      ;
    }
    inherit Str[signal_t];
  
    body "void null_signal_handler(int){}";
    const null_signal_handler: sig_t;
    proc ignore_signal(s:signal_t) { C_hack::ignore(signal(s, null_signal_handler)); }
  
    // http://pubs.opengroup.org/onlinepubs/007904975/functions/sigaction.html
    body ctrl_c_handling = """
      void set_ctrl_c_flag(int);
      void trap_ctrl_c () {
        struct sigaction sa;
        sa.sa_handler = set_ctrl_c_flag;
        sigemptyset(&sa.sa_mask);
        sa.sa_flags = SA_RESTART;
        sigaction(SIGINT, &sa, NULL);
     }
    """ requires ctrl_c_flag;
  
    inherit Signal_class[Posix];
  
    instance Signal_class[Posix] {
      proc trap_ctrl_c: unit requires ctrl_c_handling;
    }
  }