/*
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__ */