Files
Halyde/halyde/kernel/modules/tsched.lua
T
WahPlus c1c6a50b09 Added user system.
Default users are `admin` (password `admin`, UID 1) and `user` (password
`user`, UID 2).
2025-10-28 19:15:20 +02:00

120 lines
3.6 KiB
Lua

local module = {}
module.dependencies = {}
function module.check()
return true
end
function module.init()
_G._PUBLIC.tsched = {}
_G.tsched = {}
_G.tsched.tasks = {}
local component = require("component")
local filesystem = require("filesystem")
local gpu = component.gpu
local log = require("log")
local idCounter = 1
function _G._PUBLIC.tsched.runAsTask(path, ...)
checkArg(1, path, "string")
local args = { ... }
local function taskFunction()
local result, errorMessage = xpcall(function(...)
local args = table.pack(...)
if not filesystem.exists(path) then
error("No such file: " .. path)
end
local handle, data, tmpdata = filesystem.open(path), "", nil
repeat
tmpdata = handle:read(math.huge or math.maxinteger)
data = data .. (tmpdata or "")
until not tmpdata
handle:close()
-- Userland environment definition
local userland = table.copy(_PUBLIC)
userland._G = userland
userland.load = function(chunk, chunkname, mode, env)
if not env or env == _G then
env = userland
end -- if they SOMEHOW get the kernel environment they're not running jack shit
return load(chunk, chunkname, mode, env)
end
userland.require = reqgen(userland.load)
assert(load(data, "=" .. path, "t", userland))(table.unpack(args))
end, function(errorMessage)
return errorMessage .. "\n \n" .. debug.traceback()
end, --[[ path,]] table.unpack(args))
if not result then
if print then
gpu.freeAllBuffers()
print("\n\27[91m" .. errorMessage)
else
error(errorMessage)
end
end
--require(path, table.unpack(args))
end
local _, taskInfo = _PUBLIC.tsched.addTask(taskFunction, string.match(tostring(path), "([^/]+)%.lua$"))
taskInfo.path = path
taskInfo.args = table.copy(args)
end
function _G._PUBLIC.tsched.addTask(func, name)
checkArg(1, func, "function")
checkArg(2, name, "string")
local task = coroutine.create(func)
local taskInfo = { ["task"] = task, ["name"] = name, ["id"] = idCounter}
if type(tsched.currentTask) == "table" and type(tsched.currentTask.id) == "number" then
taskInfo.parent = tsched.currentTask.id
taskInfo.user = tsched.currentTask.user
end
table.insert(tsched.tasks, taskInfo)
idCounter = idCounter + 1
if taskInfo.parent then
log.kernel.info(
("[tsched] Created task %s (PID %d) by parent PID %d as UID %d"):format(name, idCounter - 1, taskInfo.parent, taskInfo.user)
)
else
taskInfo.user = 1 -- It's probably being run from kernel level
log.kernel.info(string.format("[tsched] Created task %s (PID %d) as UID 1 (no parent found)", name, idCounter - 1))
end
return task, taskInfo
end
function _G._PUBLIC.tsched.removeTask(id)
checkArg(1, id, "number")
-- TODO: Check for user permissions before running
for index, task in pairs(tsched.tasks) do
if task.id == id then
table.remove(tsched.tasks, index)
log.kernel.info(string.format("[tsched] Removed task with PID %d", id))
return true
end
end
log.kernel.warn(string.format("[tsched] Tried to remove task that doesn't exist - PID %d", id))
return false
end
function _G._PUBLIC.tsched.getCurrentTask()
return table.copy(tsched.currentTask)
end
function _G._PUBLIC.tsched.getTasks()
return table.copy(tsched.tasks)
end
end
function module.exit()
-- why would you even want to
_G._PUBLIC.tsched = nil
_G.tsched = nil
_G.tsched.tasks = nil
end
return module