|
@@ -375,275 +375,75 @@ end;
|
|
******************************************************************************}
|
|
******************************************************************************}
|
|
|
|
|
|
|
|
|
|
-Const
|
|
|
|
- RtlFindSize = 15;
|
|
|
|
-Type
|
|
|
|
- RtlFindRecType = Record
|
|
|
|
- DirFD : LongInt;
|
|
|
|
- SearchNum,
|
|
|
|
- LastUsed : LongInt;
|
|
|
|
- End;
|
|
|
|
-Var
|
|
|
|
- RtlFindRecs : Array[1..RtlFindSize] of RtlFindRecType;
|
|
|
|
- CurrSearchNum : LongInt;
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-Procedure FindClose(Var f: SearchRec);
|
|
|
|
-{
|
|
|
|
- Closes dirfd if it is open
|
|
|
|
-}
|
|
|
|
-Var
|
|
|
|
- res: __wasi_errno_t;
|
|
|
|
- i : longint;
|
|
|
|
-Begin
|
|
|
|
- if f.SearchType=0 then
|
|
|
|
- begin
|
|
|
|
- i:=1;
|
|
|
|
- repeat
|
|
|
|
- if (RtlFindRecs[i].SearchNum=f.SearchNum) then
|
|
|
|
- break;
|
|
|
|
- inc(i);
|
|
|
|
- until (i>RtlFindSize);
|
|
|
|
- If i<=RtlFindSize Then
|
|
|
|
- Begin
|
|
|
|
- RtlFindRecs[i].SearchNum:=0;
|
|
|
|
- if f.dirfd<>-1 then
|
|
|
|
- repeat
|
|
|
|
- res:=__wasi_fd_close(f.dirfd);
|
|
|
|
- until (res=__WASI_ERRNO_SUCCESS) or (res<>__WASI_ERRNO_INTR);
|
|
|
|
- End;
|
|
|
|
- end;
|
|
|
|
- f.dirfd:=-1;
|
|
|
|
-End;
|
|
|
|
|
|
+procedure SearchRec2WasiSearchRec(const i: SearchRec; var o: TWasiSearchRec);
|
|
|
|
+var
|
|
|
|
+ DT: DateTime;
|
|
|
|
+begin
|
|
|
|
+ FillChar(o,SizeOf(o),0);
|
|
|
|
+ o.SearchPos:=i.SearchPos;
|
|
|
|
+ o.SearchNum:=i.SearchNum;
|
|
|
|
+ o.DirFD:=i.DirFD;
|
|
|
|
+ o.SearchType:=i.SearchType;
|
|
|
|
+ o.SearchAttr:=i.SearchAttr;
|
|
|
|
+ o.Mode:=i.Mode;
|
|
|
|
+ o.Attr:=i.Attr;
|
|
|
|
+ UnpackTime(i.Time,DT);
|
|
|
|
+ o.Time:=DTToWasiDate(DT);
|
|
|
|
+ o.Size:=i.Size;
|
|
|
|
+ o.Name:=i.Name;
|
|
|
|
+ o.SearchSpec:=i.SearchSpec;
|
|
|
|
+ o.NamePos:=i.NamePos;
|
|
|
|
+end;
|
|
|
|
|
|
|
|
|
|
-Function FindGetFileInfo(const s:string;var f:SearchRec):boolean;
|
|
|
|
|
|
+procedure WasiSearchRec2SearchRec(const i: TWasiSearchRec; var o: SearchRec);
|
|
var
|
|
var
|
|
- DT : DateTime;
|
|
|
|
- st : __wasi_filestat_t;
|
|
|
|
- fd : __wasi_fd_t;
|
|
|
|
- pr : RawByteString;
|
|
|
|
- Info : record
|
|
|
|
- FMode: LongInt;
|
|
|
|
- FSize: __wasi_filesize_t;
|
|
|
|
- FMTime: __wasi_timestamp_t;
|
|
|
|
- end;
|
|
|
|
|
|
+ DT: DateTime;
|
|
begin
|
|
begin
|
|
- FindGetFileInfo:=false;
|
|
|
|
- if ConvertToFdRelativePath(s,fd,pr)<>0 then
|
|
|
|
- exit;
|
|
|
|
- { todo: __WASI_LOOKUPFLAGS_SYMLINK_FOLLOW??? }
|
|
|
|
- if __wasi_path_filestat_get(fd,0,PChar(pr),Length(pr),@st)<>__WASI_ERRNO_SUCCESS then
|
|
|
|
- exit;
|
|
|
|
- info.FSize:=st.size;
|
|
|
|
- info.FMTime:=st.mtim;
|
|
|
|
- if st.filetype=__WASI_FILETYPE_DIRECTORY then
|
|
|
|
- info.fmode:=$10
|
|
|
|
- else
|
|
|
|
- info.fmode:=$0;
|
|
|
|
- {if (st.st_mode and STAT_IWUSR)=0 then
|
|
|
|
- info.fmode:=info.fmode or 1;}
|
|
|
|
- if s[f.NamePos+1]='.' then
|
|
|
|
- info.fmode:=info.fmode or $2;
|
|
|
|
-
|
|
|
|
- If ((Info.FMode and Not(f.searchattr))=0) Then
|
|
|
|
- Begin
|
|
|
|
- f.Name:=Copy(s,f.NamePos+1,255);
|
|
|
|
- f.Attr:=Info.FMode;
|
|
|
|
- f.Size:=Info.FSize;
|
|
|
|
- {f.mode:=st.st_mode;}
|
|
|
|
- WasiDateToDT(Info.FMTime, DT);
|
|
|
|
- PackTime(DT,f.Time);
|
|
|
|
- FindGetFileInfo:=true;
|
|
|
|
- End;
|
|
|
|
|
|
+ FillChar(o,SizeOf(o),0);
|
|
|
|
+ o.SearchPos:=i.SearchPos;
|
|
|
|
+ o.SearchNum:=i.SearchNum;
|
|
|
|
+ o.DirFD:=i.DirFD;
|
|
|
|
+ o.SearchType:=i.SearchType;
|
|
|
|
+ o.SearchAttr:=i.SearchAttr;
|
|
|
|
+ o.Mode:=i.Mode;
|
|
|
|
+ o.Attr:=i.Attr;
|
|
|
|
+ WasiDateToDt(i.Time,DT);
|
|
|
|
+ PackTime(DT,o.Time);
|
|
|
|
+ o.Size:=i.Size;
|
|
|
|
+ o.Name:=i.Name;
|
|
|
|
+ o.SearchSpec:=i.SearchSpec;
|
|
|
|
+ o.NamePos:=i.NamePos;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
-Function FindLastUsed: Longint;
|
|
|
|
-{
|
|
|
|
- Find unused or least recently used dirpointer slot in findrecs array
|
|
|
|
-}
|
|
|
|
-Var
|
|
|
|
- BestMatch,i : Longint;
|
|
|
|
- Found : Boolean;
|
|
|
|
|
|
+Procedure FindClose(Var f: SearchRec);
|
|
|
|
+var
|
|
|
|
+ wf: TWasiSearchRec;
|
|
Begin
|
|
Begin
|
|
- BestMatch:=1;
|
|
|
|
- i:=1;
|
|
|
|
- Found:=False;
|
|
|
|
- While (i <= RtlFindSize) And (Not Found) Do
|
|
|
|
- Begin
|
|
|
|
- If (RtlFindRecs[i].SearchNum = 0) Then
|
|
|
|
- Begin
|
|
|
|
- BestMatch := i;
|
|
|
|
- Found := True;
|
|
|
|
- End
|
|
|
|
- Else
|
|
|
|
- Begin
|
|
|
|
- If RtlFindRecs[i].LastUsed > RtlFindRecs[BestMatch].LastUsed Then
|
|
|
|
- BestMatch := i;
|
|
|
|
- End;
|
|
|
|
- Inc(i);
|
|
|
|
- End;
|
|
|
|
- FindLastUsed := BestMatch;
|
|
|
|
|
|
+ SearchRec2WasiSearchRec(f,wf);
|
|
|
|
+ WasiFindClose(wf);
|
|
|
|
+ WasiSearchRec2SearchRec(wf,f);
|
|
End;
|
|
End;
|
|
|
|
|
|
|
|
|
|
-
|
|
|
|
Procedure FindNext(Var f: SearchRec);
|
|
Procedure FindNext(Var f: SearchRec);
|
|
-{
|
|
|
|
- re-opens dir if not already in array and calls FindWorkProc
|
|
|
|
-}
|
|
|
|
-Var
|
|
|
|
- fd,ourfd: __wasi_fd_t;
|
|
|
|
- pr: RawByteString;
|
|
|
|
- res: __wasi_errno_t;
|
|
|
|
- DirName : RawByteString;
|
|
|
|
- i,
|
|
|
|
- ArrayPos : Longint;
|
|
|
|
- FName,
|
|
|
|
- SName : string;
|
|
|
|
- Found,
|
|
|
|
- Finished : boolean;
|
|
|
|
- Buf: array [0..SizeOf(__wasi_dirent_t)+256-1] of Byte;
|
|
|
|
- BufUsed: __wasi_size_t;
|
|
|
|
|
|
+var
|
|
|
|
+ wf: TWasiSearchRec;
|
|
Begin
|
|
Begin
|
|
- If f.SearchType=0 Then
|
|
|
|
- Begin
|
|
|
|
- ArrayPos:=0;
|
|
|
|
- For i:=1 to RtlFindSize Do
|
|
|
|
- Begin
|
|
|
|
- If RtlFindRecs[i].SearchNum = f.SearchNum Then
|
|
|
|
- ArrayPos:=i;
|
|
|
|
- Inc(RtlFindRecs[i].LastUsed);
|
|
|
|
- End;
|
|
|
|
- If ArrayPos=0 Then
|
|
|
|
- Begin
|
|
|
|
- If f.NamePos = 0 Then
|
|
|
|
- DirName:='./'
|
|
|
|
- Else
|
|
|
|
- DirName:=Copy(f.SearchSpec,1,f.NamePos);
|
|
|
|
- if ConvertToFdRelativePath(DirName,fd,pr)=0 then
|
|
|
|
- begin
|
|
|
|
- repeat
|
|
|
|
- res:=__wasi_path_open(fd,
|
|
|
|
- 0,
|
|
|
|
- PChar(pr),
|
|
|
|
- length(pr),
|
|
|
|
- __WASI_OFLAGS_DIRECTORY,
|
|
|
|
- __WASI_RIGHTS_FD_READDIR,
|
|
|
|
- __WASI_RIGHTS_FD_READDIR,
|
|
|
|
- 0,
|
|
|
|
- @ourfd);
|
|
|
|
- until (res=__WASI_ERRNO_SUCCESS) or (res<>__WASI_ERRNO_INTR);
|
|
|
|
- If res=__WASI_ERRNO_SUCCESS Then
|
|
|
|
- begin
|
|
|
|
- f.DirFD := ourfd;
|
|
|
|
- ArrayPos:=FindLastUsed;
|
|
|
|
- If RtlFindRecs[ArrayPos].SearchNum > 0 Then
|
|
|
|
- repeat
|
|
|
|
- res:=__wasi_fd_close(RtlFindRecs[arraypos].DirFD);
|
|
|
|
- until (res=__WASI_ERRNO_SUCCESS) or (res<>__WASI_ERRNO_INTR);
|
|
|
|
- RtlFindRecs[ArrayPos].SearchNum := f.SearchNum;
|
|
|
|
- RtlFindRecs[ArrayPos].DirFD := f.DirFD;
|
|
|
|
- end
|
|
|
|
- else
|
|
|
|
- f.DirFD:=-1;
|
|
|
|
- end
|
|
|
|
- else
|
|
|
|
- f.DirFD:=-1;
|
|
|
|
- End;
|
|
|
|
- if ArrayPos>0 then
|
|
|
|
- RtlFindRecs[ArrayPos].LastUsed:=0;
|
|
|
|
- end;
|
|
|
|
-{Main loop}
|
|
|
|
- SName:=Copy(f.SearchSpec,f.NamePos+1,255);
|
|
|
|
- Found:=False;
|
|
|
|
- Finished:=(f.DirFD=-1);
|
|
|
|
- While Not Finished Do
|
|
|
|
- Begin
|
|
|
|
- res:=__wasi_fd_readdir(f.DirFD,
|
|
|
|
- @buf,
|
|
|
|
- SizeOf(buf),
|
|
|
|
- f.searchpos,
|
|
|
|
- @bufused);
|
|
|
|
- if (res<>__WASI_ERRNO_SUCCESS) or (bufused<=SizeOf(__wasi_dirent_t)) then
|
|
|
|
- FName:=''
|
|
|
|
- else
|
|
|
|
- begin
|
|
|
|
- if P__wasi_dirent_t(@buf)^.d_namlen<=255 then
|
|
|
|
- SetLength(FName,P__wasi_dirent_t(@buf)^.d_namlen)
|
|
|
|
- else
|
|
|
|
- SetLength(FName,255);
|
|
|
|
- Move(buf[SizeOf(__wasi_dirent_t)],FName[1],Length(FName));
|
|
|
|
- f.searchpos:=P__wasi_dirent_t(@buf)^.d_next;
|
|
|
|
- end;
|
|
|
|
- If FName='' Then
|
|
|
|
- Finished:=True
|
|
|
|
- Else
|
|
|
|
- Begin
|
|
|
|
- If FNMatch(SName,FName) Then
|
|
|
|
- Begin
|
|
|
|
- Found:=FindGetFileInfo(Copy(f.SearchSpec,1,f.NamePos)+FName,f);
|
|
|
|
- if Found then
|
|
|
|
- Finished:=true;
|
|
|
|
- End;
|
|
|
|
- End;
|
|
|
|
- End;
|
|
|
|
-{Shutdown}
|
|
|
|
- If Found Then
|
|
|
|
- DosError:=0
|
|
|
|
- Else
|
|
|
|
- Begin
|
|
|
|
- FindClose(f);
|
|
|
|
- DosError:=18;
|
|
|
|
- End;
|
|
|
|
|
|
+ SearchRec2WasiSearchRec(f,wf);
|
|
|
|
+ doserror:=WasiFindNext(wf);
|
|
|
|
+ WasiSearchRec2SearchRec(wf,f);
|
|
End;
|
|
End;
|
|
|
|
|
|
|
|
|
|
Procedure FindFirst(Const Path: PathStr; Attr: Word; Var f: SearchRec);
|
|
Procedure FindFirst(Const Path: PathStr; Attr: Word; Var f: SearchRec);
|
|
-{
|
|
|
|
- opens dir and calls FindWorkProc
|
|
|
|
-}
|
|
|
|
|
|
+var
|
|
|
|
+ wf: TWasiSearchRec;
|
|
Begin
|
|
Begin
|
|
- fillchar(f,sizeof(f),0);
|
|
|
|
- if Path='' then
|
|
|
|
- begin
|
|
|
|
- DosError:=3;
|
|
|
|
- exit;
|
|
|
|
- end;
|
|
|
|
-{Create Info}
|
|
|
|
- f.SearchSpec := Path;
|
|
|
|
- {We always also search for readonly and archive, regardless of Attr:}
|
|
|
|
- f.SearchAttr := Attr or archive or readonly;
|
|
|
|
- f.SearchPos := 0;
|
|
|
|
- f.NamePos := Length(f.SearchSpec);
|
|
|
|
- while (f.NamePos>0) and not (f.SearchSpec[f.NamePos] in AllowDirectorySeparators) do
|
|
|
|
- dec(f.NamePos);
|
|
|
|
-{Wildcards?}
|
|
|
|
- if (Pos('?',Path)=0) and (Pos('*',Path)=0) then
|
|
|
|
- begin
|
|
|
|
- if FindGetFileInfo(Path,f) then
|
|
|
|
- DosError:=0
|
|
|
|
- else
|
|
|
|
- begin
|
|
|
|
- { According to tdos2 test it should return 18
|
|
|
|
- if ErrNo=Sys_ENOENT then
|
|
|
|
- DosError:=3
|
|
|
|
- else }
|
|
|
|
- DosError:=18;
|
|
|
|
- end;
|
|
|
|
- f.DirFD:=-1;
|
|
|
|
- f.SearchType:=1;
|
|
|
|
- f.searchnum:=-1;
|
|
|
|
- end
|
|
|
|
- else
|
|
|
|
-{Find Entry}
|
|
|
|
- begin
|
|
|
|
- Inc(CurrSearchNum);
|
|
|
|
- f.SearchNum:=CurrSearchNum;
|
|
|
|
- f.SearchType:=0;
|
|
|
|
- FindNext(f);
|
|
|
|
- end;
|
|
|
|
|
|
+ SearchRec2WasiSearchRec(f,wf);
|
|
|
|
+ doserror:=WasiFindFirst(Path,Attr,wf);
|
|
|
|
+ WasiSearchRec2SearchRec(wf,f);
|
|
End;
|
|
End;
|
|
|
|
|
|
|
|
|