From 774e0f912213dcba17d6f0e0a876d0b243f47df4 Mon Sep 17 00:00:00 2001 From: florian Date: Sun, 7 Jan 2024 13:53:05 +0100 Subject: [PATCH] + support for fputimens on non-linux OSes * reworked fputimens support on linux + FileSetDate for all unix OSes --- rtl/bsd/bunxsysc.inc | 7 +++++++ rtl/linux/bunxsysc.inc | 20 ++++++++++++++++++++ rtl/linux/linux.pp | 11 ----------- rtl/unix/bunxh.inc | 24 ++++++++++++++++++++++++ rtl/unix/oscdeclh.inc | 3 +++ rtl/unix/sysutils.pp | 9 +++++---- 6 files changed, 59 insertions(+), 15 deletions(-) diff --git a/rtl/bsd/bunxsysc.inc b/rtl/bsd/bunxsysc.inc index de48364914..0bf2bc2a20 100644 --- a/rtl/bsd/bunxsysc.inc +++ b/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; diff --git a/rtl/linux/bunxsysc.inc b/rtl/linux/bunxsysc.inc index 7f23bf546d..87c5d48704 100644 --- a/rtl/linux/bunxsysc.inc +++ b/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; diff --git a/rtl/linux/linux.pp b/rtl/linux/linux.pp index a72797094e..c32c872ef1 100644 --- a/rtl/linux/linux.pp +++ b/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} diff --git a/rtl/unix/bunxh.inc b/rtl/unix/bunxh.inc index ed94d8286b..79d31fdc81 100644 --- a/rtl/unix/bunxh.inc +++ b/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} diff --git a/rtl/unix/oscdeclh.inc b/rtl/unix/oscdeclh.inc index 5350251ae4..7e4f65f22e 100644 --- a/rtl/unix/oscdeclh.inc +++ b/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'; diff --git a/rtl/unix/sysutils.pp b/rtl/unix/sysutils.pp index 04f81abd92..91c4ccca2e 100644 --- a/rtl/unix/sysutils.pp +++ b/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;