/* sys/syscalls.h (emx+gcc) -- Copyright (c) 1992-1996 by Eberhard Mattes */

#include <sys/signal.h>

#if !defined (NULL)
#define NULL ((void *)0)
#endif

#if !defined (INIT)
#define EXTERN extern
#define INIT(x)
#endif

#define BEGIN do {
#define END   } while (0)

#if !defined (_OS2EMX_H)
typedef unsigned long ULONG;
#endif

/* This macro is used for accessing FDATE or FTIME values as
   USHORT. */

#define XUSHORT(x) (*(USHORT *)&(x))

/* Fetch this many FILEFINDBUF3 entries at once with DosFindFirst and
   DosFindNext. */

#define FIND_COUNT      4

/* Maximum number of heap objects (16 = 512 / 32). */

#define MAX_HEAP_OBJS   16

/* This structure describes one heap object. */

struct heap_obj
{
  ULONG base;                   /* Base address */
  ULONG end;                    /* End address */
  ULONG brk;                    /* Address of first unused byte */
};

EXTERN int _sys_umask INIT (0022);
EXTERN unsigned _sys_uflags INIT (0);
EXTERN unsigned long _sys_clock0_ms INIT (0);
EXTERN long _sys_ino INIT (0x100000);
EXTERN int _sys_pid;
EXTERN int _sys_ppid;

/* The top heap object.  This points into _sys_heap_objs[] or is NULL.
   While this variable is NULL, no memory has been allocated. */

struct heap_obj *_sys_top_heap_obj;

/* This array holds information on all the heap objects.  The heap
   objects are managed in LIFO fashion. */

struct heap_obj _sys_heap_objs[MAX_HEAP_OBJS];

/* This is the number of heap objects. */

EXTERN unsigned _sys_heap_obj_count;

/* This variable can be initialized by the application to control the
   size of the heap object(s). */

extern unsigned _sys_heap_size;


#if defined (_OS2EMX_H)

#define FTIMEZEROP(x) (*(USHORT *)&(x) == 0)
#define FDATEZEROP(x) (*(USHORT *)&(x) == 0)

struct find_data
{
  HDIR find_handle;
  ULONG find_count;
  FILEFINDBUF3 find_buf[FIND_COUNT];
  const FILEFINDBUF3 *find_next;
};

typedef struct
{
  struct find_data fd;
  sigset_t sig_blocked;
  sigset_t sig_pending;
  struct sigaction signals[NSIG];
} thread_data;

#if defined (INCL_DOSEXCEPTIONS)
EXTERN PEXCEPTIONREGISTRATIONRECORD _sys_xreg INIT (NULL);
ULONG _sys_exception (PEXCEPTIONREPORTRECORD report,
    PEXCEPTIONREGISTRATIONRECORD registration, PCONTEXTRECORD context,
    PVOID whatever);
#endif /* defined (INCL_DOSEXCEPTIONS) */

/* TODO: SIGSTOP */
#define SET_BLOCKED(tp,set) ((tp)->sig_blocked = (set) & ~_SIGMASK (SIGKILL))

enum sig_type
{
  ST_TERM,                      /* Terminate process (SIGINT for instance) */
  ST_NEXT,                      /* Pass on to next exception handler */
  ST_IGNORE                     /* Ignore exception and continue thread */
};

struct sig_descr
{
  const char *name;             /* Name of the signal */
  enum sig_type dfl_action;     /* Default action */
  enum sig_type fun_action;     /* Action taken after calling handler */
};

extern char const _sys_sig_valid[NSIG];
extern struct sig_descr const sig_info[NSIG];

long _sys_p2t (FTIME t, FDATE d);
void _sys_init_thread (thread_data *tp);
void _sys_deliver_pending_signals (thread_data *tp);

#if defined (__MT__)

#define MAX_THREADS 1024

/* This mutex semaphore protects the heap. */
#ifdef _FMC_SHARED
EXTERN _fmutex _sys_heap_fmutex;
#endif
EXTERN void *_sys_private_heap INIT (NULL);
EXTERN thread_data *_sys_thread_table[MAX_THREADS];

thread_data *_sys_thread (void);
#define SYS_THREAD (_sys_thread ())

#else /* !defined (_MT) */

EXTERN thread_data _sys_thread_one;
#define SYS_THREAD (&_sys_thread_one)

#endif /* !defined (_MT) */

#endif /* _OS2EMX_H */

void _sys_set_errno (unsigned long rc);
void _sys_get_clock (unsigned long *ms);
ULONG _sys_expand_heap_obj_by (ULONG incr);
ULONG _sys_expand_heap_by (ULONG incr, ULONG sbrk_model);
ULONG _sys_shrink_heap_to (ULONG new_brk);
ULONG _sys_shrink_heap_by (ULONG decr, ULONG sbrk_model);
ULONG _sys_shrink_heap_obj_by (ULONG decr);
