FPPS4/sys/sys_dev.pas

320 lines
6.1 KiB
Plaintext
Raw Normal View History

2022-11-11 13:49:05 +00:00
unit sys_dev;
{$mode ObjFPC}{$H+}
interface
uses
Windows,
Classes,
SysUtils,
RWLock,
sys_kernel,
sys_fd;
2022-11-12 21:59:35 +00:00
procedure _sys_dev_init;
function _sys_dev_open(const path:RawByteString;flags,mode:Integer):Integer;
function _sys_dev_stat(Const path:RawByteString;stat:PSceKernelStat):Integer;
2022-11-11 13:49:05 +00:00
implementation
type
TDevFile=class(TCustomFile)
Constructor Create;
2022-11-29 07:42:53 +00:00
function lseek (offset:Int64;whence:Integer):Int64; override;
function ftruncate(size:Int64):Integer; override;
function fstat (stat:PSceKernelStat):Integer; override;
2022-11-11 13:49:05 +00:00
end;
TDevRandom=class(TDevFile)
2023-01-09 19:06:26 +00:00
function read (data:Pointer;size:Int64):Int64; override;
function pread (data:Pointer;size,offset:Int64):Int64; override;
function readv (vector:p_iovec;count:Integer):Int64; override;
function preadv(vector:p_iovec;count:Integer;offset:Int64):Int64; override;
function write (data:Pointer;size:Int64):Int64; override;
function pwrite(data:Pointer;size,offset:Int64):Int64; override;
function writev(vector:p_iovec;count:Integer):Int64; override;
2022-11-11 13:49:05 +00:00
end;
TDevStd=class(TDevFile)
2022-11-11 21:02:45 +00:00
var
RText,WText:PText;
2022-11-11 21:02:45 +00:00
lock:TRWLock;
cache:RawByteString;
Constructor Create(r,w:PText);
2022-11-11 13:49:05 +00:00
Destructor Destroy; override;
2023-01-09 19:06:26 +00:00
function read (data:Pointer;size:Int64):Int64; override;
function pread (data:Pointer;size,offset:Int64):Int64; override;
function readv (vector:p_iovec;count:Integer):Int64; override;
function preadv(vector:p_iovec;count:Integer;offset:Int64):Int64; override;
function write (data:Pointer;size:Int64):Int64; override;
function pwrite(data:Pointer;size,offset:Int64):Int64; override;
function writev(vector:p_iovec;count:Integer):Int64; override;
2022-11-11 13:49:05 +00:00
end;
2022-11-12 21:59:35 +00:00
procedure _sys_dev_init;
begin
_sys_dev_open('stdin' ,O_RDWR,0); //0
_sys_dev_open('stdout',O_RDWR,0); //1
_sys_dev_open('stderr',O_RDWR,0); //2
2022-11-12 21:59:35 +00:00
end;
2022-11-11 13:49:05 +00:00
function _sys_dev_open(const path:RawByteString;flags,mode:Integer):Integer;
var
f:TCustomFile;
begin
Case path of
'stdin' :f:=TDevStd.Create(@Input,@StdOut);
'stdout':f:=TDevStd.Create(@Input,@StdOut);
'stderr':f:=TDevStd.Create(@Input,@StdErr);
2022-11-11 13:49:05 +00:00
'random',
'urandom':
begin
f:=TDevRandom.Create;
end;
else
Exit(-ENOENT);
end;
2022-12-16 11:06:02 +00:00
Result:=_sys_open_fd(f,flags);
2022-11-11 13:49:05 +00:00
if (Result<0) then
begin
2022-11-12 21:59:35 +00:00
f.Destroy;
2022-11-11 13:49:05 +00:00
end else
begin
2022-11-12 21:59:35 +00:00
f.Release;
2022-11-11 13:49:05 +00:00
end;
end;
//
2022-11-12 21:59:35 +00:00
function _sys_dev_stat(Const path:RawByteString;stat:PSceKernelStat):Integer;
begin
Result:=0;
stat^:=Default(SceKernelStat);
stat^.st_mode :=S_IFCHR;
stat^.st_nlink:=1;
end;
//
2022-11-11 13:49:05 +00:00
Constructor TDevFile.Create;
begin
Handle:=INVALID_HANDLE_VALUE;
end;
function TDevFile.lseek (offset:Int64;whence:Integer):Int64;
begin
Result:=-ESPIPE;
end;
2022-11-29 07:42:53 +00:00
function TDevFile.ftruncate(size:Int64):Integer;
begin
Result:=EACCES;
end;
2022-11-11 13:49:05 +00:00
function TDevFile.fstat (stat:PSceKernelStat):Integer;
begin
Result:=0;
stat^:=Default(SceKernelStat);
stat^.st_dev :=fd;
stat^.st_rdev :=fd;
stat^.st_mode :=S_IFCHR;
stat^.st_nlink:=1;
end;
//
function TDevRandom.read (data:Pointer;size:Int64):Int64;
begin
2023-01-11 11:06:55 +00:00
if (data=nil) or (size=0) then Exit(0);
2022-11-11 13:49:05 +00:00
Assert(size<High(DWORD));
BCryptGenRandom(nil,data,size,BCRYPT_USE_SYSTEM_PREFERRED_RNG);
Result:=size;
end;
function TDevRandom.pread (data:Pointer;size,offset:Int64):Int64;
begin
2023-01-09 19:06:26 +00:00
Result:=read(data,size);
2022-11-11 13:49:05 +00:00
end;
function TDevRandom.readv (vector:p_iovec;count:Integer):Int64;
var
i:Integer;
begin
Result:=0;
For i:=0 to count-1 do
begin
2023-01-09 19:06:26 +00:00
Result:=Result+read(vector[i].iov_base,vector[i].iov_len);
2022-11-11 13:49:05 +00:00
end;
end;
2023-01-09 19:06:26 +00:00
function TDevRandom.preadv(vector:p_iovec;count:Integer;offset:Int64):Int64;
begin
Result:=readv(vector,count);
end;
2022-11-11 13:49:05 +00:00
function TDevRandom.write (data:Pointer;size:Int64):Int64;
begin
Result:=size;
end;
function TDevRandom.pwrite(data:Pointer;size,offset:Int64):Int64;
begin
Result:=size;
end;
function TDevRandom.writev(vector:p_iovec;count:Integer):Int64;
var
i:Integer;
begin
Result:=0;
For i:=0 to count-1 do
begin
Result:=Result+vector[i].iov_len;
end;
end;
2022-11-11 13:49:05 +00:00
//
Constructor TDevStd.Create(r,w:PText);
2022-11-11 13:49:05 +00:00
type
PTextRec=^TextRec;
begin
Handle:=PTextRec(w)^.Handle;
RText:=r;
WText:=w;
2022-11-11 21:02:45 +00:00
rwlock_init(lock);
cache:='';
2022-11-11 13:49:05 +00:00
end;
Destructor TDevStd.Destroy;
begin
2022-11-11 21:02:45 +00:00
rwlock_destroy(lock);
cache:='';
2022-11-11 13:49:05 +00:00
end;
function TDevStd.read (data:Pointer;size:Int64):Int64;
2022-11-11 21:02:45 +00:00
var
S:RawByteString;
2022-11-11 13:49:05 +00:00
begin
2023-01-11 11:06:55 +00:00
if (data=nil) or (size=0) then Exit(0);
2022-11-11 21:02:45 +00:00
rwlock_wrlock(lock);
if (Length(cache)<>0) then
begin
if (size>Length(cache)) then
begin
size:=Length(cache);
end;
Move(PChar(cache)^,data^,size);
Delete(cache,1,size);
rwlock_unlock(lock);
Exit(size);
end;
rwlock_unlock(lock);
S:='';
System.ReadLn(RText^,S);
2022-11-11 21:02:45 +00:00
S:=S+#10;
if (Length(S)>size) then
begin
Move(PChar(S)^,data^,size);
Result:=size;
Delete(S,1,size);
rwlock_wrlock(lock);
cache:=cache+S;
rwlock_unlock(lock);
end else
begin
size:=Length(S);
Move(PChar(S)^,data^,size);
Result:=size;
end;
2022-11-11 13:49:05 +00:00
end;
function TDevStd.pread (data:Pointer;size,offset:Int64):Int64;
begin
2022-11-11 21:02:45 +00:00
Result:=read(data,size);
2022-11-11 13:49:05 +00:00
end;
function TDevStd.readv (vector:p_iovec;count:Integer):Int64;
2022-11-11 21:02:45 +00:00
var
i,n:Integer;
2022-11-11 13:49:05 +00:00
begin
2022-11-11 21:02:45 +00:00
Result:=0;
For i:=0 to count-1 do
begin
n:=read(vector[i].iov_base,vector[i].iov_len);
if (n>0) then
begin
Result:=Result+n;
if (n<vector[i].iov_len) then Exit;
end else
begin
Exit(-EIO);
Break;
end;
end;
2022-11-11 13:49:05 +00:00
end;
2023-01-09 19:06:26 +00:00
function TDevStd.preadv(vector:p_iovec;count:Integer;offset:Int64):Int64;
begin
Result:=readv(vector,count);
end;
2022-11-11 13:49:05 +00:00
function TDevStd.write (data:Pointer;size:Int64):Int64;
2022-11-11 21:02:45 +00:00
var
S:RawByteString;
2022-11-11 13:49:05 +00:00
begin
2022-11-11 21:02:45 +00:00
SetString(S,data,size);
System.Write(WText^,S);
2022-11-11 21:02:45 +00:00
Result:=size;
2022-11-11 13:49:05 +00:00
end;
function TDevStd.pwrite(data:Pointer;size,offset:Int64):Int64;
begin
2022-11-11 21:02:45 +00:00
Result:=write(data,size);
2022-11-11 13:49:05 +00:00
end;
function TDevStd.writev(vector:p_iovec;count:Integer):Int64;
var
i,n:Integer;
begin
Result:=0;
For i:=0 to count-1 do
begin
n:=write(vector[i].iov_base,vector[i].iov_len);
if (n>0) then
begin
Result:=Result+n;
if (n<vector[i].iov_len) then Exit;
end else
begin
Exit(-EIO);
Break;
end;
end;
end;
2022-11-11 21:02:45 +00:00
//
2022-11-11 13:49:05 +00:00
end.