This commit is contained in:
Pavel 2023-08-01 15:29:56 +03:00
parent 071795ea0d
commit b6926ffff1
15 changed files with 451 additions and 35 deletions

82
sys/dev/dev_dmem.pas Normal file
View File

@ -0,0 +1,82 @@
unit dev_dmem;
{$mode ObjFPC}{$H+}
{$CALLING SysV_ABI_CDecl}
interface
uses
kern_conf;
procedure dmemdev_init();
implementation
uses
errno,
vuio,
subr_uio,
vm,
kern_dmem;
Const
SCE_KERNEL_MAIN_DMEM_SIZE=$180000000; //6GB
Function dmem_ioctl(dev:p_cdev;cmd:QWORD;data:Pointer;fflag:Integer):Integer;
begin
Result:=0;
Writeln('dmem_ioctl("',dev^.si_name,'",0x',HexStr(cmd,8),',0x',HexStr(fflag,8),')');
case cmd of
$4008800A: //sceKernelGetDirectMemorySize
begin
PQWORD(data)^:=SCE_KERNEL_MAIN_DMEM_SIZE;
end;
else
Assert(False);
end;
end;
Function dmem_mmap(dev:p_cdev;offset:vm_ooffset_t;paddr:p_vm_paddr_t;nprot:Integer;memattr:p_vm_memattr_t):Integer;
begin
Result:=0;
Writeln('dmem_mmap("',dev^.si_name,'",0x',HexStr(offset,8),',0x',HexStr(paddr),',',nprot,')');
Assert(False);
end;
const
dmem_cdevsw:t_cdevsw=(
d_version :D_VERSION;
d_flags :0;
d_name :'dmem';
d_open :nil;
d_fdopen :nil;
d_close :nil;
d_read :nil;
d_write :nil;
d_ioctl :@dmem_ioctl;
d_poll :nil;
d_mmap :@dmem_mmap;
d_strategy :nil;
d_dump :nil;
d_kqfilter :nil;
d_purge :nil;
d_mmap_single:nil;
);
procedure dmemdev_init();
var
i:Integer;
begin
For i:=0 to 2 do
begin
make_dev(@dmem_cdevsw,i,0,0,&777,'dmem%d',[i]);
end;
end;
end.

View File

@ -13,9 +13,9 @@ const
var
zero_region:Pointer;
_zero_region:array[0..ZERO_REGION_SIZE-1] of Byte;
procedure init_zero_region;
procedure free_zero_region;
Function null_modevent(_mod,_type:Integer):Integer; //DEV_MODULE(nil, null_modevent, nil);
@ -109,7 +109,9 @@ begin
end;
end;
else
begin
error:=ENOIOCTL;
end;
end;
Exit(error);
@ -132,21 +134,36 @@ begin
end;
end;
else
begin
error:=ENOIOCTL;
end;
end;
Exit(error);
end;
procedure init_zero_region;
var
buf:Pointer;
begin
if (zero_region=nil) then
begin
FillChar(_zero_region,SizeOf(_zero_region),0);
zero_region:=@_zero_region;
buf:=AllocMem(ZERO_REGION_SIZE);
if (System.InterlockedCompareExchange(zero_region,buf,nil)<>nil) then
begin
FreeMem(buf);
end;
end;
end;
procedure free_zero_region;
var
buf:Pointer;
begin
buf:=System.InterlockedExchange(zero_region,nil);
FreeMem(buf);
end;
{ ARGSUSED }
Function zero_read(dev:p_cdev;uio:p_uio;ioflag:Integer):Integer;
var
@ -188,6 +205,7 @@ begin
begin
destroy_dev(null_dev);
destroy_dev(zero_dev);
free_zero_region;
end;
MOD_SHUTDOWN:;

View File

