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);

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to