Files
HyperionOS/Test/Hyperion-kernel-v0.1.0/lib/modules/Hyperion/99_init.kmod

210 lines
5.9 KiB
Plaintext
Executable File

local args = {...}
local kernel = args[1]
local tasks={}
local currentTask={}
local signals={}
local tid=2
local gid=2
local hookuuid=0
local sys={}
function sys.hookSig(sig, func)
if not currentTask.signal[sig] then
currentTask.signal[sig]={}
end
hookuuid=hookuuid+1
currentTask.signal[sig][tostring(hookuuid)]=func
callbackid=tostring(hookuuid)
return {
remove=function()
currentTask.signal[sig][callbackid]=nil
end
}
end
function sys.clearSigHooks(typ)
if not typ or typ == "all" then
signals[tostring(currentTask.pid)]={}
currentTask.signal=signals[tostring(currentTask.pid)]
else
if currentTask.signal[typ] then
currentTask.signal[typ]={}
end
end
end
function sys.sendSig(pid, signal, ...)
if pid=="all" then
for i,v in pairs(tasks) do+
v.sigQ[#v.sigQ+1]={signal, ...}
end
return
end
if not tasks[tostring(pid)] then return false end
tasks[tostring(pid)].sigQ[#tasks[tostring(pid)].sigQ+1]={signal, ...}
return true
end
function sys.flushSigs()
local sigs = {}
for i,v in ipairs(currentTask.sigQ) do
sigs[i]=v
end
for i=1, #sigs do
local sig = sigs[i]
if currentTask.signal[sig[1]] then
for k,v in pairs(currentTask.signal[sig[1]]) do
coroutine.resumeWithTimeout(coroutine.create(function()
local ok,err = xpcall(v,debug.traceback,table.unpack(sig))
if not ok and sig[1]~="callbackErr" then
sys.sendSig(currentTask.pid, "callbackErr", sig[1], k, err)
end
end),10)
end
else
for k,v in pairs(currentTask.signal["unhandledSignal"]) do
coroutine.resumeWithTimeout(coroutine.create(function()
local ok,err = xpcall(v,debug.traceback,table.unpack(sig))
if not ok and sig[1]~="callbackErr" then
sys.sendSig(currentTask.pid, "callbackErr", sig[1], k, err)
end
end),10)
end
end
end
end
function sys.spawn(func, name, evars, args, stdin, stdout, stderr)
local id=tid
tid=tid+1
name=name or tostring(id)
signals[tostring(id)]={}
tasks[tostring(id)]={
coro=coroutine.create(function()
local ret = {xpcall(func, debug.traceback, table.unpack(args))}
if not ret[1] then
sys.sendSig(currentTask.ppid, "ChildTaskError", id, err)
else
sys.sendSig(currentTask.ppid, "ChildTaskExit", id, table.unpack(ret, 2))
end
currentTask.status="Z"
end),
name=name,
pid=id,
ppid=currentTask.pid,
tgid=currentTask.tgid,
user=kernel.user,
uid=kernel.uid,
evars=evars,
args=args,
vy=0,
ivy=0,
status="R",
sleep=0,
signal=signals[tostring(id)],
parent=currentTask,
children={},
sibling=currentTask.children,
sigQ={}
}
end
function sys.exit(...)
sys.sendSig(currentTask.ppid, "ChildTaskExit", currentTask.pid, ...)
currentTask.status="Z"
coroutine.yield()
end
local function collectZombieProc()
local ret = {}
for _,v in pairs(tasks) do
if v.status=="Z" then
local pid = v.pid
for _,c in ipairs(v.children) do
c.parent=tasks["1"]
c.sibling=tasks["1"].children
c.ppid=1
c.tgid=1
end
signals[tostring(pid)]=nil
tasks[tostring(pid)]=nil
table.insert(ret, pid)
end
end
return ret
end
kernel.log("initPath is: " .. tostring(kernel.initPath))
signals["1"]={}
tasks["1"]={
coro=coroutine.create(function()
local ok, code_or_err = xpcall(function() return kernel.fs.readAllText(kernel.initPath) end, debug.traceback)
if not ok then currentTask.status="Z"; kernel.panic(code_or_err) end
local code = code_or_err
local func, err = load(code, "@SysInit", nil, kernel._U)
if not func then currentTask.status="Z"; kernel.panic(err) end
local ok, err = xpcall(func, debug.traceback, kernel)
if not ok then
currentTask.status="Z"
kernel.panic(err)
else
currentTask.status="Z"
kernel.panic("Attempted to kill init!")
end
end),
name="SysInit",
pid=1,
ppid=0,
tgid=1,
user="root",
uid=0,
evars={},
args={kernel},
vy=0,
ivy=0,
status="R",
sleep=0,
signal=signals["1"],
parent={name="Hyprkrnl",pid=0},
children={},
sibling={},
sigQ={}
}
tasks["1"].sibling={tasks["1"]}
kernel.log("Created pid 1")
kernel.cache.preload.sys=table.proxy(sys)
kernel.cache.preload.system=kernel.cache.preload.sys
kernel.cache.preload.os=kernel.cache.preload.sys
kernel.hpv=sys
kernel.tasks=tasks
kernel.signals=signals
kernel.currentTask=currentTask
kernel.saveLog()
kernel.status="running"
while kernel.status~="Panic" do
for k,v in pairs(tasks) do
currentTask=v
kernel.currentTask=v
kernel.process=currentTask.name
kernel.user=currentTask.user
kernel.uid=currentTask.uid
sys.flushSigs()
local status = coroutine.resumeWithTimeout(currentTask.coro, 50)
if status then
currentTask.vy=currentTask.vy+1
else
currentTask.ivy=currentTask.ivy+1
end
end
collectZombieProc()
end
kernel.process="Kernel"
kernel.user="root"
kernel.uid=0
kernel.panic(kernel.reason or "Exited pid 0")