mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-19 12:29:19 +02:00
+ linux.fputimensat which properly uses the _tim64 version if needed and available
+ test
git-svn-id: trunk@48470 -
(cherry picked from commit 0c77536f11
)
This commit is contained in:
parent
d0765540c5
commit
8be1d885e8
@ -540,6 +540,19 @@ Type
|
|||||||
|
|
||||||
function Fpstatx(dfd: cint; filename: pchar; flags,mask: cuint; var buf: statx):cint; {$ifdef FPC_USE_LIBC} cdecl; external name 'statx'; {$ENDIF}
|
function Fpstatx(dfd: cint; filename: pchar; flags,mask: cuint; var buf: statx):cint; {$ifdef FPC_USE_LIBC} cdecl; external 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;
|
||||||
|
|
||||||
|
Function fputimensat(dfd: cint; path:pchar;const times:tkernel_timespecs;flags:cint):cint; {$ifdef FPC_USE_LIBC} cdecl; external name 'statx'; {$ENDIF}
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
|
||||||
@ -846,4 +859,23 @@ end;
|
|||||||
|
|
||||||
{$endif}
|
{$endif}
|
||||||
|
|
||||||
|
Function fputimensat(dfd: cint; path:pchar;const times:tkernel_timespecs;flags:cint):cint;
|
||||||
|
var
|
||||||
|
tsa: Array[0..1] of timespec;
|
||||||
|
begin
|
||||||
|
{$if sizeof(clong)<=4}
|
||||||
|
fputimensat:=do_syscall(syscall_nr_utimensat_time64,dfd,TSysParam(path),TSysParam(@times),0);
|
||||||
|
if (fputimensat>=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;
|
||||||
|
fputimensat:=do_syscall(syscall_nr_utimensat,dfd,TSysParam(path),TSysParam(@tsa),0);
|
||||||
|
{$else sizeof(clong)<=4}
|
||||||
|
fputimensat:=do_syscall(syscall_nr_utimensat,dfd,TSysParam(path),TSysParam(@times),0);
|
||||||
|
{$endif sizeof(clong)<=4}
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
83
tests/test/units/linux/tutimensat.pp
Normal file
83
tests/test/units/linux/tutimensat.pp
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
{ %target=linux }
|
||||||
|
uses
|
||||||
|
ctypes,baseunix,linux;
|
||||||
|
|
||||||
|
var
|
||||||
|
un : utsname;
|
||||||
|
res : cint;
|
||||||
|
f1,f2 : text;
|
||||||
|
err : word;
|
||||||
|
mystatx1,mystatx2 : statx;
|
||||||
|
times : tkernel_timespecs;
|
||||||
|
st,major,minor : string;
|
||||||
|
i,p,e : longint;
|
||||||
|
major_release, minor_release : longint;
|
||||||
|
begin
|
||||||
|
fpuname(un);
|
||||||
|
st:=un.release;
|
||||||
|
for i:=1 to UTSNAME_LENGTH do
|
||||||
|
if st[i]='.' then
|
||||||
|
begin
|
||||||
|
p:=i;
|
||||||
|
major:=system.copy(st,1,p-1);
|
||||||
|
system.val(major,major_release,err);
|
||||||
|
if err<>0 then
|
||||||
|
begin
|
||||||
|
writeln('Unable to parse first part of linux version ',st,'(',major,') correctly');
|
||||||
|
halt(2);
|
||||||
|
end;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
|
||||||
|
for i:=p+1 to UTSNAME_LENGTH do
|
||||||
|
if st[i]='.' then
|
||||||
|
begin
|
||||||
|
e:=i;
|
||||||
|
minor:=system.copy(st,p+1,e-p-1);
|
||||||
|
system.val(minor,minor_release,err);
|
||||||
|
if err<>0 then
|
||||||
|
begin
|
||||||
|
writeln('Unable to second part of parse linux version ',st,'i(',minor,') correctly');
|
||||||
|
halt(2);
|
||||||
|
end;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
if (major_release<4) or ((major_release=4) and (minor_release<11)) then
|
||||||
|
begin
|
||||||
|
writeln('This version of Linux: ',st,' does not have fstatx syscall');
|
||||||
|
halt(0);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
writeln('This linux version ',st,' should support statx syscall');
|
||||||
|
|
||||||
|
assign(f1,'tutimensat1.txt');
|
||||||
|
rewrite(f1);
|
||||||
|
write(f1,'ccccc');
|
||||||
|
close(f1);
|
||||||
|
assign(f2,'tutimensat2.txt');
|
||||||
|
rewrite(f2);
|
||||||
|
write(f2,'ccccc');
|
||||||
|
close(f2);
|
||||||
|
|
||||||
|
res:=fpstatx(AT_FDCWD,'tutimensat1.txt',AT_SYMLINK_NOFOLLOW,STATX_ALL,mystatx1);
|
||||||
|
if res<>0 then
|
||||||
|
halt(1);
|
||||||
|
times[0].tv_sec:=mystatx1.stx_atime.tv_sec;
|
||||||
|
times[0].tv_nsec:=mystatx1.stx_atime.tv_nsec;
|
||||||
|
times[1].tv_sec:=mystatx1.stx_mtime.tv_sec;
|
||||||
|
times[1].tv_nsec:=mystatx1.stx_mtime.tv_nsec;
|
||||||
|
res:=fputimensat(AT_FDCWD,'tutimensat2.txt',times,0);
|
||||||
|
if res<>0 then
|
||||||
|
halt(1);
|
||||||
|
res:=fpstatx(AT_FDCWD,'tutimensat2.txt',AT_SYMLINK_NOFOLLOW,STATX_ALL,mystatx2);
|
||||||
|
if res<>0 then
|
||||||
|
halt(1);
|
||||||
|
|
||||||
|
erase(f1);
|
||||||
|
erase(f2);
|
||||||
|
|
||||||
|
if (mystatx1.stx_atime.tv_sec<>mystatx2.stx_atime.tv_sec) or (mystatx1.stx_atime.tv_nsec<>mystatx2.stx_atime.tv_nsec) or
|
||||||
|
(mystatx1.stx_mtime.tv_sec<>mystatx2.stx_mtime.tv_sec) or (mystatx1.stx_mtime.tv_nsec<>mystatx2.stx_mtime.tv_nsec) then
|
||||||
|
halt(1);
|
||||||
|
writeln('ok');
|
||||||
|
end.
|
Loading…
Reference in New Issue
Block a user