
const
 _SIG_WORDS     =4;
 _SIG_MAXSIG    =128;

const
 SIG_BLOCK   =1;
 SIG_UNBLOCK =2;
 SIG_SETMASK =3;

 SIGPROCMASK_OLD         =$0001;
 SIGPROCMASK_PROC_LOCKED =$0002;
 SIGPROCMASK_PS_LOCKED   =$0004;
 SIGPROCMASK_FASTBLK     =$0008;

const
 SIGHUP   =1;       // hangup
 SIGINT   =2;       // interrupt
 SIGQUIT  =3;       // quit
 SIGILL   =4;       // illegal instr. (not reset when caught)
 SIGTRAP  =5;       // trace trap (not reset when caught)
 SIGABRT  =6;       // abort()
 SIGIOT   =SIGABRT; // compatibility
 SIGEMT   =7;       // EMT instruction
 SIGFPE   =8;       // floating point exception
 SIGKILL  =9;       // kill (cannot be caught or ignored)
 SIGBUS   =10;      // bus error
 SIGSEGV  =11;      // segmentation violation
 SIGSYS   =12;      // non-existent system call invoked
 SIGPIPE  =13;      // write on a pipe with no one to read it
 SIGALRM  =14;      // alarm clock
 SIGTERM  =15;      // software termination signal from kill
 SIGURG   =16;      // urgent condition on IO channel
 SIGSTOP  =17;      // sendable stop signal not from tty
 SIGTSTP  =18;      // stop signal from tty
 SIGCONT  =19;      // continue a stopped process
 SIGCHLD  =20;      // to parent on child stop or exit
 SIGTTIN  =21;      // to readers pgrp upon background tty read
 SIGTTOU  =22;      // like TTIN if (tp->t_local&LTOSTOP)
 SIGIO    =23;      // input/output possible signal
 SIGXCPU  =24;      // exceeded CPU time limit
 SIGXFSZ  =25;      // exceeded file size limit
 SIGVTALRM=26;      // virtual time alarm
 SIGPROF  =27;      // profiling time alarm
 SIGWINCH =28;      // window size changes
 SIGINFO  =29;      // information request
 SIGUSR1  =30;      // user defined signal 1
 SIGUSR2  =31;      // user defined signal 2
 SIGTHR   =32;      // reserved by thread library.
 SIGLWP   =SIGTHR;
 SIGCANCEL=SIGTHR;

 SIGRTMIN=65;
 SIGRTMAX=126;

 SIG_DFL  = 0; //default
 SIG_IGN  = 1; //ignore
 SIG_ERR  =-1;
 SIG_CATCH= 2; //See signalvar.h
 SIG_HOLD = 3;

 SA_ONSTACK   =$0001; // take signal on signal stack
 SA_RESTART   =$0002; // restart system call on signal return
 SA_RESETHAND =$0004; // reset to SIG_DFL when taking signal
 SA_NODEFER   =$0010; // don't mask the signal we're delivering
 SA_NOCLDWAIT =$0020; // don't keep zombies around
 SA_SIGINFO   =$0040; // signal handler with SA_SIGINFO args

 SI_NOINFO =0;       // No signal info besides si_signo.
 SI_USER   =$10001;  // Signal sent by kill().
 SI_QUEUE  =$10002;  // Signal sent by the sigqueue().
 SI_TIMER  =$10003;  // Signal generated by expiration of a timer set by timer_settime().
 SI_ASYNCIO=$10004;  // Signal generated by completion of an asynchronous I/O request.
 SI_MESGQ  =$10005;  // Signal generated by arrival of a message on an empty message queue.
 SI_KERNEL =$10006;
 SI_LWP    =$10007;  // Signal sent by thr_kill

 _MC_FPFMT_XMM  =$10002;
 _MC_FPOWNED_FPU=$20001; // FP state came from FPU

 //mc_flags bits. Shall be in sync with TF_XXX.
 _MC_HASSEGS    =$1;
 _MC_HASBASES   =$2;
 _MC_HASFPXSTATE=$4;
 _MC_FLAG_MASK  =(_MC_HASSEGS or _MC_HASBASES or _MC_HASFPXSTATE);

