From 822072156397aa5dfc8016b6999c3eea1cf4450c Mon Sep 17 00:00:00 2001 From: Pavel <68122101+red-prig@users.noreply.github.com> Date: Tue, 17 Oct 2023 14:02:41 +0300 Subject: [PATCH] + --- sys/fs/fdescfs/fdesc_vnops.pas | 22 +++++++++++-- sys/kern/kern_event.pas | 35 ++++++++++++++++++--- sys/kern/kern_id.pas | 1 + sys/kern/kern_namedobj.pas | 57 +++++++++++++++++++++++++++++++++- sys/kern/kern_thread.pas | 14 +++++++++ sys/sys_event.pas | 31 ++++++++++++++++++ sys/vfs/kern_descrip.pas | 1 + sys/vfs/vfs_syscalls.pas | 3 ++ 8 files changed, 156 insertions(+), 8 deletions(-) diff --git a/sys/fs/fdescfs/fdesc_vnops.pas b/sys/fs/fdescfs/fdesc_vnops.pas index 75a8c2b6..f092ec3d 100644 --- a/sys/fs/fdescfs/fdesc_vnops.pas +++ b/sys/fs/fdescfs/fdesc_vnops.pas @@ -87,7 +87,6 @@ function fdesc_allocvp(ftype:fdntype;fd_fd,ix:Integer;mp:p_mount;vpp:pp_vnode): implementation uses - sysutils, errno, time, vfile, @@ -192,7 +191,9 @@ loop: VI_LOCK(vp); mtx_unlock(fdesc_hashmtx); if (vget(vp, LK_EXCLUSIVE or LK_INTERLOCK)<>0) then + begin goto loop; + end; vpp^:=vp; Exit(0); end; @@ -259,7 +260,9 @@ loop: vput(vp); { If we didn't get it, return no vnode. } if (error<>0) then + begin vp2:=nil; + end; vpp^:=vp2; Exit(error); end; @@ -348,7 +351,9 @@ begin } error:=fget(fd, 0, @fp); if (error<>0) then + begin goto bad; + end; { Check if we're looking up ourselves. } if (VTOFDESC(dvp)^.fd_ix=FD_DESC + fd) then @@ -387,7 +392,9 @@ begin end; if (error<>0) then + begin goto bad; + end; vpp^:=fvp; Exit(0); @@ -483,7 +490,9 @@ begin * Can't mess with the root vnode } if (VTOFDESC(ap^.a_vp)^.fd_type=_Froot) then + begin Exit(EACCES); + end; fd:=VTOFDESC(ap^.a_vp)^.fd_fd; @@ -539,7 +548,9 @@ begin dp:=@d; if (VTOFDESC(ap^.a_vp)^.fd_type<>_Froot) then + begin Assert(False,'fdesc_readdir: not dir'); + end; if (ap^.a_ncookies<>nil) then ap^.a_ncookies^:=0; @@ -550,7 +561,10 @@ begin (off < 0) or ((off mod UIO_MX)<>0) or (uio^.uio_resid < UIO_MX) then + begin Exit(EINVAL); + end; + i:=off div UIO_MX; error:=0; @@ -577,10 +591,12 @@ begin begin tmp:=fget_unlocked(fcnt); //check exists if (tmp=nil) then + begin goto _break; + end; fdrop(tmp); - dp^.d_name :=IntToStr(fcnt); + Str(fcnt,dp^.d_name); dp^.d_namlen:=strlen(dp^.d_name); dp^.d_reclen:=UIO_MX; dp^.d_type :=DT_CHR; @@ -597,7 +613,9 @@ begin FILEDESC_SUNLOCK(@fd_table); error:=uiomove(dp, UIO_MX, uio); if (error<>0) then + begin goto done; + end; FILEDESC_SLOCK(@fd_table); end; Inc(i); diff --git a/sys/kern/kern_event.pas b/sys/kern/kern_event.pas index fb54439d..3a549d5a 100644 --- a/sys/kern/kern_event.pas +++ b/sys/kern/kern_event.pas @@ -24,7 +24,8 @@ uses vcapability, vselinfo, vpoll, - vstat; + vstat, + trap; //TASKQUEUE_DEFINE_THREAD(kqueue); @@ -119,7 +120,9 @@ uses vsys_generic, kern_proc, kern_callout, - kern_timeout; + kern_timeout, + kern_named_id, + kern_namedobj; //static MALLOC_DEFINE(M_KQUEUE, 'kqueue', 'memory for kqueue system'); @@ -974,9 +977,11 @@ function kern_kevent(fd:Integer; label done_norel, done; +type + t_keva=array[0..KQ_NEVENTS-1] of t_kevent; var td:p_kthread; - keva:array[0..KQ_NEVENTS-1] of t_kevent; + keva:t_keva; kevp,changes:p_kevent; kq:p_kqueue; fp:p_file; @@ -991,7 +996,20 @@ begin error:=kqueue_acquire(fp, @kq); if (error<>0) then goto done_norel; + //cache + if (kq^.kq_name[0]=#0) and (kq^.kq_name[1]<>#1) then + begin + get_obj_name(Pointer(fd),$107,@kq^.kq_name); + if (kq^.kq_name[0]=#0) then + begin + kq^.kq_name[1]:=#1; + end; + end; + + Writeln('kern_kevent:',kq^.kq_name); + nerrors:=0; + keva:=Default(t_keva); while (nchanges > 0) do begin @@ -1026,6 +1044,7 @@ begin end; Dec(nchanges,n); end; + if (nerrors<>0) then begin td^.td_retval[0]:=nerrors; @@ -1147,9 +1166,13 @@ begin if (sysfilt_ops[not filt].fop=nil) then begin - Writeln(stderr,'kqueue_fo_find:',filt); + Writeln(stderr,'kqueue filterops not found:',EVFILT_NAME(filt)); sysfilt_ops[not filt].fop:=@null_filtops; + end else + begin + Writeln('kqueue_fo_find:',EVFILT_NAME(filt)); end; + mtx_unlock(filterops_lock); Exit(sysfilt_ops[not filt].fop); @@ -1270,7 +1293,9 @@ findkn: begin if (kev^.ident=kn^.kn_id) and (kev^.filter=kn^.kn_filter) then + begin break; + end; kn:=SLIST_NEXT(kn,@kn^.kn_link); end; end; @@ -1296,7 +1321,7 @@ findkn: end; { - * kn now contains the matching knote, or nil if no match + * kn now contains the matching knote, or null if no match } if (kn=nil) then begin diff --git a/sys/kern/kern_id.pas b/sys/kern/kern_id.pas index 9f9baf93..0b7e01b9 100644 --- a/sys/kern/kern_id.pas +++ b/sys/kern/kern_id.pas @@ -55,6 +55,7 @@ end; Procedure id_release(d:p_id_desc); begin if (d=nil) then Exit; + Assert(d^.refs>0); if (System.InterlockedDecrement(d^.refs)=0) then if (d^.free<>nil) then begin diff --git a/sys/kern/kern_namedobj.pas b/sys/kern/kern_namedobj.pas index 522925b3..b144e590 100644 --- a/sys/kern/kern_namedobj.pas +++ b/sys/kern/kern_namedobj.pas @@ -6,11 +6,13 @@ unit kern_namedobj; interface uses + mqueue, kern_named_id; type p_namedobj=^t_namedobj; t_namedobj=packed object(t_id_named_desc) + link:TAILQ_ENTRY; objp:Pointer; end; @@ -19,6 +21,8 @@ var procedure named_table_init; //SYSINIT +function get_obj_name(objp:Pointer;objt:Integer;name:PChar):Boolean; + function sys_namedobj_create(name:PChar;objp:Pointer;objt:Integer):Integer; function sys_namedobj_delete(id,objt:Integer):Integer; @@ -31,18 +35,66 @@ implementation uses errno, systm, - kern_thr; + kern_thr, + kern_rwlock; + +var + namedobj_list:TAILQ_HEAD=(tqh_first:nil;tqh_last:@namedobj_list.tqh_first); + namedobj_lock:Pointer; procedure named_table_init; begin id_table_init(@named_table,1); end; +procedure namedobj_add(data:p_namedobj); +begin + rw_wlock(namedobj_lock); + TAILQ_INSERT_TAIL(@namedobj_list,data,@data^.link); + rw_wunlock(namedobj_lock); +end; + +procedure namedobj_rem(data:p_namedobj); +begin + rw_wlock(namedobj_lock); + TAILQ_REMOVE(@namedobj_list,data,@data^.link); + rw_wunlock(namedobj_lock); +end; + procedure namedobj_free(data:pointer); begin + namedobj_rem(data); FreeMem(data); end; +function get_obj_name(objp:Pointer;objt:Integer;name:PChar):Boolean; +var + entry:p_namedobj; +begin + Result:=False; + objt:=Word(objt) or NAMED_OBJT; + + rw_rlock(namedobj_lock); + + entry:=TAILQ_FIRST(@namedobj_list); + while (entry<>nil) do + begin + if (entry^.objp=objp) and + (entry^.objt=objt) then + begin + Result:=True; + + copystr(entry^.name,name,SizeOf(entry^.name),nil); + + Break; + end; + + entry:=TAILQ_NEXT(entry,@entry^.link); + end; + + rw_runlock(namedobj_lock); +end; + function sys_namedobj_create(name:PChar;objp:Pointer;objt:Integer):Integer; var td:p_kthread; @@ -68,11 +120,14 @@ begin obj^.name:=name; obj^.objp:=objp; + namedobj_add(obj); + if not id_name_new(@named_table,obj,@key) then begin namedobj_free(obj); Exit(EAGAIN); end; + id_release(obj); td^.td_retval[0]:=key; diff --git a/sys/kern/kern_thread.pas b/sys/kern/kern_thread.pas index 221413ab..bdf4915d 100644 --- a/sys/kern/kern_thread.pas +++ b/sys/kern/kern_thread.pas @@ -355,6 +355,16 @@ begin ipi_sigreturn; //switch end; +procedure thread0_param(td:p_kthread); +begin + td^.td_base_user_pri:=700; + td^.td_lend_user_pri:=1023; + td^.td_base_pri :=68; + td^.td_priority :=68; + td^.td_pri_class :=10; + td^.td_user_pri :=700; +end; + function create_thread(td :p_kthread; //calling thread ctx :p_mcontext_t; start_func:Pointer; @@ -432,6 +442,8 @@ begin newtd:=thread_alloc; if (newtd=nil) then Exit(ENOMEM); + thread0_param(newtd); + //user stack newtd^.td_ustack.stack:=stack_base+stack_size; newtd^.td_ustack.sttop:=stack_base; @@ -563,6 +575,8 @@ begin newtd:=thread_alloc; if (newtd=nil) then Exit(ENOMEM); + thread0_param(newtd); + stack.ss_sp :=newtd^.td_kstack.sttop; stack.ss_size:=(ptruint(newtd^.td_kstack.stack)-ptruint(newtd^.td_kstack.sttop)); diff --git a/sys/sys_event.pas b/sys/sys_event.pas index e8092389..d47716b5 100644 --- a/sys/sys_event.pas +++ b/sys/sys_event.pas @@ -228,6 +228,7 @@ type {$IF sizeof(t_kevent_copyops)<>24}{$STOP sizeof(t_kevent_copyops)<>24}{$ENDIF} procedure EV_SET(kevp:p_kevent;a:PtrUint;b:SmallInt;c:Word;d:DWORD;e:Ptrint;f:Pointer); +function EVFILT_NAME(i:Integer):RawByteString; implementation @@ -241,6 +242,36 @@ begin (kevp)^.udata :=(f); end; +function EVFILT_NAME(i:Integer):RawByteString; +begin + Result:=''; + case i of + EVFILT_READ :Result:='EVFILT_READ'; + EVFILT_WRITE :Result:='EVFILT_WRITE'; + EVFILT_AIO :Result:='EVFILT_AIO'; + EVFILT_VNODE :Result:='EVFILT_VNODE'; + EVFILT_PROC :Result:='EVFILT_PROC'; + EVFILT_SIGNAL :Result:='EVFILT_SIGNAL'; + EVFILT_TIMER :Result:='EVFILT_TIMER'; + EVFILT_FS :Result:='EVFILT_FS'; + EVFILT_LIO :Result:='EVFILT_LIO'; + EVFILT_USER :Result:='EVFILT_USER'; + EVFILT_POLLING :Result:='EVFILT_POLLING'; + EVFILT_DISPLAY :Result:='EVFILT_DISPLAY'; + EVFILT_GRAPHICS_CORE :Result:='EVFILT_GRAPHICS_CORE'; + EVFILT_HRTIMER :Result:='EVFILT_HRTIMER'; + EVFILT_UVD_TRAP :Result:='EVFILT_UVD_TRAP'; + EVFILT_VCE_TRAP :Result:='EVFILT_VCE_TRAP'; + EVFILT_SDMA_TRAP :Result:='EVFILT_SDMA_TRAP'; + EVFILT_REG_EV :Result:='EVFILT_REG_EV'; + EVFILT_GPU_EXCEPTION :Result:='EVFILT_GPU_EXCEPTION'; + EVFILT_GPU_SYSTEM_EXCEPTION:Result:='EVFILT_GPU_SYSTEM_EXCEPTION'; + EVFILT_GPU_DBGGC_EV :Result:='EVFILT_GPU_DBGGC_EV'; + EVFILT_CPUMODE :Result:='EVFILT_CPUMODE'; + else + Str(i,Result); + end; +end; end. diff --git a/sys/vfs/kern_descrip.pas b/sys/vfs/kern_descrip.pas index e1494fec..a0e983fa 100644 --- a/sys/vfs/kern_descrip.pas +++ b/sys/vfs/kern_descrip.pas @@ -1189,6 +1189,7 @@ begin fp:=AllocMem(SizeOf(t_file)); if (fp=nil) then Exit(ENOMEM); + fp^.desc.refs:=1; fp^.desc.free:=@_fdrop; fp^.f_ops :=@badfileops; fp^.f_data :=nil; diff --git a/sys/vfs/vfs_syscalls.pas b/sys/vfs/vfs_syscalls.pas index 4987ba25..1d18acc9 100644 --- a/sys/vfs/vfs_syscalls.pas +++ b/sys/vfs/vfs_syscalls.pas @@ -913,6 +913,7 @@ begin Exit(error); end; + td^.td_dupfd:=0; vfslocked:=NDHASGIANT(@nd); NDFREE(@nd, NDF_ONLY_PNBUF); @@ -1006,8 +1007,10 @@ success: fdrop(fp); td^.td_retval[0]:=indx; Exit(0); + bad: VFS_UNLOCK_GIANT(vfslocked); + bad_unlocked: if (indx<>-1) then begin