From f46b8539d06d43797242462f7a7d8c58ab209a74 Mon Sep 17 00:00:00 2001 From: svenbarth Date: Thu, 3 Oct 2019 12:07:33 +0000 Subject: [PATCH] * implement FileSymLinkGetTarget for *nix systems git-svn-id: trunk@43113 - --- rtl/objpas/sysutils/filutil.inc | 6 +++ rtl/objpas/sysutils/filutilh.inc | 6 +++ rtl/unix/sysutils.pp | 71 +++++++++++++++++++------------- 3 files changed, 55 insertions(+), 28 deletions(-) diff --git a/rtl/objpas/sysutils/filutil.inc b/rtl/objpas/sysutils/filutil.inc index 3790066832..ebe7ef9cb7 100644 --- a/rtl/objpas/sysutils/filutil.inc +++ b/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; diff --git a/rtl/objpas/sysutils/filutilh.inc b/rtl/objpas/sysutils/filutilh.inc index 35108086c7..1bee09be0a 100644 --- a/rtl/objpas/sysutils/filutilh.inc +++ b/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} diff --git a/rtl/unix/sysutils.pp b/rtl/unix/sysutils.pp index aafd466432..6e4f8e917a 100644 --- a/rtl/unix/sysutils.pp +++ b/rtl/unix/sysutils.pp @@ -609,9 +609,50 @@ begin end; -function FileGetSymLinkTarget(const FileName: RawByteString; out SymLinkRec: TRawbyteSymLinkRec): Boolean; +Function LinuxToWinAttr (const FN : RawByteString; Const Info : Stat) : Longint; +Var + LinkInfo : Stat; + nm : RawByteString; begin - Result := False; + 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 + 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;