writev/sceKernelWritev and extended char fd

This commit is contained in:
Pavel 2023-01-23 15:43:15 +03:00
parent bb1a892ce5
commit 82f7cbd35f
6 changed files with 177 additions and 16 deletions

View File

@ -41,6 +41,9 @@ function ps4_sceKernelWrite(fd:Integer;buf:Pointer;nbytes:Int64):Int64; SysV_ABI
function ps4_pwrite(fd:Integer;data:Pointer;size,offset:Int64):Int64; SysV_ABI_CDecl; function ps4_pwrite(fd:Integer;data:Pointer;size,offset:Int64):Int64; SysV_ABI_CDecl;
function ps4_sceKernelPwrite(fd:Integer;buf:Pointer;nbytes,offset:Int64):Int64; SysV_ABI_CDecl; function ps4_sceKernelPwrite(fd:Integer;buf:Pointer;nbytes,offset:Int64):Int64; SysV_ABI_CDecl;
function ps4_writev(fd:Integer;vector:p_iovec;count:Integer):Int64; SysV_ABI_CDecl;
function ps4_sceKernelWritev(fd:Integer;iov:p_iovec;iovcnt:Integer):Int64; SysV_ABI_CDecl;
function ps4_ftruncate(fd:Integer;size:Int64):Integer; SysV_ABI_CDecl; function ps4_ftruncate(fd:Integer;size:Int64):Integer; SysV_ABI_CDecl;
function ps4_sceKernelFtruncate(fd:Integer;size:Int64):Integer; SysV_ABI_CDecl; function ps4_sceKernelFtruncate(fd:Integer;size:Int64):Integer; SysV_ABI_CDecl;
@ -99,7 +102,7 @@ begin
Result:=0; Result:=0;
if (path=nil) then Exit(-EINVAL); if (path=nil) then Exit(-EINVAL);
Writeln(SysLogPrefix, 'open:',path,' ',flags,' (',OctStr(mode,3),')'); Writeln(SysLogPrefix, 'open:',path,' 0x',HexStr(flags,4),' (',OctStr(mode,3),')');
if ((flags and WR_RDWR)=WR_RDWR) then if ((flags and WR_RDWR)=WR_RDWR) then
begin begin
@ -416,6 +419,38 @@ begin
end; end;
end; end;
function ps4_writev(fd:Integer;vector:p_iovec;count:Integer):Int64; SysV_ABI_CDecl;
begin
_sig_lock;
Result:=_sys_writev(fd,vector,count);
_sig_unlock;
if (Result<0) then
begin
Result:=_set_errno(-Result);
end else
begin
_set_errno(0);
end;
end;
function ps4_sceKernelWritev(fd:Integer;iov:p_iovec;iovcnt:Integer):Int64; SysV_ABI_CDecl;
begin
_sig_lock;
Result:=_sys_writev(fd,iov,iovcnt);
_sig_unlock;
if (Result<0) then
begin
Result:=-Result;
_set_errno(Result);
Result:=px2sce(Result);
end else
begin
_set_errno(0);
end;
end;
function ps4_ftruncate(fd:Integer;size:Int64):Integer; SysV_ABI_CDecl; function ps4_ftruncate(fd:Integer;size:Int64):Integer; SysV_ABI_CDecl;
begin begin
_sig_lock; _sig_lock;
@ -1106,6 +1141,8 @@ begin
if (path=nil) then Exit(EFAULT); if (path=nil) then Exit(EFAULT);
//Writeln('access:',path,' ',mode);
if (path[0]=#0) then if (path[0]=#0) then
begin begin
Exit(ENOENT); Exit(ENOENT);

View File

@ -1480,6 +1480,7 @@ begin
lib^.set_proc($C938FAD88EE4C38B,@ps4_sceKernelPreadv); lib^.set_proc($C938FAD88EE4C38B,@ps4_sceKernelPreadv);
lib^.set_proc($E304B37BDD8184B2,@ps4_sceKernelWrite); lib^.set_proc($E304B37BDD8184B2,@ps4_sceKernelWrite);
lib^.set_proc($9CA5A2FCDD87055E,@ps4_sceKernelPwrite); lib^.set_proc($9CA5A2FCDD87055E,@ps4_sceKernelPwrite);
lib^.set_proc($900B7A5436C79ABA,@ps4_sceKernelWritev);
lib^.set_proc($556DD355988CE3F1,@ps4_sceKernelFtruncate); lib^.set_proc($556DD355988CE3F1,@ps4_sceKernelFtruncate);
lib^.set_proc($901C023EC617FE6E,@ps4_sceKernelFstat); lib^.set_proc($901C023EC617FE6E,@ps4_sceKernelFstat);
@ -1511,6 +1512,9 @@ begin
lib^.set_proc($0B6909FDBC92E6B3,@ps4_pwrite); lib^.set_proc($0B6909FDBC92E6B3,@ps4_pwrite);
lib^.set_proc($6121D10512E7DA92,@ps4_writev); //_writev
lib^.set_proc($67668A771CD2E0A1,@ps4_writev); //writev
lib^.set_proc($8A1E020FDFE08213,@ps4_ftruncate); lib^.set_proc($8A1E020FDFE08213,@ps4_ftruncate);
lib^.set_proc($9AA40C875CCF3D3F,@ps4_fstat); lib^.set_proc($9AA40C875CCF3D3F,@ps4_fstat);

View File

@ -33,14 +33,15 @@ type
function preadv(vector:p_iovec;count:Integer;offset:Int64):Int64; override; function preadv(vector:p_iovec;count:Integer;offset:Int64):Int64; override;
function write (data:Pointer;size:Int64):Int64; override; function write (data:Pointer;size:Int64):Int64; override;
function pwrite(data:Pointer;size,offset:Int64):Int64; override; function pwrite(data:Pointer;size,offset:Int64):Int64; override;
function writev(vector:p_iovec;count:Integer):Int64; override;
end; end;
TDevStd=class(TDevFile) TDevStd=class(TDevFile)
var var
Text:PText; RText,WText:PText;
lock:TRWLock; lock:TRWLock;
cache:RawByteString; cache:RawByteString;
Constructor Create(t:PText); Constructor Create(r,w:PText);
Destructor Destroy; override; Destructor Destroy; override;
function read (data:Pointer;size:Int64):Int64; override; function read (data:Pointer;size:Int64):Int64; override;
function pread (data:Pointer;size,offset:Int64):Int64; override; function pread (data:Pointer;size,offset:Int64):Int64; override;
@ -48,13 +49,14 @@ type
function preadv(vector:p_iovec;count:Integer;offset:Int64):Int64; override; function preadv(vector:p_iovec;count:Integer;offset:Int64):Int64; override;
function write (data:Pointer;size:Int64):Int64; override; function write (data:Pointer;size:Int64):Int64; override;
function pwrite(data:Pointer;size,offset:Int64):Int64; override; function pwrite(data:Pointer;size,offset:Int64):Int64; override;
function writev(vector:p_iovec;count:Integer):Int64; override;
end; end;
procedure _sys_dev_init; procedure _sys_dev_init;
begin begin
_sys_dev_open('stdin' ,O_RDONLY,0); //0 _sys_dev_open('stdin' ,O_RDWR,0); //0
_sys_dev_open('stdout',O_WRONLY,0); //1 _sys_dev_open('stdout',O_RDWR,0); //1
_sys_dev_open('stderr',O_WRONLY,0); //2 _sys_dev_open('stderr',O_RDWR,0); //2
end; end;
function _sys_dev_open(const path:RawByteString;flags,mode:Integer):Integer; function _sys_dev_open(const path:RawByteString;flags,mode:Integer):Integer;
@ -63,9 +65,9 @@ var
begin begin
Case path of Case path of
'stdin' :f:=TDevStd.Create(@Input); 'stdin' :f:=TDevStd.Create(@Input,@StdOut);
'stdout':f:=TDevStd.Create(@StdOut); 'stdout':f:=TDevStd.Create(@Input,@StdOut);
'stderr':f:=TDevStd.Create(@StdErr); 'stderr':f:=TDevStd.Create(@Input,@StdErr);
'random', 'random',
'urandom': 'urandom':
@ -167,14 +169,27 @@ begin
Result:=size; Result:=size;
end; 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;
// //
Constructor TDevStd.Create(t:PText); Constructor TDevStd.Create(r,w:PText);
type type
PTextRec=^TextRec; PTextRec=^TextRec;
begin begin
Handle:=PTextRec(t)^.Handle; Handle:=PTextRec(w)^.Handle;
Text:=t; RText:=r;
WText:=w;
rwlock_init(lock); rwlock_init(lock);
cache:=''; cache:='';
end; end;
@ -207,7 +222,7 @@ begin
rwlock_unlock(lock); rwlock_unlock(lock);
S:=''; S:='';
System.ReadLn(Text^,S); System.ReadLn(RText^,S);
S:=S+#10; S:=S+#10;
if (Length(S)>size) then if (Length(S)>size) then
@ -266,7 +281,7 @@ var
S:RawByteString; S:RawByteString;
begin begin
SetString(S,data,size); SetString(S,data,size);
System.Write(Text^,S); System.Write(WText^,S);
Result:=size; Result:=size;
end; end;
@ -275,6 +290,29 @@ begin
Result:=write(data,size); Result:=write(data,size);
end; 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;
// //
end. end.

View File

@ -63,6 +63,7 @@ type
function preadv (vector:p_iovec;count:Integer;offset:Int64):Int64; override; function preadv (vector:p_iovec;count:Integer;offset:Int64):Int64; override;
function write (data:Pointer;size:Int64):Int64; override; function write (data:Pointer;size:Int64):Int64; override;
function pwrite (data:Pointer;size,offset:Int64):Int64; override; function pwrite (data:Pointer;size,offset:Int64):Int64; override;
function writev (vector:p_iovec;count:Integer):Int64; override;
function ftruncate (size:Int64):Integer; override; function ftruncate (size:Int64):Integer; override;
function fstat (stat:PSceKernelStat):Integer; override; function fstat (stat:PSceKernelStat):Integer; override;
function lseek (offset:Int64;whence:Integer):Int64; override; function lseek (offset:Int64;whence:Integer):Int64; override;
@ -360,6 +361,11 @@ begin
Result:=-EISDIR; Result:=-EISDIR;
end; end;
function TDirFile.writev(vector:p_iovec;count:Integer):Int64;
begin
Result:=-EISDIR;
end;
function TDirFile.ftruncate(size:Int64):Integer; function TDirFile.ftruncate(size:Int64):Integer;
begin begin
Result:=EISDIR; Result:=EISDIR;

View File

@ -207,6 +207,7 @@ type
function preadv (vector:p_iovec;count:Integer;offset:Int64):Int64; virtual; function preadv (vector:p_iovec;count:Integer;offset:Int64):Int64; virtual;
function write (data:Pointer;size:Int64):Int64; virtual; function write (data:Pointer;size:Int64):Int64; virtual;
function pwrite (data:Pointer;size,offset:Int64):Int64; virtual; function pwrite (data:Pointer;size,offset:Int64):Int64; virtual;
function writev (vector:p_iovec;count:Integer):Int64; virtual;
function ftruncate (size:Int64):Integer; virtual; function ftruncate (size:Int64):Integer; virtual;
function fstat (stat:PSceKernelStat):Integer; virtual; function fstat (stat:PSceKernelStat):Integer; virtual;
function fsync ():Integer; virtual; function fsync ():Integer; virtual;
@ -224,6 +225,7 @@ function _sys_pread(fd:Integer;data:Pointer;size,offset:Int64):Int64;
function _sys_readv(fd:Integer;vector:p_iovec;count:Integer):Int64; function _sys_readv(fd:Integer;vector:p_iovec;count:Integer):Int64;
function _sys_preadv(fd:Integer;vector:p_iovec;count:Integer;offset:Int64):Int64; function _sys_preadv(fd:Integer;vector:p_iovec;count:Integer;offset:Int64):Int64;
function _sys_write(fd:Integer;data:Pointer;size:Int64):Int64; function _sys_write(fd:Integer;data:Pointer;size:Int64):Int64;
function _sys_writev(fd:Integer;vector:p_iovec;count:Integer):Int64;
function _sys_pwrite(fd:Integer;data:Pointer;size,offset:Int64):Int64; function _sys_pwrite(fd:Integer;data:Pointer;size,offset:Int64):Int64;
function _sys_ftruncate(fd:Integer;size:Int64):Integer; function _sys_ftruncate(fd:Integer;size:Int64):Integer;
function _sys_fstat(fd:Integer;stat:PSceKernelStat):Integer; function _sys_fstat(fd:Integer;stat:PSceKernelStat):Integer;
@ -273,6 +275,11 @@ begin
Result:=-ENOTSUP; Result:=-ENOTSUP;
end; end;
function TCustomFile.writev(vector:p_iovec;count:Integer):Int64;
begin
Result:=-ENOTSUP;
end;
function TCustomFile.ftruncate(size:Int64):Integer; function TCustomFile.ftruncate(size:Int64):Integer;
begin begin
Result:=ENOTSUP; Result:=ENOTSUP;
@ -427,7 +434,6 @@ end;
function _sys_readv(fd:Integer;vector:p_iovec;count:Integer):Int64; function _sys_readv(fd:Integer;vector:p_iovec;count:Integer):Int64;
var var
f:TCustomFile; f:TCustomFile;
i:Integer;
begin begin
if (fd<0) then Exit(-EINVAL); if (fd<0) then Exit(-EINVAL);
@ -452,7 +458,6 @@ end;
function _sys_preadv(fd:Integer;vector:p_iovec;count:Integer;offset:Int64):Int64; function _sys_preadv(fd:Integer;vector:p_iovec;count:Integer;offset:Int64):Int64;
var var
f:TCustomFile; f:TCustomFile;
i:Integer;
begin begin
if (fd<0) then Exit(-EINVAL); if (fd<0) then Exit(-EINVAL);
@ -523,6 +528,30 @@ begin
f.Release; f.Release;
end; end;
function _sys_writev(fd:Integer;vector:p_iovec;count:Integer):Int64;
var
f:TCustomFile;
begin
if (fd<0) then Exit(-EINVAL);
if (vector=nil) or (count=0) then //zero check
begin
f:=_sys_acqure_fd(fd);
if (f=nil) then Exit(-EBADF);
f.Release;
Exit(0);
end;
if (count<=0) or (count>IOV_MAX) then Exit(-EINVAL);
f:=_sys_acqure_fd(fd);
if (f=nil) then Exit(-EBADF);
Result:=f.writev(vector,count);
f.Release;
end;
function _sys_ftruncate(fd:Integer;size:Int64):Integer; function _sys_ftruncate(fd:Integer;size:Int64):Integer;
var var
f:TCustomFile; f:TCustomFile;

View File

@ -32,6 +32,7 @@ type
function preadv (vector:p_iovec;count:Integer;offset:Int64):Int64; override; function preadv (vector:p_iovec;count:Integer;offset:Int64):Int64; override;
function write (data:Pointer;size:Int64):Int64; override; function write (data:Pointer;size:Int64):Int64; override;
function pwrite (data:Pointer;size,offset:Int64):Int64; override; function pwrite (data:Pointer;size,offset:Int64):Int64; override;
function writev (vector:p_iovec;count:Integer):Int64; override;
function ftruncate(size:Int64):Integer; override; function ftruncate(size:Int64):Integer; override;
function fstat (stat:PSceKernelStat):Integer; override; function fstat (stat:PSceKernelStat):Integer; override;
function fsync ():Integer; override; function fsync ():Integer; override;
@ -476,6 +477,52 @@ begin
end; end;
end; end;
function TFile.writev(vector:p_iovec;count:Integer):Int64;
label
_exit;
var
s:IO_STATUS_BLOCK;
e:Integer;
i:Integer;
v:iovec;
begin
Result:=0;
rwlock_wrlock(lock);
For i:=0 to count-1 do
begin
v:=vector[i];
if (v.iov_base<>nil) and (v.iov_len<>0) then
begin
s:=Default(IO_STATUS_BLOCK);
e:=NtWriteFile(Handle,0,nil,nil,@s,v.iov_base,v.iov_len,nil,nil);
if (e=STATUS_PENDING) then e:=NtWaitForSingleObject(Handle,False,nil);
e:=-ntf2px(e);
if (e<>0) then
begin
Result:=e;
Goto _exit;
end else
begin
Result:=Result+Int64(s.Information);
if (Int64(s.Information)<v.iov_len) then
begin
Goto _exit;
end;
end;
end;
end;
_exit:
rwlock_unlock(lock);
end;
function TFile.ftruncate(size:Int64):Integer; function TFile.ftruncate(size:Int64):Integer;
var var
s:IO_STATUS_BLOCK; s:IO_STATUS_BLOCK;