forked from Hyperion/HyperionOS
210 lines
5.9 KiB
Plaintext
Executable File
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") |