diff --git a/rtl/wasi/sysfile.inc b/rtl/wasi/sysfile.inc index 8cb5fea437..99d25cf4b1 100644 --- a/rtl/wasi/sysfile.inc +++ b/rtl/wasi/sysfile.inc @@ -100,6 +100,99 @@ begin end; procedure Do_Open(var f; p: pchar; flags: longint; pchangeable: boolean); -begin - DebugWriteLn('Do_Open'); +{ + FileRec and textrec have both Handle and mode as the first items so + they could use the same routine for opening/creating. + when (flags and $100) the file will be append + when (flags and $1000) the file will be truncate/rewritten + when (flags and $10000) there is no check for close (needed for textfiles) +} +var + oflags : __wasi_oflags_t = 0; + fs_rights_base: __wasi_rights_t = 0; + fdflags: __wasi_fdflags_t = 0; + ourfd: __wasi_fd_t; + res: __wasi_errno_t; +Begin +{ close first if opened } + if ((flags and $10000)=0) then + begin + case FileRec(f).mode of + fminput,fmoutput,fminout : Do_Close(FileRec(f).Handle); + fmclosed : ; + else + begin + inoutres:=102; {not assigned} + exit; + end; + end; + end; +{ reset file Handle } + FileRec(f).Handle:=UnusedHandle; +{ We do the conversion of filemodes here, concentrated on 1 place } + case (flags and 3) of + 0 : begin + fs_rights_base :=__WASI_RIGHTS_FD_READ; + FileRec(f).mode:=fminput; + end; + 1 : begin + fs_rights_base :=__WASI_RIGHTS_FD_WRITE; + FileRec(f).mode:=fmoutput; + end; + 2 : begin + fs_rights_base :=__WASI_RIGHTS_FD_READ or __WASI_RIGHTS_FD_WRITE; + FileRec(f).mode:=fminout; + end; + end; + if (flags and $1000)=$1000 then + oflags:=oflags or (__WASI_OFLAGS_CREAT or __WASI_OFLAGS_TRUNC) + else + if (flags and $100)=$100 then + fdflags:=fdflags or __WASI_FDFLAGS_APPEND; +{ empty name is special } + if p[0]=#0 then + begin + case FileRec(f).mode of + fminput : + FileRec(f).Handle:=StdInputHandle; + fminout, { this is set by rewrite } + fmoutput : + FileRec(f).Handle:=StdOutputHandle; + fmappend : + begin + FileRec(f).Handle:=StdOutputHandle; + FileRec(f).mode:=fmoutput; {fool fmappend} + end; + end; + exit; + end; +{ real open call } + repeat + res:=path_open(0, + 0, + p, + strlen(p), + oflags, + fs_rights_base, + fs_rights_base, + fdflags, + @ourfd); + until (res=__WASI_ERRNO_SUCCESS) or (res<>__WASI_ERRNO_INTR); + {if (res=__WASI_ERRNO_ROFS) and ((OFlags and O_RDWR)<>0) then + begin + Oflags:=Oflags and not(O_RDWR); + repeat + FileRec(f).Handle:=Fpopen(p,oflags,MODE_OPEN); + until (FileRec(f).Handle<>-1) or (geterrno<>ESysEINTR); + end;} + If res<>__WASI_ERRNO_SUCCESS Then + begin + FileRec(f).mode:=fmclosed; + InOutRes:=Errno2InoutRes(res); + end + else + begin + FileRec(f).Handle:=ourfd; + InOutRes:=0; + end; end; diff --git a/rtl/wasi/system.pp b/rtl/wasi/system.pp index ef1749a3cf..2c3c66b449 100644 --- a/rtl/wasi/system.pp +++ b/rtl/wasi/system.pp @@ -46,6 +46,7 @@ implementation type P__wasi_size_t = ^__wasi_size_t; __wasi_size_t = longint; + P__wasi_fd_t = ^__wasi_fd_t; __wasi_fd_t = longint; size_t = longint; __wasi_errno_t = longint; @@ -209,6 +210,20 @@ type fs_rights_inheriting: __wasi_rights_t; end; + __wasi_lookupflags_t = UInt32; + +const + __WASI_LOOKUPFLAGS_SYMLINK_FOLLOW = 1; + +type + __wasi_oflags_t = UInt16; + +const + __WASI_OFLAGS_CREAT = 1; + __WASI_OFLAGS_DIRECTORY = 2; + __WASI_OFLAGS_EXCL = 4; + __WASI_OFLAGS_TRUNC = 8; + function fd_write(fd: __wasi_fd_t; iovs: P__wasi_ciovec_t; iovs_len: size_t; @@ -220,6 +235,15 @@ function fd_read(fd: __wasi_fd_t; procedure proc_exit(rval: __wasi_exitcode_t); noreturn; external 'wasi_snapshot_preview1'; function fd_fdstat_get(fd: __wasi_fd_t; stat: P__wasi_fdstat_t): __wasi_errno_t; external 'wasi_snapshot_preview1'; +function path_open(fd: __wasi_fd_t; + dirflags: __wasi_lookupflags_t; + path: PChar; + path_len: size_t; + oflags: __wasi_oflags_t; + fs_rights_base, + fs_rights_inherting: __wasi_rights_t; + fdflags: __wasi_fdflags_t; + opened_fd: P__wasi_fd_t): __wasi_errno_t; external 'wasi_snapshot_preview1'; {$I system.inc}