unit sys_dev; {$mode ObjFPC}{$H+} interface uses Windows, Classes, SysUtils, RWLock, sys_kernel, sys_crt, sys_fd; 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; implementation type TDevFile=class(TCustomFile) Constructor Create; function lseek (offset:Int64;whence:Integer):Int64; override; function ftruncate(size:Int64):Integer; override; function fstat (stat:PSceKernelStat):Integer; override; end; TDevRandom=class(TDevFile) 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; end; TDevStd=class(TDevFile) var RText,WText:PText; lock:TRWLock; cache:RawByteString; Constructor Create(r,w:PText); Destructor Destroy; override; 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; function ioctl(cmd:Integer;param1:ptruint):Integer; override; end; 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 end; 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); 'random', 'urandom': begin f:=TDevRandom.Create; end; else Exit(-ENOENT); end; Result:=_sys_open_fd(f,flags); if (Result<0) then begin f.Destroy; end else begin f.Release; end; end; // 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; // Constructor TDevFile.Create; begin Handle:=INVALID_HANDLE_VALUE; end; function TDevFile.lseek (offset:Int64;whence:Integer):Int64; begin Result:=-ESPIPE; end; function TDevFile.ftruncate(size:Int64):Integer; begin Result:=EACCES; end; 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 if (data=nil) or (size=0) then Exit(0); Assert(size0) 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); 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; end; function TDevStd.pread (data:Pointer;size,offset:Int64):Int64; begin Result:=read(data,size); end; function TDevStd.readv (vector:p_iovec;count:Integer):Int64; var i,n:Integer; begin 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=0) then begin Result:=Result+n; if (n