mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-10 14:46:02 +02:00
+ futimens syscall
* make use of futimens syscall in sysutils unit + tests git-svn-id: trunk@48472 -
This commit is contained in:
parent
e6f575d43c
commit
b8ab06aae7
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -16110,6 +16110,7 @@ tests/test/units/fpwidestring/twide6fpwidestring.pp svneol=native#text/pascal
|
||||
tests/test/units/fpwidestring/twide7fpwidestring.pp svneol=native#text/pascal
|
||||
tests/test/units/lineinfo/tlininfo.pp svneol=native#text/plain
|
||||
tests/test/units/linux/tepoll1.pp svneol=native#text/pascal
|
||||
tests/test/units/linux/tfutimesen.pp svneol=native#text/pascal
|
||||
tests/test/units/linux/tstatx.pp svneol=native#text/pascal
|
||||
tests/test/units/linux/tutimensat.pp svneol=native#text/pascal
|
||||
tests/test/units/math/tcmpnan.pp svneol=native#text/plain
|
||||
|
@ -555,7 +555,8 @@ Type
|
||||
|
||||
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}
|
||||
Function fputimensat(dfd: cint; path:pchar;const times:tkernel_timespecs;flags:cint):cint; {$ifdef FPC_USE_LIBC} cdecl; external name 'statx'; {$ENDIF}
|
||||
Function fpfutimens(fd: cint; const times:tkernel_timespecs):cint; {$ifdef FPC_USE_LIBC} cdecl; external name 'futimens'; {$ENDIF}
|
||||
|
||||
implementation
|
||||
|
||||
@ -893,4 +894,25 @@ begin
|
||||
{$endif sizeof(clong)<=4}
|
||||
end;
|
||||
|
||||
|
||||
Function fpfutimens(fd: cint; const times:tkernel_timespecs):cint;
|
||||
var
|
||||
tsa: Array[0..1] of timespec;
|
||||
begin
|
||||
{$if sizeof(clong)<=4}
|
||||
fpfutimens:=do_syscall(syscall_nr_utimensat_time64,fd,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,fd,TSysParam(nil),TSysParam(@tsa),0);
|
||||
{$else sizeof(clong)<=4}
|
||||
fpfutimens:=do_syscall(syscall_nr_utimensat,fd,TSysParam(nil),TSysParam(@times),0);
|
||||
{$endif sizeof(clong)<=4}
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
@ -58,6 +58,7 @@ uses
|
||||
{$if defined(LINUX)}
|
||||
{$DEFINE USE_STATX}
|
||||
{$DEFINE USE_UTIMENSAT}
|
||||
{$DEFINE USE_FUTIMES}
|
||||
{$endif}
|
||||
|
||||
{ Include platform independent interface part }
|
||||
@ -1027,10 +1028,22 @@ end;
|
||||
|
||||
|
||||
Function FileSetDate (Handle : Longint;Age : Int64) : Longint;
|
||||
|
||||
{$ifdef USE_UTIMENSAT}
|
||||
var
|
||||
times : tkernel_timespecs;
|
||||
{$endif USE_UTIMENSAT}
|
||||
begin
|
||||
// Impossible under Linux from FileHandle !!
|
||||
Result:=0;
|
||||
{$ifdef USE_FUTIMES}
|
||||
times[0].tv_sec:=Age;
|
||||
times[0].tv_nsec:=0;
|
||||
times[1].tv_sec:=Age;
|
||||
times[1].tv_nsec:=0;
|
||||
if fpfutimens(Handle,times) = -1 then
|
||||
Result:=fpgeterrno;
|
||||
{$else USE_FUTIMES}
|
||||
FileSetDate:=-1;
|
||||
{$endif USE_FUTIMES}
|
||||
end;
|
||||
|
||||
|
||||
|
84
tests/test/units/linux/tfutimesen.pp
Normal file
84
tests/test/units/linux/tfutimesen.pp
Normal file
@ -0,0 +1,84 @@
|
||||
{ %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');
|
||||
assign(f2,'tutimensat2.txt');
|
||||
rewrite(f2);
|
||||
write(f2,'ccccc');
|
||||
|
||||
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:=fpfutimens(textrec(f2).handle,times);
|
||||
if res<>0 then
|
||||
halt(1);
|
||||
res:=fpstatx(AT_FDCWD,'tutimensat2.txt',AT_SYMLINK_NOFOLLOW,STATX_ALL,mystatx2);
|
||||
if res<>0 then
|
||||
halt(1);
|
||||
|
||||
close(f1);
|
||||
close(f2);
|
||||
|
||||
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.
|
@ -32,6 +32,13 @@ BEGIN
|
||||
if FileSetDate('datetest.dat', DateTimeToFileDate(dateTime))<>0 then
|
||||
do_error(1002);
|
||||
|
||||
dateTime := IncMonth(Now, -1);
|
||||
Assign(f,'datetest.dat');
|
||||
Rewrite(f);
|
||||
if FileSetDate(filerec(f).handle, DateTimeToFileDate(dateTime))<>0 then
|
||||
do_error(1003);
|
||||
Close(f);
|
||||
|
||||
if FileExists('datetest.dat') then
|
||||
begin
|
||||
Assign(f,'datetest.dat');
|
||||
|
Loading…
Reference in New Issue
Block a user