Переглянути джерело

* implement FollowLink=False handling for DirectoryExists and FileExists on *nix systems

git-svn-id: trunk@43112 -
svenbarth 5 роки тому
батько
коміт
2a38d07d8f
1 змінених файлів з 16 додано та 2 видалено
  1. 16 2
      rtl/unix/sysutils.pp

+ 16 - 2
rtl/unix/sysutils.pp

@@ -619,25 +619,39 @@ Function FileExists (Const FileName : RawByteString; FollowLink : Boolean) : Boo
 var
 var
   Info : Stat;
   Info : Stat;
   SystemFileName: RawByteString;
   SystemFileName: RawByteString;
+  isdir: Boolean;
 begin
 begin
   SystemFileName:=ToSingleByteFileSystemEncodedFileName(FileName);
   SystemFileName:=ToSingleByteFileSystemEncodedFileName(FileName);
   // Don't use stat. It fails on files >2 GB.
   // Don't use stat. It fails on files >2 GB.
   // Access obeys the same access rules, so the result should be the same.
   // Access obeys the same access rules, so the result should be the same.
   FileExists:=fpAccess(pointer(SystemFileName),F_OK)=0;
   FileExists:=fpAccess(pointer(SystemFileName),F_OK)=0;
   { we need to ensure however that we aren't dealing with a directory }
   { we need to ensure however that we aren't dealing with a directory }
+  isdir:=False;
   if FileExists then begin
   if FileExists then begin
-    if (fpstat(pointer(SystemFileName),Info)>=0) and fpS_ISDIR(Info.st_mode) then
+    if (fpstat(pointer(SystemFileName),Info)>=0) and fpS_ISDIR(Info.st_mode) then begin
       FileExists:=False;
       FileExists:=False;
+      isdir:=True;
+    end;
   end;
   end;
+  { if we shall not follow the link we only need to check for a symlink if the
+    target file itself should not exist }
+  if not FileExists and not isdir and not FollowLink then
+    FileExists:=(fplstat(pointer(SystemFileName),Info)>=0) and fpS_ISLNK(Info.st_mode);
 end;
 end;
 
 
 Function DirectoryExists (Const Directory : RawByteString; FollowLink : Boolean) : Boolean;
 Function DirectoryExists (Const Directory : RawByteString; FollowLink : Boolean) : Boolean;
 Var
 Var
   Info : Stat;
   Info : Stat;
   SystemFileName: RawByteString;
   SystemFileName: RawByteString;
+  exists: Boolean;
 begin
 begin
   SystemFileName:=ToSingleByteFileSystemEncodedFileName(Directory);
   SystemFileName:=ToSingleByteFileSystemEncodedFileName(Directory);
-  DirectoryExists:=(fpstat(pointer(SystemFileName),Info)>=0) and fpS_ISDIR(Info.st_mode);
+  exists:=fpstat(pointer(SystemFileName),Info)>=0;
+  DirectoryExists:=exists and fpS_ISDIR(Info.st_mode);
+  { if we shall not follow the link we only need to check for a symlink if the
+    target directory itself should not exist }
+  if not exists and not FollowLink then
+    DirectoryExists:=(fplstat(pointer(SystemFileName),Info)>=0) and fpS_ISLNK(Info.st_mode);
 end;
 end;
 
 
 Function LinuxToWinAttr (const FN : RawByteString; Const Info : Stat) : Longint;
 Function LinuxToWinAttr (const FN : RawByteString; Const Info : Stat) : Longint;