#ifndef _SYS_SIGNAL_H
#define _SYS_SIGNAL_H

/*
 *  Everything here must match definitions in kernel.
 */

/* Signal numbers */
#define SIGHUP		 1
#define SIGINT		 2
#define SIGQUIT		 3
#define SIGILL		 4
#define SIGTRAP		 5
#define SIGABRT		 6
#define SIGIOT		 6
#define SIGBUS		 7
#define SIGFPE		 8
#define SIGKILL		 9
#define SIGUSR1		10
#define SIGSEGV		11
#define SIGUSR2		12
#define SIGPIPE		13
#define SIGALRM		14
#define SIGTERM		15
#define SIGSTKFLT	16
#define SIGCHLD		17
#define SIGCONT		18
#define SIGSTOP		19
#define SIGTSTP		20
#define SIGTTIN		21
#define SIGTTOU		22
#define SIGURG		23
#define SIGXCPU		24
#define SIGXFSZ		25
#define SIGVTALRM	26
#define SIGPROF		27
#define SIGWINCH	28
#define SIGIO		29
#define SIGPOLL		SIGIO
#define SIGPWR		30
#define SIGSYS		31
#define SIGRTMIN    32
#define SIGRTMAX    (NSIG-1)

#define NSIG        64

#define _SIG_BITS_IN_WORD   (8 * sizeof(long))

#define _NSIG_WORDS         (NSIG / _SIG_BITS_IN_WORD)
#define __sigmask(x)        (1ul << (((x) - 1) % _SIG_BITS_IN_WORD))
#define __sigword(x)        (((x) - 1) / _SIG_BITS_IN_WORD)

/*
 * SA_FLAGS values
 */
#define SA_NOCLDSTOP    0x00000001
#define SA_NOCLDWAIT    0x00000002
#define SA_SIGINFO      0x00000004
#define SA_ONSTACK      0x08000000
#define SA_RESTART      0x10000000
#define SA_NODEFER      0x40000000
#define SA_RESETHAND    0x80000000

#define SA_NOMASK       SA_NODEFER
#define SA_ONESHOT      SA_RESETHAND

/* 
 * sigaltstack controls
 */
#define SS_ONSTACK	1
#define SS_DISABLE	2

#define MINSIGSTKSZ	4096
#define SIGSTKSZ	8192

/* sigblock */
#define SIG_BLOCK          0	/* for blocking signals */
#define SIG_UNBLOCK        1	/* for unblocking signals */
#define SIG_SETMASK        2	/* for setting the signal mask */

/*
 *  siginfo
 */
#define __SI_MASK       0xffff0000u
#define __SI_KILL       (0 << 16)
#define __SI_TIMER      (1 << 16)
#define __SI_POLL       (2 << 16)
#define __SI_FAULT      (3 << 16)
#define __SI_CHLD       (4 << 16)
#define __SI_RT         (5 << 16)
#define __SI_MESGQ      (6 << 16)
#define __SI_CODE(T,N)  ((T) | ((N) & 0xffff))

#define SI_USER		0		/* sent by kill, sigsend, raise */
#define SI_KERNEL	0x80		/* sent by the kernel from somewhere */
#define SI_QUEUE	-1		/* sent by sigqueue */
#define SI_TIMER __SI_CODE(__SI_TIMER,-2) /* sent by timer expiration */
#define SI_MESGQ __SI_CODE(__SI_MESGQ,-3) /* sent by real time mesq state change */
#define SI_ASYNCIO	-4		/* sent by AIO completion */
#define SI_SIGIO	-5		/* sent by queued SIGIO */
#define SI_TKILL	-6		/* sent by tkill system call */
#define SI_DETHREAD	-7		/* sent by execve() killing subsidiary threads */

/*
 * SIGILL si_codes
 */
#define ILL_ILLOPC	(__SI_FAULT|1)	/* illegal opcode */
#define ILL_ILLOPN	(__SI_FAULT|2)	/* illegal operand */
#define ILL_ILLADR	(__SI_FAULT|3)	/* illegal addressing mode */
#define ILL_ILLTRP	(__SI_FAULT|4)	/* illegal trap */
#define ILL_PRVOPC	(__SI_FAULT|5)	/* privileged opcode */
#define ILL_PRVREG	(__SI_FAULT|6)	/* privileged register */
#define ILL_COPROC	(__SI_FAULT|7)	/* coprocessor error */
#define ILL_BADSTK	(__SI_FAULT|8)	/* internal stack error */

/*
 * SIGFPE si_codes
 */
#define FPE_INTDIV	(__SI_FAULT|1)	/* integer divide by zero */
#define FPE_INTOVF	(__SI_FAULT|2)	/* integer overflow */
#define FPE_FLTDIV	(__SI_FAULT|3)	/* floating point divide by zero */
#define FPE_FLTOVF	(__SI_FAULT|4)	/* floating point overflow */
#define FPE_FLTUND	(__SI_FAULT|5)	/* floating point underflow */
#define FPE_FLTRES	(__SI_FAULT|6)	/* floating point inexact result */
#define FPE_FLTINV	(__SI_FAULT|7)	/* floating point invalid operation */
#define FPE_FLTSUB	(__SI_FAULT|8)	/* subscript out of range */

/*
 * SIGSEGV si_codes
 */
