mirror of https://github.com/red-prig/fpPS4.git
This commit is contained in:
parent
efd934f00b
commit
ecf4f7d7bc
|
@ -846,6 +846,14 @@
|
|||
<Filename Value="sys\dev\display_interface.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="sys\dev\devfs_int.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="sys\sys_conf.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
|
|
|
@ -9,6 +9,7 @@ uses
|
|||
Classes,
|
||||
SysUtils,
|
||||
kern_thr,
|
||||
md_sleep,
|
||||
md_pipe,
|
||||
host_ipc,
|
||||
md_host_ipc,
|
||||
|
@ -54,6 +55,8 @@ uses
|
|||
sys_tty,
|
||||
md_exception, //<- install custom
|
||||
|
||||
sys_event,
|
||||
|
||||
kern_proc,
|
||||
md_systm,
|
||||
|
||||
|
@ -106,6 +109,8 @@ begin
|
|||
//init all
|
||||
sys_init;
|
||||
|
||||
kern_ipc.thread_new;
|
||||
|
||||
PROC_INIT_HOST_IPC(kern_ipc);
|
||||
|
||||
Writeln(Item.FGameInfo.Exec);
|
||||
|
@ -204,7 +209,7 @@ begin
|
|||
r:=kthread_add(@prepare,Item,@td,'[main]');
|
||||
Assert(r=0);
|
||||
|
||||
sleep(-1);
|
||||
msleep_td(0);
|
||||
end;
|
||||
|
||||
function run_item(const cfg:TGameRunConfig;Item:TGameItem):TGameProcess;
|
||||
|
@ -213,6 +218,10 @@ var
|
|||
|
||||
kern2mgui:array[0..1] of THandle;
|
||||
|
||||
fork_info:t_fork_proc;
|
||||
|
||||
kev:t_kevent;
|
||||
|
||||
p_mgui_ipc:THostIpcPipeMGUI;
|
||||
|
||||
s_kern_ipc:THostIpcSimpleKERN;
|
||||
|
@ -228,6 +237,8 @@ begin
|
|||
SetStdHandle(STD_OUTPUT_HANDLE,cfg.hOutput);
|
||||
SetStdHandle(STD_ERROR_HANDLE ,cfg.hError );
|
||||
|
||||
fork_info:=Default(t_fork_proc);
|
||||
|
||||
if cfg.fork_proc then
|
||||
begin
|
||||
Result:=TGameProcessPipe.Create;
|
||||
|
@ -252,9 +263,11 @@ begin
|
|||
|
||||
Item.Serialize(mem);
|
||||
|
||||
r:=md_fork_process(@fork_process,mem.Memory,mem.Size,fork_info);
|
||||
|
||||
with TGameProcessPipe(Result) do
|
||||
begin
|
||||
FProcess:=md_fork_process(@fork_process,mem.Memory,mem.Size);
|
||||
FProcess:=fork_info.hProcess;
|
||||
end;
|
||||
|
||||
mem.Free;
|
||||
|
@ -278,10 +291,23 @@ begin
|
|||
|
||||
Ftd:=nil;
|
||||
r:=kthread_add(@prepare,Item,@Ftd,'[main]');
|
||||
|
||||
fork_info.fork_pid:=GetProcessID;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
Result.g_ipc.thread_new;
|
||||
|
||||
kev.ident :=fork_info.fork_pid;
|
||||
kev.filter:=EVFILT_PROC;
|
||||
kev.flags :=EV_ADD;
|
||||
kev.fflags:=NOTE_EXIT or NOTE_EXEC;
|
||||
kev.data :=0;
|
||||
kev.udata :=nil;
|
||||
|
||||
Result.g_ipc.kevent(@kev,1);
|
||||
|
||||
runing:=True;
|
||||
end;
|
||||
|
||||
|
|
48
gui/main.pas
48
gui/main.pas
|
@ -78,8 +78,7 @@ uses
|
|||
TypInfo,
|
||||
Rtti,
|
||||
|
||||
evbuffer,
|
||||
evpoll;
|
||||
sys_event;
|
||||
|
||||
//
|
||||
|
||||
|
@ -123,28 +122,49 @@ type
|
|||
TGuiIpcHandler=class(THostIpcHandler)
|
||||
Form:TfrmMain;
|
||||
function OnMessage(mtype:t_mtype;mlen:DWORD;buf:Pointer):Ptruint; override;
|
||||
function OnKevent(kev:p_kevent;count:Integer):Ptruint;
|
||||
end;
|
||||
|
||||
function TGuiIpcHandler.OnMessage(mtype:t_mtype;mlen:DWORD;buf:Pointer):Ptruint;
|
||||
begin
|
||||
Result:=0;
|
||||
case mtype of
|
||||
iKNOTE:
|
||||
with PHostIpcKnote(buf)^ do
|
||||
begin
|
||||
ShowMessage('iKNOTE pid:'+IntToStr(pid)+
|
||||
' filter:'+IntToStr(filter)+
|
||||
' hint:'+HexStr(hint,16)
|
||||
);
|
||||
end;
|
||||
|
||||
|
||||
iKEV_EVENT:Result:=OnKevent(buf,mlen div sizeof(t_kevent));
|
||||
else;
|
||||
ShowMessage(GetEnumName(TypeInfo(mtype),ord(mtype)));
|
||||
end;
|
||||
end;
|
||||
|
||||
//PHostIpcKnote
|
||||
function TGuiIpcHandler.OnKevent(kev:p_kevent;count:Integer):Ptruint;
|
||||
var
|
||||
i:Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
|
||||
i:=0;
|
||||
while (i<>count) do
|
||||
begin
|
||||
case kev[i].filter of
|
||||
EVFILT_PROC:
|
||||
begin
|
||||
if ((kev[i].fflags and NOTE_EXIT)<>0) then
|
||||
begin
|
||||
ShowMessage('NOTE_EXIT pid:'+IntToStr(kev[i].ident));
|
||||
end;
|
||||
if ((kev[i].fflags and NOTE_EXEC)<>0) then
|
||||
begin
|
||||
ShowMessage('NOTE_EXEC pid:'+IntToStr(kev[i].ident));
|
||||
end;
|
||||
end;
|
||||
|
||||
else;
|
||||
end;
|
||||
|
||||
Inc(i);
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
|
||||
var
|
||||
IpcHandler:TGuiIpcHandler;
|
||||
|
@ -409,7 +429,7 @@ begin
|
|||
cfg.hOutput:=FAddHandle;
|
||||
cfg.hError :=FAddHandle;
|
||||
|
||||
cfg.fork_proc:=False;
|
||||
cfg.fork_proc:=True;
|
||||
|
||||
GameProcess:=run_item(cfg,Item);
|
||||
end;
|
||||
|
|
|
@ -9,7 +9,7 @@ uses
|
|||
sysutils,
|
||||
vm,
|
||||
vmparam,
|
||||
kern_conf,
|
||||
sys_conf,
|
||||
sys_event,
|
||||
time,
|
||||
kern_mtx,
|
||||
|
@ -38,7 +38,6 @@ uses
|
|||
subr_backtrace,
|
||||
sys_vm_object,
|
||||
vm_pager,
|
||||
kern_event,
|
||||
md_time,
|
||||
kern_proc,
|
||||
kern_timeout;
|
||||
|
@ -755,10 +754,13 @@ type
|
|||
rout :PQWORD; //extraout of result
|
||||
end;
|
||||
|
||||
var
|
||||
f_eop_count:Integer=0;
|
||||
|
||||
Function dce_submit_flip(dev:p_cdev;data:p_submit_flip_args):Integer;
|
||||
var
|
||||
submit:t_submit_flip;
|
||||
eop_val:PQWORD;
|
||||
submit_eop:QWORD;
|
||||
ures:QWORD;
|
||||
begin
|
||||
Result:=0;
|
||||
|
@ -766,24 +768,12 @@ begin
|
|||
if (data^.canary<>$a5a5) then Exit(EINVAL);
|
||||
|
||||
if (data^.bufferIndex>15) then Exit(EINVAL);
|
||||
if (data^.eop_nz>1) then Exit(EINVAL);
|
||||
|
||||
submit.bufferIndex:=data^.bufferIndex;
|
||||
submit.flipMode :=data^.flipMode;
|
||||
submit.flipArg :=data^.flipArg;
|
||||
submit.flipArg2 :=data^.flipArg2;
|
||||
|
||||
// count canary
|
||||
//eop=0x[00000001] [ff] [00] [a5a5]
|
||||
|
||||
if (data^.eop_nz=1) then
|
||||
begin
|
||||
eop_val:=data^.eop_val;
|
||||
end else
|
||||
begin
|
||||
eop_val:=nil;
|
||||
end;
|
||||
|
||||
mtx_lock(dce_mtx);
|
||||
|
||||
if (dce_handle=nil) then
|
||||
|
@ -791,7 +781,22 @@ begin
|
|||
Result:=EINVAL;
|
||||
end else
|
||||
begin
|
||||
Result:=dce_handle.SubmitFlip(@submit,eop_val);
|
||||
|
||||
if (data^.eop_nz=1) then
|
||||
begin
|
||||
// count canary
|
||||
//eop=0x[00000001] [ff] [00] [a5a5]
|
||||
|
||||
f_eop_count:=f_eop_count+1;
|
||||
|
||||
submit_eop:=(QWORD(f_eop_count) shl 32) or QWORD($ff00a5a5);
|
||||
|
||||
Result:=dce_handle.SubmitFlipEop(@submit,submit_eop);
|
||||
end else
|
||||
begin
|
||||
Result:=dce_handle.SubmitFlip(@submit);
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
mtx_unlock(dce_mtx);
|
||||
|
@ -805,6 +810,11 @@ begin
|
|||
|
||||
flipArg:=data^.flipArg;
|
||||
|
||||
if (data^.eop_nz=1) then
|
||||
begin
|
||||
Result:=copyout(@submit_eop,data^.eop_val,SizeOf(QWORD));
|
||||
end;
|
||||
|
||||
if (data^.rout<>nil) then
|
||||
begin
|
||||
ures:=Result;
|
||||
|
|
|
@ -6,7 +6,7 @@ unit dev_dipsw;
|
|||
interface
|
||||
|
||||
uses
|
||||
kern_conf;
|
||||
sys_conf;
|
||||
|
||||
procedure dipsw_init();
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ unit dev_dmem;
|
|||
interface
|
||||
|
||||
uses
|
||||
kern_conf;
|
||||
sys_conf;
|
||||
|
||||
procedure dmemdev_init();
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ unit dev_gc;
|
|||
interface
|
||||
|
||||
uses
|
||||
kern_conf;
|
||||
sys_conf;
|
||||
|
||||
procedure gc_initialize();
|
||||
|
||||
|
@ -16,7 +16,6 @@ uses
|
|||
errno,
|
||||
kern_mtx,
|
||||
sys_event,
|
||||
kern_event,
|
||||
kern_authinfo,
|
||||
vm,
|
||||
vmparam,
|
||||
|
@ -265,6 +264,8 @@ var
|
|||
cap:Boolean;
|
||||
unk:Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
|
||||
event_id:=Byte(kn^.kn_data);
|
||||
|
||||
cap:=sceSblACMgrHasUseHp3dPipeCapability(@g_authinfo);
|
||||
|
@ -333,7 +334,7 @@ begin
|
|||
begin
|
||||
Result:=1;
|
||||
|
||||
event_id:=PByte(@kn^.kn_kevent.data)[1];
|
||||
event_id:=Byte(kn^.kn_kevent.data shr 8);
|
||||
|
||||
kn^.kn_kevent.data:=(hint and QWORD($ffffffffffff00ff)) or
|
||||
(QWORD(event_id) shl 8);
|
||||
|
|
|
@ -6,7 +6,7 @@ unit dev_null;
|
|||
interface
|
||||
|
||||
uses
|
||||
kern_conf;
|
||||
sys_conf;
|
||||
|
||||
const
|
||||
ZERO_REGION_SIZE=(2 * 1024 * 1024); // 2MB
|
||||
|
|
|
@ -6,7 +6,7 @@ unit dev_rng;
|
|||
interface
|
||||
|
||||
uses
|
||||
kern_conf;
|
||||
sys_conf;
|
||||
|
||||
procedure rng_init();
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ uses
|
|||
sysutils,
|
||||
vselinfo,
|
||||
kern_thr,
|
||||
kern_conf,
|
||||
sys_conf,
|
||||
sys_tty;
|
||||
|
||||
var
|
||||
|
|
|
@ -0,0 +1,235 @@
|
|||
unit devfs_int;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
{$CALLING SysV_ABI_CDecl}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
mqueue,
|
||||
time,
|
||||
vfile,
|
||||
vdirent,
|
||||
vnode,
|
||||
vmount,
|
||||
sys_conf,
|
||||
kern_mtx,
|
||||
kern_sx;
|
||||
|
||||
const
|
||||
DEVFS_MAGIC=$db0a087a;
|
||||
|
||||
{
|
||||
* Identifiers. The ruleset and rule numbers are 16-bit values. The
|
||||
* "rule ID" is a combination of the ruleset and rule number; it
|
||||
* should be able to univocally describe a rule in the system. In
|
||||
* this implementation, the upper 16 bits of the rule ID is the
|
||||
* ruleset number; the lower 16 bits, the rule number within the
|
||||
* aforementioned ruleset.
|
||||
}
|
||||
type
|
||||
p_devfs_rnum=^devfs_rnum;
|
||||
devfs_rnum=WORD;
|
||||
|
||||
p_devfs_rsnum=^devfs_rsnum;
|
||||
devfs_rsnum=WORD;
|
||||
|
||||
p_devfs_rid=^devfs_rid;
|
||||
devfs_rid=DWORD;
|
||||
|
||||
ino_t=Integer;
|
||||
|
||||
const
|
||||
DRC_DSWFLAGS =$001;
|
||||
DRC_PATHPTRN =$002;
|
||||
DEVFS_MAXPTRNLEN=200;
|
||||
|
||||
DRA_BACTS =$001;
|
||||
DRA_UID =$002;
|
||||
DRA_GID =$004;
|
||||
DRA_MODE =$008;
|
||||
DRA_INCSET=$010;
|
||||
|
||||
DRB_HIDE =$001; { Hide entry (DE_WHITEOUT). }
|
||||
DRB_UNHIDE=$002; { Unhide entry. }
|
||||
|
||||
{
|
||||
* Plain DEVFS rule. This gets shared between kernel and userland
|
||||
* verbatim, so it shouldn't contain any pointers or other kernel- or
|
||||
* userland-specific values.
|
||||
}
|
||||
type
|
||||
p_devfs_rule=^t_devfs_rule;
|
||||
t_devfs_rule=packed record
|
||||
dr_magic:DWORD; { Magic number. }
|
||||
dr_id :devfs_rid; { Identifier. }
|
||||
|
||||
{
|
||||
* Conditions under which this rule should be applied. These
|
||||
* are ANDed together since OR can be simulated by using
|
||||
* multiple rules. dr_icond determines which of the other
|
||||
* variables we should process.
|
||||
}
|
||||
dr_icond:Integer;
|
||||
|
||||
dr_dswflags:Integer; { cdevsw flags to match. }
|
||||
|
||||
dr_pathptrn:array[0..DEVFS_MAXPTRNLEN-1] of AnsiChar; { Pattern to match path. }
|
||||
|
||||
{
|
||||
* Things to change. dr_iacts determines which of the other
|
||||
* variables we should process.
|
||||
}
|
||||
dr_iacts:Integer;
|
||||
|
||||
dr_bacts:Integer; { Boolean (on/off) action. }
|
||||
|
||||
dr_uid :uid_t;
|
||||
dr_gid :gid_t;
|
||||
dr_mode :mode_t;
|
||||
dr_incset:devfs_rsnum; { Included ruleset. }
|
||||
end;
|
||||
|
||||
const
|
||||
{
|
||||
* Rule-related ioctls.
|
||||
}
|
||||
DEVFSIO_RADD =$C0F04400;
|
||||
DEVFSIO_RDEL =$80044401;
|
||||
DEVFSIO_RAPPLY =$80F04402;
|
||||
DEVFSIO_RAPPLYID=$80044403;
|
||||
DEVFSIO_RGETNEXT=$C0F04404;
|
||||
|
||||
DEVFSIO_SUSE =$8002440A;
|
||||
DEVFSIO_SAPPLY =$8002440B;
|
||||
DEVFSIO_SGETNEXT=$C002440C;
|
||||
|
||||
{ XXX: DEVFSIO_RS_GET_INFO for refcount, active if any, etc. }
|
||||
|
||||
DE_WHITEOUT=$01;
|
||||
DE_DOT =$02;
|
||||
DE_DOTDOT =$04;
|
||||
DE_DOOMED =$08;
|
||||
DE_COVERED =$10;
|
||||
DE_USER =$20;
|
||||
|
||||
CDP_ACTIVE =(1 shl 0);
|
||||
CDP_SCHED_DTR=(1 shl 1);
|
||||
CDP_UNREF_DTR=(1 shl 2);
|
||||
|
||||
type
|
||||
t_cdpd_dtr=procedure(P:Pointer);
|
||||
|
||||
p_cdev_privdata=^t_cdev_privdata;
|
||||
t_cdev_privdata=packed record
|
||||
cdpd_fp :p_file;
|
||||
cdpd_data:Pointer;
|
||||
cdpd_dtr :t_cdpd_dtr;
|
||||
cdpd_list:LIST_ENTRY; //cdev_privdata
|
||||
end;
|
||||
|
||||
pp_devfs_dirent=^p_devfs_dirent;
|
||||
p_devfs_dirent=^t_devfs_dirent;
|
||||
|
||||
p_cdev_priv=^t_cdev_priv;
|
||||
t_cdev_priv=packed record
|
||||
cdp_c:t_cdev;
|
||||
cdp_list:TAILQ_ENTRY; //cdev_priv
|
||||
|
||||
cdp_inode:DWORD;
|
||||
cdp_flags:DWORD;
|
||||
|
||||
cdp_inuse :DWORD;
|
||||
cdp_maxdirent:DWORD;
|
||||
|
||||
cdp_dirents:pp_devfs_dirent;
|
||||
cdp_dirent0:p_devfs_dirent;
|
||||
|
||||
cdp_dtr_list:TAILQ_ENTRY; //cdev_priv
|
||||
|
||||
cdp_dtr_cb :t_cdpd_dtr;
|
||||
cdp_dtr_cb_arg:Pointer;
|
||||
|
||||
cdp_fdpriv:LIST_HEAD; //cdev_privdata
|
||||
end;
|
||||
|
||||
devfs_dlist_head=TAILQ_HEAD; //devfs_dirent
|
||||
|
||||
t_devfs_dirent=record
|
||||
de_cdp :p_cdev_priv;
|
||||
de_inode :Integer;
|
||||
de_flags :Integer;
|
||||
de_holdcnt:Integer;
|
||||
de_dirent :p_dirent;
|
||||
de_list :TAILQ_ENTRY;
|
||||
de_dlist :devfs_dlist_head;
|
||||
de_dir :p_devfs_dirent;
|
||||
de_links :Integer;
|
||||
de_mode :mode_t;
|
||||
de_uid :uid_t;
|
||||
de_gid :gid_t;
|
||||
//label *de_label;
|
||||
de_atime :timespec;
|
||||
de_mtime :timespec;
|
||||
de_ctime :timespec;
|
||||
de_vnode :p_vnode;
|
||||
de_symlink:PChar;
|
||||
end;
|
||||
|
||||
p_devfs_mount=^t_devfs_mount;
|
||||
t_devfs_mount=record
|
||||
dm_idx :DWORD ;
|
||||
dm_mount :p_mount ;
|
||||
dm_rootdir :p_devfs_dirent;
|
||||
dm_generation:DWORD ;
|
||||
dm_holdcnt :Integer ;
|
||||
dm_lock :t_sx ;
|
||||
dm_ruleset :devfs_rsnum ;
|
||||
end;
|
||||
|
||||
const
|
||||
DEVFS_ROOTINO=2;
|
||||
|
||||
DEVFS_DEL_VNLOCKED =$01;
|
||||
DEVFS_DEL_NORECURSE=$02;
|
||||
|
||||
var
|
||||
devfs_rule_depth:DWORD=0;
|
||||
|
||||
type
|
||||
p_dirlistent=^t_dirlistent;
|
||||
t_dirlistent=record
|
||||
dir :PChar;
|
||||
refcnt:Integer;
|
||||
link :LIST_ENTRY; //dirlistent
|
||||
end;
|
||||
|
||||
var
|
||||
devfs_dirlist:LIST_HEAD=(lh_first:nil); //dirlistent
|
||||
dirlist_mtx :mtx; //MTX_SYSINIT(dirlist_mtx, &dirlist_mtx, "devfs dirlist lock", MTX_DEF);
|
||||
|
||||
devfs_de_interlock:mtx; //MTX_SYSINIT(devfs_de_interlock, @devfs_de_interlock, 'devfs interlock', MTX_DEF);
|
||||
cdevpriv_mtx :mtx; //MTX_SYSINIT(cdevpriv_mtx, @cdevpriv_mtx, 'cdevpriv lock', MTX_DEF);
|
||||
clone_drain_lock :t_sx=(n:'clone events drain lock';c:nil;m:0);
|
||||
|
||||
devfs_generation:DWORD=0;
|
||||
|
||||
var
|
||||
cdevp_list:TAILQ_HEAD=(tqh_first:nil;tqh_last:@cdevp_list.tqh_first);
|
||||
|
||||
function devfs_alloc(flags:Integer):p_cdev; external;
|
||||
function devfs_dev_exists(name:PChar):Integer; external;
|
||||
procedure devfs_free(cdev:p_cdev); external;
|
||||
procedure devfs_create(dev:p_cdev); external;
|
||||
procedure devfs_destroy(dev:p_cdev); external;
|
||||
procedure devfs_destroy_cdevpriv(p:p_cdev_privdata); external;
|
||||
|
||||
function devfs_dir_find(path:PChar):Integer; external;
|
||||
procedure devfs_dir_ref_de(dm:p_devfs_mount;de:p_devfs_dirent); external;
|
||||
procedure devfs_dir_unref_de(dm:p_devfs_mount;de:p_devfs_dirent); external;
|
||||
function devfs_pathpath(p1,p2:PChar):Integer; external;
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
||||
|
|
@ -65,7 +65,8 @@ type
|
|||
function SubmitBufferAttribute (attrid:Byte;attr:p_register_buffer_attr):Integer; virtual;
|
||||
function RegisterBuffer (buf:p_register_buffer):Integer; virtual;
|
||||
function UnregisterBuffer (index:Integer):Integer; virtual;
|
||||
function SubmitFlip (submit:p_submit_flip;eop_val:PQWORD):Integer; virtual;
|
||||
function SubmitFlip (submit:p_submit_flip):Integer; virtual;
|
||||
function SubmitFlipEop (submit:p_submit_flip;submit_id:QWORD):Integer; virtual;
|
||||
end;
|
||||
|
||||
TDisplayInterface=class
|
||||
|
@ -118,11 +119,15 @@ begin
|
|||
Result:=0;
|
||||
end;
|
||||
|
||||
function TDisplayHandle.SubmitFlip(submit:p_submit_flip;eop_val:PQWORD):Integer;
|
||||
function TDisplayHandle.SubmitFlip(submit:p_submit_flip):Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function TDisplayHandle.SubmitFlipEop(submit:p_submit_flip;submit_id:QWORD):Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
|
|
@ -7,196 +7,13 @@ interface
|
|||
|
||||
uses
|
||||
sysutils,
|
||||
devfs_int,
|
||||
mqueue,
|
||||
kern_param,
|
||||
vfile,
|
||||
vdirent,
|
||||
vnode,
|
||||
vmount,
|
||||
time,
|
||||
kern_conf,
|
||||
kern_mtx,
|
||||
kern_sx;
|
||||
|
||||
const
|
||||
DEVFS_MAGIC=$db0a087a;
|
||||
|
||||
{
|
||||
* Identifiers. The ruleset and rule numbers are 16-bit values. The
|
||||
* "rule ID" is a combination of the ruleset and rule number; it
|
||||
* should be able to univocally describe a rule in the system. In
|
||||
* this implementation, the upper 16 bits of the rule ID is the
|
||||
* ruleset number; the lower 16 bits, the rule number within the
|
||||
* aforementioned ruleset.
|
||||
}
|
||||
type
|
||||
p_devfs_rnum=^devfs_rnum;
|
||||
devfs_rnum=WORD;
|
||||
|
||||
p_devfs_rsnum=^devfs_rsnum;
|
||||
devfs_rsnum=WORD;
|
||||
|
||||
p_devfs_rid=^devfs_rid;
|
||||
devfs_rid=DWORD;
|
||||
|
||||
ino_t=Integer;
|
||||
|
||||
const
|
||||
DRC_DSWFLAGS =$001;
|
||||
DRC_PATHPTRN =$002;
|
||||
DEVFS_MAXPTRNLEN=200;
|
||||
|
||||
DRA_BACTS =$001;
|
||||
DRA_UID =$002;
|
||||
DRA_GID =$004;
|
||||
DRA_MODE =$008;
|
||||
DRA_INCSET=$010;
|
||||
|
||||
DRB_HIDE =$001; { Hide entry (DE_WHITEOUT). }
|
||||
DRB_UNHIDE=$002; { Unhide entry. }
|
||||
|
||||
{
|
||||
* Plain DEVFS rule. This gets shared between kernel and userland
|
||||
* verbatim, so it shouldn't contain any pointers or other kernel- or
|
||||
* userland-specific values.
|
||||
}
|
||||
type
|
||||
p_devfs_rule=^t_devfs_rule;
|
||||
t_devfs_rule=packed record
|
||||
dr_magic:DWORD; { Magic number. }
|
||||
dr_id :devfs_rid; { Identifier. }
|
||||
|
||||
{
|
||||
* Conditions under which this rule should be applied. These
|
||||
* are ANDed together since OR can be simulated by using
|
||||
* multiple rules. dr_icond determines which of the other
|
||||
* variables we should process.
|
||||
}
|
||||
dr_icond:Integer;
|
||||
|
||||
dr_dswflags:Integer; { cdevsw flags to match. }
|
||||
|
||||
dr_pathptrn:array[0..DEVFS_MAXPTRNLEN-1] of AnsiChar; { Pattern to match path. }
|
||||
|
||||
{
|
||||
* Things to change. dr_iacts determines which of the other
|
||||
* variables we should process.
|
||||
}
|
||||
dr_iacts:Integer;
|
||||
|
||||
dr_bacts:Integer; { Boolean (on/off) action. }
|
||||
|
||||
dr_uid :uid_t;
|
||||
dr_gid :gid_t;
|
||||
dr_mode :mode_t;
|
||||
dr_incset:devfs_rsnum; { Included ruleset. }
|
||||
end;
|
||||
|
||||
const
|
||||
{
|
||||
* Rule-related ioctls.
|
||||
}
|
||||
DEVFSIO_RADD =$C0F04400;
|
||||
DEVFSIO_RDEL =$80044401;
|
||||
DEVFSIO_RAPPLY =$80F04402;
|
||||
DEVFSIO_RAPPLYID=$80044403;
|
||||
DEVFSIO_RGETNEXT=$C0F04404;
|
||||
|
||||
DEVFSIO_SUSE =$8002440A;
|
||||
DEVFSIO_SAPPLY =$8002440B;
|
||||
DEVFSIO_SGETNEXT=$C002440C;
|
||||
|
||||
{ XXX: DEVFSIO_RS_GET_INFO for refcount, active if any, etc. }
|
||||
|
||||
DE_WHITEOUT=$01;
|
||||
DE_DOT =$02;
|
||||
DE_DOTDOT =$04;
|
||||
DE_DOOMED =$08;
|
||||
DE_COVERED =$10;
|
||||
DE_USER =$20;
|
||||
|
||||
CDP_ACTIVE =(1 shl 0);
|
||||
CDP_SCHED_DTR=(1 shl 1);
|
||||
CDP_UNREF_DTR=(1 shl 2);
|
||||
|
||||
type
|
||||
t_cdpd_dtr=procedure(P:Pointer);
|
||||
|
||||
p_cdev_privdata=^t_cdev_privdata;
|
||||
t_cdev_privdata=packed record
|
||||
cdpd_fp :p_file;
|
||||
cdpd_data:Pointer;
|
||||
cdpd_dtr :t_cdpd_dtr;
|
||||
cdpd_list:LIST_ENTRY; //cdev_privdata
|
||||
end;
|
||||
|
||||
pp_devfs_dirent=^p_devfs_dirent;
|
||||
p_devfs_dirent=^t_devfs_dirent;
|
||||
|
||||
p_cdev_priv=^t_cdev_priv;
|
||||
t_cdev_priv=packed record
|
||||
cdp_c:t_cdev;
|
||||
cdp_list:TAILQ_ENTRY; //cdev_priv
|
||||
|
||||
cdp_inode:DWORD;
|
||||
cdp_flags:DWORD;
|
||||
|
||||
cdp_inuse :DWORD;
|
||||
cdp_maxdirent:DWORD;
|
||||
|
||||
cdp_dirents:pp_devfs_dirent;
|
||||
cdp_dirent0:p_devfs_dirent;
|
||||
|
||||
cdp_dtr_list:TAILQ_ENTRY; //cdev_priv
|
||||
|
||||
cdp_dtr_cb :t_cdpd_dtr;
|
||||
cdp_dtr_cb_arg:Pointer;
|
||||
|
||||
cdp_fdpriv:LIST_HEAD; //cdev_privdata
|
||||
end;
|
||||
|
||||
devfs_dlist_head=TAILQ_HEAD; //devfs_dirent
|
||||
|
||||
t_devfs_dirent=record
|
||||
de_cdp :p_cdev_priv;
|
||||
de_inode :Integer;
|
||||
de_flags :Integer;
|
||||
de_holdcnt:Integer;
|
||||
de_dirent :p_dirent;
|
||||
de_list :TAILQ_ENTRY;
|
||||
de_dlist :devfs_dlist_head;
|
||||
de_dir :p_devfs_dirent;
|
||||
de_links :Integer;
|
||||
de_mode :mode_t;
|
||||
de_uid :uid_t;
|
||||
de_gid :gid_t;
|
||||
//label *de_label;
|
||||
de_atime :timespec;
|
||||
de_mtime :timespec;
|
||||
de_ctime :timespec;
|
||||
de_vnode :p_vnode;
|
||||
de_symlink:PChar;
|
||||
end;
|
||||
|
||||
p_devfs_mount=^t_devfs_mount;
|
||||
t_devfs_mount=record
|
||||
dm_idx :DWORD ;
|
||||
dm_mount :p_mount ;
|
||||
dm_rootdir :p_devfs_dirent;
|
||||
dm_generation:DWORD ;
|
||||
dm_holdcnt :Integer ;
|
||||
dm_lock :t_sx ;
|
||||
dm_ruleset :devfs_rsnum ;
|
||||
end;
|
||||
|
||||
const
|
||||
DEVFS_ROOTINO=2;
|
||||
|
||||
DEVFS_DEL_VNLOCKED =$01;
|
||||
DEVFS_DEL_NORECURSE=$02;
|
||||
|
||||
var
|
||||
devfs_rule_depth:DWORD=0;
|
||||
sys_conf,
|
||||
kern_mtx;
|
||||
|
||||
function rid2rsn(rid:devfs_rid):devfs_rsnum;
|
||||
function rid2rn (rid:devfs_rid):devfs_rnum;
|
||||
|
@ -210,58 +27,38 @@ function DEVFS_DMP_DROP(dmp:p_devfs_mount):Boolean;
|
|||
|
||||
//
|
||||
|
||||
type
|
||||
p_dirlistent=^t_dirlistent;
|
||||
t_dirlistent=record
|
||||
dir :PChar;
|
||||
refcnt:Integer;
|
||||
link :LIST_ENTRY; //dirlistent
|
||||
end;
|
||||
|
||||
var
|
||||
devfs_dirlist:LIST_HEAD=(lh_first:nil); //dirlistent
|
||||
dirlist_mtx :mtx; //MTX_SYSINIT(dirlist_mtx, &dirlist_mtx, "devfs dirlist lock", MTX_DEF);
|
||||
|
||||
devfs_de_interlock:mtx; //MTX_SYSINIT(devfs_de_interlock, @devfs_de_interlock, 'devfs interlock', MTX_DEF);
|
||||
cdevpriv_mtx :mtx; //MTX_SYSINIT(cdevpriv_mtx, @cdevpriv_mtx, 'cdevpriv lock', MTX_DEF);
|
||||
clone_drain_lock :t_sx=(n:'clone events drain lock';c:nil;m:0);
|
||||
|
||||
devfs_generation:DWORD=0;
|
||||
|
||||
function devfs_dir_find(path:PChar):Integer;
|
||||
function devfs_dir_findent_locked(dir:PChar):p_dirlistent;
|
||||
procedure devfs_dir_ref(dir:PChar);
|
||||
procedure devfs_dir_ref_de(dm:p_devfs_mount;de:p_devfs_dirent);
|
||||
procedure devfs_dir_unref(dir:PChar);
|
||||
procedure devfs_dir_unref_de(dm:p_devfs_mount;de:p_devfs_dirent);
|
||||
function devfs_pathpath(p1,p2:PChar):Integer;
|
||||
procedure devfs_mtx_init;
|
||||
|
||||
var
|
||||
cdevp_list:TAILQ_HEAD=(tqh_first:nil;tqh_last:@cdevp_list.tqh_first);
|
||||
|
||||
function devfs_alloc(flags:Integer):p_cdev; external;
|
||||
function devfs_dev_exists(name:PChar):Integer; external;
|
||||
procedure devfs_free(cdev:p_cdev); external;
|
||||
function devfs_find(dd:p_devfs_dirent;name:PChar;namelen:Integer;_type:Integer):p_devfs_dirent; external;
|
||||
function devfs_newdirent(name:PChar;namelen:Integer):p_devfs_dirent; external;
|
||||
function devfs_parent_dirent(de:p_devfs_dirent):p_devfs_dirent; external;
|
||||
function devfs_vmkdir(dmp:p_devfs_mount;name:PChar;namelen:Integer;dotdot:p_devfs_dirent;inode:DWORD):p_devfs_dirent; external;
|
||||
procedure devfs_dirent_free(de:p_devfs_dirent); external;
|
||||
procedure devfs_rmdir_empty(dm:p_devfs_mount;de:p_devfs_dirent); external;
|
||||
procedure devfs_delete(dm:p_devfs_mount;de:p_devfs_dirent;flags:Integer); external;
|
||||
procedure devfs_purge(dm:p_devfs_mount;dd:p_devfs_dirent); external;
|
||||
procedure devfs_metoo(cdp:p_cdev_priv;dm:p_devfs_mount); external;
|
||||
function devfs_populate_loop(dm:p_devfs_mount;cleanup:Integer):Integer; external;
|
||||
procedure devfs_populate(dm:p_devfs_mount); external;
|
||||
procedure devfs_cleanup(dm:p_devfs_mount); external;
|
||||
procedure devfs_create(dev:p_cdev); external;
|
||||
procedure devfs_destroy(dev:p_cdev); external;
|
||||
function devfs_alloc_cdp_inode():ino_t; external;
|
||||
procedure devfs_free_cdp_inode(ino:ino_t); external;
|
||||
procedure devfs_rules_apply(dm:p_devfs_mount;de:p_devfs_dirent); external;
|
||||
procedure devfs_rules_cleanup(dm:p_devfs_mount); external;
|
||||
function devfs_rules_ioctl(dm:p_devfs_mount;cmd:QWORD;data:Pointer):Integer; external;
|
||||
|
||||
procedure devfs_ruleset_set(rsnum:devfs_rsnum;dm:p_devfs_mount); external;
|
||||
procedure devfs_ruleset_apply(dm:p_devfs_mount); external;
|
||||
function devfs_allocv(de:p_devfs_dirent;mp:p_mount;lockmode:Integer;vpp:pp_vnode):Integer; external;
|
||||
function devfs_fqpn(buf:PChar;dmp:p_devfs_mount;dd:p_devfs_dirent;cnp:Pointer):PChar; external;
|
||||
|
||||
procedure devfs_delete(dm:p_devfs_mount;de:p_devfs_dirent;flags:Integer); external;
|
||||
procedure devfs_dirent_free(de:p_devfs_dirent); external;
|
||||
procedure devfs_populate(dm:p_devfs_mount); external;
|
||||
procedure devfs_cleanup(dm:p_devfs_mount); external;
|
||||
|
||||
procedure devfs_unmount_final(fmp:p_devfs_mount); external;
|
||||
|
||||
function devfs_newdirent(name:PChar;namelen:Integer):p_devfs_dirent; external;
|
||||
function devfs_parent_dirent(de:p_devfs_dirent):p_devfs_dirent; external;
|
||||
function devfs_vmkdir(dmp:p_devfs_mount;
|
||||
name:PChar;namelen:Integer;
|
||||
dotdot:p_devfs_dirent;
|
||||
inode:DWORD):p_devfs_dirent; external;
|
||||
function devfs_find(dd:p_devfs_dirent;
|
||||
name:PChar;namelen:Integer;
|
||||
_type:Integer):p_devfs_dirent; external;
|
||||
|
||||
implementation
|
||||
|
||||
{
|
||||
|
@ -307,7 +104,7 @@ end;
|
|||
//
|
||||
|
||||
{ Exits 1 if the path is in the directory list. }
|
||||
function devfs_dir_find(path:PChar):Integer;
|
||||
function devfs_dir_find(path:PChar):Integer; public;
|
||||
var
|
||||
dle:p_dirlistent;
|
||||
begin
|
||||
|
@ -414,7 +211,7 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure devfs_dir_unref_de(dm:p_devfs_mount;de:p_devfs_dirent);
|
||||
procedure devfs_dir_unref_de(dm:p_devfs_mount;de:p_devfs_dirent); public;
|
||||
var
|
||||
dirname:array[0..SPECNAMELEN] of AnsiChar;
|
||||
namep:PChar;
|
||||
|
@ -426,7 +223,7 @@ begin
|
|||
end;
|
||||
|
||||
{ Exits 1 if the path p1 contains the path p2. }
|
||||
function devfs_pathpath(p1,p2:PChar):Integer;
|
||||
function devfs_pathpath(p1,p2:PChar):Integer; public;
|
||||
begin
|
||||
repeat
|
||||
if (p1^<>p2^) then
|
||||
|
|
|
@ -8,7 +8,8 @@ interface
|
|||
uses
|
||||
mqueue,
|
||||
kern_id,
|
||||
kern_conf,
|
||||
sys_conf,
|
||||
devfs_int,
|
||||
devfs;
|
||||
|
||||
function devfs_alloc(flags:Integer):p_cdev;
|
||||
|
@ -42,8 +43,7 @@ uses
|
|||
kern_sx,
|
||||
vfs_vnops,
|
||||
vfs_subr,
|
||||
vnode_if,
|
||||
devfs_rule;
|
||||
vnode_if;
|
||||
|
||||
var
|
||||
devfs_desc:t_id_desc=(free:nil;refs:0);
|
||||
|
|
|
@ -8,7 +8,8 @@ interface
|
|||
uses
|
||||
mqueue,
|
||||
kern_param,
|
||||
kern_conf,
|
||||
sys_conf,
|
||||
devfs_int,
|
||||
devfs,
|
||||
kern_sx;
|
||||
|
||||
|
@ -84,7 +85,7 @@ uses
|
|||
* exposed to the userland. This should be called with an exclusive
|
||||
* lock on dm in case we need to run anything.
|
||||
}
|
||||
procedure devfs_rules_apply(dm:p_devfs_mount;de:p_devfs_dirent);
|
||||
procedure devfs_rules_apply(dm:p_devfs_mount;de:p_devfs_dirent); public;
|
||||
var
|
||||
ds:p_devfs_ruleset;
|
||||
begin
|
||||
|
@ -104,7 +105,7 @@ end;
|
|||
{
|
||||
* Rule subsystem ioctl hook.
|
||||
}
|
||||
function devfs_rules_ioctl(dm:p_devfs_mount;cmd:QWORD;data:Pointer):Integer;
|
||||
function devfs_rules_ioctl(dm:p_devfs_mount;cmd:QWORD;data:Pointer):Integer; public;
|
||||
label
|
||||
_break;
|
||||
var
|
||||
|
@ -807,7 +808,7 @@ begin
|
|||
Exit(0);
|
||||
end;
|
||||
|
||||
procedure devfs_rules_cleanup(dm:p_devfs_mount);
|
||||
procedure devfs_rules_cleanup(dm:p_devfs_mount); public;
|
||||
var
|
||||
ds:p_devfs_ruleset;
|
||||
begin
|
||||
|
@ -823,7 +824,7 @@ end;
|
|||
{
|
||||
* Make rsnum the active ruleset for dm (locked)
|
||||
}
|
||||
procedure devfs_ruleset_set(rsnum:devfs_rsnum;dm:p_devfs_mount);
|
||||
procedure devfs_ruleset_set(rsnum:devfs_rsnum;dm:p_devfs_mount); public;
|
||||
begin
|
||||
sx_assert(@dm^.dm_lock);
|
||||
sx_xlock(@sx_rules);
|
||||
|
@ -834,7 +835,7 @@ end;
|
|||
{
|
||||
* Apply the current active ruleset on a mount
|
||||
}
|
||||
procedure devfs_ruleset_apply(dm:p_devfs_mount);
|
||||
procedure devfs_ruleset_apply(dm:p_devfs_mount); public;
|
||||
var
|
||||
ds:p_devfs_ruleset;
|
||||
begin
|
||||
|
|
|
@ -9,6 +9,7 @@ uses
|
|||
kern_param,
|
||||
vnode,
|
||||
vmount,
|
||||
devfs_int,
|
||||
devfs,
|
||||
kern_id;
|
||||
|
||||
|
@ -66,13 +67,7 @@ uses
|
|||
vfs_mount,
|
||||
vfs_subr,
|
||||
vnode_if,
|
||||
devfs_rule;
|
||||
|
||||
//
|
||||
|
||||
function devfs_allocv(de:p_devfs_dirent;mp:p_mount;lockmode:Integer;vpp:pp_vnode):Integer; external;
|
||||
|
||||
//
|
||||
devfs_devs;
|
||||
|
||||
var
|
||||
unr_desc:t_id_desc=(free:nil;refs:0);
|
||||
|
@ -217,7 +212,7 @@ begin
|
|||
Exit(0);
|
||||
end;
|
||||
|
||||
procedure devfs_unmount_final(fmp:p_devfs_mount);
|
||||
procedure devfs_unmount_final(fmp:p_devfs_mount); public;
|
||||
begin
|
||||
sx_destroy(@fmp^.dm_lock);
|
||||
FreeMem(fmp);
|
||||
|
|
|
@ -23,10 +23,11 @@ uses
|
|||
vnode_if,
|
||||
vfs_default,
|
||||
vfs_vnops,
|
||||
devfs_int,
|
||||
devfs,
|
||||
kern_mtx,
|
||||
kern_sx,
|
||||
kern_conf;
|
||||
sys_conf;
|
||||
|
||||
function devfs_fp_check(fp:p_file;devp:pp_cdev;dswp:pp_cdevsw;ref:PInteger):Integer;
|
||||
function devfs_get_cdevpriv(datap:PPointer):Integer;
|
||||
|
@ -200,8 +201,7 @@ uses
|
|||
kern_thr,
|
||||
vfs_subr,
|
||||
vsys_generic,
|
||||
devfs_rule,
|
||||
devfs_vfsops,
|
||||
//devfs_vfsops,
|
||||
kern_proc,
|
||||
kern_descrip,
|
||||
kern_mtxpool,
|
||||
|
@ -236,7 +236,7 @@ begin
|
|||
Exit(0);
|
||||
end;
|
||||
|
||||
function devfs_get_cdevpriv(datap:PPointer):Integer;
|
||||
function devfs_get_cdevpriv(datap:PPointer):Integer; public;
|
||||
var
|
||||
fp:p_file;
|
||||
p:p_cdev_privdata;
|
||||
|
@ -258,7 +258,7 @@ begin
|
|||
Exit(error);
|
||||
end;
|
||||
|
||||
function devfs_set_cdevpriv(priv:Pointer;priv_dtr:cdevpriv_dtr_t):Integer;
|
||||
function devfs_set_cdevpriv(priv:Pointer;priv_dtr:cdevpriv_dtr_t):Integer; public;
|
||||
var
|
||||
fp:p_file;
|
||||
cdp:p_cdev_priv;
|
||||
|
@ -289,7 +289,7 @@ begin
|
|||
Exit(error);
|
||||
end;
|
||||
|
||||
procedure devfs_destroy_cdevpriv(p:p_cdev_privdata);
|
||||
procedure devfs_destroy_cdevpriv(p:p_cdev_privdata); public;
|
||||
begin
|
||||
mtx_assert(cdevpriv_mtx);
|
||||
p^.cdpd_fp^.f_cdevpriv:=nil;
|
||||
|
@ -299,7 +299,7 @@ begin
|
|||
FreeMem(p);
|
||||
end;
|
||||
|
||||
procedure devfs_fpdrop(fp:p_file);
|
||||
procedure devfs_fpdrop(fp:p_file); public;
|
||||
var
|
||||
p:p_cdev_privdata;
|
||||
begin
|
||||
|
@ -313,7 +313,7 @@ begin
|
|||
devfs_destroy_cdevpriv(p);
|
||||
end;
|
||||
|
||||
procedure devfs_clear_cdevpriv();
|
||||
procedure devfs_clear_cdevpriv(); public;
|
||||
var
|
||||
fp:p_file;
|
||||
begin
|
||||
|
|
167
sys/host_ipc.pas
167
sys/host_ipc.pas
|
@ -6,17 +6,20 @@ interface
|
|||
|
||||
uses
|
||||
Classes,
|
||||
time,
|
||||
mqueue,
|
||||
LFQueue,
|
||||
kern_thr,
|
||||
kern_thread,
|
||||
sys_event,
|
||||
kern_mtx;
|
||||
|
||||
type
|
||||
t_mtype=(
|
||||
iRESULT,
|
||||
iMOUNT,
|
||||
iKNOTE
|
||||
iKEV_CHANGE,
|
||||
iKEV_EVENT,
|
||||
iMOUNT
|
||||
);
|
||||
|
||||
PNodeHeader=^TNodeHeader;
|
||||
|
@ -42,13 +45,6 @@ type
|
|||
tid :DWORD;
|
||||
end;
|
||||
|
||||
PHostIpcKnote=^THostIpcKnote;
|
||||
THostIpcKnote=packed record
|
||||
pid :Integer;
|
||||
filter:Integer;
|
||||
hint :QWORD
|
||||
end;
|
||||
|
||||
THostIpcHandler=class
|
||||
function OnMessage(mtype:t_mtype;mlen:DWORD;buf:Pointer):Ptruint; virtual;
|
||||
end;
|
||||
|
@ -58,6 +54,7 @@ type
|
|||
FQueue:TIntrusiveMPSCQueue;
|
||||
FWaits:LIST_HEAD;
|
||||
FWLock:mtx;
|
||||
Fkq:Pointer;
|
||||
procedure SyncResult(tid:DWORD;value:Ptruint);
|
||||
function NewNodeSync:PNodeIpcSync;
|
||||
procedure FreeNodeSync(node:PNodeIpcSync);
|
||||
|
@ -66,9 +63,12 @@ type
|
|||
function Recv:PQNode;
|
||||
procedure Flush;
|
||||
procedure RecvSync(node:PQNode);
|
||||
procedure RecvKevent(node:PQNode);
|
||||
procedure UpdateKevent();
|
||||
procedure WakeupKevent(); virtual;
|
||||
public
|
||||
//
|
||||
procedure knote(pid,filter:Integer;hint:QWORD);
|
||||
procedure kevent(kev:p_kevent;count:Integer);
|
||||
//
|
||||
function SendSync(mtype:t_mtype;mlen:DWORD;buf:Pointer):Ptruint;
|
||||
procedure SendAsyn(mtype:t_mtype;mlen:DWORD;buf:Pointer);
|
||||
|
@ -77,6 +77,8 @@ type
|
|||
//
|
||||
Constructor Create;
|
||||
Destructor Destroy; override;
|
||||
procedure thread_new; virtual;
|
||||
procedure thread_free; virtual;
|
||||
end;
|
||||
|
||||
THostIpcSimpleKERN=class;
|
||||
|
@ -93,15 +95,17 @@ type
|
|||
FHandler:THostIpcHandler;
|
||||
Constructor Create;
|
||||
Destructor Destroy; override;
|
||||
procedure thread_new; override;
|
||||
procedure thread_free; override;
|
||||
procedure Send(mtype:t_mtype;mlen,mtid:DWORD;buf:Pointer); override;
|
||||
procedure Update(Handler:THostIpcHandler); override;
|
||||
procedure WakeupKevent(); override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
function THostIpcHandler.OnMessage(mtype:t_mtype;mlen:DWORD;buf:Pointer):Ptruint;
|
||||
begin
|
||||
//
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
Constructor THostIpcConnect.Create;
|
||||
|
@ -115,9 +119,23 @@ Destructor THostIpcConnect.Destroy;
|
|||
begin
|
||||
Flush;
|
||||
mtx_destroy(FWLock);
|
||||
if (Fkq<>nil) then
|
||||
begin
|
||||
kqueue_close2(Fkq);
|
||||
end;
|
||||
inherited;
|
||||
end;
|
||||
|
||||
procedure THostIpcConnect.thread_new;
|
||||
begin
|
||||
//
|
||||
end;
|
||||
|
||||
procedure THostIpcConnect.thread_free;
|
||||
begin
|
||||
//
|
||||
end;
|
||||
|
||||
procedure THostIpcConnect.Pack(mtype:t_mtype;mlen,mtid:DWORD;buf:Pointer);
|
||||
var
|
||||
node:PQNode;
|
||||
|
@ -166,6 +184,64 @@ begin
|
|||
TriggerNodeSync(node^.header.mtid,value);
|
||||
end;
|
||||
|
||||
procedure kq_wakeup(data:Pointer); SysV_ABI_CDecl;
|
||||
begin
|
||||
THostIpcConnect(data).WakeupKevent();
|
||||
end;
|
||||
|
||||
procedure THostIpcConnect.RecvKevent(node:PQNode);
|
||||
var
|
||||
kev:p_kevent;
|
||||
value:Ptruint;
|
||||
count:Integer;
|
||||
begin
|
||||
kev :=@node^.buf;
|
||||
count:=node^.header.mlen div SizeOf(t_kevent);
|
||||
|
||||
Writeln('RecvKevent ',kev^.ident,' ',count);
|
||||
|
||||
if (Fkq=nil) then
|
||||
begin
|
||||
Fkq:=kern_kqueue2('[ipc]',@kq_wakeup,Pointer(Self));
|
||||
end;
|
||||
|
||||
//changelist
|
||||
value:=kern_kevent2(Fkq,kev,count,nil,0,nil,@count);
|
||||
|
||||
//is sync
|
||||
if (node^.header.mtid<>0) then
|
||||
begin
|
||||
SyncResult(node^.header.mtid,value);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure THostIpcConnect.UpdateKevent();
|
||||
var
|
||||
kev:array[0..7] of t_kevent;
|
||||
t:timespec;
|
||||
r:Integer;
|
||||
begin
|
||||
if (Fkq=nil) then Exit;
|
||||
t:=Default(timespec);
|
||||
|
||||
repeat
|
||||
|
||||
r:=0;
|
||||
kern_kevent2(Fkq,nil,0,@kev,8,@t,@r);
|
||||
|
||||
if (r>0) then
|
||||
begin
|
||||
SendAsyn(iKEV_EVENT,r*SizeOf(t_kevent),@kev);
|
||||
end;
|
||||
|
||||
until (r<>8);
|
||||
end;
|
||||
|
||||
procedure THostIpcConnect.WakeupKevent();
|
||||
begin
|
||||
//
|
||||
end;
|
||||
|
||||
procedure THostIpcConnect.Update(Handler:THostIpcHandler);
|
||||
var
|
||||
node:PQNode;
|
||||
|
@ -175,21 +251,25 @@ begin
|
|||
while (node<>nil) do
|
||||
begin
|
||||
//
|
||||
if (node^.header.mtype=DWORD(iRESULT)) then
|
||||
begin
|
||||
RecvSync(node);
|
||||
end else
|
||||
if (Handler<>nil) then
|
||||
begin
|
||||
value:=Handler.OnMessage(t_mtype(node^.header.mtype),node^.header.mlen,@node^.buf);
|
||||
|
||||
//is sync
|
||||
if (node^.header.mtid<>0) then
|
||||
begin
|
||||
SyncResult(node^.header.mtid,value);
|
||||
end;
|
||||
case t_mtype(node^.header.mtype) of
|
||||
iRESULT :RecvSync(node);
|
||||
iKEV_CHANGE:RecvKevent(node);
|
||||
|
||||
else
|
||||
if (Handler<>nil) then
|
||||
begin
|
||||
value:=Handler.OnMessage(t_mtype(node^.header.mtype),node^.header.mlen,@node^.buf);
|
||||
|
||||
//is sync
|
||||
if (node^.header.mtid<>0) then
|
||||
begin
|
||||
SyncResult(node^.header.mtid,value);
|
||||
end;
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
//
|
||||
FreeMem(node);
|
||||
//
|
||||
|
@ -204,15 +284,9 @@ begin
|
|||
Send(iRESULT,SizeOf(Ptruint),tid,@value);
|
||||
end;
|
||||
|
||||
procedure THostIpcConnect.knote(pid,filter:Integer;hint:QWORD);
|
||||
var
|
||||
note:THostIpcKnote;
|
||||
procedure THostIpcConnect.kevent(kev:p_kevent;count:Integer);
|
||||
begin
|
||||
note.pid :=pid;
|
||||
note.filter:=filter;
|
||||
note.hint :=hint;
|
||||
//
|
||||
SendAsyn(iKNOTE,SizeOf(note),@note);
|
||||
SendAsyn(iKEV_CHANGE,count*SizeOf(t_kevent),kev);
|
||||
end;
|
||||
|
||||
//
|
||||
|
@ -312,6 +386,10 @@ begin
|
|||
ipc:=THostIpcSimpleKERN(parameter);
|
||||
|
||||
repeat
|
||||
if ipc.FQueue.IsEmpty then
|
||||
begin
|
||||
RTLEventWaitFor(ipc.FEvent);
|
||||
end;
|
||||
ipc.Update(ipc.FHandler);
|
||||
until false;
|
||||
|
||||
|
@ -321,24 +399,30 @@ Constructor THostIpcSimpleKERN.Create;
|
|||
begin
|
||||
inherited;
|
||||
FEvent:=RTLEventCreate;
|
||||
Ftd:=nil;
|
||||
kthread_add(@simple_kern_thread,Self,@Ftd,'[ipc_pipe]');
|
||||
end;
|
||||
|
||||
Destructor THostIpcSimpleKERN.Destroy;
|
||||
begin
|
||||
thread_dec_ref(Ftd);
|
||||
thread_free;
|
||||
RTLEventDestroy(FEvent);
|
||||
inherited;
|
||||
end;
|
||||
|
||||
procedure THostIpcSimpleKERN.Update(Handler:THostIpcHandler);
|
||||
procedure THostIpcSimpleKERN.thread_new;
|
||||
begin
|
||||
if FQueue.IsEmpty then
|
||||
if (Ftd=nil) then
|
||||
begin
|
||||
RTLEventWaitFor(FEvent);
|
||||
kthread_add(@simple_kern_thread,Self,@Ftd,'[ipc_pipe]');
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure THostIpcSimpleKERN.thread_free;
|
||||
begin
|
||||
if (Ftd<>nil) then
|
||||
begin
|
||||
thread_dec_ref(Ftd);
|
||||
Ftd:=nil;
|
||||
end;
|
||||
inherited Update(Handler);
|
||||
end;
|
||||
|
||||
procedure THostIpcSimpleKERN.Send(mtype:t_mtype;mlen,mtid:DWORD;buf:Pointer);
|
||||
|
@ -355,5 +439,10 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure THostIpcSimpleKERN.WakeupKevent();
|
||||
begin
|
||||
UpdateKevent();
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ uses
|
|||
kern_descrip,
|
||||
vfile,
|
||||
vfcntl,
|
||||
kern_conf,
|
||||
sys_conf,
|
||||
vstat;
|
||||
|
||||
function blockpool_ioctl(fp:p_file;com:QWORD;data:Pointer):Integer;
|
||||
|
|
|
@ -99,18 +99,18 @@ function kqfd_register(fd:Integer;kev:p_kevent):Integer;
|
|||
|
||||
function sys_kqueue():Integer;
|
||||
function sys_kqueueex(name:PChar):Integer;
|
||||
function sys_kevent(fd:Integer;
|
||||
|
||||
function sys_kevent(fd :Integer;
|
||||
changelist:Pointer;
|
||||
nchanges:Integer;
|
||||
eventlist:Pointer;
|
||||
nevents:Integer;
|
||||
timeout:Pointer):Integer;
|
||||
nchanges :Integer;
|
||||
eventlist :Pointer;
|
||||
nevents :Integer;
|
||||
timeout :Pointer):Integer;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
errno,
|
||||
md_proc,
|
||||
md_time,
|
||||
kern_sig,
|
||||
kern_sx,
|
||||
|
@ -438,7 +438,7 @@ begin
|
|||
immediate:=1;
|
||||
end;
|
||||
|
||||
kn^.kn_ptr.p_proc:=nil;
|
||||
kn^.kn_ptr.p_proc:=@p_proc;
|
||||
kn^.kn_flags:=kn^.kn_flags or EV_CLEAR; { automatically set }
|
||||
|
||||
{
|
||||
|
@ -453,7 +453,7 @@ begin
|
|||
|
||||
if (immediate=0) then
|
||||
begin
|
||||
knlist_add(@p_proc.p_klist, kn, 1);
|
||||
knlist_add(@p_proc.p_klist, kn, 0);
|
||||
end;
|
||||
|
||||
{
|
||||
|
@ -843,7 +843,34 @@ end;
|
|||
|
||||
//
|
||||
|
||||
function kern_kqueue(pfd:PInteger;name:PAnsiChar):Integer;
|
||||
function kern_kqueue2(name:PAnsiChar;
|
||||
w_cb:t_kqueue_wakeup_cb;
|
||||
data:Pointer):p_kqueue; public;
|
||||
var
|
||||
kq:p_kqueue;
|
||||
begin
|
||||
kq:=AllocMem(SizeOf(t_kqueue));
|
||||
if (kq=nil) then Exit;
|
||||
|
||||
mtx_init(kq^.kq_lock, 'kqueue');
|
||||
TAILQ_INIT(@kq^.kq_head);
|
||||
//kq^.kq_fdp:=fdp;
|
||||
knlist_init_mtx(@kq^.kq_sel.si_note, @kq^.kq_lock);
|
||||
//TASK_INIT(@kq^.kq_task, 0, kqueue_task, kq);
|
||||
|
||||
if (name<>nil) then
|
||||
begin
|
||||
kq^.kq_name:=name;
|
||||
end;
|
||||
|
||||
kq^.kq_wakeup:=w_cb;
|
||||
kq^.kq_data :=data;
|
||||
|
||||
Result:=kq;
|
||||
end;
|
||||
|
||||
function kern_kqueue(pfd :PInteger;
|
||||
name:PAnsiChar):Integer;
|
||||
var
|
||||
kq:p_kqueue;
|
||||
fp:p_file;
|
||||
|
@ -856,18 +883,9 @@ begin
|
|||
if (error<>0) then Exit(error);
|
||||
|
||||
{ An extra reference on `nfp' has been held for us by falloc(). }
|
||||
kq:=AllocMem(SizeOf(t_kqueue));
|
||||
|
||||
mtx_init(kq^.kq_lock, 'kqueue');
|
||||
TAILQ_INIT(@kq^.kq_head);
|
||||
//kq^.kq_fdp:=fdp;
|
||||
knlist_init_mtx(@kq^.kq_sel.si_note, @kq^.kq_lock);
|
||||
//TASK_INIT(@kq^.kq_task, 0, kqueue_task, kq);
|
||||
|
||||
if (name<>nil) then
|
||||
begin
|
||||
kq^.kq_name:=name;
|
||||
end;
|
||||
kq:=kern_kqueue2(name,nil,nil);
|
||||
if (kq=nil) then Exit(ENOMEM);
|
||||
|
||||
FILEDESC_XLOCK(@fd_table);
|
||||
TAILQ_INSERT_HEAD(@fd_table.fd_kqlist, kq, @kq^.kq_list);
|
||||
|
@ -922,12 +940,10 @@ end;
|
|||
type
|
||||
p_kevent_args=^t_kevent_args;
|
||||
t_kevent_args=record
|
||||
fd :Integer;
|
||||
changelist:p_kevent;
|
||||
nchanges :Integer;
|
||||
eventlist :p_kevent;
|
||||
nevents :Integer;
|
||||
timeout :p_timespec;
|
||||
end;
|
||||
|
||||
{
|
||||
|
@ -949,6 +965,19 @@ begin
|
|||
Exit(error);
|
||||
end;
|
||||
|
||||
function kevent_copyout2(arg:Pointer;kevp:p_kevent;count:Integer):Integer;
|
||||
var
|
||||
uap:p_kevent_args;
|
||||
begin
|
||||
Assert(count <= KQ_NEVENTS, Format('count (%d) > KQ_NEVENTS', [count]));
|
||||
uap:=arg;
|
||||
|
||||
Move(kevp^,uap^.eventlist^,count*sizeof(t_kevent));
|
||||
|
||||
Inc(uap^.eventlist,count);
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
{
|
||||
* Copy 'count' items from the list pointed to by uap^.changelist.
|
||||
}
|
||||
|
@ -968,23 +997,97 @@ begin
|
|||
Exit(error);
|
||||
end;
|
||||
|
||||
function kevent_copyin2(arg:Pointer;kevp:p_kevent;count:Integer):Integer;
|
||||
var
|
||||
uap:p_kevent_args;
|
||||
begin
|
||||
Assert(count <= KQ_NEVENTS, Format('count (%d) > KQ_NEVENTS', [count]));
|
||||
uap:=arg;
|
||||
|
||||
Move(uap^.changelist^,kevp^,count*sizeof(t_kevent));
|
||||
|
||||
Inc(uap^.changelist,count);
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function _kern_kevent(td:p_kthread;
|
||||
kq:p_kqueue;
|
||||
nchanges:Integer;
|
||||
nevents:Integer;
|
||||
k_ops:p_kevent_copyops;
|
||||
timeout:p_timespec):Integer;
|
||||
type
|
||||
t_keva=array[0..KQ_NEVENTS-1] of t_kevent;
|
||||
var
|
||||
keva:t_keva;
|
||||
kevp,changes:p_kevent;
|
||||
i,n,nerrors:Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
|
||||
nerrors:=0;
|
||||
keva:=Default(t_keva);
|
||||
|
||||
while (nchanges > 0) do
|
||||
begin
|
||||
if (nchanges > KQ_NEVENTS) then
|
||||
n:=KQ_NEVENTS
|
||||
else
|
||||
n:=nchanges;
|
||||
|
||||
Result:=k_ops^.k_copyin(k_ops^.arg, keva, n);
|
||||
if (Result<>0) then Exit; //goto done;
|
||||
|
||||
changes:=keva;
|
||||
|
||||
For i:=0 to n-1 do
|
||||
begin
|
||||
kevp:=@changes[i];
|
||||
if (kevp^.filter=0) then continue;
|
||||
kevp^.flags:=kevp^.flags and (not EV_SYSFLAGS);
|
||||
Result:=kqueue_register(kq, kevp);
|
||||
if (Result<>0) or ((kevp^.flags and EV_RECEIPT)<>0) then
|
||||
begin
|
||||
if (nevents<>0) then
|
||||
begin
|
||||
kevp^.flags:=EV_ERROR;
|
||||
kevp^.data :=Result;
|
||||
k_ops^.k_copyout(k_ops^.arg, kevp, 1);
|
||||
Dec(nevents);
|
||||
Inc(nerrors);
|
||||
end else
|
||||
begin
|
||||
Exit(0); //goto done;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
Dec(nchanges,n);
|
||||
end;
|
||||
|
||||
if (nerrors<>0) then
|
||||
begin
|
||||
td^.td_retval[0]:=nerrors;
|
||||
Exit(0); //goto done;
|
||||
end;
|
||||
|
||||
Result:=kqueue_scan(kq, nevents, k_ops, timeout, keva);
|
||||
end;
|
||||
|
||||
function kern_kevent(fd:Integer;
|
||||
nchanges:Integer;
|
||||
nevents:Integer;
|
||||
k_ops:p_kevent_copyops;
|
||||
timeout:p_timespec):Integer;
|
||||
label
|
||||
done_norel,
|
||||
done;
|
||||
done_norel;
|
||||
type
|
||||
t_keva=array[0..KQ_NEVENTS-1] of t_kevent;
|
||||
var
|
||||
td:p_kthread;
|
||||
keva:t_keva;
|
||||
kevp,changes:p_kevent;
|
||||
kq:p_kqueue;
|
||||
fp:p_file;
|
||||
i,n,nerrors,error:Integer;
|
||||
error:Integer;
|
||||
begin
|
||||
td:=curkthread;
|
||||
if (td=nil) then Exit(-1);
|
||||
|
@ -1007,64 +1110,27 @@ begin
|
|||
|
||||
Writeln('kern_kevent:',kq^.kq_name);
|
||||
|
||||
nerrors:=0;
|
||||
keva:=Default(t_keva);
|
||||
error:=_kern_kevent(td,
|
||||
kq,
|
||||
nchanges,
|
||||
nevents,
|
||||
k_ops,
|
||||
timeout);
|
||||
|
||||
while (nchanges > 0) do
|
||||
begin
|
||||
if (nchanges > KQ_NEVENTS) then
|
||||
n:=KQ_NEVENTS
|
||||
else
|
||||
n:=nchanges;
|
||||
|
||||
error:=k_ops^.k_copyin(k_ops^.arg, keva, n);
|
||||
if (error<>0) then goto done;
|
||||
changes:=keva;
|
||||
For i:=0 to n-1 do
|
||||
begin
|
||||
kevp:=@changes[i];
|
||||
if (kevp^.filter=0) then continue;
|
||||
kevp^.flags:=kevp^.flags and (not EV_SYSFLAGS);
|
||||
error:=kqueue_register(kq, kevp);
|
||||
if (error<>0) or ((kevp^.flags and EV_RECEIPT)<>0) then
|
||||
begin
|
||||
if (nevents<>0) then
|
||||
begin
|
||||
kevp^.flags:=EV_ERROR;
|
||||
kevp^.data :=error;
|
||||
k_ops^.k_copyout(k_ops^.arg, kevp, 1);
|
||||
Dec(nevents);
|
||||
Inc(nerrors);
|
||||
end else
|
||||
begin
|
||||
goto done;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
Dec(nchanges,n);
|
||||
end;
|
||||
|
||||
if (nerrors<>0) then
|
||||
begin
|
||||
td^.td_retval[0]:=nerrors;
|
||||
error:=0;
|
||||
goto done;
|
||||
end;
|
||||
|
||||
error:=kqueue_scan(kq, nevents, k_ops, timeout, keva);
|
||||
done:
|
||||
//done:
|
||||
kqueue_release(kq, 0);
|
||||
|
||||
done_norel:
|
||||
fdrop(fp);
|
||||
Exit(error);
|
||||
end;
|
||||
|
||||
function sys_kevent(fd:Integer;
|
||||
function sys_kevent(fd :Integer;
|
||||
changelist:Pointer;
|
||||
nchanges:Integer;
|
||||
eventlist:Pointer;
|
||||
nevents:Integer;
|
||||
timeout:Pointer):Integer;
|
||||
nchanges :Integer;
|
||||
eventlist :Pointer;
|
||||
nevents :Integer;
|
||||
timeout :Pointer):Integer;
|
||||
var
|
||||
ts:timespec;
|
||||
tsp:p_timespec;
|
||||
|
@ -1082,12 +1148,10 @@ begin
|
|||
tsp:=nil;
|
||||
end;
|
||||
|
||||
uap.fd :=fd ;
|
||||
uap.changelist:=changelist;
|
||||
uap.nchanges :=nchanges ;
|
||||
uap.eventlist :=eventlist ;
|
||||
uap.nevents :=nevents ;
|
||||
uap.timeout :=timeout ;
|
||||
|
||||
k_ops.arg :=@uap;
|
||||
k_ops.k_copyout:=@kevent_copyout;
|
||||
|
@ -1098,7 +1162,44 @@ begin
|
|||
Exit(error);
|
||||
end;
|
||||
|
||||
function kqueue_add_filteropts(filt:Integer;filtops:p_filterops):Integer;
|
||||
function kern_kevent2(kq :p_kqueue;
|
||||
changelist:p_kevent;
|
||||
nchanges :Integer;
|
||||
eventlist :p_kevent;
|
||||
nevents :Integer;
|
||||
timeout :p_timespec;
|
||||
p_ncount :PInteger):Integer; public;
|
||||
var
|
||||
td:p_kthread;
|
||||
error:Integer;
|
||||
uap:t_kevent_args;
|
||||
k_ops:t_kevent_copyops;
|
||||
begin
|
||||
td:=curkthread;
|
||||
if (td=nil) then Exit(-1);
|
||||
|
||||
uap.changelist:=changelist;
|
||||
uap.nchanges :=nchanges ;
|
||||
uap.eventlist :=eventlist ;
|
||||
uap.nevents :=nevents ;
|
||||
|
||||
k_ops.arg :=@uap;
|
||||
k_ops.k_copyout:=@kevent_copyout2;
|
||||
k_ops.k_copyin :=@kevent_copyin2;
|
||||
|
||||
error:=_kern_kevent(td,
|
||||
kq,
|
||||
nchanges,
|
||||
nevents,
|
||||
@k_ops,
|
||||
timeout);
|
||||
|
||||
p_ncount^:=td^.td_retval[0];
|
||||
|
||||
Exit(error);
|
||||
end;
|
||||
|
||||
function kqueue_add_filteropts(filt:Integer;filtops:p_filterops):Integer; public;
|
||||
var
|
||||
error:Integer;
|
||||
begin
|
||||
|
@ -1123,7 +1224,7 @@ begin
|
|||
Exit(error);
|
||||
end;
|
||||
|
||||
function kqueue_del_filteropts(filt:Integer):Integer;
|
||||
function kqueue_del_filteropts(filt:Integer):Integer; public;
|
||||
var
|
||||
error:Integer;
|
||||
begin
|
||||
|
@ -1349,7 +1450,7 @@ findkn:
|
|||
kev^.fflags:=0;
|
||||
kev^.data:=0;
|
||||
kn^.kn_kevent:=kev^;
|
||||
kn^.kn_kevent.flags:=kn^.kn_kevent.flags and (not (EV_ADD or EV_DELETE or EV_ENABLE or EV_DISABLE));
|
||||
kn^.kn_kevent.flags:=kn^.kn_kevent.flags and (not EV_ACTION);
|
||||
kn^.kn_status:=KN_INFLUX or KN_DETACHED;
|
||||
|
||||
error:=knote_attach(kn, kq);
|
||||
|
@ -1462,7 +1563,7 @@ done:
|
|||
Exit(error);
|
||||
end;
|
||||
|
||||
procedure kqueue_deregister(filter:SmallInt;pid,ident:PtrUint);
|
||||
procedure kqueue_deregister(filter:SmallInt;pid,ident:PtrUint); public;
|
||||
label
|
||||
_lock,
|
||||
_again;
|
||||
|
@ -2018,21 +2119,13 @@ begin
|
|||
Exit(0);
|
||||
end;
|
||||
|
||||
{ARGSUSED}
|
||||
function kqueue_close(fp:p_file):Integer;
|
||||
procedure kqueue_close2(kq:p_kqueue); public;
|
||||
var
|
||||
kq:p_kqueue;
|
||||
kn:p_knote;
|
||||
i:Integer;
|
||||
error:Integer;
|
||||
filedesc_unlock:Integer;
|
||||
begin
|
||||
kq:=fp^.f_data;
|
||||
if (kq=nil) then Exit;
|
||||
|
||||
error:=kqueue_acquire(fp, @kq);
|
||||
if (error<>0) then Exit(error);
|
||||
|
||||
filedesc_unlock:=0;
|
||||
KQ_LOCK(kq);
|
||||
|
||||
Assert((kq^.kq_state and KQ_CLOSING)<>KQ_CLOSING,'kqueue already closing');
|
||||
|
@ -2120,6 +2213,39 @@ begin
|
|||
|
||||
KQ_UNLOCK(kq);
|
||||
|
||||
seldrain(@kq^.kq_sel);
|
||||
knlist_destroy(@kq^.kq_sel.si_note);
|
||||
mtx_destroy(kq^.kq_lock);
|
||||
//kq^.kq_fdp:=nil;
|
||||
|
||||
if (kq^.kq_knhash<>nil) then
|
||||
begin
|
||||
FreeMem(kq^.kq_knhash);
|
||||
end;
|
||||
if (kq^.kq_knlist<>nil) then
|
||||
begin
|
||||
FreeMem(kq^.kq_knlist);
|
||||
end;
|
||||
|
||||
//funsetown(@kq^.kq_sigio);
|
||||
|
||||
FreeMem(kq);
|
||||
end;
|
||||
|
||||
{ARGSUSED}
|
||||
function kqueue_close(fp:p_file):Integer;
|
||||
var
|
||||
kq:p_kqueue;
|
||||
error:Integer;
|
||||
filedesc_unlock:Integer;
|
||||
begin
|
||||
kq:=fp^.f_data;
|
||||
|
||||
error:=kqueue_acquire(fp, @kq);
|
||||
if (error<>0) then Exit(error);
|
||||
|
||||
filedesc_unlock:=0;
|
||||
|
||||
{
|
||||
* We could be called due to the knote_drop() doing fdrop(),
|
||||
* called from kqueue_register(). In this case the global
|
||||
|
@ -2142,22 +2268,8 @@ begin
|
|||
FILEDESC_XUNLOCK(@fd_table);
|
||||
end;
|
||||
|
||||
seldrain(@kq^.kq_sel);
|
||||
knlist_destroy(@kq^.kq_sel.si_note);
|
||||
mtx_destroy(kq^.kq_lock);
|
||||
//kq^.kq_fdp:=nil;
|
||||
kqueue_close2(kq);
|
||||
|
||||
if (kq^.kq_knhash<>nil) then
|
||||
begin
|
||||
FreeMem(kq^.kq_knhash);
|
||||
end;
|
||||
if (kq^.kq_knlist<>nil) then
|
||||
begin
|
||||
FreeMem(kq^.kq_knlist);
|
||||
end;
|
||||
|
||||
//funsetown(@kq^.kq_sigio);
|
||||
FreeMem(kq);
|
||||
fp^.f_data:=nil;
|
||||
|
||||
Exit(0);
|
||||
|
@ -2188,6 +2300,12 @@ begin
|
|||
begin
|
||||
//pgsigio(@kq^.kq_sigio, SIGIO, 0);
|
||||
end;
|
||||
|
||||
if (kq^.kq_wakeup<>nil) then
|
||||
begin
|
||||
kq^.kq_wakeup(kq^.kq_data);
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
{
|
||||
|
@ -2655,6 +2773,7 @@ begin
|
|||
TAILQ_INSERT_TAIL(@kq^.kq_head,kn,@kn^.kn_tqe);
|
||||
kn^.kn_status:=kn^.kn_status or KN_QUEUED;
|
||||
Inc(kq^.kq_count);
|
||||
|
||||
kqueue_wakeup(kq);
|
||||
end;
|
||||
|
||||
|
@ -2697,7 +2816,7 @@ end;
|
|||
{
|
||||
* Register the kev w/ the kq specified by fd.
|
||||
}
|
||||
function kqfd_register(fd:Integer;kev:p_kevent):Integer;
|
||||
function kqfd_register(fd:Integer;kev:p_kevent):Integer; public;
|
||||
label
|
||||
noacquire;
|
||||
var
|
||||
|
|
|
@ -59,7 +59,6 @@ uses
|
|||
sys_resource,
|
||||
kern_resource,
|
||||
sys_event,
|
||||
kern_event,
|
||||
machdep,
|
||||
kern_dlsym,
|
||||
kern_authinfo,
|
||||
|
|
|
@ -70,7 +70,7 @@ uses
|
|||
systm,
|
||||
kern_proc,
|
||||
sys_event,
|
||||
kern_event,
|
||||
md_sleep,
|
||||
md_proc;
|
||||
|
||||
function _WSTATUS(x:Integer):Integer; inline;
|
||||
|
@ -136,6 +136,9 @@ begin
|
|||
if halt_on_exit then
|
||||
begin
|
||||
md_halt(rv);
|
||||
end else
|
||||
begin
|
||||
msleep_td(0);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
|
|
@ -129,48 +129,9 @@ begin
|
|||
mtx_unlock(p_proc.p_mtx);
|
||||
end;
|
||||
|
||||
function filt_host_ipc_attach(kn:p_knote):Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
procedure filt_host_ipc_detach(kn:p_knote);
|
||||
begin
|
||||
//
|
||||
end;
|
||||
|
||||
function filt_host_ipc_event(kn:p_knote;hint:QWORD):Integer;
|
||||
begin
|
||||
p_proc.p_host_ipc.knote(p_proc.p_pid,EVFILT_PROC,hint);
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
const
|
||||
filterops_host_ipc:t_filterops=(
|
||||
f_isfd :0;
|
||||
_align :0;
|
||||
f_attach:@filt_host_ipc_attach;
|
||||
f_detach:@filt_host_ipc_detach;
|
||||
f_event :@filt_host_ipc_event;
|
||||
);
|
||||
|
||||
procedure PROC_INIT_HOST_IPC(host_ipc:THostIpcConnect);
|
||||
var
|
||||
kn:p_knote;
|
||||
begin
|
||||
if (host_ipc=nil) then Exit;
|
||||
|
||||
p_proc.p_host_ipc:=host_ipc;
|
||||
|
||||
kn:=knote_alloc();
|
||||
|
||||
kn^.kn_fop:=@filterops_host_ipc;
|
||||
|
||||
kn^.kn_status:=KN_INFLUX or KN_DETACHED or KN_SCAN;
|
||||
kn^.kn_ptr.p_proc:=@p_proc;
|
||||
kn^.kn_flags:=kn^.kn_flags or EV_CLEAR;
|
||||
|
||||
knlist_add(@p_proc.p_klist, kn, 0);
|
||||
end;
|
||||
|
||||
procedure PROC_INIT;
|
||||
|
|
|
@ -14,7 +14,7 @@ implementation
|
|||
uses
|
||||
kern_thr,
|
||||
kern_descrip,
|
||||
kern_conf,
|
||||
sys_conf,
|
||||
vsocket,
|
||||
vfile,
|
||||
vfcntl,
|
||||
|
|
|
@ -13,6 +13,7 @@ uses
|
|||
machdep,
|
||||
md_context,
|
||||
md_proc,
|
||||
kern_exit,
|
||||
kern_thr,
|
||||
subr_backtrace,
|
||||
trap,
|
||||
|
@ -330,8 +331,6 @@ begin
|
|||
Writeln(stderr,_get_msg(Msg),' (',FName,', line ',LineNo,').');
|
||||
print_backtrace(stderr,Get_pc_addr,get_frame,2);
|
||||
|
||||
//sleep(-1);
|
||||
|
||||
if IsDebuggerPresent then
|
||||
Raise EAssertionFailed.
|
||||
Createfmt('%s (%s, line %d).',
|
||||
|
@ -343,9 +342,7 @@ begin
|
|||
// int3
|
||||
//end;
|
||||
|
||||
sleep(-1);
|
||||
|
||||
md_halt(217);
|
||||
kern_exit.exit1(217);
|
||||
end;
|
||||
|
||||
var
|
||||
|
|
|
@ -35,9 +35,8 @@ type
|
|||
procedure set_pipe(fd:THandle);
|
||||
procedure Recv; virtual;
|
||||
Function Push(Node:Pointer):Boolean; virtual;
|
||||
procedure thread_new; virtual;
|
||||
procedure thread_free; virtual;
|
||||
procedure Send(mtype:t_mtype;mlen,mtid:DWORD;buf:Pointer); override;
|
||||
procedure WakeupKevent(); override;
|
||||
Constructor Create;
|
||||
Destructor Destroy; override;
|
||||
end;
|
||||
|
@ -168,26 +167,26 @@ begin
|
|||
Result:=FQueue.Push(node);
|
||||
end;
|
||||
|
||||
procedure THostIpcPipe.thread_new;
|
||||
begin
|
||||
//
|
||||
end;
|
||||
|
||||
procedure THostIpcPipe.thread_free;
|
||||
begin
|
||||
//
|
||||
end;
|
||||
|
||||
procedure THostIpcPipe.Send(mtype:t_mtype;mlen,mtid:DWORD;buf:Pointer);
|
||||
begin
|
||||
proto.Send(mtype,mlen,mtid,buf);
|
||||
end;
|
||||
|
||||
Procedure ev_wakeup(param1:SizeUInt;param2:Pointer); register;
|
||||
begin
|
||||
THostIpcPipe(param2).UpdateKevent();
|
||||
end;
|
||||
|
||||
procedure THostIpcPipe.WakeupKevent();
|
||||
begin
|
||||
evpoll_post(@evpoll,@ev_wakeup,0,Pointer(Self));
|
||||
end;
|
||||
|
||||
Constructor THostIpcPipe.Create;
|
||||
begin
|
||||
inherited;
|
||||
evpoll_init(@evpoll,nil);
|
||||
thread_new;
|
||||
//thread_new;
|
||||
end;
|
||||
|
||||
Destructor THostIpcPipe.Destroy;
|
||||
|
@ -213,13 +212,20 @@ end;
|
|||
|
||||
procedure THostIpcPipeMGUI.thread_new;
|
||||
begin
|
||||
Ftd:=BeginThread(@pipe_gui_thread,@evpoll);
|
||||
if (Ftd=0) then
|
||||
begin
|
||||
Ftd:=BeginThread(@pipe_gui_thread,@evpoll);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure THostIpcPipeMGUI.thread_free;
|
||||
begin
|
||||
WaitForThreadTerminate(Ftd,0);
|
||||
CloseThread(Ftd);
|
||||
if (Ftd<>0) then
|
||||
begin
|
||||
WaitForThreadTerminate(Ftd,0);
|
||||
CloseThread(Ftd);
|
||||
Ftd:=0;
|
||||
end;
|
||||
end;
|
||||
|
||||
//
|
||||
|
@ -233,13 +239,19 @@ end;
|
|||
|
||||
procedure THostIpcPipeKERN.thread_new;
|
||||
begin
|
||||
Ftd:=nil;
|
||||
kthread_add(@pipe_kern_thread,@evpoll,@Ftd,'[ipc_pipe]');
|
||||
if (Ftd=nil) then
|
||||
begin
|
||||
kthread_add(@pipe_kern_thread,@evpoll,@Ftd,'[ipc_pipe]');
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure THostIpcPipeKERN.thread_free;
|
||||
begin
|
||||
thread_dec_ref(Ftd);
|
||||
if (Ftd<>nil) then
|
||||
begin
|
||||
thread_dec_ref(Ftd);
|
||||
Ftd:=nil;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
|
|
|
@ -13,6 +13,12 @@ uses
|
|||
type
|
||||
t_fork_cb=procedure(data:Pointer;size:QWORD); SysV_ABI_CDecl;
|
||||
|
||||
p_fork_proc=^t_fork_proc;
|
||||
t_fork_proc=record
|
||||
hProcess:THandle;
|
||||
fork_pid:Integer;
|
||||
end;
|
||||
|
||||
function md_copyin (hProcess:THandle;udaddr,kaddr:Pointer;len:ptruint;lencopied:pptruint):Integer;
|
||||
function md_copyout(hProcess:THandle;kaddr,udaddr:Pointer;len:ptruint;lencopied:pptruint):Integer;
|
||||
|
||||
|
@ -25,7 +31,7 @@ function md_pidfd_open (pid:DWORD):THandle;
|
|||
|
||||
procedure md_run_forked;
|
||||
procedure md_fork_unshare;
|
||||
function md_fork_process(proc:Pointer;data:Pointer;size:QWORD):THandle;
|
||||
function md_fork_process(proc:Pointer;data:Pointer;size:QWORD;var info:t_fork_proc):Integer;
|
||||
|
||||
implementation
|
||||
|
||||
|
@ -172,23 +178,23 @@ function SetInformationJobObject(hJob:HANDLE;
|
|||
|
||||
function AssignProcessToJobObject(hJob,hProcess:THandle):BOOL; stdcall; external kernel32;
|
||||
|
||||
function NtQueryTeb(td_handle:THandle):p_teb;
|
||||
function NtQueryTeb(td_handle:THandle;var teb:p_teb):Integer;
|
||||
var
|
||||
TBI:THREAD_BASIC_INFORMATION;
|
||||
err:Integer;
|
||||
begin
|
||||
Result:=nil;
|
||||
Result:=0;
|
||||
teb:=nil;
|
||||
TBI:=Default(THREAD_BASIC_INFORMATION);
|
||||
|
||||
err:=NtQueryInformationThread(
|
||||
td_handle,
|
||||
ThreadBasicInformation,
|
||||
@TBI,
|
||||
SizeOf(THREAD_BASIC_INFORMATION),
|
||||
nil);
|
||||
if (err<>0) then Exit;
|
||||
Result:=NtQueryInformationThread(
|
||||
td_handle,
|
||||
ThreadBasicInformation,
|
||||
@TBI,
|
||||
SizeOf(THREAD_BASIC_INFORMATION),
|
||||
nil);
|
||||
if (Result<>0) then Exit;
|
||||
|
||||
Result:=TBI.TebBaseAddress;
|
||||
teb:=TBI.TebBaseAddress;
|
||||
end;
|
||||
|
||||
procedure NtGetVirtualInfo(hProcess:THandle;var base:Pointer;var size:QWORD);
|
||||
|
@ -259,8 +265,8 @@ begin
|
|||
err:=NtGetContextThread(hThread,Context);
|
||||
if (err<>0) then Exit(err);
|
||||
|
||||
teb:=NtQueryTeb(hThread);
|
||||
if (teb=nil) then Exit(-1);
|
||||
err:=NtQueryTeb(hThread,teb);
|
||||
if (err<>0) then Exit(err);
|
||||
|
||||
kstack:=Default(t_td_stack);
|
||||
err:=md_copyin(hProcess,@teb^.stack,@kstack,SizeOf(t_td_stack),nil);
|
||||
|
@ -432,13 +438,15 @@ end;
|
|||
function NtCreateShared(hProcess:THandle;proc:Pointer;data:Pointer;size:QWORD):Integer;
|
||||
var
|
||||
base:p_shared_info;
|
||||
full:QWORD;
|
||||
shared_info:t_shared_info;
|
||||
begin
|
||||
base:=Pointer(WIN_SHARED_ADDR);
|
||||
size:=SizeOf(Pointer)+size;
|
||||
size:=(size+(MD_PAGE_SIZE-1)) and (not (MD_PAGE_SIZE-1));
|
||||
|
||||
Result:=md_mmap(hProcess,base,size,MD_PROT_RW);
|
||||
full:=SizeOf(shared_info)+size;
|
||||
full:=(size+(MD_PAGE_SIZE-1)) and (not (MD_PAGE_SIZE-1));
|
||||
|
||||
Result:=md_mmap(hProcess,base,full,MD_PROT_RW);
|
||||
if (Result<>0) then Exit;
|
||||
|
||||
shared_info:=Default(t_shared_info);
|
||||
|
@ -450,7 +458,6 @@ begin
|
|||
shared_info.hStdError :=md_dup_to_pidfd(hProcess,GetStdHandle(STD_ERROR_HANDLE));
|
||||
|
||||
shared_info.proc:=proc;
|
||||
|
||||
shared_info.size:=size;
|
||||
|
||||
Result:=md_copyout(hProcess,@shared_info,base,SizeOf(shared_info),nil);
|
||||
|
@ -462,7 +469,7 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function md_fork_process(proc:Pointer;data:Pointer;size:QWORD):THandle;
|
||||
function md_fork_process(proc:Pointer;data:Pointer;size:QWORD;var info:t_fork_proc):Integer;
|
||||
var
|
||||
si:TSTARTUPINFO;
|
||||
pi:PROCESS_INFORMATION;
|
||||
|
@ -471,7 +478,6 @@ var
|
|||
DATA :array[0..MAX_PATH*2] of WideChar;
|
||||
end;
|
||||
LEN:ULONG;
|
||||
R:DWORD;
|
||||
b:BOOL;
|
||||
begin
|
||||
Result:=0;
|
||||
|
@ -479,12 +485,12 @@ begin
|
|||
FillChar(BUF,SizeOf(BUF),0);
|
||||
LEN:=SizeOf(BUF);
|
||||
|
||||
R:=NtQueryInformationProcess(NtCurrentProcess,
|
||||
ProcessImageFileNameWin32,
|
||||
@BUF,
|
||||
LEN,
|
||||
@LEN);
|
||||
if (R<>0) then Exit;
|
||||
Result:=NtQueryInformationProcess(NtCurrentProcess,
|
||||
ProcessImageFileNameWin32,
|
||||
@BUF,
|
||||
LEN,
|
||||
@LEN);
|
||||
if (Result<>0) then Exit;
|
||||
|
||||
si:=Default(TSTARTUPINFO);
|
||||
pi:=Default(PROCESS_INFORMATION);
|
||||
|
@ -492,18 +498,27 @@ begin
|
|||
si.cb:=SizeOf(si);
|
||||
|
||||
b:=CreateProcessW(PWideChar(@BUF.DATA),nil,nil,nil,False,CREATE_SUSPENDED,nil,nil,@si,@pi);
|
||||
if not b then Exit;
|
||||
if not b then Exit(-1);
|
||||
|
||||
b:=AssignProcessToJobObject(NtFetchJob, pi.hProcess);
|
||||
if not b then Exit(-1);
|
||||
|
||||
NtMoveStack(pi.hProcess,pi.hThread);
|
||||
NtReserve(pi.hProcess);
|
||||
NtCreateShared(pi.hProcess,proc,data,size);
|
||||
Result:=NtMoveStack(pi.hProcess,pi.hThread);
|
||||
if (Result<>0) then Exit;
|
||||
|
||||
Result:=NtReserve(pi.hProcess);
|
||||
if (Result<>0) then Exit;
|
||||
|
||||
Result:=NtCreateShared(pi.hProcess,proc,data,size);
|
||||
if (Result<>0) then Exit;
|
||||
|
||||
Result:=NtResumeProcess(pi.hProcess);
|
||||
if (Result<>0) then Exit;
|
||||
|
||||
NtResumeProcess(pi.hProcess);
|
||||
NtClose(pi.hThread);
|
||||
|
||||
Result:=pi.hProcess;
|
||||
info.hProcess:=pi.hProcess;
|
||||
info.fork_pid:=pi.dwProcessId;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
|
|
@ -0,0 +1,450 @@
|
|||
unit sys_conf;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
{$CALLING SysV_ABI_CDecl}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
mqueue,
|
||||
time,
|
||||
kern_param,
|
||||
vmount,
|
||||
vfile,
|
||||
vuio,
|
||||
vnode,
|
||||
sys_event,
|
||||
vm,
|
||||
sys_vm_object,
|
||||
kern_mtx;
|
||||
|
||||
const
|
||||
//modeventtype
|
||||
MOD_LOAD =0;
|
||||
MOD_UNLOAD =1;
|
||||
MOD_SHUTDOWN=2;
|
||||
MOD_QUIESCE =3;
|
||||
|
||||
SI_ETERNAL =$0001; { never destroyed }
|
||||
SI_ALIAS =$0002; { carrier of alias name }
|
||||
SI_NAMED =$0004; { make_dev _alias has been called }
|
||||
SI_CHEAPCLONE=$0008; { can be removed_dev'ed when vnode reclaims }
|
||||
SI_CHILD =$0010; { child of another struct cdev *}
|
||||
SI_DEVOPEN =$0020; { opened by device }
|
||||
SI_CONSOPEN =$0040; { opened by console }
|
||||
SI_DUMPDEV =$0080; { is kernel dumpdev }
|
||||
SI_CANDELETE =$0100; { can do BIO_DELETE }
|
||||
SI_CLONELIST =$0200; { on a clone list }
|
||||
SI_UNMAPPED =$0400; { can handle unmapped I/O }
|
||||
|
||||
type
|
||||
pp_cdev=^p_cdev;
|
||||
p_cdev=^t_cdev;
|
||||
t_cdev=packed record
|
||||
si_mountpt :p_mount;
|
||||
si_flags :DWORD;
|
||||
_align1 :Integer;
|
||||
si_atime :timespec;
|
||||
si_ctime :timespec;
|
||||
si_mtime :timespec;
|
||||
si_uid :uid_t;
|
||||
si_gid :gid_t;
|
||||
si_mode :mode_t;
|
||||
si_drv0 :Integer;
|
||||
si_refcount :Integer;
|
||||
_align2 :Integer;
|
||||
si_list :LIST_ENTRY; //(cdev)
|
||||
si_clone :LIST_ENTRY; //(cdev)
|
||||
si_children :LIST_HEAD ; //(cdev)
|
||||
si_siblings :LIST_ENTRY; //(cdev)
|
||||
si_parent :p_cdev;
|
||||
si_name :PChar;
|
||||
si_drv1 :Pointer;
|
||||
si_drv2 :Pointer;
|
||||
si_devsw :Pointer; //cdevsw
|
||||
si_iosize_max :Integer; { maximum I/O size (for physio &al) }
|
||||
_align3 :Integer;
|
||||
si_usecount :QWORD;
|
||||
si_threadcount:QWORD;
|
||||
si_snapdata :Pointer; //snapdata
|
||||
__si_namebuf :array[0..SPECNAMELEN] of AnsiChar;
|
||||
end;
|
||||
|
||||
d_open_t =Function (dev:p_cdev;oflags,devtype:Integer):Integer;
|
||||
d_fdopen_t =Function (dev:p_cdev;oflags:Integer;fp:p_file):Integer;
|
||||
d_close_t =Function (dev:p_cdev;fflag,devtype:Integer):Integer;
|
||||
d_strategy_t =Procedure(bp:Pointer);//bio
|
||||
d_ioctl_t =Function (dev:p_cdev;cmd:QWORD;data:Pointer;fflag:Integer):Integer;
|
||||
|
||||
d_read_t =Function (dev:p_cdev;uio:p_uio;ioflag:Integer):Integer;
|
||||
d_write_t =Function (dev:p_cdev;uio:p_uio;ioflag:Integer):Integer;
|
||||
d_poll_t =Function (dev:p_cdev;events:Integer):Integer;
|
||||
d_kqfilter_t =Function (dev:p_cdev;kn:p_knote):Integer;
|
||||
d_mmap_t =Function (dev:p_cdev;offset:vm_ooffset_t;paddr:p_vm_paddr_t;nprot:Integer;memattr:p_vm_memattr_t):Integer;
|
||||
d_mmap_single_t =Function (dev:p_cdev;offset:p_vm_ooffset_t;size:vm_size_t;obj:p_vm_object_t;nprot:Integer):Integer;
|
||||
d_mmap_single2_t=Function (dev:p_cdev;offset:p_vm_ooffset_t;size:vm_size_t;obj:p_vm_object_t;nprot:Integer;maxprotp:p_vm_prot_t;flagsp:PInteger):Integer;
|
||||
d_purge_t =Procedure(dev:p_cdev);
|
||||
|
||||
dumper_t=Function(
|
||||
_priv:Pointer ; { Private to the driver. }
|
||||
_virtual:Pointer ; { Virtual (mapped) address. }
|
||||
_physical:vm_offset_t; { Physical address of virtual. }
|
||||
_offset:Int64 ; { Byte-offset to write at. }
|
||||
_length:QWORD):Integer; { Number of bytes to dump. }
|
||||
|
||||
const
|
||||
{
|
||||
* Types for d_flags.
|
||||
}
|
||||
D_TAPE=$0001;
|
||||
D_DISK=$0002;
|
||||
D_TTY =$0004;
|
||||
D_MEM =$0008;
|
||||
|
||||
D_TYPEMASK=$ffff;
|
||||
|
||||
{
|
||||
* Flags for d_flags which the drivers can set.
|
||||
}
|
||||
D_TRACKCLOSE =$00080000; { track all closes }
|
||||
D_MMAP_ANON =$00100000; { special treatment in vm_mmap.c }
|
||||
D_PSEUDO =$00200000; { make_dev() can return NULL }
|
||||
D_NEEDGIANT =$00400000; { driver want Giant }
|
||||
D_NEEDMINOR =$00800000; { driver uses clone_create() }
|
||||
D_UNMAPPED_IO=$01000000; { d_strategy can accept unmapped IO }
|
||||
|
||||
{
|
||||
* Version numbers.
|
||||
}
|
||||
D_VERSION_00=$20011966;
|
||||
D_VERSION_01=$17032005; { Add d_uid,gid,mode & kind }
|
||||
D_VERSION_02=$28042009; { Add d_mmap_single }
|
||||
D_VERSION_03=$17122009; { d_mmap takes memattr,vm_ooffset_t }
|
||||
D_VERSION=D_VERSION_03;
|
||||
|
||||
{
|
||||
* Flags used for internal housekeeping
|
||||
}
|
||||
D_INIT =$80000000; { cdevsw initialized }
|
||||
|
||||
{
|
||||
* Character device switch table
|
||||
}
|
||||
type
|
||||
pp_cdevsw=^p_cdevsw;
|
||||
p_cdevsw=^t_cdevsw;
|
||||
t_cdevsw=packed record
|
||||
d_version :Integer;
|
||||
d_flags :DWORD;
|
||||
d_name :PChar;
|
||||
d_open :d_open_t;
|
||||
d_fdopen :d_fdopen_t;
|
||||
d_close :d_close_t;
|
||||
d_read :d_read_t;
|
||||
d_write :d_write_t;
|
||||
d_ioctl :d_ioctl_t;
|
||||
d_poll :d_poll_t;
|
||||
d_mmap :d_mmap_t;
|
||||
d_strategy :d_strategy_t;
|
||||
d_dump :dumper_t;
|
||||
d_kqfilter :d_kqfilter_t;
|
||||
d_purge :d_purge_t;
|
||||
d_mmap_single :d_mmap_single_t;
|
||||
d_mmap_single2:d_mmap_single2_t;
|
||||
|
||||
d_spare0:array[0..1] of Integer;
|
||||
d_spare1:array[0..2] of Pointer;
|
||||
|
||||
{ These fields should not be messed with by drivers }
|
||||
d_devs:Pointer; //cdev
|
||||
d_spare2:array[0..1] of Integer;
|
||||
d_gianttrick:p_cdevsw;
|
||||
d_postfree_list:SLIST_ENTRY; //cdevsw
|
||||
end;
|
||||
|
||||
const
|
||||
MAKEDEV_REF =$01;
|
||||
MAKEDEV_WHTOUT =$02;
|
||||
MAKEDEV_NOWAIT =$04;
|
||||
MAKEDEV_WAITOK =$08;
|
||||
MAKEDEV_ETERNAL =$10;
|
||||
MAKEDEV_CHECKNAME=$20;
|
||||
|
||||
UID_ROOT =0;
|
||||
UID_BIN =3;
|
||||
UID_UUCP =66;
|
||||
UID_NOBODY =65534;
|
||||
|
||||
GID_WHEEL =0;
|
||||
GID_KMEM =2;
|
||||
GID_TTY =4;
|
||||
GID_OPERATOR=5;
|
||||
GID_BIN =7;
|
||||
GID_GAMES =13;
|
||||
GID_DIALER =68;
|
||||
GID_NOBODY =65534;
|
||||
|
||||
var
|
||||
devmtx:mtx;
|
||||
|
||||
cdevp_free_list:TAILQ_HEAD=(tqh_first:nil;tqh_last:@cdevp_free_list.tqh_first);
|
||||
cdevsw_gt_post_list:SLIST_HEAD=(slh_first:nil);
|
||||
|
||||
type
|
||||
cdevpriv_dtr_t=Procedure(data:Pointer);
|
||||
|
||||
function devfs_get_cdevpriv(datap:PPointer):Integer; external;
|
||||
function devfs_set_cdevpriv(priv:Pointer;priv_dtr:cdevpriv_dtr_t):Integer; external;
|
||||
procedure devfs_clear_cdevpriv(); external;
|
||||
procedure devfs_fpdrop(fp:p_file); external;
|
||||
|
||||
type
|
||||
ino_t=Integer;
|
||||
|
||||
function devfs_alloc_cdp_inode():ino_t; external;
|
||||
procedure devfs_free_cdp_inode(ino:ino_t); external;
|
||||
|
||||
procedure dev_lock(); external;
|
||||
procedure dev_unlock(); external;
|
||||
procedure dev_ref(dev:p_cdev); external;
|
||||
procedure dev_refl(dev:p_cdev); external;
|
||||
procedure dev_rel(dev:p_cdev); external;
|
||||
|
||||
function dev_refthread(dev:p_cdev;ref:PInteger):p_cdevsw; external;
|
||||
function devvn_refthread(vp:p_vnode;devp:pp_cdev;ref:PInteger):p_cdevsw; external;
|
||||
procedure dev_relthread(dev:p_cdev;ref:Integer); external;
|
||||
|
||||
procedure destroy_dev(dev:p_cdev); external;
|
||||
|
||||
function dev2unit(d:p_cdev):Integer;
|
||||
function devtoname(dev:p_cdev):PChar;
|
||||
|
||||
function make_dev_credv(flags:Integer;
|
||||
dres:pp_cdev;
|
||||
devsw:p_cdevsw;
|
||||
_unit:Integer;
|
||||
uid:uid_t;
|
||||
gid:gid_t;
|
||||
mode:Integer;
|
||||
fmt:PChar;
|
||||
const Args:Array of const):Integer; register; external;
|
||||
|
||||
function make_dev(devsw:p_cdevsw;
|
||||
_unit:Integer;
|
||||
uid:uid_t;
|
||||
gid:gid_t;
|
||||
mode:Integer;
|
||||
fmt:PChar;
|
||||
const Args:Array of const):p_cdev; register;
|
||||
|
||||
function make_dev_cred(devsw:p_cdevsw;
|
||||
_unit:Integer;
|
||||
uid:uid_t;
|
||||
gid:gid_t;
|
||||
mode:Integer;
|
||||
fmt:PChar;
|
||||
const Args:Array of const):p_cdev; register;
|
||||
|
||||
function make_dev_credf(flags:Integer;
|
||||
devsw:p_cdevsw;
|
||||
_unit:Integer;
|
||||
uid:uid_t;
|
||||
gid:gid_t;
|
||||
mode:Integer;
|
||||
fmt:PChar;
|
||||
const Args:Array of const):p_cdev; register;
|
||||
|
||||
function make_dev_p(flags:Integer;
|
||||
cdev:pp_cdev;
|
||||
devsw:p_cdevsw;
|
||||
uid:uid_t;
|
||||
gid:gid_t;
|
||||
mode:Integer;
|
||||
fmt:PChar;
|
||||
const Args:Array of const):Integer; register;
|
||||
|
||||
function make_dev_alias_v(flags:Integer;
|
||||
cdev:pp_cdev;
|
||||
pdev:p_cdev;
|
||||
fmt:PChar;
|
||||
const Args:Array of const):Integer; register; external;
|
||||
|
||||
function make_dev_alias(pdev:p_cdev;
|
||||
fmt:PChar;
|
||||
const Args:Array of const):p_cdev; register;
|
||||
|
||||
function make_dev_alias_p(flags:Integer;
|
||||
cdev:pp_cdev;
|
||||
pdev:p_cdev;
|
||||
fmt:PChar;
|
||||
const Args:Array of const):Integer; register;
|
||||
|
||||
function make_dev_physpath_alias(flags:Integer;
|
||||
cdev:pp_cdev;
|
||||
pdev,old_alias:p_cdev;
|
||||
physpath:PChar):Integer; external;
|
||||
|
||||
function _nullop():Integer;
|
||||
function _eopnotsupp():Integer;
|
||||
function _enxio():Integer;
|
||||
function _enodev():Integer;
|
||||
function _einval():Integer;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
errno;
|
||||
|
||||
function dev2unit(d:p_cdev):Integer; inline;
|
||||
begin
|
||||
Result:=d^.si_drv0;
|
||||
end;
|
||||
|
||||
function devtoname(dev:p_cdev):PChar; inline;
|
||||
begin
|
||||
Result:=dev^.si_name;
|
||||
end;
|
||||
|
||||
function _nullop():Integer;
|
||||
begin
|
||||
Exit(0);
|
||||
end;
|
||||
|
||||
function _eopnotsupp():Integer;
|
||||
begin
|
||||
Exit(EOPNOTSUPP);
|
||||
end;
|
||||
|
||||
function _enxio():Integer;
|
||||
begin
|
||||
Exit(ENXIO);
|
||||
end;
|
||||
|
||||
function _enodev():Integer;
|
||||
begin
|
||||
Exit(ENODEV);
|
||||
end;
|
||||
|
||||
function _einval():Integer;
|
||||
begin
|
||||
Exit(EINVAL);
|
||||
end;
|
||||
|
||||
function make_dev(devsw:p_cdevsw;
|
||||
_unit:Integer;
|
||||
uid:uid_t;
|
||||
gid:gid_t;
|
||||
mode:Integer;
|
||||
fmt:PChar;
|
||||
const Args:Array of const):p_cdev; register; public;
|
||||
var
|
||||
dev:p_cdev;
|
||||
res:Integer;
|
||||
begin
|
||||
res:=make_dev_credv(0, @dev, devsw, _unit, uid, gid, mode, fmt, Args);
|
||||
|
||||
Assert((res=0) and (dev<>nil),'make_dev: failed make_dev_credv (error=%d)');
|
||||
|
||||
if (res=0) then
|
||||
Exit(dev)
|
||||
else
|
||||
Exit(nil);
|
||||
end;
|
||||
|
||||
function make_dev_cred(devsw:p_cdevsw;
|
||||
_unit:Integer;
|
||||
uid:uid_t;
|
||||
gid:gid_t;
|
||||
mode:Integer;
|
||||
fmt:PChar;
|
||||
const Args:Array of const):p_cdev; register; public;
|
||||
var
|
||||
dev:p_cdev;
|
||||
res:Integer;
|
||||
begin
|
||||
res:=make_dev_credv(0, @dev, devsw, _unit, uid, gid, mode, fmt, Args);
|
||||
|
||||
Assert((res=0) and (dev<>nil),'make_dev_cred: failed make_dev_credv (error=%d)');
|
||||
|
||||
if (res=0) then
|
||||
Exit(dev)
|
||||
else
|
||||
Exit(nil);
|
||||
end;
|
||||
|
||||
function make_dev_credf(flags:Integer;
|
||||
devsw:p_cdevsw;
|
||||
_unit:Integer;
|
||||
uid:uid_t;
|
||||
gid:gid_t;
|
||||
mode:Integer;
|
||||
fmt:PChar;
|
||||
const Args:Array of const):p_cdev; register; public;
|
||||
var
|
||||
dev:p_cdev;
|
||||
res:Integer;
|
||||
begin
|
||||
res:=make_dev_credv(flags, @dev, devsw, _unit, uid, gid, mode, fmt, Args);
|
||||
|
||||
Assert((((flags and MAKEDEV_NOWAIT)<>0) and (res=ENOMEM)) or
|
||||
(((flags and MAKEDEV_CHECKNAME)<>0) and (res<>ENOMEM)) or
|
||||
(res=0),'make_dev_credf: failed make_dev_credv (error=%d)');
|
||||
|
||||
if (res=0) then
|
||||
Exit(dev)
|
||||
else
|
||||
Exit(nil);
|
||||
end;
|
||||
|
||||
function make_dev_p(flags:Integer;
|
||||
cdev:pp_cdev;
|
||||
devsw:p_cdevsw;
|
||||
uid:uid_t;
|
||||
gid:gid_t;
|
||||
mode:Integer;
|
||||
fmt:PChar;
|
||||
const Args:Array of const):Integer; register; public;
|
||||
var
|
||||
res:Integer;
|
||||
begin
|
||||
res:=make_dev_credv(flags, cdev, devsw, 0, uid, gid, mode, fmt, Args);
|
||||
|
||||
Assert((((flags and MAKEDEV_NOWAIT)<>0) and (res=ENOMEM)) or
|
||||
(((flags and MAKEDEV_CHECKNAME)<>0) and (res<>ENOMEM)) or
|
||||
(res=0),'make_dev_p: failed make_dev_credv (error=%d)');
|
||||
|
||||
Exit(res);
|
||||
end;
|
||||
|
||||
function make_dev_alias(pdev:p_cdev;
|
||||
fmt:PChar;
|
||||
const Args:Array of const):p_cdev; register; public;
|
||||
var
|
||||
dev:p_cdev;
|
||||
res:Integer;
|
||||
begin
|
||||
res:=make_dev_alias_v(MAKEDEV_WAITOK, @dev, pdev, fmt, Args);
|
||||
|
||||
Assert((res=0) and (dev<>nil),'make_dev_alias: failed make_dev_alias_v (error=%d)');
|
||||
|
||||
if (res=0) then
|
||||
Exit(dev)
|
||||
else
|
||||
Exit(nil);
|
||||
end;
|
||||
|
||||
function make_dev_alias_p(flags:Integer;
|
||||
cdev:pp_cdev;
|
||||
pdev:p_cdev;
|
||||
fmt:PChar;
|
||||
const Args:Array of const):Integer; register; public;
|
||||
var
|
||||
res:Integer;
|
||||
begin
|
||||
res:=make_dev_alias_v(flags, cdev, pdev, fmt, Args);
|
||||
|
||||
Exit(res);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
|
@ -6,6 +6,7 @@ unit sys_event;
|
|||
interface
|
||||
|
||||
uses
|
||||
time,
|
||||
mqueue;
|
||||
|
||||
const
|
||||
|
@ -39,6 +40,7 @@ const
|
|||
EV_DELETE =$0002; // delete event from kq
|
||||
EV_ENABLE =$0004; // enable event
|
||||
EV_DISABLE =$0008; // disable event (not reported)
|
||||
EV_ACTION =EV_ADD or EV_DELETE or EV_ENABLE or EV_DISABLE;
|
||||
|
||||
// flags
|
||||
EV_ONESHOT =$0010; // only report one occurrence
|
||||
|
@ -227,6 +229,8 @@ type
|
|||
end;
|
||||
{$IF sizeof(t_kevent_copyops)<>24}{$STOP sizeof(t_kevent_copyops)<>24}{$ENDIF}
|
||||
|
||||
t_kqueue_wakeup_cb=procedure(data:Pointer);
|
||||
|
||||
function knote_alloc():p_knote; external;
|
||||
procedure knote_free(kn:p_knote); external;
|
||||
|
||||
|
@ -243,6 +247,25 @@ procedure knlist_init_mtx(knl:p_knlist;lock:Pointer); external;
|
|||
procedure knlist_destroy (knl:p_knlist); external;
|
||||
procedure knlist_cleardel(knl:p_knlist;islocked,killkn:Integer); external;
|
||||
|
||||
function kern_kqueue2(name:PAnsiChar;
|
||||
w_cb:t_kqueue_wakeup_cb;
|
||||
data:Pointer):Pointer; external;
|
||||
|
||||
procedure kqueue_close2(kq:Pointer); external;
|
||||
|
||||
function kern_kevent2(kq :Pointer;
|
||||
changelist:p_kevent;
|
||||
nchanges :Integer;
|
||||
eventlist :p_kevent;
|
||||
nevents :Integer;
|
||||
timeout :p_timespec;
|
||||
p_ncount :PInteger):Integer; external;
|
||||
|
||||
function kqueue_add_filteropts(filt:Integer;filtops:p_filterops):Integer; external;
|
||||
function kqueue_del_filteropts(filt:Integer):Integer; external;
|
||||
function kqfd_register(fd:Integer;kev:p_kevent):Integer; external;
|
||||
procedure kqueue_deregister(filter:SmallInt;pid,ident:PtrUint); external;
|
||||
|
||||
//
|
||||
|
||||
procedure KNOTE_LOCKED (list:p_knlist;hint:QWORD);
|
||||
|
|
|
@ -44,6 +44,8 @@ type
|
|||
kq_knhashmask:QWORD; // size of knhash
|
||||
kq_knhash :p_klist; // hash table for knotes
|
||||
//kq_task:task;
|
||||
kq_wakeup :t_kqueue_wakeup_cb;
|
||||
kq_data :Pointer;
|
||||
kq_name :t_kq_name;
|
||||
end;
|
||||
|
||||
|
|
|
@ -12,6 +12,9 @@ implementation
|
|||
uses
|
||||
init_sysent, //compile spec
|
||||
kern_rtprio, //compile spec
|
||||
kern_conf, //compile spec
|
||||
devfs_vnops, //compile spec
|
||||
devfs_rule, //compile spec
|
||||
time,
|
||||
kern_time,
|
||||
subr_sleepqueue,
|
||||
|
@ -42,7 +45,7 @@ uses
|
|||
ufs,
|
||||
kern_descrip,
|
||||
vfs_mountroot,
|
||||
kern_conf,
|
||||
sys_conf,
|
||||
dev_null,
|
||||
dev_tty,
|
||||
dev_dmem,
|
||||
|
|
|
@ -7,8 +7,8 @@ interface
|
|||
|
||||
uses
|
||||
mqueue,
|
||||
sys_conf,
|
||||
kern_param,
|
||||
sys_event,
|
||||
vmount,
|
||||
vfile,
|
||||
vuio,
|
||||
|
@ -18,274 +18,12 @@ uses
|
|||
sys_vm_object,
|
||||
kern_mtx;
|
||||
|
||||
const
|
||||
//modeventtype
|
||||
MOD_LOAD =0;
|
||||
MOD_UNLOAD =1;
|
||||
MOD_SHUTDOWN=2;
|
||||
MOD_QUIESCE =3;
|
||||
|
||||
SI_ETERNAL =$0001; { never destroyed }
|
||||
SI_ALIAS =$0002; { carrier of alias name }
|
||||
SI_NAMED =$0004; { make_dev _alias has been called }
|
||||
SI_CHEAPCLONE=$0008; { can be removed_dev'ed when vnode reclaims }
|
||||
SI_CHILD =$0010; { child of another struct cdev *}
|
||||
SI_DEVOPEN =$0020; { opened by device }
|
||||
SI_CONSOPEN =$0040; { opened by console }
|
||||
SI_DUMPDEV =$0080; { is kernel dumpdev }
|
||||
SI_CANDELETE =$0100; { can do BIO_DELETE }
|
||||
SI_CLONELIST =$0200; { on a clone list }
|
||||
SI_UNMAPPED =$0400; { can handle unmapped I/O }
|
||||
|
||||
type
|
||||
pp_cdev=^p_cdev;
|
||||
p_cdev=^t_cdev;
|
||||
t_cdev=packed record
|
||||
si_mountpt :p_mount;
|
||||
si_flags :DWORD;
|
||||
_align1 :Integer;
|
||||
si_atime :timespec;
|
||||
si_ctime :timespec;
|
||||
si_mtime :timespec;
|
||||
si_uid :uid_t;
|
||||
si_gid :gid_t;
|
||||
si_mode :mode_t;
|
||||
si_drv0 :Integer;
|
||||
si_refcount :Integer;
|
||||
_align2 :Integer;
|
||||
si_list :LIST_ENTRY; //(cdev)
|
||||
si_clone :LIST_ENTRY; //(cdev)
|
||||
si_children :LIST_HEAD ; //(cdev)
|
||||
si_siblings :LIST_ENTRY; //(cdev)
|
||||
si_parent :p_cdev;
|
||||
si_name :PChar;
|
||||
si_drv1 :Pointer;
|
||||
si_drv2 :Pointer;
|
||||
si_devsw :Pointer; //cdevsw
|
||||
si_iosize_max :Integer; { maximum I/O size (for physio &al) }
|
||||
_align3 :Integer;
|
||||
si_usecount :QWORD;
|
||||
si_threadcount:QWORD;
|
||||
si_snapdata :Pointer; //snapdata
|
||||
__si_namebuf :array[0..SPECNAMELEN] of AnsiChar;
|
||||
end;
|
||||
|
||||
d_open_t =Function (dev:p_cdev;oflags,devtype:Integer):Integer;
|
||||
d_fdopen_t =Function (dev:p_cdev;oflags:Integer;fp:p_file):Integer;
|
||||
d_close_t =Function (dev:p_cdev;fflag,devtype:Integer):Integer;
|
||||
d_strategy_t =Procedure(bp:Pointer);//bio
|
||||
d_ioctl_t =Function (dev:p_cdev;cmd:QWORD;data:Pointer;fflag:Integer):Integer;
|
||||
|
||||
d_read_t =Function (dev:p_cdev;uio:p_uio;ioflag:Integer):Integer;
|
||||
d_write_t =Function (dev:p_cdev;uio:p_uio;ioflag:Integer):Integer;
|
||||
d_poll_t =Function (dev:p_cdev;events:Integer):Integer;
|
||||
d_kqfilter_t =Function (dev:p_cdev;kn:p_knote):Integer;
|
||||
d_mmap_t =Function (dev:p_cdev;offset:vm_ooffset_t;paddr:p_vm_paddr_t;nprot:Integer;memattr:p_vm_memattr_t):Integer;
|
||||
d_mmap_single_t =Function (dev:p_cdev;offset:p_vm_ooffset_t;size:vm_size_t;obj:p_vm_object_t;nprot:Integer):Integer;
|
||||
d_mmap_single2_t=Function (dev:p_cdev;offset:p_vm_ooffset_t;size:vm_size_t;obj:p_vm_object_t;nprot:Integer;maxprotp:p_vm_prot_t;flagsp:PInteger):Integer;
|
||||
d_purge_t =Procedure(dev:p_cdev);
|
||||
|
||||
dumper_t=Function(
|
||||
_priv:Pointer ; { Private to the driver. }
|
||||
_virtual:Pointer ; { Virtual (mapped) address. }
|
||||
_physical:vm_offset_t; { Physical address of virtual. }
|
||||
_offset:Int64 ; { Byte-offset to write at. }
|
||||
_length:QWORD):Integer; { Number of bytes to dump. }
|
||||
|
||||
const
|
||||
{
|
||||
* Types for d_flags.
|
||||
}
|
||||
D_TAPE=$0001;
|
||||
D_DISK=$0002;
|
||||
D_TTY =$0004;
|
||||
D_MEM =$0008;
|
||||
|
||||
D_TYPEMASK=$ffff;
|
||||
|
||||
{
|
||||
* Flags for d_flags which the drivers can set.
|
||||
}
|
||||
D_TRACKCLOSE =$00080000; { track all closes }
|
||||
D_MMAP_ANON =$00100000; { special treatment in vm_mmap.c }
|
||||
D_PSEUDO =$00200000; { make_dev() can return NULL }
|
||||
D_NEEDGIANT =$00400000; { driver want Giant }
|
||||
D_NEEDMINOR =$00800000; { driver uses clone_create() }
|
||||
D_UNMAPPED_IO=$01000000; { d_strategy can accept unmapped IO }
|
||||
|
||||
{
|
||||
* Version numbers.
|
||||
}
|
||||
D_VERSION_00=$20011966;
|
||||
D_VERSION_01=$17032005; { Add d_uid,gid,mode & kind }
|
||||
D_VERSION_02=$28042009; { Add d_mmap_single }
|
||||
D_VERSION_03=$17122009; { d_mmap takes memattr,vm_ooffset_t }
|
||||
D_VERSION=D_VERSION_03;
|
||||
|
||||
{
|
||||
* Flags used for internal housekeeping
|
||||
}
|
||||
D_INIT =$80000000; { cdevsw initialized }
|
||||
|
||||
{
|
||||
* Character device switch table
|
||||
}
|
||||
type
|
||||
pp_cdevsw=^p_cdevsw;
|
||||
p_cdevsw=^t_cdevsw;
|
||||
t_cdevsw=packed record
|
||||
d_version :Integer;
|
||||
d_flags :DWORD;
|
||||
d_name :PChar;
|
||||
d_open :d_open_t;
|
||||
d_fdopen :d_fdopen_t;
|
||||
d_close :d_close_t;
|
||||
d_read :d_read_t;
|
||||
d_write :d_write_t;
|
||||
d_ioctl :d_ioctl_t;
|
||||
d_poll :d_poll_t;
|
||||
d_mmap :d_mmap_t;
|
||||
d_strategy :d_strategy_t;
|
||||
d_dump :dumper_t;
|
||||
d_kqfilter :d_kqfilter_t;
|
||||
d_purge :d_purge_t;
|
||||
d_mmap_single :d_mmap_single_t;
|
||||
d_mmap_single2:d_mmap_single2_t;
|
||||
|
||||
d_spare0:array[0..1] of Integer;
|
||||
d_spare1:array[0..2] of Pointer;
|
||||
|
||||
{ These fields should not be messed with by drivers }
|
||||
d_devs:Pointer; //cdev
|
||||
d_spare2:array[0..1] of Integer;
|
||||
d_gianttrick:p_cdevsw;
|
||||
d_postfree_list:SLIST_ENTRY; //cdevsw
|
||||
end;
|
||||
|
||||
const
|
||||
MAKEDEV_REF =$01;
|
||||
MAKEDEV_WHTOUT =$02;
|
||||
MAKEDEV_NOWAIT =$04;
|
||||
MAKEDEV_WAITOK =$08;
|
||||
MAKEDEV_ETERNAL =$10;
|
||||
MAKEDEV_CHECKNAME=$20;
|
||||
|
||||
UID_ROOT =0;
|
||||
UID_BIN =3;
|
||||
UID_UUCP =66;
|
||||
UID_NOBODY =65534;
|
||||
|
||||
GID_WHEEL =0;
|
||||
GID_KMEM =2;
|
||||
GID_TTY =4;
|
||||
GID_OPERATOR=5;
|
||||
GID_BIN =7;
|
||||
GID_GAMES =13;
|
||||
GID_DIALER =68;
|
||||
GID_NOBODY =65534;
|
||||
|
||||
function dev2unit(d:p_cdev):Integer; inline;
|
||||
function devtoname(dev:p_cdev):PChar;
|
||||
|
||||
type
|
||||
cdevpriv_dtr_t=Procedure(data:Pointer);
|
||||
|
||||
var
|
||||
devmtx:mtx;
|
||||
|
||||
cdevp_free_list:TAILQ_HEAD=(tqh_first:nil;tqh_last:@cdevp_free_list.tqh_first);
|
||||
cdevsw_gt_post_list:SLIST_HEAD=(slh_first:nil);
|
||||
|
||||
function _nullop():Integer;
|
||||
function _eopnotsupp():Integer;
|
||||
function _enxio():Integer;
|
||||
function _enodev():Integer;
|
||||
function _einval():Integer;
|
||||
|
||||
procedure dev_lock();
|
||||
procedure dev_unlock();
|
||||
procedure dev_ref(dev:p_cdev);
|
||||
procedure dev_refl(dev:p_cdev);
|
||||
procedure dev_rel(dev:p_cdev);
|
||||
|
||||
function dev_refthread(dev:p_cdev;ref:PInteger):p_cdevsw;
|
||||
function devvn_refthread(vp:p_vnode;devp:pp_cdev;ref:PInteger):p_cdevsw;
|
||||
procedure dev_relthread(dev:p_cdev;ref:Integer);
|
||||
|
||||
procedure destroy_dev(dev:p_cdev);
|
||||
|
||||
function make_dev_credv(flags:Integer;
|
||||
dres:pp_cdev;
|
||||
devsw:p_cdevsw;
|
||||
_unit:Integer;
|
||||
uid:uid_t;
|
||||
gid:gid_t;
|
||||
mode:Integer;
|
||||
fmt:PChar;
|
||||
const Args:Array of const):Integer; register;
|
||||
|
||||
function make_dev(devsw:p_cdevsw;
|
||||
_unit:Integer;
|
||||
uid:uid_t;
|
||||
gid:gid_t;
|
||||
mode:Integer;
|
||||
fmt:PChar;
|
||||
const Args:Array of const):p_cdev; register;
|
||||
|
||||
function make_dev_cred(devsw:p_cdevsw;
|
||||
_unit:Integer;
|
||||
uid:uid_t;
|
||||
gid:gid_t;
|
||||
mode:Integer;
|
||||
fmt:PChar;
|
||||
const Args:Array of const):p_cdev; register;
|
||||
|
||||
function make_dev_credf(flags:Integer;
|
||||
devsw:p_cdevsw;
|
||||
_unit:Integer;
|
||||
uid:uid_t;
|
||||
gid:gid_t;
|
||||
mode:Integer;
|
||||
fmt:PChar;
|
||||
const Args:Array of const):p_cdev; register;
|
||||
|
||||
function make_dev_p(flags:Integer;
|
||||
cdev:pp_cdev;
|
||||
devsw:p_cdevsw;
|
||||
uid:uid_t;
|
||||
gid:gid_t;
|
||||
mode:Integer;
|
||||
fmt:PChar;
|
||||
const Args:Array of const):Integer; register;
|
||||
|
||||
function make_dev_alias_v(flags:Integer;
|
||||
cdev:pp_cdev;
|
||||
pdev:p_cdev;
|
||||
fmt:PChar;
|
||||
const Args:Array of const):Integer; register;
|
||||
|
||||
function make_dev_alias(pdev:p_cdev;
|
||||
fmt:PChar;
|
||||
const Args:Array of const):p_cdev; register;
|
||||
|
||||
function make_dev_alias_p(flags:Integer;
|
||||
cdev:pp_cdev;
|
||||
pdev:p_cdev;
|
||||
fmt:PChar;
|
||||
const Args:Array of const):Integer; register;
|
||||
|
||||
function make_dev_physpath_alias(flags:Integer;
|
||||
cdev:pp_cdev;
|
||||
pdev,old_alias:p_cdev;
|
||||
physpath:PChar):Integer;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
sysutils,
|
||||
errno,
|
||||
devfs,
|
||||
devfs_vnops,
|
||||
devfs_int,
|
||||
vsys_generic,
|
||||
kern_synch;
|
||||
|
||||
|
@ -304,30 +42,30 @@ begin
|
|||
Result:=c-ptruint(@p_cdev_priv(nil)^.cdp_c);
|
||||
end;
|
||||
|
||||
procedure dev_lock();
|
||||
procedure dev_lock(); public;
|
||||
begin
|
||||
mtx_lock(devmtx);
|
||||
end;
|
||||
|
||||
procedure dev_unlock();
|
||||
procedure dev_unlock(); public;
|
||||
begin
|
||||
mtx_unlock(devmtx);
|
||||
end;
|
||||
|
||||
procedure dev_ref(dev:p_cdev);
|
||||
procedure dev_ref(dev:p_cdev); public;
|
||||
begin
|
||||
mtx_lock(devmtx);
|
||||
Inc(dev^.si_refcount);
|
||||
mtx_unlock(devmtx);
|
||||
end;
|
||||
|
||||
procedure dev_refl(dev:p_cdev);
|
||||
procedure dev_refl(dev:p_cdev); public;
|
||||
begin
|
||||
mtx_assert(devmtx);
|
||||
Inc(dev^.si_refcount);
|
||||
end;
|
||||
|
||||
procedure dev_rel(dev:p_cdev);
|
||||
procedure dev_rel(dev:p_cdev); public;
|
||||
var
|
||||
flag:Integer;
|
||||
begin
|
||||
|
@ -350,7 +88,7 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function dev_refthread(dev:p_cdev;ref:PInteger):p_cdevsw;
|
||||
function dev_refthread(dev:p_cdev;ref:PInteger):p_cdevsw; public;
|
||||
var
|
||||
csw:p_cdevsw;
|
||||
cdp:p_cdev_priv;
|
||||
|
@ -375,7 +113,7 @@ begin
|
|||
Exit(csw);
|
||||
end;
|
||||
|
||||
function devvn_refthread(vp:p_vnode;devp:pp_cdev;ref:PInteger):p_cdevsw;
|
||||
function devvn_refthread(vp:p_vnode;devp:pp_cdev;ref:PInteger):p_cdevsw; public;
|
||||
var
|
||||
csw:p_cdevsw;
|
||||
cdp:p_cdev_priv;
|
||||
|
@ -418,7 +156,7 @@ begin
|
|||
Exit(csw);
|
||||
end;
|
||||
|
||||
procedure dev_relthread(dev:p_cdev;ref:Integer);
|
||||
procedure dev_relthread(dev:p_cdev;ref:Integer); public;
|
||||
begin
|
||||
if (ref=0) then Exit;
|
||||
dev_lock();
|
||||
|
@ -486,31 +224,6 @@ begin
|
|||
SLIST_INSERT_HEAD(@cdevsw_gt_post_list,csw,@csw^.d_postfree_list);
|
||||
end;
|
||||
|
||||
function _nullop():Integer;
|
||||
begin
|
||||
Exit(0);
|
||||
end;
|
||||
|
||||
function _eopnotsupp():Integer;
|
||||
begin
|
||||
Exit(EOPNOTSUPP);
|
||||
end;
|
||||
|
||||
function _enxio():Integer;
|
||||
begin
|
||||
Exit(ENXIO);
|
||||
end;
|
||||
|
||||
function _enodev():Integer;
|
||||
begin
|
||||
Exit(ENODEV);
|
||||
end;
|
||||
|
||||
function _einval():Integer;
|
||||
begin
|
||||
Exit(EINVAL);
|
||||
end;
|
||||
|
||||
procedure dead_strategy(bp:Pointer);
|
||||
begin
|
||||
//biofinish(bp, nil, ENXIO);
|
||||
|
@ -1000,7 +713,7 @@ function make_dev_credv(flags:Integer;
|
|||
gid:gid_t;
|
||||
mode:Integer;
|
||||
fmt:PChar;
|
||||
const Args:Array of const):Integer; register;
|
||||
const Args:Array of const):Integer; register; public name 'make_dev_credv';
|
||||
var
|
||||
dev,dev_new:p_cdev;
|
||||
res:Integer;
|
||||
|
@ -1074,92 +787,6 @@ begin
|
|||
Exit(0);
|
||||
end;
|
||||
|
||||
function make_dev(devsw:p_cdevsw;
|
||||
_unit:Integer;
|
||||
uid:uid_t;
|
||||
gid:gid_t;
|
||||
mode:Integer;
|
||||
fmt:PChar;
|
||||
const Args:Array of const):p_cdev; register;
|
||||
var
|
||||
dev:p_cdev;
|
||||
res:Integer;
|
||||
begin
|
||||
res:=make_dev_credv(0, @dev, devsw, _unit, uid, gid, mode, fmt, Args);
|
||||
|
||||
Assert((res=0) and (dev<>nil),'make_dev: failed make_dev_credv (error=%d)');
|
||||
|
||||
if (res=0) then
|
||||
Exit(dev)
|
||||
else
|
||||
Exit(nil);
|
||||
end;
|
||||
|
||||
function make_dev_cred(devsw:p_cdevsw;
|
||||
_unit:Integer;
|
||||
uid:uid_t;
|
||||
gid:gid_t;
|
||||
mode:Integer;
|
||||
fmt:PChar;
|
||||
const Args:Array of const):p_cdev; register;
|
||||
var
|
||||
dev:p_cdev;
|
||||
res:Integer;
|
||||
begin
|
||||
res:=make_dev_credv(0, @dev, devsw, _unit, uid, gid, mode, fmt, Args);
|
||||
|
||||
Assert((res=0) and (dev<>nil),'make_dev_cred: failed make_dev_credv (error=%d)');
|
||||
|
||||
if (res=0) then
|
||||
Exit(dev)
|
||||
else
|
||||
Exit(nil);
|
||||
end;
|
||||
|
||||
function make_dev_credf(flags:Integer;
|
||||
devsw:p_cdevsw;
|
||||
_unit:Integer;
|
||||
uid:uid_t;
|
||||
gid:gid_t;
|
||||
mode:Integer;
|
||||
fmt:PChar;
|
||||
const Args:Array of const):p_cdev; register;
|
||||
var
|
||||
dev:p_cdev;
|
||||
res:Integer;
|
||||
begin
|
||||
res:=make_dev_credv(flags, @dev, devsw, _unit, uid, gid, mode, fmt, Args);
|
||||
|
||||
Assert((((flags and MAKEDEV_NOWAIT)<>0) and (res=ENOMEM)) or
|
||||
(((flags and MAKEDEV_CHECKNAME)<>0) and (res<>ENOMEM)) or
|
||||
(res=0),'make_dev_credf: failed make_dev_credv (error=%d)');
|
||||
|
||||
if (res=0) then
|
||||
Exit(dev)
|
||||
else
|
||||
Exit(nil);
|
||||
end;
|
||||
|
||||
function make_dev_p(flags:Integer;
|
||||
cdev:pp_cdev;
|
||||
devsw:p_cdevsw;
|
||||
uid:uid_t;
|
||||
gid:gid_t;
|
||||
mode:Integer;
|
||||
fmt:PChar;
|
||||
const Args:Array of const):Integer; register;
|
||||
var
|
||||
res:Integer;
|
||||
begin
|
||||
res:=make_dev_credv(flags, cdev, devsw, 0, uid, gid, mode, fmt, Args);
|
||||
|
||||
Assert((((flags and MAKEDEV_NOWAIT)<>0) and (res=ENOMEM)) or
|
||||
(((flags and MAKEDEV_CHECKNAME)<>0) and (res<>ENOMEM)) or
|
||||
(res=0),'make_dev_p: failed make_dev_credv (error=%d)');
|
||||
|
||||
Exit(res);
|
||||
end;
|
||||
|
||||
procedure dev_dependsl(pdev,cdev:p_cdev);
|
||||
begin
|
||||
cdev^.si_parent:=pdev;
|
||||
|
@ -1178,7 +805,7 @@ function make_dev_alias_v(flags:Integer;
|
|||
cdev:pp_cdev;
|
||||
pdev:p_cdev;
|
||||
fmt:PChar;
|
||||
const Args:Array of const):Integer; register;
|
||||
const Args:Array of const):Integer; register; public name 'make_dev_alias_v';
|
||||
var
|
||||
dev:p_cdev;
|
||||
error:Integer;
|
||||
|
@ -1217,40 +844,10 @@ begin
|
|||
Exit(0);
|
||||
end;
|
||||
|
||||
function make_dev_alias(pdev:p_cdev;
|
||||
fmt:PChar;
|
||||
const Args:Array of const):p_cdev; register;
|
||||
var
|
||||
dev:p_cdev;
|
||||
res:Integer;
|
||||
begin
|
||||
res:=make_dev_alias_v(MAKEDEV_WAITOK, @dev, pdev, fmt, Args);
|
||||
|
||||
Assert((res=0) and (dev<>nil),'make_dev_alias: failed make_dev_alias_v (error=%d)');
|
||||
|
||||
if (res=0) then
|
||||
Exit(dev)
|
||||
else
|
||||
Exit(nil);
|
||||
end;
|
||||
|
||||
function make_dev_alias_p(flags:Integer;
|
||||
cdev:pp_cdev;
|
||||
pdev:p_cdev;
|
||||
fmt:PChar;
|
||||
const Args:Array of const):Integer; register;
|
||||
var
|
||||
res:Integer;
|
||||
begin
|
||||
res:=make_dev_alias_v(flags, cdev, pdev, fmt, Args);
|
||||
|
||||
Exit(res);
|
||||
end;
|
||||
|
||||
function make_dev_physpath_alias(flags:Integer;
|
||||
cdev:pp_cdev;
|
||||
pdev,old_alias:p_cdev;
|
||||
physpath:PChar):Integer;
|
||||
physpath:PChar):Integer; public;
|
||||
label
|
||||
_ret,
|
||||
_out;
|
||||
|
@ -1473,7 +1070,7 @@ begin
|
|||
dev_unlock();
|
||||
end;
|
||||
|
||||
procedure destroy_dev(dev:p_cdev);
|
||||
procedure destroy_dev(dev:p_cdev); public;
|
||||
begin
|
||||
dev_lock();
|
||||
destroy_devl(dev);
|
||||
|
|
|
@ -137,7 +137,7 @@ uses
|
|||
sys_resource,
|
||||
kern_resource,
|
||||
kern_mtx,
|
||||
kern_conf;
|
||||
sys_conf;
|
||||
|
||||
//
|
||||
|
||||
|
@ -809,7 +809,7 @@ begin
|
|||
Exit(0);
|
||||
end;
|
||||
|
||||
function kern_close(fd:Integer):Integer;
|
||||
function kern_close(fd:Integer):Integer; public;
|
||||
var
|
||||
fp,fp_object:p_file;
|
||||
begin
|
||||
|
|
|
@ -193,7 +193,7 @@ uses
|
|||
sys_vm_object,
|
||||
vsys_generic,
|
||||
rtprio,
|
||||
kern_conf;
|
||||
sys_conf;
|
||||
|
||||
//
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ uses
|
|||
errno,
|
||||
vmparam,
|
||||
vm_pmap,
|
||||
kern_conf;
|
||||
sys_conf;
|
||||
|
||||
function OFF_TO_IDX(x:QWORD):DWORD; inline;
|
||||
begin
|
||||
|
|
|
@ -66,7 +66,7 @@ uses
|
|||
vnode,
|
||||
vfs_subr,
|
||||
vnode_if,
|
||||
kern_conf,
|
||||
sys_conf,
|
||||
vm_pager;
|
||||
|
||||
function vm_mmap_cdev(objsize :vm_size_t;
|
||||
|
|
Loading…
Reference in New Issue