소스 검색

FIX & UPD: copy file with CreationTime on MacOS (intel CPU supported) (#938)

rich2014 2 년 전
부모
커밋
aa9ef42524
1개의 변경된 파일61개의 추가작업 그리고 7개의 파일을 삭제
  1. 61 7
      components/doublecmd/dcosutils.pas

+ 61 - 7
components/doublecmd/dcosutils.pas

@@ -17,6 +17,11 @@
 
    You should have received a copy of the GNU General Public License
    along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+   Notes:
+   1. TDarwinStat64 is the workaround for the bug of BaseUnix.Stat in FPC.
+      on MacOS with x86_64, Stat64 should be used instead of Stat.
+      and lstat64() should be called instead of lstat().
 }
 
 unit DCOSUtils;
@@ -51,6 +56,37 @@ const
 {$ENDIF}
 
 type
+{$IF DEFINED(DARWIN)}
+  TDarwinStat64 = record { the types are real}
+       st_dev        : dev_t;             // inode's device
+       st_mode       : mode_t;            // inode protection mode
+       st_nlink      : nlink_t;           // number of hard links
+       st_ino        : cuint64;             // inode's number
+       st_uid        : uid_t;             // user ID of the file's owner
+       st_gid        : gid_t;             // group ID of the file's group
+       st_rdev       : dev_t;             // device type
+       st_atime      : time_t;            // time of last access
+       st_atimensec  : clong;             // nsec of last access
+       st_mtime      : time_t;            // time of last data modification
+       st_mtimensec  : clong;             // nsec of last data modification
+       st_ctime      : time_t;            // time of last file status change
+       st_ctimensec  : clong;             // nsec of last file status change
+       st_birthtime  : time_t;            // File creation time
+       st_birthtimensec : clong;          // nsec of file creation time
+       st_size       : off_t;             // file size, in bytes
+       st_blocks     : cint64;            // blocks allocated for file
+       st_blksize    : cuint32;           // optimal blocksize for I/O
+       st_flags      : cuint32;           // user defined flags for file
+       st_gen        : cuint32;           // file generation number
+       st_lspare     : cint32;
+       st_qspare     : array[0..1] Of cint64;
+  end;
+
+  TDCStat = TDarwinStat64;
+{$ELSE}
+  TDCStat = BaseUnix.Stat;
+{$ENDIF}
+
   TFileMapRec = record
     FileHandle : System.THandle;
     FileSize : Int64;
@@ -309,6 +345,27 @@ uses
 {$ENDIF}
   DCStrUtils, LazUTF8;
 
+{$IF DEFINED(DARWIN)}
+
+Function fpLstat64( path:pchar; Info:pstat ): cint; cdecl; external clib name 'lstat64';
+
+Function DC_fpLstat( const path:RawByteString; var Info:TDCStat ): cint; inline;
+var
+  SystemPath: RawByteString;
+begin
+  SystemPath:=ToSingleByteFileSystemEncodedFileName( path );
+  Result:= fpLstat64( pchar(SystemPath), @info );
+end;
+
+{$ELSE}
+
+Function DC_fpLstat( const path:RawByteString; var Info:TDCStat ): cint; inline;
+begin
+  fpLstat( path, info );
+end;
+
+{$ENDIF}
+
 {$IFDEF UNIX}
 function SetModeReadOnly(mode: TMode; ReadOnly: Boolean): TMode;
 begin
@@ -542,11 +599,11 @@ end;
 {$ELSE}  // *nix
 var
   Option: TCopyAttributesOption;
-  StatInfo : BaseUnix.Stat;
+  StatInfo : TDCStat;
   utb : BaseUnix.TUTimBuf;
   mode : TMode;
 begin
-  if fpLStat(UTF8ToSys(sSrc), StatInfo) < 0 then
+  if DC_fpLStat(UTF8ToSys(sSrc), StatInfo) < 0 then
   begin
     Result := Options;
     if Assigned(Errors) then
@@ -584,10 +641,7 @@ begin
       if caoCopyTime in Options then
       begin
         utb.actime  := time_t(StatInfo.st_atime);  // last access time
-{$if (defined(darwin) and (defined(cpuarm) or defined(cpuaarch64))) or defined(iphonesim)}
-  {$define darwin_new_iostructs}
-{$endif}
-{$IF DEFINED(darwin_new_iostructs)}
+{$IF DEFINED(DARWIN)}
         utb.modtime := time_t(StatInfo.st_birthtime);  // creation time
 {$ELSE}
         utb.modtime := time_t(StatInfo.st_mtime);  // last modification time
@@ -597,7 +651,7 @@ begin
           Include(Result, caoCopyTime);
           if Assigned(Errors) then Errors^[caoCopyTime]:= GetLastOSError;
         end;
-{$IF DEFINED(darwin_new_iostructs)}
+{$IF DEFINED(DARWIN)}
         // creation time supported in MacOS:
         // 1. the first call fputime above: set creation time
         // 2. the second call here: set modification time