#define SEGV_MAPERR	(__SI_FAULT|1)	/* address not mapped to object */
#define SEGV_ACCERR	(__SI_FAULT|2)	/* invalid permissions for mapped object */
#define SEGV_BOUNDS	(__SI_FAULT|3)  /* Bounds overflow */

/*
 * SIGBUS si_codes
 */
#define BUS_ADRALN	(__SI_FAULT|1)	/* invalid address alignment */
#define BUS_ADRERR	(__SI_FAULT|2)	/* non-existant physical address */
#define BUS_OBJERR	(__SI_FAULT|3)	/* object specific hardware error */

/*
 * SIGTRAP si_codes
 */
#define TRAP_BRKPT	    (__SI_FAULT|1)	/* process breakpoint */
#define TRAP_TRACE	    (__SI_FAULT|2)	/* process trace trap */
#define TRAP_DIAG_CT	(__SI_FAULT|3)  /* Diagnostic CT condition */
#define TRAP_DIAG_ADDR	(__SI_FAULT|4)  /* Diagnostic address */
#define TRAP_DIAG_PRED	(__SI_FAULT|5)  /* Diagnostic predicate */
#define TRAP_DIAG_OP	(__SI_FAULT|6)  /* Diagnostic operand */
#define TRAP_MEM_LOCK	(__SI_FAULT|7)  /* Memory lock */

/*
 * SIGCHLD si_codes
 */
#define CLD_EXITED	(__SI_CHLD|1)	/* child has exited */
#define CLD_KILLED	(__SI_CHLD|2)	/* child was killed */
#define CLD_DUMPED	(__SI_CHLD|3)	/* child terminated abnormally */
#define CLD_TRAPPED	(__SI_CHLD|4)	/* traced child has trapped */
#define CLD_STOPPED	(__SI_CHLD|5)	/* child has stopped */
#define CLD_CONTINUED	(__SI_CHLD|6)	/* stopped child has continued */

/*
 * SIGPOLL si_codes
 */
#define POLL_IN		(__SI_POLL|1)	/* data input available */
#define POLL_OUT	(__SI_POLL|2)	/* output buffers available */
#define POLL_MSG	(__SI_POLL|3)	/* input message available */
#define POLL_ERR	(__SI_POLL|4)	/* i/o error */
#define POLL_PRI	(__SI_POLL|5)	/* high priority input available */
#define POLL_HUP	(__SI_POLL|6)	/* device disconnected */


typedef union sigval {
	int sival_int;
	void *sival_ptr;
} sigval_t;


#define __SI_MAX_SIZE       128
#define __SI_PAD_SIZE       ((__SI_MAX_SIZE/sizeof(int)) - 4)

typedef struct siginfo {
	int si_signo;
	int si_errno;
	int si_code;

	union {
		int _pad[__SI_PAD_SIZE];

		/* kill() */
		struct {
			pid_t _pid;		/* sender's pid */
			uid_t _uid;	    /* sender's uid */
		} _kill;

		/* POSIX.1b timers */
		struct {
			int _tid;		    /* timer id */
			int _overrun;		/* overrun count */
			sigval_t _sigval;	/* same as below */
		} _timer;

		/* POSIX.1b signals */
		struct {
			pid_t _pid;		/* sender's pid */
			uid_t _uid;	/* sender's uid */
			sigval_t _sigval;
		} _rt;

		/* SIGCHLD */
		struct {
			pid_t _pid;		/* which child */
			uid_t _uid;	/* sender's uid */
			int _status;		/* exit code */
			clock_t _utime;
			clock_t _stime;
		} _sigchld;

		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
		struct {
			void *_addr; /* faulting insn/memory ref. */
			int _trapno;	/* TRAP # which caused the signal */
		} _sigfault;

		/* SIGPOLL */
		struct {
			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
			int _fd;
		} _sigpoll;
	} _sifields;
} siginfo_t;

#define si_pid		_sifields._kill._pid
#define si_uid		_sifields._kill._uid
#define si_tid		_sifields._timer._tid
#define si_overrun	_sifields._timer._overrun
#define si_status	_sifields._sigchld._status
#define si_utime	_sifields._sigchld._utime
#define si_stime	_sifields._sigchld._stime
#define si_value	_sifields._rt._sigval
#define si_int		_sifields._rt._sigval.sival_int
#define si_ptr		_sifields._rt._sigval.sival_ptr
#define si_addr		_sifields._sigfault._addr
#define si_trapno	_sifields._sigfault._trapno
#define si_band		_sifields._sigpoll._band
#define si_fd		_sifields._sigpoll._fd


/* Type of a signal handler.  */
typedef void (*sighandler_t)(int);

#define SIG_DFL	    ((sighandler_t)0)       /* default signal handling */
#define SIG_IGN	    ((sighandler_t)1)       /* ignore signal */
#define SIG_ERR	    ((sighandler_t)-1)      /* error return from signal */

/* Sigmask */
typedef struct {
	unsigned long sig[_NSIG_WORDS];
} sigset_t;

struct sigaction {
    union
    {
    	sighandler_t   sa_handler;
        void           (*sa_sigaction)(int, siginfo_t *, void *);
    };
	unsigned long   sa_flags;
	void (*sa_restorer)(void);
	sigset_t        sa_mask;		/* mask last for extensibility */
};

typedef struct sigaltstack
{
    void*  ss_sp;
    int    ss_flags;
    size_t ss_size;
} stack_t;

#endif /* _SYS_SIGNAL_H */

