FPPS4/sys/dev/dev_random.pas

150 lines
2.4 KiB
Plaintext

unit dev_random;
{$mode ObjFPC}{$H+}
{$CALLING SysV_ABI_CDecl}
interface
uses
sys_conf;
procedure random_init();
implementation
uses
errno,
vuio,
vfilio,
vpoll,
md_arc4random;
const
RANDOM_MINOR=0;
Function random_close(dev:p_cdev;fflag,devtype:Integer):Integer;
begin
Result:=0;
end;
Function random_read(dev:p_cdev;uio:p_uio;ioflag:Integer):Integer;
var
iov :p_iovec;
cnt :QWORD;
begin
while (uio^.uio_resid >0) and
(uio^.uio_iovcnt>0) do
begin
iov:=uio^.uio_iov;
cnt:=iov^.iov_len;
if (cnt > uio^.uio_resid) then
begin
cnt:=uio^.uio_resid;
end;
arc4rand(iov^.iov_base,cnt,0);
Inc(iov^.iov_base ,cnt);
Dec(iov^.iov_len ,cnt);
Dec(uio^.uio_resid ,cnt);
Inc(uio^.uio_offset,cnt);
Inc(uio^.uio_iov);
Dec(uio^.uio_iovcnt);
end;
Exit(0);
end;
Function random_write(dev:p_cdev;uio:p_uio;ioflag:Integer):Integer;
var
iov :p_iovec;
cnt :QWORD;
begin
while (uio^.uio_resid >0) and
(uio^.uio_iovcnt>0) do
begin
iov:=uio^.uio_iov;
cnt:=iov^.iov_len;
if (cnt > uio^.uio_resid) then
begin
cnt:=uio^.uio_resid;
end;
//
Inc(iov^.iov_base ,cnt);
Dec(iov^.iov_len ,cnt);
Dec(uio^.uio_resid ,cnt);
Inc(uio^.uio_offset,cnt);
Inc(uio^.uio_iov);
Dec(uio^.uio_iovcnt);
end;
Exit(0);
end;
Function random_ioctl(dev:p_cdev;cmd:QWORD;data:Pointer;fflag:Integer):Integer;
begin
Result:=0;
//Writeln('random_ioctl(0x',HexStr(cmd,8),')');
case cmd of
//Really handled in upper layer
FIOASYNC:;
FIONBIO :;
else
Result:=ENOTTY;
end;
end;
Function random_poll(dev:p_cdev;events:Integer):Integer;
var
revents:Integer;
begin
revents:=0;
if (events and (POLLIN or POLLRDNORM))<>0 then
begin
revents:=events and (POLLIN or POLLRDNORM);
end;
Result:=(revents);
end;
const
random_cdevsw:t_cdevsw=(
d_version :D_VERSION;
d_flags :0;
d_name :'random';
d_close :@random_close;
d_read :@random_read;
d_write :@random_write;
d_ioctl :@random_ioctl;
d_poll :@random_poll;
);
procedure random_init();
var
random_dev:p_cdev;
begin
random_dev:=make_dev_credf(MAKEDEV_ETERNAL_KLD,
@random_cdevsw,
RANDOM_MINOR,
UID_ROOT,
GID_WHEEL,
&666,
'random',
[]);
make_dev_alias(random_dev, 'urandom', []);
end;
end.