@ -33,7 +33,7 @@ var
}
Function ttydev_open(dev:p_cdev;oflags,devtype:Integer):Integer;
begin
Writeln('ttydev_open(',dev^.si_name,',',oflags,',',devtype,')');
Writeln('ttydev_open("',dev^.si_name,'",',oflags,',',devtype,')');
Result:=0;
end;
@ -110,7 +110,7 @@ begin
else;
end;
Writeln('ttydev_ioctl(0',dev^.si_name,',0x',HexStr(cmd,8),',0x',HexStr(data),',0x',HexStr(fflag,8));
Writeln('ttydev_ioctl("',dev^.si_name,'",0x',HexStr(cmd,8),',0x',HexStr(data),',0x',HexStr(fflag,8),')');
//error:=tty_ioctl(tp, cmd, data, fflag, td);
//done:
@ -343,27 +343,27 @@ const
* will be logged in the kernel message buffer.
}
function tty_makedev(fmt:PChar;const Args:Array of const):p_cdev; register;
var
dev:p_cdev;
uid:uid_t;
gid:gid_t;
mode:mode_t;
begin
// User device.
uid :=0;
gid :=GID_TTY;
mode:=S_IRUSR or S_IWUSR or S_IWGRP;
function tty_makedev(fmt:PChar;const Args:Array of const):p_cdev; register;
var
dev:p_cdev;
uid:uid_t;
gid:gid_t;
mode:mode_t;
begin
// User device.
uid :=0;
gid :=GID_TTY;
mode:=S_IRUSR or S_IWUSR or S_IWGRP;
dev:=make_dev_cred(@ttydev_cdevsw, 0, uid, gid, mode, fmt, Args);
dev:=make_dev_cred(@ttydev_cdevsw, 0, uid, gid, mode, fmt, Args);
Result:=dev;
end;
Result:=dev;
end;
procedure ttyconsdev_init();
begin
dev_console:=make_dev_credf(MAKEDEV_ETERNAL, @ttyconsdev_cdevsw, 0, UID_ROOT, GID_WHEEL, &600, 'console',[]);
//
tty_makedev('deci_stderr',[]);
tty_makedev('deci_stdin' ,[]);
tty_makedev('deci_stdout',[]);

View File

