unit sys_dev; {$mode ObjFPC}{$H+} interface uses Windows, Classes, SysUtils, RWLock, sys_kernel, 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 write (data:Pointer;size:Int64):Int64; override; function pwrite(data:Pointer;size,offset:Int64):Int64; override; end; TDevStd=class(TDevFile) var Text:PText; lock:TRWLock; cache:RawByteString; Constructor Create(t: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 write (data:Pointer;size:Int64):Int64; override; function pwrite(data:Pointer;size,offset:Int64):Int64; override; end; procedure _sys_dev_init; begin _sys_dev_open('stdin' ,O_RDONLY,0); //0 _sys_dev_open('stdout',O_WRONLY,0); //1 _sys_dev_open('stderr',O_WRONLY,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':f:=TDevStd.Create(@StdOut); 'stderr':f:=TDevStd.Create(@StdErr); 'random', 'urandom': begin f:=TDevRandom.Create; end; else Exit(-ENOENT); end; f.status:=flags and O_FL_STATUS; Result:=_sys_open_fd(f); 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 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(Text^,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