type
 p_sigset_t=^sigset_t;
 sigset_t=packed record
  Case Byte of
   0:(bits:array[0.._SIG_WORDS-1] of DWORD);
   1:(qwords:array[0..(_SIG_WORDS div 2)-1] of QWORD);
 end;

 sigval=packed record
  Case Byte of
   // Members as suggested by Annex C of POSIX 1003.1b.
   0:(sival_int:Integer);
   1:(sival_ptr:Pointer);
   //6.0 compatibility
   2:(sigval_int:Integer);
   3:(sigval_ptr:Pointer);
 end;

 sigevent=packed record
  sigev_notify:Integer; //Notification type
  sigev_signo :Integer; //Signal number
  sigev_value :sigval;  //Signal value

  _sigev_un:packed record
   Case Byte of
    0:(_threadid:Integer); //__lwpid_t
    1:(_sigev_thread:packed record
        _function :Pointer; //void (*_function)(union sigval);
        _attribute:Pointer; //pthread_attr_t
       end);
    2:(__spare__:array[0..7] of QWORD);
  end;

 end;

 p_siginfo_t=^siginfo_t;
 siginfo_t=packed record
  si_signo:Integer; //signal number
  si_errno:Integer; //errno association
  {
   * Cause of signal, one of the SI_ macros or signal-specific
   * values, i.e. one of the FPE_... values for SIGFPE.  This
   * value is equivalent to the second argument to an old-style
   * FreeBSD signal handler.
  }
  si_code  :Integer;  // signal code           SI_USER
  si_pid   :Integer;  // sending process
  si_uid   :DWORD;    // sender's ruid
  si_status:Integer;  // exit value
  si_addr  :Pointer;  // faulting instruction
  si_value :sigval;   // signal value

  _reason:packed record
   Case Byte of
    0:(_fault:packed record
        _trapno:Integer; // machine specific trap code
       end);
    1:(_timer:packed record
        _timerid:Integer;
        _overrun:Integer;
       end);
    2:(_mesgq:packed record
        _mqd:Integer;
       end);
    3:(_poll:packed record
       _band:QWORD;        // band event for SIGPOLL
      end);
    4:(__spare__:packed record
        __spare1__:QWORD;
        __spare2__:array[0..6] of Integer;
       end);
  end;

 end;

 sa_handler  =procedure(sig,code:Integer;ctx:Pointer); SysV_ABI_CDecl;
 sa_sigaction=procedure(sig:Integer;info:p_siginfo_t;ctx:Pointer); SysV_ABI_CDecl;

 sig_t=sa_handler;

 p_sigaction_t=^sigaction_t;
 sigaction_t=packed record

  __sigaction_u:packed record        // signal handler
   Case Byte of
    0:(__code:Ptrint);               //SIG_DFL
    1:(__sa_handler:sa_handler);     //void (*__sa_handler)(int);
    2:(__sa_sigaction:sa_sigaction); //void (*__sa_sigaction)(int, struct __siginfo *, void *); (sa_flags and SA_SIGINFO)<>0
  end;

  sa_flags:Integer; //SA_SIGINFO
  sa_mask:sigset_t; //signal mask to apply     (signal mask inside signal)

  _align:Integer;
 end;

 sigcontext=packed record //0x490(1168)
  sc_mask:sigset_t; //signal mask to restore =1 if (SS_ONSTACK)
  sc_onstack:QWORD; //sigstack state to restore
  sc_rdi:QWORD;     //machine state (struct trapframe)
  sc_rsi:QWORD;
  sc_rdx:QWORD;
  sc_rcx:QWORD;
  sc_r8 :QWORD;
  sc_r9 :QWORD;
  sc_rax:QWORD;
  sc_rbx:QWORD;
  sc_rbp:QWORD;
  sc_r10:QWORD;
  sc_r11:QWORD;
  sc_r12:QWORD;
  sc_r13:QWORD;
  sc_r14:QWORD;
  sc_r15:QWORD;

  sc_trapno:Integer;
  sc_fs:Word;
  sc_gs:Word;

  sc_addr:QWORD;

  sc_flags:Integer; //_MC_HASSEGS
  sc_es:Word;
  sc_ds:Word;

  sc_err   :QWORD; //errno
  sc_rip   :QWORD;
  sc_cs    :QWORD;
  sc_rflags:QWORD; //EFlags
  sc_rsp   :QWORD;
  sc_ss    :QWORD;
  sc_len   :QWORD; //sizeof(mcontext_t)

  {
   * XXX - See <machine/ucontext.h> and <machine/fpu.h> for
   *       the following fields.
  }

  sc_fpformat:QWORD; //_MC_FPFMT_XMM
  sc_ownedfp :QWORD; //_MC_FPOWNED_FPU
  sc_lbrfrom :QWORD; //LastBranchFromRip
  sc_lbrto   :QWORD; //LastBranchToRip
  sc_aux1    :QWORD;
  sc_aux2    :QWORD;

  sc_fpstate:array[0..103] of QWORD; //__aligned(16); =XMM_SAVE_AREA32+XSTATE

  sc_fsbase:QWORD;
  sc_gsbase:QWORD;

  sc_spare:array[0..5] of QWORD; //6(qword) 12(int)
 end;

 p_mcontext_t=^mcontext_t;
 mcontext_t=packed record
  mc_onstack:QWORD; //sigstack state to restore  =1 if (SS_ONSTACK)
  mc_rdi:QWORD;     //machine state (struct trapframe)
  mc_rsi:QWORD;
  mc_rdx:QWORD;
  mc_rcx:QWORD;
  mc_r8 :QWORD;
  mc_r9 :QWORD;
  mc_rax:QWORD;
  mc_rbx:QWORD;
  mc_rbp:QWORD;
  mc_r10:QWORD;
  mc_r11:QWORD;
  mc_r12:QWORD;
  mc_r13:QWORD;
  mc_r14:QWORD;
  mc_r15:QWORD;

  mc_trapno:Integer;
  mc_fs:Word;
  mc_gs:Word;

  mc_addr:QWORD;

  mc_flags:Integer; //_MC_HASSEGS
  mc_es:Word;
  mc_ds:Word;

  mc_err   :QWORD; //errno
  mc_rip   :QWORD;
  mc_cs    :QWORD;
  mc_rflags:QWORD; //EFlags
  mc_rsp   :QWORD;
  mc_ss    :QWORD;
  mc_len   :QWORD; //sizeof(mcontext_t)

  {
   * XXX - See <machine/ucontext.h> and <machine/fpu.h> for
   *       the following fields.
  }

  mc_fpformat:QWORD; //_MC_FPFMT_XMM
  mc_ownedfp :QWORD; //_MC_FPOWNED_FPU
  mc_lbrfrom :QWORD; //LastBranchFromRip
  mc_lbrto   :QWORD; //LastBranchToRip
  mc_aux1    :QWORD;
  mc_aux2    :QWORD;

  mc_fpstate:array[0..103] of QWORD; //__aligned(16); =XMM_SAVE_AREA32+XSTATE

  mc_fsbase:QWORD;
  mc_gsbase:QWORD;

  mc_spare:array[0..5] of QWORD; //6(qword) 12(int)
 end;

 sigaltstack=packed record
  ss_sp:Pointer;    //signal stack base
  ss_size:size_t;   //signal stack length SIGSTKSZ
  ss_flags:Integer; //SS_DISABLE and/or SS_ONSTACK
 end;

const
 SS_ONSTACK  =$0001;   // take signal on alternate stack
 SS_DISABLE  =$0004;   // disable taking signals on alternate stack
 MINSIGSTKSZ =(512*4); // minimum stack size
 SIGSTKSZ    =(MINSIGSTKSZ+32768); // recommended stack size

// uc_flags
 _UC_SIGMASK=$01;  // valid uc_sigmask
 _UC_STACK  =$02;  // valid uc_stack
 _UC_CPU    =$04;  // valid GPR context in uc_mcontext
 _UC_FPU    =$08;  // valid FPU context in uc_mcontext

type
 p_ucontext_t=^_ucontext_t;
 _ucontext_t=packed record  //size=0x500(1280)
  uc_sigmask:sigset_t;      //2(qword) 4(int)

  uc_mcontext:mcontext_t;

  uc_link:Pointer;      //__ucontext
  uc_stack:sigaltstack; //__stack_t
  uc_flags:Integer;

  //fix me
  _unknow_data:array[0..9] of QWORD; //10(qword) 20(int)
 end;



