From ecf4f7d7bced46d8349a8131a5b10453ccb5230c Mon Sep 17 00:00:00 2001
From: Pavel <68122101+red-prig@users.noreply.github.com>
Date: Sun, 18 Feb 2024 02:08:40 +0300
Subject: [PATCH] +
---
fpPS4.lpi | 8 +
gui/game_run.pas | 30 ++-
gui/main.pas | 48 ++--
sys/dev/dev_dce.pas | 42 ++--
sys/dev/dev_dipsw.pas | 2 +-
sys/dev/dev_dmem.pas | 2 +-
sys/dev/dev_gc.pas | 7 +-
sys/dev/dev_null.pas | 2 +-
sys/dev/dev_rng.pas | 2 +-
sys/dev/dev_tty.pas | 2 +-
sys/dev/devfs_int.pas | 235 ++++++++++++++++++
sys/dev/display_interface.pas | 9 +-
sys/fs/devfs/devfs.pas | 261 +++-----------------
sys/fs/devfs/devfs_devs.pas | 6 +-
sys/fs/devfs/devfs_rule.pas | 13 +-
sys/fs/devfs/devfs_vfsops.pas | 11 +-
sys/fs/devfs/devfs_vnops.pas | 16 +-
sys/host_ipc.pas | 167 ++++++++++---
sys/kern/kern_blockpool.pas | 2 +-
sys/kern/kern_event.pas | 337 +++++++++++++++++--------
sys/kern/kern_exec.pas | 1 -
sys/kern/kern_exit.pas | 5 +-
sys/kern/kern_proc.pas | 39 ---
sys/kern/uipc_syscalls.pas | 2 +-
sys/md/md_exception.pas | 7 +-
sys/md/md_host_ipc.pas | 50 ++--
sys/md/md_systm.pas | 79 +++---
sys/sys_conf.pas | 450 ++++++++++++++++++++++++++++++++++
sys/sys_event.pas | 23 ++
sys/sys_eventvar.pas | 2 +
sys/sys_sysinit.pas | 5 +-
sys/vfs/kern_conf.pas | 431 ++------------------------------
sys/vfs/kern_descrip.pas | 4 +-
sys/vfs/vfs_subr.pas | 2 +-
sys/vm/device_pager.pas | 2 +-
sys/vm/vm_mmap.pas | 2 +-
36 files changed, 1337 insertions(+), 969 deletions(-)
create mode 100644 sys/dev/devfs_int.pas
create mode 100644 sys/sys_conf.pas
diff --git a/fpPS4.lpi b/fpPS4.lpi
index a1642674..1fe6b3da 100644
--- a/fpPS4.lpi
+++ b/fpPS4.lpi
@@ -846,6 +846,14 @@
+
+
+
+
+
+
+
+
diff --git a/gui/game_run.pas b/gui/game_run.pas
index 5763c1fb..3f307af4 100644
--- a/gui/game_run.pas
+++ b/gui/game_run.pas
@@ -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;
diff --git a/gui/main.pas b/gui/main.pas
index f2407cbe..ef036fc7 100644
--- a/gui/main.pas
+++ b/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;
diff --git a/sys/dev/dev_dce.pas b/sys/dev/dev_dce.pas
index 946c4477..2e9299c1 100644
--- a/sys/dev/dev_dce.pas
+++ b/sys/dev/dev_dce.pas
@@ -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;
diff --git a/sys/dev/dev_dipsw.pas b/sys/dev/dev_dipsw.pas
index 866565e2..cbcb0e54 100644
--- a/sys/dev/dev_dipsw.pas
+++ b/sys/dev/dev_dipsw.pas
@@ -6,7 +6,7 @@ unit dev_dipsw;
interface
uses
- kern_conf;
+ sys_conf;
procedure dipsw_init();
diff --git a/sys/dev/dev_dmem.pas b/sys/dev/dev_dmem.pas
index 7ef9300b..ce5719c1 100644
--- a/sys/dev/dev_dmem.pas
+++ b/sys/dev/dev_dmem.pas
@@ -6,7 +6,7 @@ unit dev_dmem;
interface
uses
- kern_conf;
+ sys_conf;
procedure dmemdev_init();
diff --git a/sys/dev/dev_gc.pas b/sys/dev/dev_gc.pas
index 2605f4e1..c2806a6d 100644
--- a/sys/dev/dev_gc.pas
+++ b/sys/dev/dev_gc.pas
@@ -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);
diff --git a/sys/dev/dev_null.pas b/sys/dev/dev_null.pas
index 67e78e16..1e44128f 100644
--- a/sys/dev/dev_null.pas
+++ b/sys/dev/dev_null.pas
@@ -6,7 +6,7 @@ unit dev_null;
interface
uses
- kern_conf;
+ sys_conf;
const
ZERO_REGION_SIZE=(2 * 1024 * 1024); // 2MB
diff --git a/sys/dev/dev_rng.pas b/sys/dev/dev_rng.pas
index 3385c2f4..ea927c0c 100644
--- a/sys/dev/dev_rng.pas
+++ b/sys/dev/dev_rng.pas
@@ -6,7 +6,7 @@ unit dev_rng;
interface
uses
- kern_conf;
+ sys_conf;
procedure rng_init();
diff --git a/sys/dev/dev_tty.pas b/sys/dev/dev_tty.pas
index c535e963..3052c4a7 100644
--- a/sys/dev/dev_tty.pas
+++ b/sys/dev/dev_tty.pas
@@ -9,7 +9,7 @@ uses
sysutils,
vselinfo,
kern_thr,
- kern_conf,
+ sys_conf,
sys_tty;
var
diff --git a/sys/dev/devfs_int.pas b/sys/dev/devfs_int.pas
new file mode 100644
index 00000000..8ff221db
--- /dev/null
+++ b/sys/dev/devfs_int.pas
@@ -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.
+
diff --git a/sys/dev/display_interface.pas b/sys/dev/display_interface.pas
index f1f0c408..72a4d91f 100644
--- a/sys/dev/display_interface.pas
+++ b/sys/dev/display_interface.pas
@@ -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.
diff --git a/sys/fs/devfs/devfs.pas b/sys/fs/devfs/devfs.pas
index 9d22199a..731d9e75 100644
--- a/sys/fs/devfs/devfs.pas
+++ b/sys/fs/devfs/devfs.pas
@@ -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
diff --git a/sys/fs/devfs/devfs_devs.pas b/sys/fs/devfs/devfs_devs.pas
index 25607a50..19779660 100644
--- a/sys/fs/devfs/devfs_devs.pas
+++ b/sys/fs/devfs/devfs_devs.pas
@@ -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);
diff --git a/sys/fs/devfs/devfs_rule.pas b/sys/fs/devfs/devfs_rule.pas
index c4770d84..b66edd57 100644
--- a/sys/fs/devfs/devfs_rule.pas
+++ b/sys/fs/devfs/devfs_rule.pas
@@ -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
diff --git a/sys/fs/devfs/devfs_vfsops.pas b/sys/fs/devfs/devfs_vfsops.pas
index a4275246..25f78b66 100644
--- a/sys/fs/devfs/devfs_vfsops.pas
+++ b/sys/fs/devfs/devfs_vfsops.pas
@@ -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);
diff --git a/sys/fs/devfs/devfs_vnops.pas b/sys/fs/devfs/devfs_vnops.pas
index 39b774d1..07b4e278 100644
--- a/sys/fs/devfs/devfs_vnops.pas
+++ b/sys/fs/devfs/devfs_vnops.pas
@@ -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
diff --git a/sys/host_ipc.pas b/sys/host_ipc.pas
index 83cc30fd..503edef9 100644
--- a/sys/host_ipc.pas
+++ b/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.
diff --git a/sys/kern/kern_blockpool.pas b/sys/kern/kern_blockpool.pas
index 6b300838..370f01da 100644
--- a/sys/kern/kern_blockpool.pas
+++ b/sys/kern/kern_blockpool.pas
@@ -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;
diff --git a/sys/kern/kern_event.pas b/sys/kern/kern_event.pas
index a6d2cae1..3cbd0ee8 100644
--- a/sys/kern/kern_event.pas
+++ b/sys/kern/kern_event.pas
@@ -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
diff --git a/sys/kern/kern_exec.pas b/sys/kern/kern_exec.pas
index 8c04eb29..71eed5ba 100644
--- a/sys/kern/kern_exec.pas
+++ b/sys/kern/kern_exec.pas
@@ -59,7 +59,6 @@ uses
sys_resource,
kern_resource,
sys_event,
- kern_event,
machdep,
kern_dlsym,
kern_authinfo,
diff --git a/sys/kern/kern_exit.pas b/sys/kern/kern_exit.pas
index a1fd6566..fdb383fb 100644
--- a/sys/kern/kern_exit.pas
+++ b/sys/kern/kern_exit.pas
@@ -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;
diff --git a/sys/kern/kern_proc.pas b/sys/kern/kern_proc.pas
index 5dbb0ded..b5bb3e02 100644
--- a/sys/kern/kern_proc.pas
+++ b/sys/kern/kern_proc.pas
@@ -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;
diff --git a/sys/kern/uipc_syscalls.pas b/sys/kern/uipc_syscalls.pas
index 1887a4a1..4a1e88be 100644
--- a/sys/kern/uipc_syscalls.pas
+++ b/sys/kern/uipc_syscalls.pas
@@ -14,7 +14,7 @@ implementation
uses
kern_thr,
kern_descrip,
- kern_conf,
+ sys_conf,
vsocket,
vfile,
vfcntl,
diff --git a/sys/md/md_exception.pas b/sys/md/md_exception.pas
index ef635123..a4c98acb 100644
--- a/sys/md/md_exception.pas
+++ b/sys/md/md_exception.pas
@@ -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
diff --git a/sys/md/md_host_ipc.pas b/sys/md/md_host_ipc.pas
index feec941e..50b89b87 100644
--- a/sys/md/md_host_ipc.pas
+++ b/sys/md/md_host_ipc.pas
@@ -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;
diff --git a/sys/md/md_systm.pas b/sys/md/md_systm.pas
index fb94e10a..cd59b021 100644
--- a/sys/md/md_systm.pas
+++ b/sys/md/md_systm.pas
@@ -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.
diff --git a/sys/sys_conf.pas b/sys/sys_conf.pas
new file mode 100644
index 00000000..db9c5b0d
--- /dev/null
+++ b/sys/sys_conf.pas
@@ -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.
+
diff --git a/sys/sys_event.pas b/sys/sys_event.pas
index 75858e90..9f3db94b 100644
--- a/sys/sys_event.pas
+++ b/sys/sys_event.pas
@@ -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);
diff --git a/sys/sys_eventvar.pas b/sys/sys_eventvar.pas
index 160c424e..f527c80a 100644
--- a/sys/sys_eventvar.pas
+++ b/sys/sys_eventvar.pas
@@ -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;
diff --git a/sys/sys_sysinit.pas b/sys/sys_sysinit.pas
index f1c80f79..72e1b9b8 100644
--- a/sys/sys_sysinit.pas
+++ b/sys/sys_sysinit.pas
@@ -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,
diff --git a/sys/vfs/kern_conf.pas b/sys/vfs/kern_conf.pas
index 5e6b68c9..cda87876 100644
--- a/sys/vfs/kern_conf.pas
+++ b/sys/vfs/kern_conf.pas
@@ -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);
diff --git a/sys/vfs/kern_descrip.pas b/sys/vfs/kern_descrip.pas
index 1e2b21f8..933f65d2 100644
--- a/sys/vfs/kern_descrip.pas
+++ b/sys/vfs/kern_descrip.pas
@@ -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
diff --git a/sys/vfs/vfs_subr.pas b/sys/vfs/vfs_subr.pas
index eb81303b..3b227666 100644
--- a/sys/vfs/vfs_subr.pas
+++ b/sys/vfs/vfs_subr.pas
@@ -193,7 +193,7 @@ uses
sys_vm_object,
vsys_generic,
rtprio,
- kern_conf;
+ sys_conf;
//
diff --git a/sys/vm/device_pager.pas b/sys/vm/device_pager.pas
index 269bb9bd..d3b0133b 100644
--- a/sys/vm/device_pager.pas
+++ b/sys/vm/device_pager.pas
@@ -23,7 +23,7 @@ uses
errno,
vmparam,
vm_pmap,
- kern_conf;
+ sys_conf;
function OFF_TO_IDX(x:QWORD):DWORD; inline;
begin
diff --git a/sys/vm/vm_mmap.pas b/sys/vm/vm_mmap.pas
index c13b54ec..5bddf387 100644
--- a/sys/vm/vm_mmap.pas
+++ b/sys/vm/vm_mmap.pas
@@ -66,7 +66,7 @@ uses
vnode,
vfs_subr,
vnode_if,
- kern_conf,
+ sys_conf,
vm_pager;
function vm_mmap_cdev(objsize :vm_size_t;