Browse Source

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

git-svn-id: trunk@13074 -

Jonas Maebe 16 years ago
parent
commit
99a02a93ca
3 changed files with 35 additions and 17 deletions
  1. 1 0
      .gitattributes
  2. 22 17
      rtl/unix/sysutils.pp
  3. 12 0
      tests/tbs/tb0559.pp

+ 1 - 0
.gitattributes

@@ -7243,6 +7243,7 @@ tests/tbs/tb0555.pp svneol=native#text/plain
 tests/tbs/tb0556.pp svneol=native#text/plain
 tests/tbs/tb0557.pp svneol=native#text/plain
 tests/tbs/tb0558.pp svneol=native#text/plain
+tests/tbs/tb0559.pp svneol=native#text/plain
 tests/tbs/tb205.pp svneol=native#text/plain
 tests/tbs/ub0060.pp svneol=native#text/plain
 tests/tbs/ub0069.pp svneol=native#text/plain

+ 22 - 17
rtl/unix/sysutils.pp

@@ -506,8 +506,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
@@ -520,19 +518,21 @@ 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;
@@ -541,8 +541,10 @@ begin
 {$ifndef FPUNONE}
      f.Time:=UnixToWinAge(st.st_mtime);
 {$endif}
-     result:=true;
-   End;
+     FindGetFileInfo:=true;
+   End
+  else
+    FindGetFileInfo:=false;
 end;
 
 
@@ -561,7 +563,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
@@ -611,6 +616,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
@@ -619,14 +630,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);

+ 12 - 0
tests/tbs/tb0559.pp

@@ -0,0 +1,12 @@
+uses
+ SysUtils;
+
+var
+ Info: TSearchRec;
+begin
+ // should not match, is a directory
+ if FindFirst('..',faArchive,Info)=0 then
+   halt(1);
+ FindClose(Info);
+end.
+