Jelajahi Sumber

* implement FileSymLinkGetTarget for *nix systems

git-svn-id: trunk@43113 -
svenbarth 5 tahun lalu
induk
melakukan
f46b8539d0
3 mengubah file dengan 54 tambahan dan 27 penghapusan
  1. 6 0
      rtl/objpas/sysutils/filutil.inc
  2. 6 0
      rtl/objpas/sysutils/filutilh.inc
  3. 42 27
      rtl/unix/sysutils.pp

+ 6 - 0
rtl/objpas/sysutils/filutil.inc

@@ -137,6 +137,9 @@ begin
       SymLinkRec.Attr := sr.Attr;
 {$ifdef SYMLINKREC_USEFINDDATA}
       SymLinkRec.FindData := sr.FindData;
+{$endif}
+{$ifdef unix}
+      SymLinkRec.Mode := sr.Mode;
 {$endif}
     end;
 end;
@@ -349,6 +352,9 @@ begin
       SymLinkRec.Attr := sr.Attr;
 {$ifdef SYMLINKREC_USEFINDDATA}
       SymLinkRec.FindData := sr.FindData;
+{$endif}
+{$ifdef unix}
+      SymLinkRec.Mode := sr.Mode;
 {$endif}
     end;
 end;

+ 6 - 0
rtl/objpas/sysutils/filutilh.inc

@@ -93,6 +93,9 @@ Type
     TargetName : UnicodeString;
     Attr : Longint;
     Size : Int64;
+{$ifdef unix}
+    Mode : TMode;
+{$endif unix}
 {$ifdef SYMLINKREC_USEFINDDATA}
     FindData : TFindData;
 {$endif}
@@ -106,6 +109,9 @@ Type
     TargetName : RawByteString;
     Size : Int64;
     Attr : Longint;
+{$ifdef unix}
+    Mode : TMode;
+{$endif unix}
 {$IFDEF SYMLINKREC_USEFINDDATA}
     FindData : TFindData;
 {$ENDIF}

+ 42 - 27
rtl/unix/sysutils.pp

@@ -609,9 +609,50 @@ begin
 end;
 
 
+Function LinuxToWinAttr (const FN : RawByteString; Const Info : Stat) : Longint;
+Var
+  LinkInfo : Stat;
+  nm : RawByteString;
+begin
+  Result:=faArchive;
+  If fpS_ISDIR(Info.st_mode) then
+    Result:=Result or faDirectory;
+  nm:=ExtractFileName(FN);
+  If (Length(nm)>=2) and
+     (nm[1]='.') and
+     (nm[2]<>'.')  then
+    Result:=Result or faHidden;
+  If (Info.st_Mode and S_IWUSR)=0 Then
+     Result:=Result or faReadOnly;
+  If fpS_ISSOCK(Info.st_mode) or fpS_ISBLK(Info.st_mode) or fpS_ISCHR(Info.st_mode) or fpS_ISFIFO(Info.st_mode) Then
+     Result:=Result or faSysFile;
+  If fpS_ISLNK(Info.st_mode) Then
+    begin
+      Result:=Result or faSymLink;
+      // Windows reports if the link points to a directory.
+      if (fpstat(pchar(FN),LinkInfo)>=0) and fpS_ISDIR(LinkInfo.st_mode) then
+        Result := Result or faDirectory;
+    end;
+end;
+
+
 function FileGetSymLinkTarget(const FileName: RawByteString; out SymLinkRec: TRawbyteSymLinkRec): Boolean;
+var
+  Info : Stat;
+  SystemFileName: RawByteString;
 begin
-  Result := False;
+  SystemFileName:=ToSingleByteFileSystemEncodedFileName(FileName);
+  if (fplstat(SystemFileName,Info)>=0) and fpS_ISLNK(Info.st_mode) then begin
+    FillByte(SymLinkRec, SizeOf(SymLinkRec), 0);
+    SymLinkRec.TargetName:=fpreadlink(SystemFileName);
+    if fpstat(pointer(SystemFileName), Info) < 0 then
+      raise EDirectoryNotFoundException.Create(SysErrorMessage(GetLastOSError));
+    SymLinkRec.Attr := LinuxToWinAttr(SystemFileName, Info);
+    SymLinkRec.Size := Info.st_size;
+    SymLinkRec.Mode := Info.st_mode;
+    Result:=True;
+  end else
+    Result:=False;
 end;
 
 
@@ -654,32 +695,6 @@ begin
     DirectoryExists:=(fplstat(pointer(SystemFileName),Info)>=0) and fpS_ISLNK(Info.st_mode);
 end;
 
-Function LinuxToWinAttr (const FN : RawByteString; Const Info : Stat) : Longint;
-Var
-  LinkInfo : Stat;
-  nm : RawByteString;
-begin
-  Result:=faArchive;
-  If fpS_ISDIR(Info.st_mode) then
-    Result:=Result or faDirectory;
-  nm:=ExtractFileName(FN);
-  If (Length(nm)>=2) and
-     (nm[1]='.') and
-     (nm[2]<>'.')  then
-    Result:=Result or faHidden;
-  If (Info.st_Mode and S_IWUSR)=0 Then
-     Result:=Result or faReadOnly;
-  If fpS_ISSOCK(Info.st_mode) or fpS_ISBLK(Info.st_mode) or fpS_ISCHR(Info.st_mode) or fpS_ISFIFO(Info.st_mode) Then
-     Result:=Result or faSysFile;
-  If fpS_ISLNK(Info.st_mode) Then
-    begin
-      Result:=Result or faSymLink;
-      // Windows reports if the link points to a directory.
-      if (fpstat(pchar(FN),LinkInfo)>=0) and fpS_ISDIR(LinkInfo.st_mode) then
-        Result := Result or faDirectory;
-    end;
-end;
-
 
 { assumes that pattern and name have the same code page }
 Function FNMatch(const Pattern,Name:string):Boolean;