@ -227,7 +227,9 @@ begin
if (devp^<>fp^.f_data) then
begin
if (dswp^<>nil) then
begin
dev_relthread(devp^, ref^);
end;
Exit(ENXIO);
end;
@ -252,7 +254,9 @@ begin
error:=0;
datap^:=p^.cdpd_data;
end else
begin
error:=ENOENT;
end;
Exit(error);
end;
@ -390,7 +394,9 @@ begin
error:=devfs_populate_vp(vp);
if (error<>0) then
begin
Exit(error);
end;
i:=buflen^;
dd:=vp^.v_data;
@ -500,7 +506,9 @@ var
begin
not_found:=0;
if ((de^.de_flags and DE_DOOMED)<>0) then
begin
not_found:=1;
end;
if DEVFS_DE_DROP(de) then
begin
Assert(not_found=1,'DEVFS de dropped but not doomed');
@ -632,7 +640,9 @@ loop:
VI_UNLOCK(vp);
if ((dev^.si_flags and SI_ETERNAL)<>0) then
begin
vp^.v_vflag:=vp^.v_vflag or VV_ETERNALDEV;
end;
vp^.v_op:=@devfs_specops;
end else
@ -689,16 +699,22 @@ begin
de:=vp^.v_data;
if (vp^.v_type=VDIR) then
begin
de:=de^.de_dir;
end;
error:=vaccess(vp^.v_type, de^.de_mode, de^.de_uid, de^.de_gid, ap^.a_accmode, nil);
if (error=0) then
begin
Exit(0);
end;
if (error<>EACCES) then
Exit(error);
{ We do, however, allow access to the controlling terminal }
if ((p_proc.p_flag and P_CONTROLT)=0) then
begin
Exit(error);
end;
//if (ap^.a_td^.td_proc^.p_session^.s_ttydp=de^.de_cdp) then
// Exit(0);
Exit(error);
@ -721,7 +737,9 @@ begin
* XXX: insmntque1() failure.
}
if (vp^.v_data=nil) then
begin
Exit(0);
end;
{
* Hack: a tty device that is a controlling terminal
@ -750,7 +768,9 @@ begin
//end;
//sx_xunlock(@proctree_lock);
if (oldvp<>nil) then
begin
vrele(oldvp);
end;
{
* We do not want to really close the device if it
* is still in use unless we are trying to close it
@ -865,7 +885,9 @@ begin
error:=devfs_populate_vp(vp);
if (error<>0) then
begin
Exit(error);
end;
dmp:=VFSTODEVFS(vp^.v_mount);
sx_xunlock(@dmp^.dm_lock);
@ -958,10 +980,12 @@ begin
fgn:=data;
p:=devtoname(dev);
i:=strlen(p) + 1;
if (i > fgn^.len) then
error:=EINVAL
else
error:=copyout(p, fgn^.buf, i);
td^.td_fpop:=fpop;
dev_relthread(dev, ref);
Exit(error);
@ -970,7 +994,9 @@ begin
td^.td_fpop:=nil;
dev_relthread(dev, ref);
if (error=ENOIOCTL) then
begin
error:=ENOTTY;
end;
if (error=0) and (com=TIOCSCTTY) then
begin
vp:=fp^.f_vnode;
@ -995,7 +1021,9 @@ begin
{ Get rid of reference to old control tty }
if (vpold<>nil) then
begin
vrele(vpold);
end;
end;
Exit(error);
end;
@ -1032,10 +1060,14 @@ begin
error:=0;
//error:=prison_check(td^.td_ucred, dcr);
if (error=0) then
begin
Exit(0);
end;
{ We do, however, allow access to the controlling terminal }
if ((p_proc.p_flag and P_CONTROLT)=0) then
begin
Exit(error);
end;
//if (td^.td_proc^.p_session^.s_ttydp=cdp) then
// Exit(0);
Exit(error);
@ -1067,22 +1099,32 @@ begin
vpp^:=nil;
if ((flags and ISLASTCN)<>0) and (nameiop=RENAME) then
begin
Exit(EOPNOTSUPP);
end;
if (dvp^.v_type<>VDIR) then
begin
Exit(ENOTDIR);
end;
if (((flags and ISDOTDOT)<>0) and ((dvp^.v_vflag and VV_ROOT)<>0)) then
begin
Exit(EIO);
end;
error:=VOP_ACCESS(dvp, VEXEC);
if (error<>0) then
begin
Exit(error);
end;
if (cnp^.cn_namelen=1) and (pname^='.') then
begin
if ((flags and ISLASTCN) and nameiop<>LOOKUP) then
begin
Exit(EINVAL);
end;
vpp^:=dvp;
VREF(dvp);
Exit(0);
@ -1091,7 +1133,9 @@ begin
if ((flags and ISDOTDOT)<>0) then
begin
if ((flags and ISLASTCN)<>0) and (nameiop<>LOOKUP) then
begin
Exit(EINVAL);
end;
de:=devfs_parent_dirent(dd);
if (de=nil) then Exit(ENOENT);
@ -1152,7 +1196,9 @@ begin
devfs_unmount_final(dmp);
if (cdev<>nil) then
begin
dev_rel(cdev);
end;
Exit(ENOENT);
end;
@ -1190,13 +1236,17 @@ begin
end;
if (devfs_prison_check(de)<>0) then
begin
Exit(ENOENT);
end;
if (cnp^.cn_nameiop=DELETE) and ((flags and ISLASTCN)<>0) then
begin
error:=VOP_ACCESS(dvp, VWRITE);
if (error<>0) then
begin
Exit(error);
end;
if (vpp^=dvp) then
begin
VREF(dvp);
@ -1428,7 +1478,9 @@ var
fpop:p_file;
begin
if (uio^.uio_resid > DEVFS_IOSIZE_MAX) then
begin
Exit(EINVAL);
end;
td:=curkthread;
fpop:=td^.td_fpop;
@ -1444,7 +1496,9 @@ begin
foffset_lock_uio(fp, uio, flags or FOF_NOLOCK);
error:=dsw^.d_read(dev, uio, ioflag);
if (uio^.uio_resid<>resid) or ((error=0) and (resid<>0)) then
begin
vfs_timestamp(@dev^.si_atime);
end;
td^.td_fpop:=fpop;
dev_relthread(dev, ref);
@ -1466,11 +1520,15 @@ begin
tmp_ncookies:=nil;
if (ap^.a_vp^.v_type<>VDIR) then
begin
Exit(ENOTDIR);
end;
uio:=ap^.a_uio;
if (uio^.uio_offset < 0) then
begin
Exit(EINVAL);
end;
{
* XXX: This is a temporary hack to get around this filesystem not
@ -1616,18 +1674,24 @@ begin
begin
de_cov:=devfs_find(dd, de^.de_dirent^.d_name, de^.de_dirent^.d_namlen, 0);
if (de_cov<>nil) then
begin
de_cov^.de_flags:=de_cov^.de_flags and (not DE_COVERED);
end;
end;
{ We need to unlock dvp because devfs_delete() may lock it. }
VOP_UNLOCK(vp, 0);
if (dvp<>vp) then
begin
VOP_UNLOCK(dvp, 0);
end;
devfs_delete(dmp, de, 0);
sx_xunlock(@dmp^.dm_lock);
if (dvp<>vp) then
begin
vn_lock(dvp, LK_EXCLUSIVE or LK_RETRY);
end;
vn_lock(vp, LK_EXCLUSIVE or LK_RETRY);
end else
@ -1712,7 +1776,9 @@ begin
dev_unlock();
dev_rel(@cdp^.cdp_c);
end else
begin
dev_unlock();
end;
vn_lock(vp, LK_EXCLUSIVE or LK_RETRY);
Exit(0);
@ -1781,7 +1847,9 @@ begin
de:=vp^.v_data;
if (vp^.v_type=VDIR) then
begin
de:=de^.de_dir;
end;
error:=0;
c:=0;
@ -1874,12 +1942,16 @@ begin
error:=0;
//error:=priv_check(curkthread, PRIV_DEVFS_SYMLINK);
if (error<>0) then
begin
Exit(error);
end;
dmp:=VFSTODEVFS(ap^.a_dvp^.v_mount);
if (devfs_populate_vp(ap^.a_dvp)<>0) then
begin
Exit(ENOENT);
end;
dd:=ap^.a_dvp^.v_data;
de_cov:=devfs_find(dd, ap^.a_cnp^.cn_nameptr, ap^.a_cnp^.cn_namelen, 0);
@ -1937,7 +2009,9 @@ begin
td:=curkthread;
if (uio^.uio_resid > DEVFS_IOSIZE_MAX) then
begin
Exit(EINVAL);
end;
fpop:=td^.td_fpop;
error:=devfs_fp_check(fp, @dev, @dsw, @ref);
@ -1947,7 +2021,9 @@ begin
ioflag:=fp^.f_flag and (O_NONBLOCK or O_DIRECT or O_FSYNC);
if ((ioflag and O_DIRECT)<>0) then
begin
ioflag:=ioflag or IO_DIRECT;
end;
foffset_lock_uio(fp, uio, flags or FOF_NOLOCK);

40
sys/kern/kern_dmem.pas Normal file
View File

@ -0,0 +1,40 @@
unit kern_dmem;
{$mode ObjFPC}{$H+}
{$CALLING SysV_ABI_CDecl}
interface
function sys_dmem_container(d_pool_id:Integer):Integer;
implementation
uses
errno,
kern_thr;
const
default_pool_id=1;
function sys_dmem_container(d_pool_id:Integer):Integer;
var
td:p_kthread;
begin
td:=curkthread;
if (td=nil) then Exit(-1);
td^.td_retval[0]:=default_pool_id;
Result:=0;
if (d_pool_id<>-1) then
begin
//Result:=priv_check(td,0x2ad);
//(param < 3)
Exit(EPERM);
end;
end;
end.

View File

@ -56,7 +56,8 @@ uses
kern_event,
machdep,
kern_dlsym,
kern_authinfo;
kern_authinfo,
vfs_syscalls;
function exec_alloc_args(args:p_image_args):Integer;
begin
@ -1197,6 +1198,13 @@ begin
Exit(0);
end;
procedure init_tty;
begin
kern_openat(STDIN_FILENO ,'/dev/deci_stdin' ,UIO_SYSSPACE,O_RDWR,0);
kern_openat(STDOUT_FILENO,'/dev/deci_stdout',UIO_SYSSPACE,O_RDWR,0);
kern_openat(STDERR_FILENO,'/dev/deci_stderr',UIO_SYSSPACE,O_RDWR,0);
end;
const
fexecv_proc_title='(fexecv)';
@ -1422,6 +1430,9 @@ begin
//copy authinfo
g_authinfo:=imgp^.authinfo;
//init std tty
init_tty;
{
* Free any resources malloc'd earlier that we didn't use.
}

View File

@ -414,6 +414,12 @@ begin
if (pid<>g_pid) then Exit(EINVAL);
//G_APPINFO.mmap_flags:=G_APPINFO.mmap_flags or 1;
if (p_proc.p_sce_replay_exec<>0) then
begin
G_APPINFO.mmap_flags:=G_APPINFO.mmap_flags or 2;
end;
//sceSblACMgrIsSystemUcred()!=0 -> any proc
//sceSblACMgrIsSystemUcred()==0 -> cur proc
@ -425,6 +431,10 @@ begin
if (Result=0) then
begin
G_APPINFO:=APPINFO;
if (p_proc.p_sce_replay_exec<>0) then
begin
G_APPINFO.mmap_flags:=G_APPINFO.mmap_flags or 2;
end;
end;
end;

View File

@ -544,12 +544,16 @@ end;
procedure PROC_INIT;
const
osreldate=$000DBBA0;
begin
FillChar(p_proc,SizeOf(p_proc),0);
mtx_init(p_proc.p_mtx,'process lock');
knlist_init_mtx(@p_proc.p_klist,@p_proc.p_mtx);
p_proc.p_osrel:=osreldate;
p_proc.p_randomized_path:='system';
p_proc.p_ptc:=rdtsc;

View File

@ -40,7 +40,8 @@ uses
vfs_mountroot,
kern_conf,
dev_null,
dev_tty;
dev_tty,
dev_dmem;
var
daemon_thr:p_kthread;
@ -74,6 +75,7 @@ begin
//
null_modevent(0,MOD_LOAD);
ttyconsdev_init();
dmemdev_init();
end;
//Manual order of lazy initialization

View File

@ -205,6 +205,7 @@ function budget_delete(key:Integer):Integer;
function budget_get(key:Integer;ptr:Pointer;psize:PInteger):Integer;
function budget_set(key:Integer):Integer;
function is_in_sandbox():Integer;
function dmem_container(d_pool_id:Integer):Integer;
function get_authinfo(pid:Integer;info:Pointer):Integer;
function mname(addr:Pointer;len:QWORD;name:PChar):Integer;
function dynlib_dlsym(handle:Integer;symbol:pchar;addrp:ppointer):Integer;
@ -1632,6 +1633,13 @@ asm
jmp cerror
end;
function dmem_container(d_pool_id:Integer):Integer; assembler; nostackframe;
asm
movq $586,%rax
call fast_syscall
jmp cerror
end;
function get_authinfo(pid:Integer;info:Pointer):Integer; assembler; nostackframe;
asm
movq $587,%rax

View File

@ -13,6 +13,7 @@ uses
kern_evf,
kern_gpo,
kern_sig,
kern_dmem,
kern_exec,
kern_exit,
kern_osem,
@ -2986,7 +2987,7 @@ const
),
(//[586]
sy_narg:1;
sy_call:nil;
sy_call:@sys_dmem_container;
sy_name:'sys_dmem_container'
),
(//[587]

View File

@ -633,6 +633,14 @@
<Filename Value="..\dev\dev_tty.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
<Unit>
<Filename Value="..\kern\kern_dmem.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
<Unit>
<Filename Value="..\dev\dev_dmem.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
</Units>
</ProjectOptions>
<CompilerOptions>

View File

@ -95,7 +95,8 @@ uses
kern_sysctl,
kern_budget,
kern_regmgr,
kern_authinfo;
kern_authinfo,
kern_dmem;
const
PAGE_MAP_COUNT=(qword(VM_MAXUSER_ADDRESS) shr PAGE_SHIFT);

View File

@ -105,6 +105,10 @@ const
DFLAG_PASSABLE=$01; { may be passed via unix sockets. }
DFLAG_SEEKABLE=$02; { seekable / nonsequential }
STDIN_FILENO =0; // standard input file descriptor
STDOUT_FILENO=1; // standard output file descriptor
STDERR_FILENO=2; // standard error file descriptor
type
mode_t=Integer;
uid_t =Integer;

View File

@ -126,7 +126,9 @@ var
begin
error:=fget_read(fd, CAP_READ or CAP_SEEK, @fp);
if (error<>0) then
begin
Exit(error);
end;
error:=dofileread(fd, fp, auio, -1, 0);
fdrop(fp);
Exit(error);
@ -139,7 +141,9 @@ var
begin
error:=fget_read(fd, CAP_READ, @fp);
if (error<>0) then
begin
Exit(error);
end;
if ((fp^.f_ops^.fo_flags and DFLAG_SEEKABLE)=0) then
error:=ESPIPE
else
@ -147,6 +151,7 @@ begin
error:=EINVAL
else
error:=dofileread(fd, fp, auio, offset, FOF_OFFSET);
fdrop(fp);
Exit(error);
end;
@ -158,7 +163,9 @@ var
begin
error:=fget_write(fd, CAP_WRITE or CAP_SEEK, @fp);
if (error<>0) then
begin
Exit(error);
end;
error:=dofilewrite(fd, fp, auio, -1, 0);
fdrop(fp);
Exit(error);
@ -171,7 +178,9 @@ var
begin
error:=fget_write(fd, CAP_WRITE, @fp);
if (error<>0) then
begin
Exit(error);
end;
if ((fp^.f_ops^.fo_flags and DFLAG_SEEKABLE)=0) then
error:=ESPIPE
else
@ -179,6 +188,7 @@ begin
error:=EINVAL
else
error:=dofilewrite(fd, fp, auio, offset, FOF_OFFSET);
fdrop(fp);
Exit(error);
end;
@ -234,7 +244,9 @@ var
begin
error:=copyinuio(iovp, iovcnt, @auio);
if (error<>0) then
begin
Exit(error);
end;
error:=kern_readv(fd, auio);
FreeMem(auio);
Exit(error);
@ -250,7 +262,9 @@ var
begin
error:=copyinuio(iovp, iovcnt, @auio);
if (error<>0) then
begin
Exit(error);
end;
error:=kern_preadv(fd, auio, offset);
FreeMem(auio);
Exit(error);
@ -282,7 +296,9 @@ begin
if (error<>0) then
begin
if (auio^.uio_resid<>cnt) and ((error=ERESTART) or (error=EINTR) or (error=EWOULDBLOCK)) then
begin
error:=0;
end;
end;
Dec(cnt,auio^.uio_resid);
@ -339,7 +355,9 @@ var
begin
error:=copyinuio(iovp, iovcnt, @auio);
if (error<>0) then
begin
Exit(error);
end;
error:=kern_writev(fd, auio);
FreeMem(auio);
Exit(error);
@ -355,7 +373,9 @@ var
begin
error:=copyinuio(iovp, iovcnt, @auio);
if (error<>0) then
begin
Exit(error);
end;
error:=kern_pwritev(fd, auio, offset);
FreeMem(auio);
Exit(error);
@ -385,7 +405,9 @@ begin
if (error<>0) then
begin
if (auio^.uio_resid<>cnt) and ((error=ERESTART) or (error=EINTR) or (error=EWOULDBLOCK)) then
begin
error:=0;
end;
{ Socket layer is responsible for issuing SIGPIPE. }
if (fp^.f_type<>DTYPE_SOCKET) and (error=EPIPE) then
begin
@ -412,10 +434,14 @@ var
error:Integer;
begin
if (length < 0) then
begin
Exit(EINVAL);
end;
error:=fget(fd, CAP_FTRUNCATE, @fp);
if (error<>0) then
begin
Exit(error);
end;
if ((fp^.f_flag and FWRITE)=0) then
begin
fdrop(fp);
@ -441,7 +467,9 @@ var
begin
error:=fget(fd, CAP_IOCTL, @fp);
if (error<>0) then
begin
Exit(error);
end;
if ((fp^.f_flag and (FREAD or FWRITE))=0) then
begin
fdrop(fp);
@ -461,19 +489,23 @@ begin
FIONBIO:
begin
tmp:=PInteger(data)^;
if (tmp<>0) then
atomic_set_int(@fp^.f_flag, FNONBLOCK)
else
atomic_clear_int(@fp^.f_flag, FNONBLOCK);
data:=@tmp;
end;
FIOASYNC:
begin
tmp:=PInteger(data)^;
if (tmp<>0) then
atomic_set_int(@fp^.f_flag, FASYNC)
else
atomic_clear_int(@fp^.f_flag, FASYNC);
data:=@tmp;
end;
end;
@ -490,6 +522,7 @@ var
smalldata:array[0..SYS_IOCTL_SMALL_SIZE-1] of Byte; //__aligned(SYS_IOCTL_SMALL_ALIGN)
arg,error:Integer;
size:DWORD;
kern_data:Pointer;
begin
if (com > $ffffffff) then
begin
@ -506,7 +539,9 @@ begin
((com and (IOC_VOID or IOC_IN or IOC_OUT))=0) or
(((com and (IOC_IN or IOC_OUT))<>0) and (size=0)) or
(((com and IOC_VOID)<>0) and (size > 0) and (size<>sizeof(Integer))) then
begin
Exit(ENOTTY);
end;
if (size > 0) then
begin
@ -514,22 +549,26 @@ begin
begin
{ Integer argument. }
arg:=ptrint(data);
data:=@arg;
kern_data:=@arg;
size:=0;
end else
begin
if (size > SYS_IOCTL_SMALL_SIZE) then
data:=AllocMem(size)
kern_data:=AllocMem(size)
else
data:=@smalldata;
kern_data:=@smalldata;
end;
end else
data:=@data;
begin
kern_data:=@curkthread^.td_frame.tf_rsi;
end;
if ((com and IOC_IN)<>0) then
begin
error:=copyin(data, data, size);
error:=copyin(data, kern_data, size);
if (error<>0) then
begin
goto _out;
end;
end else
if ((com and IOC_OUT)<>0) then
begin
@ -537,17 +576,21 @@ begin
* Zero the buffer so the user always
* gets back something deterministic.
}
FillChar(data,size,0);
FillChar(kern_data^,size,0);
end;
error:=kern_ioctl(fd, com, data);
error:=kern_ioctl(fd, com, kern_data);
if (error=0) and ((com and IOC_OUT)<>0) then
error:=copyout(data, data, size);
begin
error:=copyout(kern_data, data, size);
end;
_out:
if (size > SYS_IOCTL_SMALL_SIZE) then
FreeMem(data);
begin
FreeMem(kern_data);
end;
Exit(error);
end;
@ -561,7 +604,9 @@ begin
* of specific filesystem implementations.
}
if (events and (not POLLSTANDARD))<>0 then
begin
Exit(POLLNVAL);
end;
Exit(events and (POLLIN or POLLOUT or POLLRDNORM or POLLWRNORM));
end;
@ -585,7 +630,9 @@ begin
begin
error:=kern_sigprocmask(td, SIG_SETMASK, uset, @td^.td_oldsigmask, 0);
if (error<>0) then
begin
Exit(error);
end;
td^.td_pflags:=td^.td_pflags or TDP_OLDMASK;
{
* Make sure that ast() is called on Exitto
@ -613,19 +660,27 @@ begin
begin
error:=copyin(uts, @ts, sizeof(ts));
if (error<>0) then
begin
Exit(error);
end;
TIMESPEC_TO_TIMEVAL(@tv, @ts);
tvp:=@tv;
end else
begin
tvp:=nil;
end;
if (sm<>nil) then
begin
error:=copyin(sm, @_set, sizeof(_set));
if (error<>0) then
begin
Exit(error);
end;
uset:=@_set;
end else
begin
uset:=nil;
end;
Exit(kern_pselect(nd, uin, uou, uex, tvp, uset, NFDBITS));
end;
@ -639,7 +694,9 @@ begin
begin
error:=copyin(utv, @tv, sizeof(tv));
if (error<>0) then
begin
Exit(error);
end;
tvp:=@tv;
end else
tvp:=nil;
@ -663,7 +720,9 @@ var
bits:Byte;
begin
if (nd >= ndu) or (fd_in=nil) then
begin
Exit(0);
end;
oaddr:=nil;
bits:=0; { silence gcc }
@ -675,12 +734,16 @@ begin
begin
res:=fubyte(addr^);
if (res=-1) then
begin
Exit(EFAULT);
end;
oaddr:=addr;
bits:=res;
end;
if ((bits and (1 shl (i mod NBBY)))<>0) then
begin
Exit(EBADF);
end;
end;
Exit(0);
end;
@ -714,7 +777,9 @@ var
begin
error2:=copyout(@obits[x], name, ncpubytes);
if (error2<>0) then
begin
error:=error2;
end;
end;
end;
@ -731,13 +796,19 @@ begin
error:=select_check_badfd(fd_in, nd, ndu, abi_nfdbits);
if (error<>0) then
begin
Exit(error);
end;
error:=select_check_badfd(fd_ou, nd, ndu, abi_nfdbits);
if (error<>0) then
begin
Exit(error);
end;
error:=select_check_badfd(fd_ex, nd, ndu, abi_nfdbits);
if (error<>0) then
begin
Exit(error);
end;
{
* Allocate just enough bits for the non-nil fd_sets. Use the
@ -749,11 +820,17 @@ begin
nbufbytes:=0;
if (fd_in<>nil) then
begin
Inc(nbufbytes,2 * ncpbytes);
end;
if (fd_ou<>nil) then
begin
Inc(nbufbytes,2 * ncpbytes);
end;
if (fd_ex<>nil) then
begin
Inc(nbufbytes,2 * ncpbytes);
end;
if (nbufbytes <= sizeof(s_selbits)) then
selbits:=@s_selbits[0]
@ -789,12 +866,16 @@ begin
repeat
error:=selscan(td, @ibits, @obits, nd);
if (error<>0) or (td^.td_retval[0]<>0) then
begin
break;
end;
if (atv<>0) then
begin
rtv:=get_unit_uptime;
if (rtv>=atv) then
begin
break;
end;
ttv:=atv-rtv;
if (ttv>24*60*60*hz) then
@ -804,19 +885,27 @@ begin
end;
error:=seltdwait(td, timo);
if (error<>0) then
begin
break;
end;
error:=selrescan(td, @ibits, @obits);
if (error<>0) or (td^.td_retval[0]<>0) then
begin
break;
end;
until false;
seltdclear(td);
done:
{ select is not restarted after signals... }
if (error=ERESTART) then
begin
error:=EINTR;
end;
if (error=EWOULDBLOCK) then
begin
error:=0;
end;
if (error=0) then
begin
@ -826,7 +915,9 @@ done:
end;
if (selbits<>@s_selbits[0]) then
begin
FreeMem(selbits);
end;
Exit(error);
end;
@ -902,7 +993,9 @@ var
begin
fp:=fget_unlocked(fd);
if (fp=nil) then
begin
Exit(EBADF);
end;
{
* If the file descriptor is for a capability, test rights and use
* the file descriptor references by the capability.
@ -958,7 +1051,9 @@ begin
end;
error:=getselfd_cap(fd, @fp);
if (error<>0) then
begin
Exit(error);
end;
idx:=fd div NFDBITS;
bit:=fd_mask(1) shl (fd mod NFDBITS);
ev:=fo_poll(fp, selflags(ibits, idx, bit));
@ -1032,16 +1127,22 @@ var
ni:QWORD;
begin
if (nfds > maxfilesperproc) and (nfds > FD_SETSIZE) then
begin
Exit(EINVAL);
end;
td:=curkthread;
ni:=nfds * sizeof(t_pollfd);
if (ni > sizeof(smallbits)) then
bits:=AllocMem(ni)
else
bits:=@smallbits;
error:=copyin(fds, bits, ni);
if (error<>0) then
begin
goto done;
end;
if (timeout<>INFTIM) then
begin
atv:=USEC_TO_UNIT(_msec2usec(timeout));
@ -1072,28 +1173,40 @@ begin
end;
error:=seltdwait(td, timo);
if (error<>0) then
begin
break;
end;
error:=pollrescan(td);
if (error<>0) or (td^.td_retval[0]<>0) then
begin
break;
end;
until false;
seltdclear(td);
done:
{ poll is not restarted after signals... }
if (error=ERESTART) then
begin
error:=EINTR;
end;
if (error=EWOULDBLOCK) then
begin
error:=0;
end;
if (error=0) then
begin
error:=_pollout(td, bits, fds, nfds);
if (error<>0) then
begin
goto _out;
end;
end;
_out:
if (ni > sizeof(smallbits)) then
begin
FreeMem(bits);
end;
Exit(error);
end;
@ -1129,7 +1242,9 @@ begin
if (cap_funwrap(fp, CAP_POLL_EVENT, @fp)<>0) then
begin
if (fp<>nil) then
begin
fdrop(fp);
end;
//
fd^.revents:=POLLNVAL;
Inc(n);
@ -1144,7 +1259,9 @@ begin
}
fd^.revents:=fo_poll(fp, fd^.events);
if (fd^.revents<>0) then
begin
Inc(n);
end;
//
fdrop(fp);
//
@ -1168,9 +1285,13 @@ begin
begin
error:=copyout(@fds^.revents, @ufds^.revents, sizeof(ufds^.revents));
if (error<>0) then
begin
Exit(error);
end;
if (fds^.revents<>0) then
begin
Inc(n);
end;
Inc(fds);
Inc(ufds);
end;
@ -1217,14 +1338,20 @@ begin
* set simultaneously with POLLHUP.
}
if ((fds^.revents and POLLHUP)<>0) then
begin
fds^.revents:=fds^.revents and (not POLLOUT);
end;
if (fds^.revents<>0) then
begin
Inc(n);
end;
end;
//
if (fp<>nil) then
begin
fdrop(fp);
end;
end;
//
Inc(i);
@ -1245,11 +1372,15 @@ var
begin
stp:=td^.td_sel;
if (stp^.st_free1=nil) then
begin
stp^.st_free1:=AllocMem(SizeOf(t_selfd));
end;
stp^.st_free1^.sf_td:=stp;
stp^.st_free1^.sf_cookie:=cookie;
if (stp^.st_free2=nil) then
begin
stp^.st_free2:=AllocMem(SizeOf(t_selfd));
end;
stp^.st_free2^.sf_td:=stp;
stp^.st_free2^.sf_cookie:=cookie;
end;
@ -1259,7 +1390,9 @@ begin
STAILQ_REMOVE(@stp^.st_selq,sfp,@sfp^.sf_link);
mtx_lock(sfp^.sf_mtx^);
if (sfp^.sf_si<>nil) then
begin
TAILQ_REMOVE(@sfp^.sf_si^.si_tdlist,sfp,@sfp^.sf_threads);
end;
mtx_unlock(sfp^.sf_mtx^);
FreeMem(sfp);
end;
@ -1292,19 +1425,23 @@ begin
* Don't record when doing a rescan.
}
if ((stp^.st_flags and SELTD_RESCAN)<>0) then
begin
Exit;
end;
{
* Grab one of the preallocated descriptors.
}
sfp:=stp^.st_free1;
if (sfp<>nil) then
begin
stp^.st_free1:=nil
else
end else
begin
sfp:=stp^.st_free2;
if (sfp<>nil) then
begin
stp^.st_free2:=nil
else
end else
begin
Assert(false,'selrecord: No free selfd on selq');
Exit;
@ -1312,7 +1449,9 @@ begin
end;
mtxp:=sip^.si_mtx;
if (mtxp=nil) then
begin
mtxp:=mtx_pool_find(mtxpool_select, sip);
end;
{
* Initialize the sfp and queue it in the thread.
}
@ -1359,7 +1498,9 @@ var
begin
{ If it's not initialized there can't be any waiters. }
if (sip^.si_mtx=nil) then
begin
Exit;
end;
{
* Locking the selinfo locks all selfds associated with it.
}
@ -1393,7 +1534,9 @@ var
begin
stp:=td^.td_sel;
if (stp<>nil) then
begin
goto _out;
end;
stp:=AllocMem(sizeof(t_seltd));
td^.td_sel:=stp;
mtx_init(stp^.st_mtx, 'sellck');
@ -1423,10 +1566,12 @@ begin
mtx_unlock(stp^.st_mtx);
Exit(0);
end;
if (timo > 0) then
error:=_cv_timedwait_sig(@stp^.st_wait, @stp^.st_mtx, timo)
else
error:=_cv_wait_sig(@stp^.st_wait, @stp^.st_mtx);
mtx_unlock(stp^.st_mtx);
Exit(error);
@ -1438,11 +1583,17 @@ var
begin
stp:=td^.td_sel;
if (stp=nil) then
begin
Exit;
end;
if (stp^.st_free1<>nil) then
begin
FreeMem(stp^.st_free1);
end;
if (stp^.st_free2<>nil) then
begin
FreeMem(stp^.st_free2);
end;
td^.td_sel:=nil;
FreeMem(stp);
end;