duskos

dusk os fork
git clone git://git.alexwennerberg.com/duskos
Log | Files | Refs | README | LICENSE

commit c9a368e3c99fab8e6f5d8299332b8bff1563357d
parent 0a67a1747bd363c6b0921e7d7bd795c8ded0a456
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Fri, 19 Aug 2022 09:31:12 -0400

sys/file: add Path :listdir

For now, :iter and :next are only implemented in POSIX FS.

Diffstat:
Mfs/fs/fatlo.fs | 2+-
Mfs/sys/file.fs | 11+++++++++++
Mfs/xcomp/bootlo.fs | 2++
Mposix/glue.fs | 4++++
Mposix/vm.c | 55+++++++++++++++++++++++++++++++++++++++++++++++++------
5 files changed, 67 insertions(+), 7 deletions(-)

diff --git a/fs/fs/fatlo.fs b/fs/fs/fatlo.fs @@ -253,7 +253,7 @@ extends _FAT struct[ FATLO : :mountvolume ( drv -- fs ) align4 here >r dup , ( drv R:fs ) - ['] :child , ['] abort , ['] :fatopen , ['] abort , ( drv ) + ['] :child , ['] abort , ['] :fatopen , ['] abort , ['] abort , ['] abort , 0 , 0 , 0 , 0 , ( drv ) \ At this point, "here" points to the FAT-header-to-be. Read the first sector \ directly in "here": we'll have the header right here! diff --git a/fs/sys/file.fs b/fs/sys/file.fs @@ -33,6 +33,11 @@ struct[ Path dup if r> fs swap :new else rdrop then ; : :newfile ( name self -- path ) >r r@ id swap r@ fs Filesystem :newfile ( id ) r> fs swap :new ; + : :iter ( self -- path ) >r + r@ id r@ fs Filesystem :iter ( id ) r> fs swap :new ; + : :next ( self -- path-or-0 ) >r + r@ fs Filesystem :next ( id ) + dup if r> fs swap :new else rdrop then ; : :root ( self -- path ) fs 0 :new ; @@ -73,6 +78,12 @@ struct[ Path :open ['] _src rebind :open ['] _dst rebind begin ( ) _src size _src :readbuf ?dup while ( a n ) _dst :self IO :write repeat _dst :close _src :close ; + + : :listdir ( self -- ) >r + r@ :iter begin ( path-or-0 ) ?dup while + :info FSInfo name stype nl> + r@ :next repeat + rdrop ; ]struct Path _curpath structbind Path curpath diff --git a/fs/xcomp/bootlo.fs b/fs/xcomp/bootlo.fs @@ -245,6 +245,8 @@ struct[ Filesystem smethod :info smethod :open smethod :newfile + smethod :iter + smethod :next : :drv compile drv [compile] Drive ; immediate ]struct \ bootfs holds a reference to boot FS. This is used until the full sys/file diff --git a/posix/glue.fs b/posix/glue.fs @@ -1,12 +1,16 @@ : _:child ( 'data ) drop _fchild ; : _:open ( 'data ) drop _fopen ; : _:info ( 'data ) drop _finfo ; +: _:iter ( 'data ) drop _fiter ; +: _:next ( 'data ) drop _fnext ; create _POSIXFS ' abort , ' _:child , ' _:info , ' _:open , ' abort , + ' _:iter , + ' _:next , _POSIXFS to bootfs diff --git a/posix/vm.c b/posix/vm.c @@ -14,6 +14,7 @@ The VM is little endian. #include <sys/stat.h> #include <fcntl.h> #include <libgen.h> +#include <dirent.h> #undef FOPEN // some platforms' fcntl.h define FOPEN which clashes below. #define MEMSZ 0x100000 // 1MB @@ -866,8 +867,50 @@ static void FINFO() { // op: 61 memcpy(&vm.mem[dst+13], name, strlen(name)); } +static dword iterid = 0; +static DIR *dirp = NULL; + +static void FNEXT() { // op: 62 + struct dirent *d; + char path[MAXPATHSZ] = {0}; + dword res; + if (!dirp) { + printf("Calling next without an iter first!"); + vm.PC = gd(ABORT); + return; + } + do { + d = readdir(dirp); + } while (d && ((strcmp(d->d_name, ".") == 0) || (strcmp(d->d_name, "..") == 0))); + if (!d) { + ppush(0); + return; + } + strcpy(path, getpathfromid(iterid)); + strcat(path, "/"); + strcat(path, d->d_name); + res = findpath(path); + if (!res) { + while (fsids[++res][0]); + strcpy(fsids[res], path); + } + ppush(res); +} + +static void FITER() { // op: 63 + iterid = ppop(); + char *path = getpathfromid(iterid); + if (dirp) closedir(dirp); + dirp = opendir(path); + if (dirp) { + FNEXT(); + } else { + printf("Couldn't open dir %s\n", path); + vm.PC = gd(ABORT); + } +} // ( imgname -- ) -static void MOUNTDRV() { // op: 62 +static void MOUNTDRV() { // op: 64 char buf[64] = {0}; dword str = ppop(); byte slen = gb(str++); @@ -885,7 +928,7 @@ static void MOUNTDRV() { // op: 62 #define SECSZ 512 // ( sec dst drv -- ) -static void DRVRD() { // op: 63 +static void DRVRD() { // op: 65 DROP(); dword dst = ppop(); dword sec = ppop(); @@ -894,7 +937,7 @@ static void DRVRD() { // op: 63 } // ( sec src drv -- ) -static void DRVWR() { // op: 64 +static void DRVWR() { // op: 66 DROP(); dword src = ppop(); dword sec = ppop(); @@ -902,7 +945,7 @@ static void DRVWR() { // op: 64 fwrite(&vm.mem[src], SECSZ, 1, fp); } -#define OPCNT 0x65 +#define OPCNT 0x67 static void (*ops[OPCNT])() = { JUMP, CALL, RET, LIT, BYE, BYEFAIL, QUIT, ABORT_, EXECUTE, CELL, VAL, ALIAS, DOES, SLIT, BR, CBR, @@ -916,7 +959,7 @@ static void (*ops[OPCNT])() = { RSHIFT, LITN, EXECUTEWR, EXITWR, MOVE, MOVEWR, RTYPE, WNF, STACKCHK, MAYBEWORD, WORD, PARSE, REQ, FIND, APOS, COMPILING, SWR, STARTCOMP, STOPCOMP, RUNWORD, EXIT, FCHILD, FOPEN, FREADBUF, - FCLOSE, FINFO, MOUNTDRV, DRVRD, DRVWR}; + FCLOSE, FINFO, FNEXT, FITER, MOUNTDRV, DRVRD, DRVWR}; static char *opnames[OPCNT] = { NULL, NULL, NULL, NULL, "bye", "byefail", "quit", "(abort)", @@ -931,7 +974,7 @@ static char *opnames[OPCNT] = { "rshift", "litn", "execute,", "exit,", "move", "move,", "rtype", "(wnf)", "stack?", "maybeword", "word", "parse", "[]=", "find", "'", "compiling", ",\"", "]", "[", "runword", "exit", "_fchild", "_fopen", "_freadbuf", - "_fclose", "_finfo", "_mountdrv", "_drv@", "_drv!"}; + "_fclose", "_finfo", "_fnext", "_fiter", "_mountdrv", "_drv@", "_drv!"}; static void oprun1() { // run next op if (!memchk(vm.PC)) return;