diff --git a/example-src/dcload-syscall.h b/example-src/dcload-syscall.h index 0361bf7..ae195ea 100644 --- a/example-src/dcload-syscall.h +++ b/example-src/dcload-syscall.h @@ -1,8 +1,13 @@ #ifndef __DCLOAD_SYSCALL_H__ #define __DCLOAD_SYSCALL_H__ +#include + int dcloadsyscall(unsigned int syscall, ...); +/* From crt0.S */ +noreturn void __exit(int status); + #define pcreadnr 0 #define pcwritenr 1 #define pcopennr 2 diff --git a/example-src/dcload-syscalls.c b/example-src/dcload-syscalls.c index cb71ce0..1e7187b 100644 --- a/example-src/dcload-syscalls.c +++ b/example-src/dcload-syscalls.c @@ -63,7 +63,7 @@ int unlink(const char *path) { return -1; } -void exit(int status) { +noreturn void exit(int status) { if(*DCLOADMAGICADDR == DCLOADMAGICVALUE) dcloadsyscall(pcexitnr); diff --git a/host-src/tool/syscalls.c b/host-src/tool/syscalls.c index ada7aa6..2125b33 100644 --- a/host-src/tool/syscalls.c +++ b/host-src/tool/syscalls.c @@ -43,6 +43,14 @@ #define O_BINARY 0 #endif +/* Sigh... KOS treats anything under 100 as invalid for a dirent from dcload, so + we need to offset by a bit. This aught to do. */ +#define DIRENT_OFFSET 1337 + +#define MAX_OPEN_DIRS 512 + +static DIR *opendirs[MAX_OPEN_DIRS]; + void dc_fstat(void) { int filedes; struct stat filestat; @@ -362,6 +370,7 @@ void dc_opendir(void) { DIR *somedir; unsigned char *dirname; int namelen; + uint32_t i; namelen = recv_uint(); @@ -369,31 +378,50 @@ void dc_opendir(void) { recv_data(dirname, namelen, 0); - somedir = opendir((const char *)dirname); + /* Find an open entry */ + for(i = 0; i < MAX_OPEN_DIRS; ++i) { + if(!opendirs[i]) + break; + } + + if(i < MAX_OPEN_DIRS) { + if(!(opendirs[i] = opendir((const char *)dirname))) + i = 0; + else + i += DIRENT_OFFSET; + } + else { + i = 0; + } - send_uint((unsigned int)somedir); + send_uint(i); free(dirname); } void dc_closedir(void) { - DIR *somedir; int retval; + uint32_t i = recv_uint(); - somedir = (DIR *) recv_uint(); - - retval = closedir(somedir); + if(i >= DIRENT_OFFSET && i < MAX_OPEN_DIRS + DIRENT_OFFSET) { + retval = closedir(opendirs[i - DIRENT_OFFSET]); + opendirs[i - DIRENT_OFFSET] = NULL; + } + else { + retval = -1; + } send_uint(retval); } void dc_readdir(void) { - DIR *somedir; struct dirent *somedirent; + uint32_t i = recv_uint(); - somedir = (DIR *) recv_uint(); - - somedirent = readdir(somedir); + if(i >= DIRENT_OFFSET && i < MAX_OPEN_DIRS + DIRENT_OFFSET) + somedirent = readdir(opendirs[i - DIRENT_OFFSET]); + else + somedirent = NULL; if(!somedirent) { send_uint(0); @@ -424,12 +452,17 @@ void dc_readdir(void) { } void dc_rewinddir(void) { - DIR *somedir; int retval; + uint32_t i = recv_uint(); - somedir = (DIR *) recv_uint(); - - rewinddir(somedir); + if(i >= DIRENT_OFFSET && i < MAX_OPEN_DIRS + DIRENT_OFFSET) { + rewinddir(opendirs[i - DIRENT_OFFSET]); + opendirs[i - DIRENT_OFFSET] = NULL; + retval = 0; + } + else { + retval = -1; + } send_uint(0); }