ソースを参照

+ support for fputimens on non-linux OSes
* reworked fputimens support on linux
+ FileSetDate for all unix OSes

florian 1 年間 前
コミット
774e0f9122
6 ファイル変更59 行追加15 行削除
  1. 7 0
      rtl/bsd/bunxsysc.inc
  2. 20 0
      rtl/linux/bunxsysc.inc
  3. 0 11
      rtl/linux/linux.pp
  4. 24 0
      rtl/unix/bunxh.inc
  5. 3 0
      rtl/unix/oscdeclh.inc
  6. 5 4
      rtl/unix/sysutils.pp

+ 7 - 0
rtl/bsd/bunxsysc.inc

@@ -374,6 +374,13 @@ begin
  FPutime:=do_syscall(syscall_nr_utimes,TSysParam(path),TSysParam(tvp));
 end;
 
+
+Function  FpFutimens   (handle: cint;constref times: TTimespecArr):cint;
+begin
+  FpFutimens:=do_syscall(syscall_nr_futimens,TSysParam(handle),TSysParam(@times));
+end;
+
+
 {$if (defined (freebsd))}
 function FPpipe(var fildes : tfildes; flags:cint):cint;
 

+ 20 - 0
rtl/linux/bunxsysc.inc

@@ -407,6 +407,26 @@ end;
 {$endif}
 
 
+Function  FpFUtimens   (handle: cint;constref times: TTimespecArr):cint;
+var
+  tsa: Array[0..1] of timespec;
+begin
+{$if sizeof(clong)<=4}
+  FpFUtimens:=do_syscall(syscall_nr_utimensat_time64,handle,TSysParam(nil),TSysParam(@times),0);
+  if (FpFUtimens>=0) or (fpgeterrno<>ESysENOSYS) then
+    exit;
+  { try 32 bit fall back }
+  tsa[0].tv_sec := times[0].tv_sec;
+  tsa[0].tv_nsec := times[0].tv_nsec;
+  tsa[1].tv_sec := times[1].tv_sec;
+  tsa[1].tv_nsec := times[1].tv_nsec;
+  FpFUtimens:=do_syscall(syscall_nr_utimensat,handle,TSysParam(nil),TSysParam(@tsa),0);
+{$else sizeof(clong)<=4}
+  FpFUtimens:=do_syscall(syscall_nr_utimensat,handle,TSysParam(nil),TSysParam(@times),0);
+{$endif sizeof(clong)<=4}
+end;
+
+
 {$ifndef FPC_BASEUNIX_HAS_FPPIPE}
 Function fppipe(var fildes : tfildes):cint;
 

+ 0 - 11
rtl/linux/linux.pp

@@ -551,17 +551,6 @@ Type
 
   function statx(dfd: cint; filename: PAnsiChar; flags,mask: cuint; var buf: tstatx):cint; {$ifdef FPC_USE_LIBC} cdecl; weakexternal name 'statx'; {$ENDIF}
 
-Type
-   kernel_time64_t = clonglong;
-
-   kernel_timespec = record
-     tv_sec  : kernel_time64_t;
-     tv_nsec : clonglong;
-   end;
-   pkernel_timespec = ^kernel_timespec;
-
-   tkernel_timespecs = array[0..1] of kernel_timespec;
-
 {$ifndef android}
 Function utimensat(dfd: cint; path:PAnsiChar;const times:tkernel_timespecs;flags:cint):cint; {$ifdef FPC_USE_LIBC} cdecl; external name 'utimensat'; {$ENDIF}
 Function futimens(fd: cint; const times:tkernel_timespecs):cint; {$ifdef FPC_USE_LIBC} cdecl; external name 'futimens'; {$ENDIF}

+ 24 - 0
rtl/unix/bunxh.inc

@@ -18,6 +18,29 @@ Type TGrpArr = Array [0..0] of TGid;            { C style array workarounds}
      TFilDes = Array [0..1] of cInt;
      pFilDes = ^TFilDes;
 
