Files
HyperionOS/Src/Hyperion-kernel/data/lib/modules/hyperion/20_signals.kmod
T

63 lines
1.7 KiB
Plaintext

--:Minify:--
local kernel = ...
local signal = {}
kernel.signal=signal
function signal.sigsend(pid, sig)
if sig<0 or sig>256 then error("EINVAL") end
local task = kernel.tasks[tostring(pid)]
if not task then error("ENOENT") end
if not task.sigq then return end
task.sigq[#task.sigq+1] = sig
end
function signal.sigcatch(handler)
local task=kernel.currentTask
task.sigh=handler
if not task.sigq then task.sigq={} end
local handle={
error="",
active=true
}
if task.sigd then task.sigd.active=false; end
task.sigd=handle
return handle
end
function signal.sigignore()
local task=kernel.currentTask
task.sigh=nil
task.sigq=nil
if task.sigd then task.sigd.active=false end
task.sigd=nil
end
kernel.execPerTask(function(task)
if task.status=="R" then
if task.sigq and #task.sigq ~= 0 and task.sigh then
local coro = coroutine.create(task.sigh)
local status,err=coroutine.resume(coro, table.remove(task.sigq, 1))
EFI:yeild()
if status=="error" or status==false then
task.sigd.error=err or "Unknown"
task.sigd.active=false
task.sigh=nil
task.sigq=nil
task.sigd=nil
elseif status=="success" or status==true then
if err=="syscall" then
task.sigd.error="Cannot execute syscalls from signals"
task.sigd.active=false
task.sigh=nil
task.sigq=nil
task.sigd=nil
end
end
end
end
end,2)
local s=kernel.syscalls
s["sigsend"] = signal.sigsend
s["sigcatch"] = signal.sigcatch
s["sigignore"] = signal.sigignore