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.