+
+    { For 32 bit 2038 safe support, we have to use the kernel_timespec on linux which
+      makes all fields 64 bit regardless of the bit size of the CPU.
+
+      I have no idea though how to work around this when libc is used 
+    }
+{$if defined(linux) and not(defined(FPC_USE_LIBC))}
+     kernel_time64_t = clonglong;
+
+     kernel_timespec = record
+       tv_sec  : kernel_time64_t;
+       tv_nsec : clonglong;
+     end;
+     tkernel_timespec = kernel_timespec;
+     pkernel_timespec = ^kernel_timespec;
+
+     tkernel_timespecs = array[0..1] of kernel_timespec;
+
+     TTimespecArr = tkernel_timespecs;
+{$else linux}     
+     TTimespecArr = array[0..1] of ttimespec;
+{$endif linux}     
+
 // if you are looking for macro definitions or non C template overloaded versions, they are moved to bunxovlh.inc
 
     Function  FpSigProcMask  (how : cInt; nset : pSigSet; oset : pSigSet): cInt; external name 'FPC_SYSC_SIGPROCMASK';
@@ -34,6 +57,7 @@ Type TGrpArr = Array [0..0] of TGid;            { C style array workarounds}
     Function  FpChmod      (path : PAnsiChar; Mode : TMode): cInt;
     Function  FpChown      (path : PAnsiChar; owner : TUid; group : TGid): cInt;
     Function  FpUtime      (path : PAnsiChar; times : putimbuf): cInt;
+    Function  FpFUtimens   (handle: cint;constref times: TTimespecArr):cint;
 {$if defined(freebsd)}
     Function  FpPipe       (var fildes : tfildes; flags : cInt=0):cInt;
 {$else}

+ 3 - 0
rtl/unix/oscdeclh.inc

@@ -30,6 +30,8 @@ Type TGrpArr = Array [0..0] of TGid;            { C style array workarounds}
      TFilDes = Array [0..1] of cInt;
      pFilDes = ^TFilDes;
 
+     TTimespecArr = array[0..1] of ttimespec;
+
 const
 {$if (defined(linux) and defined(cpu32) and not defined(fs32bit)) or defined(aix)}
     suffix64bit = '64';
@@ -55,6 +57,7 @@ const
     Function  FpChmod      (path : PAnsiChar; Mode : TMode): cInt; cdecl; external clib name 'chmod';
     Function  FpChown   (path : PAnsiChar; owner : TUid; group : TGid): cInt; cdecl; external clib name 'chown';
     Function  FPUtime(path:PAnsiChar;times:putimbuf):cint; cdecl; external clib name 'utime';
+    Function  FPFUtimens(handle: cint;constref times: TTimespecArr):cint; cdecl; external clib name 'futimens';
     Function  FpPipe       (var fildes : tfildes):cInt; cdecl;external clib name 'pipe';
     function  FpDup     (oldd:cint):cint; cdecl; external clib name 'dup';
     function  FpDup2    (oldd:cint;newd:cint):cint; cdecl; external clib name 'dup2';

+ 5 - 4
rtl/unix/sysutils.pp

@@ -69,8 +69,9 @@ uses
 {$ENDIF}
 
 {$IF defined(DARWIN)}
-{$DEFINE HAS_ISFILENAMECASEPRESERVING}
-{$DEFINE HAS_ISFILENAMECASESENSITIVE}
+  {$DEFINE HAS_ISFILENAMECASEPRESERVING}
+  {$DEFINE HAS_ISFILENAMECASESENSITIVE}
+  {$DEFINE USE_FUTIMES}
 {$ENDIF}
 
 {$if defined(LINUX)}
@@ -1178,7 +1179,7 @@ end;
 Function FileSetDate (Handle : Longint;Age : Int64) : Longint;
 {$ifdef USE_FUTIMES}
 var
-  times : tkernel_timespecs;
+  times : TTimespecArr;
 {$endif USE_FUTIMES}
 begin
   Result:=0;
@@ -1187,7 +1188,7 @@ begin
   times[0].tv_nsec:=0;
   times[1].tv_sec:=Age;
   times[1].tv_nsec:=0;
-  if futimens(Handle,times) = -1 then
+  if fpfutimens(Handle,times) = -1 then
     Result:=fpgeterrno;
 {$else USE_FUTIMES}
   FileSetDate:=-1;