/*
   Copyright (c) 2007-2013, John Ryland
 */
#ifndef __OS_LAYER_H__
#define __OS_LAYER_H__

#define	STDIN_FILENO	    0
#define	STDOUT_FILENO	    1
#define	STDERR_FILENO	    2

#define O_RDONLY	    0
#define O_WRONLY	    1
#define O_RDWR		    2
#ifdef ARCH_MacOSX64
#define O_NONBLOCK	    4
#else
#define O_NONBLOCK	    04000
#endif

#define PROT_NONE	    0
#define PROT_READ	    1
#define PROT_WRITE	    2
#define PROT_EXEC	    4

#define MAP_SHARED	    1
#define MAP_PRIVATE	    2

#define FD_SET(d, s)	    (((s)->b[(d)/32] |=  (1L<<((d)%32))))
#define FD_CLR(d, s)	    (((s)->b[(d)/32] &= ~(1L<<((d)%32))))
#define FD_ISSET(d, s)	    (((s)->b[(d)/32] &   (1L<<((d)%32))) != 0)
#define FD_ZERO(s)	    { unsigned i; for (i = 0; i < 32; ++i) (s)->b[i] = 0; }

typedef struct {
    long b[32];
} fd_set;

typedef struct {
    long tv_sec;
    long tv_usec;
} timeval;

typedef struct {
    int tz_minuteswest;
    int tz_dsttime;
} timezone;

typedef struct {
//    int st_dev1;
//    int st_dev2;
//    short pad1;
    int st_ino;
    int st_mode;
    int st_nlink;
    int st_uid;
    int st_gid;
//    int st_rdev1;
//    int st_rdev2;
//    short pad2;
    int st_size;
    int st_blksize;
    int st_blocks;
    int st_atime;
    int unused1;
    int st_mtime;
    int unused2;
    int st_ctime;
    int unused3;
    int unused4;
    int unused5;
} stat;


// TODO: need an off_t typedef and change fsSeek, fsMmap etc to deal with >2GB files (as is is fine for embedded)

extern char **environ;
extern int errno;

extern long sysCall(int func, long a, long b, long c);
extern void sysExit(int status);
extern int sysBrk(void *end); // if 0, returns end, else sets new end
extern int sysFork(void);
extern int sysExecve(const char *prog, char *const argv[], char *const envp[]);
extern int sysSelect(int nfds, fd_set *rfds, fd_set *wfds, fd_set *xfds, timeval *timeout);
extern int sysGetTimeOfDay(timeval *t, timezone *tz);
extern int sysIoctl(int fd, unsigned long req, void *arg);
extern int fsOpen(const char *file, int flags);
extern int fsClose(int fd);
extern int fsStat(const char *file, stat *buf);
extern int fsSeek(int fd, unsigned offset, int from);
extern int fsRead(int fd, void *buf, int len);
extern int fsWrite(int fd, const void *buf, int len);
extern void *fsMmap(void *start, int len, int prot, int flags, int fd, int offset);
extern int fsMunmap(void *addr, int len);

#endif /* __OS_LAYER_H__ */

