MODULES += Input/PS2KbMouse
MODULES += x86/ISADMA x86/VGAText
-MODULES += USB/Core USB/UHCI
+MODULES += USB/Core
#MODULES += USB/EHCI
+MODULES += USB/UHCI
#USB/OHCI
MODULES += USB/HID USB/MSC
#MODULES += Interfaces/UDI
include $(dir $(lastword $(MAKEFILE_LIST)))../../Makefile.cfg
+ACPI_DEBUG ?= no
+
BIN := ../bin-$(ARCH)/libacpica.a
_VERS := $(patsubst acpica-unix-%.tar.gz,%,$(wildcard acpica-unix-*.tar.gz))
CPPFLAGS += -I $(ACPICAROOT)source/include -D _ACESS -D __KERNEL__
CPPFLAGS += -D ARCH=$(ARCH) -D ARCHDIR=$(ARCHDIR) -D PLATFORM=\"$(PLATFORM)\" -D ARCHDIR_IS_$(ARCHDIR)=1 -D PLATFORM_is_$(PLATFORM)=1
CPPFLAGS += -D KERNEL_VERSION=$(KERNEL_VERSION) -ffreestanding
+ifneq ($(ACPI_DEBUG),no)
+ CPPFLAGS += -D ACPI_DEBUG_OUTPUT=1 -D ACPI_DISASSEMBLER=1
+endif
CFLAGS += -Wall -fno-stack-protector -Wstrict-prototypes -std=gnu99 -g
SRCS := $(wildcard $(COMPDIR)*/*.c)
# C header
open(HEADER, ">include/syscalls.h");
print HEADER "/*
- * Acess2
+ * Acess2 Kernel
+ * - By John Hodge (thePowersGang)
+ *
* syscalls.h
* - System Call List
*
#define NUM_SYSCALLS ",$i,"
#define SYS_DEBUG 0x100
-#ifndef __ASSEMBLER__
+#if !defined(__ASSEMBLER__) && !defined(NO_SYSCALL_STRS)
static const char *cSYSCALL_NAMES[] = {
";
typedef signed long Sint32;
typedef signed long long Sint64;
-typedef int size_t;
+//typedef int size_t;
typedef char BOOL;
typedef Uint32 tVAddr;
CFLAGS =
ASFLAGS = -f elf
+USE_ACPICA ?= 1
USE_MP=0
ifeq ($(PLATFORM),default)
endif
ASFLAGS += -D USE_MP=$(USE_MP)
-CPPFLAGS += -DUSE_MP=$(USE_MP)
+CPPFLAGS += -DUSE_MP=$(USE_MP) -DUSE_ACPICA=$(USE_ACPICA)
A_OBJ = start.ao main.o mboot.o lib.o desctab.ao errors.o irq.o
A_OBJ += mm_phys.o mm_virt.o
A_OBJ += proc.o proc.ao time.o vm8086.o
A_OBJ += kpanic.o pci.o vpci.o
-#A_OBJ += acpica.o
-#EXTERNS += ACPICA
+ifeq ($(USE_ACPICA),1)
+A_OBJ += acpica.o
+EXTERNS += ACPICA
+endif
* acpica.c
* - ACPICA Interface
*/
+#define ACPI_DEBUG_OUTPUT 1
#define DEBUG 1
#define _AcpiModuleName "Shim"
#define _COMPONENT "Acess"
int namelen = (CacheName ? strlen(CacheName) : 0) + 1;
LOG("CacheName=%s, ObjSize=%x, MaxDepth=%x", CacheName, ObjectSize, MaxDepth);
+ namelen = (namelen + 3) & ~3;
+
ret = malloc(sizeof(*ret) + MaxDepth*sizeof(char) + namelen + MaxDepth*ObjectSize);
if( !ret ) return AE_NO_MEMORY;
void *AcpiOsAcquireObject(ACPI_CACHE_T *Cache)
{
- LOG("(Cache=%p)", Cache);
+ ENTER("pCache", Cache);
for(int i = 0; i < Cache->nObj; i ++ )
{
if( !Cache->ObjectStates[i] ) {
Cache->ObjectStates[i] = 1;
- return (char*)Cache->First + i*Cache->ObjectSize;
+ void *rv = (char*)Cache->First + i*Cache->ObjectSize;
+ LEAVE('p', rv);
+ return rv;
}
}
- // TODO
+
+ LEAVE('n');
return NULL;
}
tVAddr delta = (tVAddr)Object - (tVAddr)Cache->First;
delta /= Cache->ObjectSize;
+ LOG("delta = %i, (limit %i)", delta, Cache->nObj);
if( delta > Cache->nObj )
return AE_BAD_PARAMETER;
Uint ofs = PhysicalAddress & (PAGE_SIZE-1);
int npages = (ofs + Length + (PAGE_SIZE-1)) / PAGE_SIZE;
void *rv = ((char*)MM_MapHWPages(PhysicalAddress, npages)) + ofs;
+// MM_DumpTables(0, -1);
LOG("Map (%P+%i pg) to %p", PhysicalAddress, npages, rv);
return rv;
}
%endif
; - Assignable
%assign i 0xF1
-%rep 16
+%rep 15
DEF_IRQ i
%assign i i+1
%endrep
extern void MM_Install(int NPMemRanges, tPMemMapEnt *PMemRanges);
extern void MM_InstallVirtual(void);
extern int Time_Setup(void);
-//extern int ACPICA_Initialise(void);
+extern int ACPICA_Initialise(void);
// === PROTOTYPES ===
int kmain(Uint MbMagic, void *MbInfoPtr);
// Start Multitasking
Threads_Init();
+ #if USE_ACPICA
// Poke ACPICA
-// ACPICA_Initialise();
+ ACPICA_Initialise();
+ #endif
Log_Log("Arch", "Starting VFS...");
// Load Virtual Filesystem
{
MM_DerefPhys( gaPageTable[ i + j ] & ~0xFFF );
gaPageTable[ i + j ] = 0;
+ INVLPG( (tVAddr)(i+j) << 12 );
}
Mutex_Release( &glTempMappings );
typedef Uint64 tPAddr;
typedef Uint64 tVAddr;
-typedef Uint64 size_t;
typedef char BOOL;
#define __ASM__ __asm__ __volatile__
/*
- * Acess2
+ * Acess2 Kernel
+ * - By John Hodge (thePowersGang)
+ *
* syscalls.h
* - System Call List
*
#define NUM_SYSCALLS 88
#define SYS_DEBUG 0x100
-#ifndef __ASSEMBLER__
+#if !defined(__ASSEMBLER__) && !defined(NO_SYSCALL_STRS)
static const char *cSYSCALL_NAMES[] = {
"SYS_EXIT",
"SYS_CLONE",
if( Period > 256 )
Period = 256;
+ LOG("Endpoint=%x, bOutbound=%i, Period=%i, Length=%i", Endpoint, bOutbound, Period, Length);
+
// Round the period to the closest power of two
pow2period = 1;
period_pow = 0;
if( (tVAddr)Dest <= 256*16 )
return NULL;
+ LOG("Dest=%p, isOutbound=%i, Lengths(Setup:%i,Out:%i,In:%i)", Dest, isOutbound, SetupLength, OutLength, InLength);
+
// Check size of SETUP and status
// Allocate TDs
if [ "x$_NOUSB" != "xyes" ] ; then
QEMU_PARAMS=$QEMU_PARAMS" -usb"
-# QEMU_PARAMS=$QEMU_PARAMS" -device usb-ehci"
+ QEMU_PARAMS=$QEMU_PARAMS" -device usb-ehci"
QEMU_PARAMS=$QEMU_PARAMS" -drive id=test_usb_image,file=USB_Test_Image.img,if=none"
QEMU_PARAMS=$QEMU_PARAMS" -device usb-storage,drive=test_usb_image"
QEMU_PARAMS=$QEMU_PARAMS" -usbdevice mouse"
# qemu-system-x86_64 $QEMU_PARAMS -serial stdio | tee QemuLog.txt
#echo $QEMU $BOOTOPT $QEMU_PARAMS
if [ "x$_NOGRAPHIC" = "xyes" ] ; then
- $QEMU $BOOTOPT $QEMU_PARAMS -nographic
+ eval $QEMU $BOOTOPT $QEMU_PARAMS -nographic
exit
fi
if [ "x$_NOTEE" = "xyes" ] ; then
- $QEMU $BOOTOPT $QEMU_PARAMS -serial stdio
+ eval $QEMU $BOOTOPT $QEMU_PARAMS -serial stdio
exit
fi
- AxWin3
> Text editor (with a GP formatted text field?)
> Maybe a basic web browser using the surface support?
+ > Port freetype for nice font support
> Configuration (via lib/server)
- Omnispeak
# Get base directory
BASEDIR=`dirname "$fullpath"`
-cfgfile=`mktemp`
-make --no-print-directory -f $BASEDIR/getconfig.mk ARCH=x86 > $cfgfile
-#echo $cfgfile
-#cat $cfgfile
-. $cfgfile
-rm $cfgfile
-
_miscargs=""
_compile=0
+_linktype=Applications
while [[ $# -gt 0 ]]; do
case "$1" in
-E)
_preproc=1
;;
+ -M)
+ _makedep=1
+ ;;
-c)
_compile=1
;;
shift
_outfile="-o $1"
;;
- -I)
+ -shared)
+ _ldflags=$_ldflags" -shared -lc -lgcc"
+ _linktype=Libraries
+ ;;
+ -I|-D|-O)
+ _cflags=$_cflags" $1 $2"
shift
- _cflags=$_cflags" -I$1"
;;
-I*|-D*|-O*)
_cflags=$_cflags" $1"
arg=${arg/,/ }
_ldflags=$_ldflags" ${arg}"
;;
- -l)
+ -l|-L)
+ _libs=$_libs" $1$2"
shift
- _libs=$_libs" -l$1"
;;
-l*|-L*)
_libs=$_libs" $1"
done
run() {
-# echo $*
+# echo --- $*
$*
+ return $?
}
+cfgfile=`mktemp`
+make --no-print-directory -f $BASEDIR/getconfig.mk ARCH=x86 TYPE=$_linktype > $cfgfile
+. $cfgfile
+rm $cfgfile
+
+#echo "_compile = $_compile, _preproc = $_preproc"
+
if [[ $_preproc -eq 1 ]]; then
run $_CC -E $CFLAGS $_cflags $_miscargs $_outfile
- exit $?
-fi
-if [[ $_compile -eq 1 ]]; then
+elif [[ $_makedep -eq 1 ]]; then
+ run $_CC -M $CFLAGS $_cflags $_miscargs $_outfile
+elif [[ $_compile -eq 1 ]]; then
run $_CC $CFLAGS $_cflags $_miscargs -c $_outfile
- exit $?
-fi
-
-if echo " $_miscargs" | grep '\.c' >/dev/null; then
+elif echo " $_miscargs" | grep '\.c' >/dev/null; then
tmpout=`mktemp acess_gccproxy.XXXXXXXXXX.o --tmpdir`
- run $_CC $CFLAGS $_miscargs -c -o $tmpout
- run $_LD $LDFLAGS $_ldflags $_libs $tmpout $_outfile
+ run $_CC $CFLAGS $_cflags $_miscargs -c -o $tmpout
+ run $_LD $LDFLAGS $_ldflags $_libs $tmpout $_outfile -lgcc $_libs
rm $tmpout
else
- run $_LD $LDFLAGS $_ldflags $_miscargs $_outfile $LIBGCC_PATH
+ run $_LD$_ldflags $_miscargs $_outfile $LDFLAGS $_libs
fi
-include $(dir $(lastword $(MAKEFILE_LIST)))../../Usermode/Applications/Makefile.cfg
+include $(dir $(lastword $(MAKEFILE_LIST)))../../Usermode/$(TYPE)/Makefile.cfg
.PHONY: shellvars
--- /dev/null
+/*
+ * Acess Text Editor (ATE)
+ * - By John Hodge (thePowersGang)
+ *
+ * strings.c
+ * - String Localisation
+ */
+
+struct keyval_str
+{
+ const char *key;
+ const char *val;
+};
+
+const struct keyval_str gaDisplayStrings[] = {
+ {"BtnNew", "New"},
+ {"BtnOpen", "Open"},
+ {"BtnSave", "Save"},
+ {"BtnUndo", "Undo"}
+ };
+
--- /dev/null
+/*
+ * Acess Text Editor (ATE)
+ * - By John Hodge (thePowersGang)
+ *
+ * strings.h
+ * - String Localisation
+ */
+#ifndef _STRINGS_H_
+#define _STRINGS_H_
+
+extern const char *getstr(const char *key);
+extern const char *getimg(const char *key);
+
+#endif
+
INCFILES := stdio.h stdlib.h\r
\r
OBJ = stub.o heap.o stdlib.o env.o stdio.o string.o select.o rand.o\r
-OBJ += perror.o scanf.o signals.o strtoi.o\r
+OBJ += perror.o scanf.o signals.o strtoi.o strtof.o\r
OBJ += arch/$(ARCHDIR).ao\r
# signals.o\r
DEPFILES := $(OBJ:%.o=%.d)\r
[bits 32]
[section .text]
-[global setjmp]
+[global setjmp:function]
setjmp:
mov eax, [esp+4] ; Get base of buffer
setjmp.restore:
ret
-[global longjmp]
+[global longjmp:function]
longjmp:
mov ebp, [esp+4] ; jmp_buf
mov eax, [esp+8] ; value
--- /dev/null
+
+#define PRId64 "lld"
+#define PRIdLEAST64 "lld"
+#define PRIdFAST64 "lld"
+#define PRIdMAX
+#define PRIdPTR
+#define PRIi64
+#define PRIiLEAST64
+#define PRIiFAST64
+#define PRIiMAX
+#define PRIiPTR
+
+#define PRIx64 "llx"
#define _LIBC_SETJMP_H_
#if ARCHDIR_is_x86
-typedef uint32_t jmp_buf[8];
+typedef void *jmp_buf[8];
#elif ARCHDIR_is_x86_64
-typedef uint64_t jmp_buf[16];
+typedef void *jmp_buf[16];
#else
# error "Unknown Architecture"
#endif
extern int fileno(FILE *stream);
extern size_t fread(void *buf, size_t size, size_t n, FILE *fp);
-extern size_t fwrite(void *buf, size_t size, size_t n, FILE *fp);
+extern size_t fwrite(const void *buf, size_t size, size_t n, FILE *fp);
extern int fgetc(FILE *fp);
+extern char *fgets(char *s, int size, FILE *fp);
extern int fputc(int ch, FILE *fp);
+extern int fputs(const char *s, FILE *fp);
extern int getchar(void);
extern int putchar(int ch);
extern unsigned long long strtoull(const char *ptr, char **end, int base);\r
extern unsigned long strtoul(const char *ptr, char **end, int base);\r
extern int atoi(const char *ptr);\r
+\r
+extern double strtod(const char *ptr, char **end);\r
+extern float strtof(const char *ptr, char **end);\r
+extern float atof(const char *ptr);\r
+\r
extern void exit(int status) __attribute__((noreturn));\r
extern void abort(void);\r
extern void atexit(void (*__func)(void));\r
extern char *strcpy(char *dst, const char *src);
extern char *strncpy(char *dst, const char *src, size_t num);
extern char *strcat(char *dst, const char *src);
+extern char *strncat(char *dest, const char *src, size_t n);
extern char *strdup(const char *src);
extern char *strndup(const char *src, size_t length);
extern char *strchr(const char *str, int character);
} ptr;
long long ival;
//long double rval;
- int maxlen = 0, offset = -1;
+ int maxlen = 0;
+ // int offset = -1;
enum e_vcscanf_sizes size = _VCSCANF_UNDEF;
enum e_vcscanf_types valtype;
}
// %n$ - Direct offset selection, shouldn't be mixed with just %
+ #if 0
for( ; isdigit(fch); fch = *format++ )
maxlen = maxlen * 10 + (fch - '0');
if( fch == '$' ) {
offset = maxlen;
maxlen = 0;
}
+ #endif
// Supress assignemnt?
if( fch == '*' )
* \fn EXPORT size_t fwrite(void *ptr, size_t size, size_t num, FILE *fp)\r
* \brief Write to a stream\r
*/\r
-EXPORT size_t fwrite(void *ptr, size_t size, size_t num, FILE *fp)\r
+EXPORT size_t fwrite(const void *ptr, size_t size, size_t num, FILE *fp)\r
{\r
size_t ret;\r
\r
return ret;\r
}\r
\r
+/**\r
+ * \brief Write a string to a stream (without trailing \n)\r
+ */\r
+EXPORT int fputs(const char *s, FILE *fp)\r
+{\r
+ int len = strlen(s);\r
+ return fwrite(s, 1, len, fp);\r
+}\r
+\r
+/**\r
+ * \brief Read a line (and possible trailing \n into a buffer)\r
+ */\r
+EXPORT char *fgets(char *s, int size, FILE *fp)\r
+{\r
+ int ofs = 0;\r
+ char ch = '\0';\r
+ while( ofs < size && ch != '\n' )\r
+ {\r
+ if( fread(&ch, 1, 1, fp) != 1 )\r
+ break;\r
+ s[ofs ++] = ch;\r
+ }\r
+ if( ofs < size )\r
+ s[ofs] = '\0';\r
+ return s;\r
+}\r
+\r
/**\r
* \fn EXPORT int fputc(int c, FILE *fp)\r
* \brief Write a single character to the stream\r
return dst;
}
+EXPORT char *strncat(char *dst, const char *src, size_t n)
+{
+ char *to = dst;
+ // Find the end
+ while(*to) to++;
+ // Copy
+ while(*src && n--) *to++ = *src++;
+ // End string
+ *to = '\0';
+ return dst;
+}
+
/**
* \brief Get the length of a string
*/
--- /dev/null
+/*
+ * Acess2 C Library
+ * - By John Hodge (thePowersGang)
+ *
+ * strtof.c
+ * - strto[df]/atof implimentation
+ */
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdlib.h> // strtoll
+
+double strtod(const char *ptr, char **end)
+{
+ int negative = 0;
+ int is_hex = 0;
+ double rv = 0;
+ char *tmp;
+
+ while( isspace(*ptr) )
+ ptr ++;
+
+ if( *ptr == '+' || *ptr == '-' )
+ {
+ negative = (*ptr == '-');
+ ptr ++;
+ }
+
+ #if 0
+ // NAN.*
+ if( strncasecmp(ptr, "NAN", 3) == 0)
+ {
+ ptr += 3;
+ while( isalnum(*ptr) || *ptr == '_' )
+ ptr ++;
+
+ rv = negative ? -NAN : NAN;
+ if(end) *end = ptr;
+ return rv;
+ }
+
+ // INF/INFINITY
+ if( strncasecmp(ptr, "INF", 3) == 0 )
+ {
+ if( strncasecmp(ptr, "INFINITY", 8) == 0 )
+ ptr += 8;
+ else
+ ptr += 3;
+ rv = negative ? -INFINITY : INFINITY;
+ if(end) *end = ptr;
+ return rv;
+ }
+ #endif
+
+ if( *ptr == '0' && (ptr[1] == 'X' || ptr[1] == 'x') )
+ {
+ is_hex = 1;
+ ptr += 2;
+ }
+
+ rv = strtoll(ptr, &tmp, (is_hex ? 16 : 10));
+
+ // TODO: errors?
+
+ ptr = tmp;
+ if( *ptr == '.' )
+ {
+ ptr ++;
+ if( isspace(*ptr) || *ptr == '-' || *ptr == '+' ) {
+ goto _err;
+ }
+ double frac = strtoll(ptr, &tmp, (is_hex ? 16 : 10));
+ // TODO: Error check
+ while( ptr != tmp )
+ {
+ frac /= 10;
+ ptr ++;
+ }
+ rv += frac;
+ }
+
+ int exp = 0;
+ if( is_hex )
+ {
+ if( *ptr == 'P' || *ptr == 'p' )
+ {
+ ptr ++;
+ exp = strtoll(ptr, &tmp, 16);
+ ptr = tmp;
+ }
+ }
+ else
+ {
+ if( *ptr == 'E' || *ptr == 'e' )
+ {
+ ptr ++;
+ exp = strtoll(ptr, &tmp, 10);
+ ptr = tmp;
+ }
+ }
+
+ if( exp == 0 )
+ ;
+ else if( exp < 0 )
+ while( exp ++ )
+ rv /= 10;
+ else
+ while( exp -- )
+ rv *= 10;
+
+ if( negative )
+ rv = -rv;
+
+ if( end )
+ *end = (char*)ptr;
+
+ return rv;
+_err:
+ if( end )
+ *end = (char*)ptr;
+
+ return 0.0f;
+}
+
+float strtof(const char *ptr, char **end)
+{
+ double rv = strtod(ptr, end);
+ // TODO: ERANGE
+ return rv;
+}
+
+float atof(const char *ptr)
+{
+ return strtof(ptr, NULL);
+}
ASFLAGS +=\r
LDFLAGS += -soname libposix.so -Map map.txt\r
\r
-OBJ = main.o unistd.o\r
+OBJ = main.o unistd.o dirent.o stat.o\r
DEPFILES := $(OBJ:%.o=%.d)\r
BIN = libposix.so\r
\r
--- /dev/null
+/*
+ * Acess2 C Library
+ * - By John Hodge (thePowersGang)
+ *
+ * dirent.c
+ * - Directory Functions
+ */
+#include <dirent.h>
+#include <stddef.h> // NULL
+#include <acess/sys.h>
+#include <errno.h>
+
+struct DIR_s
+{
+ int fd;
+ int pos;
+ struct dirent tmpent;
+};
+
+// === CODE ===
+DIR *fdopendir(int fd)
+{
+ t_sysFInfo info;
+ if( _SysFInfo(fd, &info, 0) != 0 )
+ return NULL;
+
+
+
+ return NULL;
+}
+
+DIR *opendir(const char *name)
+{
+ int fd = _SysOpen(name, OPENFLAG_READ);
+ if( fd == -1 )
+ return NULL;
+
+ DIR *ret = fdopendir(fd);
+ if( !ret ) {
+ _SysClose(fd);
+ }
+ return ret;
+}
+
+int closedir(DIR *dp)
+{
+ if( !dp ) {
+ errno = EINVAL;
+ return -1;
+ }
+ return 0;
+}
+
+struct dirent *readdir(DIR *dp)
+{
+ if( !dp ) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ errno = EOK;
+ int rv = _SysReadDir(dp->fd, dp->tmpent.d_name);
+ if( rv != 1 ) {
+ // TODO: Fix kernel-land API
+ return NULL;
+ }
+ dp->tmpent.d_ino = 0;
+
+ return &dp->tmpent;
+}
+
+extern int readdir_r(DIR *, struct dirent *, struct dirent **);
+extern void rewinddir(DIR *);
+extern void seekdir(DIR *, long int);
+extern long int telldir(DIR *);
#ifndef _LIBPOSIX__SYS__DIRENT_H_
#define _LIBPOSIX__SYS__DIRENT_H_
+#include "sys/stat.h"
+
#define NAME_MAX 255
struct dirent
typedef struct DIR_s DIR;
-extern int closedir(DIR *);
extern DIR *opendir(const char *);
+extern int closedir(DIR *);
extern struct dirent *readdir(DIR *);
extern int readdir_r(DIR *, struct dirent *, struct dirent **);
extern void rewinddir(DIR *);
/*
- * Acess2 C Library
+ * Acess2 POSIX Emulation Lib
* - By John Hodge (thePowersGang)
+ *
+ * sys/stat.h
+ * - stat(2)
*/
#ifndef _SYS_STAT_H_
#define _SYS_STAT_H_
-//#include "../acess/intdefs.h" /* Evil */
-//#include "../stddef.h"
#include <stdint.h>
#include "sys/types.h" // off_t
};
extern int stat(const char *path, struct stat *buf);
+extern int lstat(const char *path, struct stat *buf);
extern int fstat(int fd, struct stat *buf);
#endif
--- /dev/null
+/*
+ * Acess2 POSIX Emulation Lib
+ * - By John Hodge (thePowersGang)
+ *
+ * sys/stat.h
+ * - stat(2)
+ */
+#include <sys/stat.h>
+#include <acess/sys.h>
+
+// === CODE ===
+int stat(const char *path, struct stat *buf)
+{
+ int fd = _SysOpen(path, 0);
+ if( !fd ) {
+ // errno is set by _SysOpen
+ return -1;
+ }
+
+ int rv = fstat(fd, buf);
+ _SysClose(fd);
+ return rv;
+}
+
+int lstat(const char *path, struct stat *buf)
+{
+ int fd = _SysOpen(path, OPENFLAG_NOLINK);
+ if( !fd ) {
+ // errno is set by _SysOpen
+ return -1;
+ }
+
+ int rv = fstat(fd, buf);
+ _SysClose(fd);
+ return rv;
+}
+
+int fstat(int fd, struct stat *buf)
+{
+ t_sysFInfo info;
+
+ int rv = _SysFInfo(fd, &info, 0);
+ if( !rv ) {
+ return -1;
+ }
+
+ // TODO: Populate buf
+ buf->st_mode = 0;
+// memset(buf, 0, sizeof(*buf));
+
+ return 0;
+}
+