diff --git a/kernel/ps4_kernel_file.pas b/kernel/ps4_kernel_file.pas index 1b3b2843..04e0d67a 100644 --- a/kernel/ps4_kernel_file.pas +++ b/kernel/ps4_kernel_file.pas @@ -47,10 +47,14 @@ function ps4_sceKernelFstat(fd:Integer;stat:PSceKernelStat):Integer; SysV_ABI_CD function ps4_getdirentries(fd:Integer;buf:Pointer;nbytes:Int64;basep:PInt64):Int64; SysV_ABI_CDecl; function ps4_getdents(fd:Integer;buf:Pointer;nbytes:Int64):Int64; SysV_ABI_CDecl; function ps4_sceKernelGetdirentries(fd:Integer;buf:Pointer;nbytes:Int64;basep:PInt64):Int64; SysV_ABI_CDecl; -function ps4_sceKernelGetdents(fd:Integer;buf:Pointer;nbytes:Int64):Int64; SysV_ABI_CDecl; +function ps4_sceKernelGetdents(fd:Integer;buf:Pointer;nbytes:Int64):Int64; SysV_ABI_CDecl +; function ps4_fsync(fd:Integer):Integer; SysV_ABI_CDecl; function ps4_sceKernelFsync(fd:Integer):Integer; SysV_ABI_CDecl; +function ps4_fcntl(fd,cmd:Integer;param1:ptruint):Integer; SysV_ABI_CDecl; +function ps4_sceKernelFcntl(fd,cmd:Integer;param1:ptruint):Integer; SysV_ABI_CDecl; + function ps4_stat(path:PChar;stat:PSceKernelStat):Integer; SysV_ABI_CDecl; function ps4_sceKernelStat(path:PChar;stat:PSceKernelStat):Integer; SysV_ABI_CDecl; @@ -689,6 +693,37 @@ begin Result:=px2sce(Result); end; +function _sys_fcntl(fd,cmd:Integer;param1:ptruint):Integer; +var + f:TCustomFile; +begin + if (fd<0) then Exit(EINVAL); + + f:=_sys_acqure_fd(fd); + if (f=nil) then Exit(EBADF); + + Result:=f.fcntl(cmd,param1); + + f.Release; +end; + +function ps4_fcntl(fd,cmd:Integer;param1:ptruint):Integer; SysV_ABI_CDecl; +begin + _sig_lock; + Result:=_set_errno(_sys_fcntl(fd,cmd,param1)); + _sig_unlock; +end; + +function ps4_sceKernelFcntl(fd,cmd:Integer;param1:ptruint):Integer; SysV_ABI_CDecl; +begin + _sig_lock; + Result:=_sys_fcntl(fd,cmd,param1); + _sig_unlock; + + _set_errno(Result); + Result:=px2sce(Result); +end; + function _sys_stat(path:PChar;stat:PSceKernelStat):Integer; var rp:RawByteString; diff --git a/kernel/ps4_libkernel.pas b/kernel/ps4_libkernel.pas index 865af90f..5a62833b 100644 --- a/kernel/ps4_libkernel.pas +++ b/kernel/ps4_libkernel.pas @@ -1236,6 +1236,7 @@ begin lib^.set_proc($B5A4568532454E01,@ps4_sceKernelGetdirentries); lib^.set_proc($8F6008A92A893F4C,@ps4_sceKernelGetdents); lib^.set_proc($7D3C7AEA5E625880,@ps4_sceKernelFsync); + lib^.set_proc($4A8664C599021DAC,@ps4_sceKernelFcntl); lib^.set_proc($C2E0ABA081A3B768,@ps4_open); //open lib^.set_proc($E9CDEB09513F7D35,@ps4_open); //_open @@ -1263,8 +1264,11 @@ begin lib^.set_proc($7F4F4ABC83F2FD06,@ps4_getdirentries); lib^.set_proc($D86EA2EA13085146,@ps4_getdents); + lib^.set_proc($8EE59B4CD33EF21C,@ps4_fsync); + lib^.set_proc($F27635F5B2A88999,@ps4_fcntl); + lib^.set_proc($13A6A8DF8C0FC3E5,@ps4_stat); lib^.set_proc($795F70003DAB8880,@ps4_sceKernelStat); diff --git a/sys/sys_dev.pas b/sys/sys_dev.pas index b7ad24f6..18cf3bc6 100644 --- a/sys/sys_dev.pas +++ b/sys/sys_dev.pas @@ -74,6 +74,8 @@ begin Exit(-ENOENT); end; + f.status:=flags and O_FL_STATUS; + Result:=_sys_open_fd(f); if (Result<0) then diff --git a/sys/sys_dir.pas b/sys/sys_dir.pas index 0b367c9d..31b909c8 100644 --- a/sys/sys_dir.pas +++ b/sys/sys_dir.pas @@ -140,6 +140,7 @@ begin end; f:=TDirFile.Create; + f.status:=flags and O_FL_STATUS; f.path:=path; if (h<>INVALID_HANDLE_VALUE) then diff --git a/sys/sys_fd.pas b/sys/sys_fd.pas index 1e9c23e8..7ee8dcfd 100644 --- a/sys/sys_fd.pas +++ b/sys/sys_fd.pas @@ -152,6 +152,9 @@ const SCE_KERNEL_LWFS_DISABLE =(0); SCE_KERNEL_LWFS_ENABLE =(1); + //fcntl + O_FL_STATUS=O_NONBLOCK or O_APPEND or O_DIRECT {or O_ASYNC} or O_SYNC or O_DSYNC; + type p_iovec=^iovec; iovec=packed record @@ -195,6 +198,7 @@ type TCustomFile=class(TClassHandle) var fd:Integer; + status:Integer; Handle:THandle; function lseek (offset:Int64;whence:Integer):Int64; virtual; function read (data:Pointer;size:Int64):Int64; virtual; @@ -205,6 +209,7 @@ type function ftruncate (size:Int64):Integer; virtual; function fstat (stat:PSceKernelStat):Integer; virtual; function fsync ():Integer; virtual; + function fcntl (cmd:Integer;param1:ptruint):Integer; virtual; function getdirentries(buf:Pointer;nbytes:Int64;basep:PInt64):Int64; virtual; end; @@ -265,6 +270,25 @@ begin Result:=EINVAL; end; +function TCustomFile.fcntl(cmd:Integer;param1:ptruint):Integer; +begin + Case cmd of + F_GETFL: + begin + Result:=status; + end; + F_SETFL: + begin + status:=Integer(param1) and O_FL_STATUS; + end; + else + begin + Assert(false,'fcntl:'+IntToStr(cmd)); + Exit(EINVAL); + end; + end; +end; + function TCustomFile.getdirentries(buf:Pointer;nbytes:Int64;basep:PInt64):Int64; begin Result:=-EINVAL; diff --git a/sys/sys_file.pas b/sys/sys_file.pas index 0a772517..6afc7cb0 100644 --- a/sys/sys_file.pas +++ b/sys/sys_file.pas @@ -33,6 +33,7 @@ type function ftruncate(size:Int64):Integer; override; function fstat (stat:PSceKernelStat):Integer; override; function fsync ():Integer; override; + function fcntl (cmd:Integer;param1:ptruint):Integer; override; end; Function get_DesiredAccess(flags:Integer):DWORD; @@ -126,6 +127,7 @@ begin f:=TFile.Create; f.Handle:=h; + f.status:=flags and O_FL_STATUS; end; function _sys_file_open(const path:RawByteString;flags,mode:Integer):Integer; @@ -466,6 +468,25 @@ begin end; end; +function TFile.fcntl(cmd:Integer;param1:ptruint):Integer; +begin + Case cmd of + F_SETFL: + begin + if (Integer(param1) and O_NONBLOCK)<>(status and O_NONBLOCK) then + begin + Writeln(StdErr,'fcntl:O_NONBLOCK:TODO'); + end; + if (Integer(param1) and O_APPEND)<>(status and O_APPEND) then + begin + Writeln(StdErr,'fcntl:O_APPEND:TODO'); + end; + end; + else; + end; + Result:=inherited; +end; + // end.