#include <qdos.h>

/* signal priority bitfields */
/* receiving job */
struct SIG_PRIOR_R {
          unsigned norm :3;   /* to interrupt job in normal state       */
          unsigned susp :3;   /*                ... waiting for IO      */
          unsigned wfio :3;   /*                ...  ...        job     */
          unsigned wfjob:3;   /*         .... a suspended job           */
     /* special bits */
          unsigned req_sigstack:1;     
                              /* use extra allocated sigstack (not yet) */
     /* to cope with progs that do untidy things with the stack         */
          unsigned reserved : 19;
                              /* other bits reserved, pad to lonword    */
          };

/* sending job */
struct SIG_PRIOR_S {
          unsigned norm : 3;  /* to interrupt job in normal state       */
          unsigned susp : 3;  /*                ... waiting for IO      */
          unsigned wfio : 3;  /*                ...  ...        job     */
          unsigned wfjob: 3;  /*         .... a suspended job           */
     /* special bits */
          unsigned df_susp   : 1;
                              /* defer sig if susp and priority too small*/
          unsigned df_wfio  : 1;
                              /*        ...   wfio                      */
          unsigned df_wfjob  : 1;
                              /*              wfjob                     */
          unsigned retry_sigsend :1;   
                              /* retry sigsending for tmout, blocks     */
                              /* sigsending job                         */
          unsigned reserved  : 17;      /* make sure it pads to longword */
          };

/* QDOS sighandler structure */
struct QDOS_SIGH {
          unsigned short m1;            /* 0x4afc */
          unsigned  long m2;            /* '%SIG' */
          void (*sighandler)();
          long stackmin;
          struct SIG_PRIOR_R priority;  /* longword */
          };

struct SREGS {
          datareg_t d0,d1,d2;
          addreg_t    a0,a1;
          };


/* SIGNATURE describes state in which job was interrupted, may 
   be used to restart io, resync job wait  etc..   */

#define  SGN_NORM 0           /* signal rcved during normal execution     */
#define  SGN_WFIO 1           /* may have interrupted io call,            */
                              /*                  check D0 for err.nc     */
#define  SGN_WFJB 2           /* ..... interrupted while waiting for job  */
#define  SGN_SUSP 3           /* ..... some other suspension              */

/* extra parameter for signal cleanup routine, pased in D4                */
#define  SIG_RETN  0          /* only jobs registers will be restored     */


/* saved state of job left on stack, this struct may change slightly
   in the future  */
struct SIGSVB {
          void (*sig_clup)();       /* cleanup routine, usually           */
                                    /* called by RTS. (a7->struct SIGSVB) */
          short signature;
          long  sf1,sf2;            /* signature specific */
          datareg_t d4,d5,d6;       /* saved registers    */
          addreg_t  a4,a5,a7;

          short sr;
          long  ret_addr;           /* interrupted here */
          };


typedef long usrval_t;

extern chanid_t _qsig_chan;
extern struct SIG_PRIOR_R _def_sigpriors;

void _sigwrap();              /* default sighandler for c progs, takes    */
/* args in d4,d5,a4 push them on stack and call user _sighandler() Function  */

void _init_qsignal(int /* 0 send only, <>0 send&recv */);
int  _qsigsend(jobid_t,timeout_t,
               long,struct SIG_PRIOR_S,usrval_t);


