duskos

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

commit 99ce90d831c4bc3677defc17a55abe7bbd0b8583
parent dd2c554111461575aaa24c8c17538d9cdb7c37d1
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Tue, 19 Jul 2022 17:36:22 -0400

Propagate the "prelude" concept to the File API

Diffstat:
Mfs/doc/file.txt | 50+++++++++++++++++++++++---------------------------
Mfs/fs/fatlo.fs | 39+++++++++++++++++++++------------------
Mfs/sys/file.fs | 3+++
Mfs/xcomp/boothi.fs | 2+-
Mfs/xcomp/glue2.fs | 1-
5 files changed, 48 insertions(+), 47 deletions(-)

diff --git a/fs/doc/file.txt b/fs/doc/file.txt @@ -1,12 +1,28 @@ -# File subsystem +# File API -This subsystems defines a "filesystem" protocol and upon it defines convenience -word around files. To be able to plug into this subsystem, a filesystem needs -to have these words (not with the same name, the words will plug into the -subsystem's aliases): +The File API is a specialization of the I/O API (doc/io) for accessing files in +a filesystem. It also works with "handles", which we call File handle. Of +course, it starts with the I/O prelude, but then adds its own prelude: -fopen ( path -- fcursor ) - Open file at path and return a cursor through which other file-related word +(I/O prelude) +fseek +fclose + +These words have the following meaning: + +fseek ( pos hdl -- ) + Place the handle at offset "pos" (in bytes). + +fclose ( hdl -- ) + Close handle and free its resources. + +## Global aliases + +On top of that, the File API also define global aliases in which the current +active filesystem will plug itself: + +fopen ( path -- hdl ) + Open file at path and return a handle through which other file-related word identify the target file. Once a file isn't used anymore, it should be closed with fclose. Aborts on error. @@ -14,23 +30,3 @@ fnewfile ( path -- direntry ) Create a new empty file at path. Errors out if path's parent is unreachabe or if path already exists. -fclose ( fcursor -- ) - Close cursor fcursor and free its resources. - -fseek ( pos fcursor -- ) - Place the cursor at offset "pos" (in bytes). - -freadbuf ( n fcursor -- a? read-n ) - Try to read "n" bytes from file from current position. Unless end of file is - reached, at least 1 byte must be read, but otherwise "read-n" can be lower - than n, even if that doesn't take the cursor to the end of the file. The idea - is to take the cursor, at most, to the end of its buffer. Return the number of - bytes read and, if it was nonzero, return an address to the beginning of that - buffer. - -fwritebuf ( a n fcursor -- written-n ) - Try to write "n" bytes from buffer "a" to file from current position, growing - the file if needed. The idea is the same as with freadbuf: the filesystem can - proceed as is best for its implementation, as long as it writes at least 1 - byte. - diff --git a/fs/fs/fatlo.fs b/fs/fs/fatlo.fs @@ -141,7 +141,8 @@ here const )fnbuf fatfindpath ( dentry ) curdir( DIRENTRYSZ move ; \ File cursor -\ 12b IO handler prelude +\ 12b IO handle prelude +\ 8b File handle prelude \ 4b flags. all zeroes = free cursor \ b0 = used \ b1 = buffer is dirty @@ -153,25 +154,25 @@ here const )fnbuf \ 4b file size \ Xb current cluster X=ClusterSize 10 const FCURSORCNT \ maximum number of opened files -: FCursorSize ClusterSize 36 + ; -: FCUR_flags ( fcur -- n ) 12 + @ ; +: FCursorSize ClusterSize 44 + ; +: FCUR_flags ( fcur -- n ) 20 + @ ; : FCUR_free? ( fcur -- f ) FCUR_flags not ; : FCUR_dirty? ( fcur -- f ) FCUR_flags 2 and ; -: FCUR_flags! ( n fcur -- ) 12 + ! ; -: FCUR_cluster ( fcur -- n ) 16 + @ ; -: FCUR_cluster! ( n fcur -- ) 16 + ! ; -: FCUR_clusteridx ( fcur -- n ) 20 + @ ; -: FCUR_clusteridx! ( n fcur -- n ) 20 + ! ; -: FCUR_pos ( fcur -- n ) 28 + @ ; -: FCUR_pos! ( n fcur -- n ) 28 + ! ; -: FCUR_pos+ ( n fcur -- ) 28 + +! ; -: FCUR_size ( fcur -- n ) 32 + @ ; -: FCUR_size! ( n fcur -- ) 32 + ! ; -: FCUR_buf( ( fcur -- a ) 36 + ; +: FCUR_flags! ( n fcur -- ) 20 + ! ; +: FCUR_cluster ( fcur -- n ) 24 + @ ; +: FCUR_cluster! ( n fcur -- ) 24 + ! ; +: FCUR_clusteridx ( fcur -- n ) 28 + @ ; +: FCUR_clusteridx! ( n fcur -- n ) 28 + ! ; +: FCUR_pos ( fcur -- n ) 36 + @ ; +: FCUR_pos! ( n fcur -- n ) 36 + ! ; +: FCUR_pos+ ( n fcur -- ) 36 + +! ; +: FCUR_size ( fcur -- n ) 40 + @ ; +: FCUR_size! ( n fcur -- ) 40 + ! ; +: FCUR_buf( ( fcur -- a ) 44 + ; : FCUR_)buf ( fcur -- a ) FCUR_buf( ClusterSize + ; : FCUR_bufpos ( fcur -- a ) dup FCUR_pos ClusterSize mod swap FCUR_buf( + ; : FCUR_dirent ( fcur -- dirent ) - 24 + @ BPB_BytsPerSec /mod ( offset sec ) 1 readsector ( off ) fatbuf( + ; + 32 + @ BPB_BytsPerSec /mod ( offset sec ) 1 readsector ( off ) fatbuf( + ; : FCUR_cluster0 ( fcur -- cl ) FCUR_dirent DIR_Cluster ; create fcursors( FCursorSize FCURSORCNT * allot0 @@ -212,16 +213,18 @@ create fcursors( FCursorSize FCURSORCNT * allot0 rot min ( a n ) dup r> FCUR_pos+ ( a n ) ; +: fatclose ( fcursor ) dup dup 8 + @ ( 'flush ) execute 0 swap FCUR_flags! ; + \ Open the specified "path" into one of the free cursors and return that \ cursor. This is the "low" part. Complete open is finalized in fs/fat : fatopenlo ( path -- fcursor ) fatfindpath findfreecursor >r \ write IO handle prelude: readbuf, writebuf, flush ['] fatreadbuf r@ ! ['] abort r@ 4 + ! ['] drop r@ 8 + ! + \ write File handle prelude: fseek fclose + ['] fatseek r@ 12 + ! ['] fatclose r@ 16 + ! \ write the rest 0 r@ FCUR_cluster! ( dirent ) 1 r@ FCUR_flags! - dup fatbuf( - bufsec BPB_BytsPerSec * + ( dirent doffset ) r@ 24 + ! + dup fatbuf( - bufsec BPB_BytsPerSec * + ( dirent doffset ) r@ 32 + ! -1 r@ FCUR_clusteridx! 0 r@ FCUR_pos! DIR_FileSize r@ FCUR_size! ( ) r> ; - -: fatclose ( fcursor ) dup dup 8 + @ ( 'flush ) execute 0 swap FCUR_flags! ; diff --git a/fs/sys/file.fs b/fs/sys/file.fs @@ -8,6 +8,9 @@ \ our cursors. $200 scratchpad$ filespad +: fseek ( pos hdl -- ) dup 12 + @ execute ; +: fclose ( hdl -- ) dup 16 + @ execute ; + \ This creates a "f<" reader with the file descriptor embedded in it. This \ allows for a straightforward override of input/output words. : [f<] ( curfd -- word ) diff --git a/fs/xcomp/boothi.fs b/fs/xcomp/boothi.fs @@ -9,7 +9,7 @@ bootfile xcomp/boothi.fs floaded 4 + fopen to curhdl to' in< @ >r ['] f< to in< begin maybeword ?dup if runword 0 else 1 then until - r> to in< curhdl fclose r> to curhdl ; + r> to in< curhdl dup 16 + @ ( 'fclose ) execute r> to curhdl ; : f<< word fload ; \ TODO: record absolute paths or some kind of unique ID here. "lib/str.fs" and \ "/lib/str.fs" are considered different. diff --git a/fs/xcomp/glue2.fs b/fs/xcomp/glue2.fs @@ -1,4 +1,3 @@ bootfile xcomp/glue2.fs \ Glue code that goes between the filesystem part and boothi alias fatopenlo fopen -alias fatclose fclose