program ftime;
{$mode objfpc}{$H+}
uses
BaseUnix, Unix, SysUtils;
//-------------not implemented in FreePascal BaseUnix-----
const
_SC_CLK_TCK = 2;
function sysconf(name: cint): clong; cdecl; external 'c';
//--------------------------------------------------------
function WIFEXITED(Status: cint): Boolean;
begin
Result := (Status and $7F) = 0;
end;
function WEXITSTATUS(Status: cint): cint;
begin
Result := (Status shr 8) and $FF;
end;
function WIFSIGNALED(Status: cint): Boolean;
begin
Result := ((Status and $7F) <> 0) and ((Status and $7F) <> $7F);
end;
function WTERMSIG(Status: cint): cint;
begin
Result := Status and $7F;
end;
function SecondsBetween(const A, B: TTimeVal): Double;
begin
Result :=
(B.tv_sec - A.tv_sec) +
(B.tv_usec - A.tv_usec) / 1000000.0;
end;
function ClockTicksPerSecond: LongInt;
begin
Result := sysconf(_SC_CLK_TCK);
if Result <= 0 then
Result := 100;
end;
procedure PrintTimes(
const StartTime, EndTime: TTimeVal;
const StartTms, EndTms: Tms;
Ticks: LongInt);
var
RealSeconds, UserSeconds, SysSeconds: Double;
begin
RealSeconds := SecondsBetween(StartTime, EndTime);
UserSeconds :=
(EndTms.tms_cutime - StartTms.tms_cutime) / Ticks;
SysSeconds :=
(EndTms.tms_cstime - StartTms.tms_cstime) / Ticks;
Writeln;
Writeln('real ', RealSeconds:0:3, 's');
Writeln('user ', UserSeconds:0:3, 's');
Writeln('sys ', SysSeconds:0:3, 's');
end;
var
StartTime, EndTime: TTimeVal;
StartTms, EndTms: Tms;
Ticks: LongInt;
Pid, Waited: TPid;
Status: cint;
Err: cint;
Args: array of PChar;
I: Integer;
begin
Ticks := ClockTicksPerSecond;
fpGetTimeOfDay(@StartTime, nil);
fpTimes(StartTms);
if ParamCount > 0 then
begin
SetLength(Args, ParamCount + 1);
for I := 1 to ParamCount do
Args[I - 1] := PChar(ParamStr(I));
Args[ParamCount] := nil;
Pid := fpFork;
if Pid = 0 then
begin
fpExecVP(Args[0], @Args[0]);
Writeln(StdErr, 'ftime: cannot execute "', ParamStr(1), '": ', fpGetErrNo);
fpExit(127);
end
else if Pid < 0 then
begin
Writeln(StdErr, 'ftime: fork failed: ', fpGetErrNo);
Halt(126);
end;
repeat
Waited := fpWaitPid(Pid, Status, 0);
Err := fpGetErrNo;
until (Waited = Pid) or ((Waited = -1) and (Err <> ESysEINTR));
end
else
begin
Waited := 0;
Status := 0;
end;
fpTimes(EndTms);
fpGetTimeOfDay(@EndTime, nil);
PrintTimes(StartTime, EndTime, StartTms, EndTms, Ticks);
if Waited = -1 then
Halt(125);
if ParamCount = 0 then
Halt(0);
if WIFEXITED(Status) then
Halt(WEXITSTATUS(Status));
if WIFSIGNALED(Status) then
Halt(128 + WTERMSIG(Status));
Halt(1);
end.