+ support for fputimens on non-linux OSes

* reworked fputimens support on linux
  + FileSetDate for all unix OSes
This commit is contained in:
florian 2024-01-07 13:53:05 +01:00
parent 5f42443db3
commit 774e0f9122
6 changed files with 59 additions and 15 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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}

View File

@ -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}

View File

@ -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';

View File

@ -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;