Package: fp-units-rtl Version: 2.2.4-1 The FindFirst() function returns true, but the filename is an empty string.
This Bug is fixed upstream. Log from revision 13074, trunk : * also consider the search attributes for findfirst if the name does not contain wildcards + test * don't return true from FindGetFileInfo if the file name is ok, but the search attributes don't match (resulted in returning multiple times the name of the previous entry that did fulfill all requirements) I have attached a patch. It's the diff from rev 13074, without the added testprogram. I had to fix one (easy) hunk manually. How to reproduce: Create an empty subdirectory './empty_dir' an start following program. It should not give any output, but writes 'Found: Len=0'. program fpc_find; uses sysutils; var SearchRec : TSearchRec; begin if ( FindFirst('./empty_dir/*', faAnyFile - faDirectory, SearchRec ) = 0 ) then with SearchRec do writeln( 'Found : ', Name,' Len=', length(Name) ); FindClose( SearchRec ); end. Thank you Stefan Kisdaroczi
This patch fixes the FindFirst and FindGetFileInfo functions. --- fpc-2.2.4.orig/fpcsrc/rtl/unix/sysutils.pp 2008-11-29 17:27:25.000000000 +0100 +++ fpc-2.2.4/fpcsrc/rtl/unix/sysutils.pp 2009-05-13 14:10:02.000000000 +0200 @@ -416,8 +416,6 @@ var UnixFindData : PUnixFindData; Begin UnixFindData:=PUnixFindData(f.FindHandle); - if UnixFindData=nil then - exit; if UnixFindData^.SearchType=0 then begin if UnixFindData^.dirptr<>nil then @@ -430,27 +428,31 @@ End; Function FindGetFileInfo(const s:string;var f:TSearchRec):boolean; var - st : baseunix.stat; - WinAttr : longint; + st : baseunix.stat; + WinAttr : longint; + ResolvedPath : string; + LinkLen : ssize_t; begin FindGetFileInfo:=false; If Assigned(F.FindHandle) and ((((PUnixFindData(f.FindHandle)^.searchattr)) and faSymlink) > 0) then - FindGetFileInfo:=(fplstat(pointer(s),st)=0) + FindGetFileInfo:=(fplstat(pointer(s),st)=0) else FindGetFileInfo:=(fpstat(pointer(s),st)=0); - If not FindGetFileInfo then - exit; + If not FindGetFileInfo then + exit; WinAttr:=LinuxToWinAttr(PChar(pointer(s)),st); - If (f.FindHandle = nil) or ((WinAttr and Not(PUnixFindData(f.FindHandle)^.searchattr))=0) Then + If ((WinAttr and Not(PUnixFindData(f.FindHandle)^.searchattr))=0) Then Begin f.Name:=ExtractFileName(s); f.Attr:=WinAttr; f.Size:=st.st_Size; f.Mode:=st.st_mode; f.Time:=UnixToWinAge(st.st_mtime); - result:=true; - End; + FindGetFileInfo:=true; + End + else + FindGetFileInfo:=false; end; @@ -469,7 +471,10 @@ Var Begin Result:=-1; UnixFindData:=PUnixFindData(Rslt.FindHandle); - if UnixFindData=nil then + { SearchSpec='' means that there were no wild cards, so only one file to + find. + } + if UnixFindData^.SearchSpec='' then exit; if (UnixFindData^.SearchType=0) and (UnixFindData^.Dirptr=nil) then @@ -519,6 +524,12 @@ Begin fillchar(Rslt,sizeof(Rslt),0); if Path='' then exit; + { Allocate UnixFindData (we always need it, for the search attributes) } + New(UnixFindData); + FillChar(UnixFindData^,sizeof(UnixFindData^),0); + Rslt.FindHandle:=UnixFindData; + {We always also search for readonly and archive, regardless of Attr:} + UnixFindData^.SearchAttr := Attr or faarchive or fareadonly; {Wildcards?} if (Pos('?',Path)=0) and (Pos('*',Path)=0) then begin @@ -527,14 +538,8 @@ Begin end else begin - { Allocate UnixFindData } - New(UnixFindData); - FillChar(UnixFindData^,sizeof(UnixFindData^),0); - Rslt.FindHandle:=UnixFindData; {Create Info} UnixFindData^.SearchSpec := Path; - {We always also search for readonly and archive, regardless of Attr:} - UnixFindData^.SearchAttr := Attr or faarchive or fareadonly; UnixFindData^.NamePos := Length(UnixFindData^.SearchSpec); while (UnixFindData^.NamePos>0) and (UnixFindData^.SearchSpec[UnixFindData^.NamePos]<>'/') do dec(UnixFindData^.NamePos);
signature.asc
Description: OpenPGP digital signature