forked from Hyperion/HyperionOS
added more hpv funcs and made primshell
This commit is contained in:
@@ -38,7 +38,6 @@ end
|
||||
|
||||
function kernel.PANIC(msg)
|
||||
if kernel.status~="Panic" then
|
||||
kernel.exitMain = true
|
||||
kernel.log("PANIC: "..msg, "PANIC")
|
||||
pcall(kernel["saveLog"])
|
||||
kernel.status="Panic"
|
||||
@@ -50,6 +49,7 @@ function kernel.PANIC(msg)
|
||||
screen:print(LOG_Text)
|
||||
screen:print("KERNEL PANIC!\n"..msg.."\nSystem halted.")
|
||||
screen:print("Press any key to continue...")
|
||||
kernel.exitMain = true
|
||||
end
|
||||
while true do
|
||||
local event={computer:getMachineEvent()}
|
||||
@@ -250,4 +250,7 @@ end
|
||||
kernel.log("Kernel initialized successfully.")
|
||||
kernel.status="running"
|
||||
kernel.main()
|
||||
if kernel.status=="panic" then
|
||||
kernel.panic()
|
||||
end
|
||||
kernel.PANIC("Execution complete")
|
||||
@@ -151,45 +151,54 @@ function table.proxy(tbl)
|
||||
return createProxy(tbl)
|
||||
end
|
||||
|
||||
local function serialize(table)
|
||||
local function serialize(tbl, seen)
|
||||
seen = seen or {}
|
||||
|
||||
-- If we've seen this table before, return a placeholder to prevent infinite loops
|
||||
if seen[tbl] then
|
||||
return '"[Circular Reference]"'
|
||||
end
|
||||
|
||||
-- Mark this table as seen
|
||||
seen[tbl] = true
|
||||
|
||||
local output = "{"
|
||||
for i,v in pairs(table) do
|
||||
local coma=true
|
||||
local first = true
|
||||
|
||||
for i, v in pairs(tbl) do
|
||||
-- Handle comma placement more cleanly
|
||||
if not first then
|
||||
output = output .. ","
|
||||
end
|
||||
first = false
|
||||
|
||||
-- Serialize Key
|
||||
if type(i) == "string" then
|
||||
output=output.."[\""..i.."\"]="
|
||||
output = output .. "[\"" .. i .. "\"]="
|
||||
elseif type(i) == "number" then
|
||||
output=output.."["..tostring(i).."]="
|
||||
output = output .. "[" .. tostring(i) .. "]="
|
||||
end
|
||||
|
||||
-- Serialize Value
|
||||
if type(v) == "table" then
|
||||
if v == table then
|
||||
output=string.sub(output,1,#output-(#i+1))
|
||||
coma=false
|
||||
else
|
||||
output=output..serialize(v)
|
||||
end
|
||||
-- Pass the 'seen' table down to the recursive call
|
||||
output = output .. serialize(v, seen)
|
||||
elseif type(v) == "string" then
|
||||
output=output.."[=["..v.."]=]"
|
||||
elseif type(v) == "number" then
|
||||
output=output..tostring(v)
|
||||
elseif type(v) == "boolean" then
|
||||
if v == true then
|
||||
output=output.."true"
|
||||
else
|
||||
output=output.."false"
|
||||
end
|
||||
output = output .. "[=[" .. v .. "]=]"
|
||||
elseif type(v) == "number" or type(v) == "boolean" then
|
||||
output = output .. tostring(v)
|
||||
elseif type(v) == "function" then
|
||||
output=output..tostring(v)
|
||||
output = output .. "\"" .. tostring(v) .. "\""
|
||||
elseif type(v) == "thread" then
|
||||
output = output .. "\"" .. tostring(v) .. "\""
|
||||
else
|
||||
error("serialization of type \""..type(v).."\" is not supported")
|
||||
end
|
||||
if coma then
|
||||
output=output..","
|
||||
error("serialization of type \"" .. type(v) .. "\" is not supported")
|
||||
end
|
||||
end
|
||||
if #table>0 or string.sub(output,#output,#output) == "," then
|
||||
output=string.sub(output,1,#output-1)
|
||||
end
|
||||
output=output.."}"
|
||||
|
||||
seen[tbl] = nil
|
||||
|
||||
output = output .. "}"
|
||||
return output
|
||||
end
|
||||
|
||||
|
||||
42
Src/Hyperion-kernel-v1.0.0/lib/modules/Hyperion/10_io.kmod
Normal file
42
Src/Hyperion-kernel-v1.0.0/lib/modules/Hyperion/10_io.kmod
Normal file
@@ -0,0 +1,42 @@
|
||||
--:Minify:--
|
||||
local kernel=...
|
||||
local io = {}
|
||||
kernel.io=io
|
||||
io.eventq={}
|
||||
|
||||
function io.pushEvent(queue, ...)
|
||||
queue=tostring(queue)
|
||||
if not io.eventq[queue] then
|
||||
io.eventq[queue]={}
|
||||
end
|
||||
io.eventq[queue][#io.eventq[queue]+1]={...}
|
||||
end
|
||||
|
||||
function io.bind(queue)
|
||||
queue=tostring(queue)
|
||||
kernel.currentTask.eventq=queue
|
||||
end
|
||||
|
||||
function io.pullEvent()
|
||||
if io.eventq[kernel.currentTask.eventq] then
|
||||
if #io.eventq[kernel.currentTask.eventq]==1 then
|
||||
local event = table.remove(io.eventq[kernel.currentTask.eventq] or {}, 1)
|
||||
io.eventq[kernel.currentTask.eventq]=nil
|
||||
return table.unpack(event)
|
||||
end
|
||||
local event = table.remove(io.eventq[kernel.currentTask.eventq] or {}, 1)
|
||||
if not event then return end
|
||||
return table.unpack(event)
|
||||
end
|
||||
end
|
||||
|
||||
function io.getBoundQueue()
|
||||
return kernel.currentTask.eventq
|
||||
end
|
||||
|
||||
kernel.syscalls["IO_pushEvent"]=io.pushEvent
|
||||
kernel.syscalls["IO_pullEvent"]=io.pullEvent
|
||||
kernel.syscalls["IO_bind"]=io.bind
|
||||
kernel.syscalls["IO_getBoundQueue"]=io.getBoundQueue
|
||||
|
||||
kernel.log("IO pipeline initialized")
|
||||
@@ -71,13 +71,9 @@ local function allocFD(task)
|
||||
return fd
|
||||
end
|
||||
|
||||
local total=0
|
||||
local function checkSystemLimit()
|
||||
-- enforce system-wide limit
|
||||
local total = 0
|
||||
for _, task in pairs(kernel.tasks or {}) do
|
||||
for _ in pairs(task.fd) do total = total + 1 end
|
||||
end
|
||||
if total >= kernel.config.maxOpenFiles then
|
||||
if total >= kernel.config.maxOpenFiles-16 then
|
||||
error("ENFILE") -- Too many open files in the system
|
||||
end
|
||||
end
|
||||
@@ -100,6 +96,7 @@ function vfs.open(path, mode)
|
||||
local file = newFileObject(disk.address, handle, mode, path)
|
||||
local fd = allocFD(task)
|
||||
task.fd[fd] = file
|
||||
total=total+1
|
||||
|
||||
return fd
|
||||
end
|
||||
@@ -114,6 +111,7 @@ function vfs.close(fd)
|
||||
if file.refcount == 0 then
|
||||
file.handle.close()
|
||||
end
|
||||
total=total-1
|
||||
return true
|
||||
end
|
||||
|
||||
@@ -184,6 +182,12 @@ function vfs.type(path)
|
||||
return disk:type(diskPath)
|
||||
end
|
||||
|
||||
function vfs.isDirectory(path)
|
||||
local disk, diskPath = resolvePath(path)
|
||||
if not disk then return false end
|
||||
return disk:directoryExists(diskPath)
|
||||
end
|
||||
|
||||
-- CWD
|
||||
function vfs.getcwd()
|
||||
return kernel.currentTask.cwd
|
||||
@@ -274,5 +278,6 @@ kernel.syscalls["VFS_setcwd"] = vfs.setcwd
|
||||
kernel.syscalls["VFS_whereis"] = vfs.whereis
|
||||
kernel.syscalls["VFS_dup"] = vfs.dup
|
||||
kernel.syscalls["VFS_dup2"] = vfs.dup2
|
||||
kernel.syscalls["VFS_isDirectory"]= vfs.isDirectory
|
||||
|
||||
kernel.log("VFS module loaded")
|
||||
@@ -1,6 +1,5 @@
|
||||
--:Minify:--
|
||||
local kernel = ...
|
||||
local events = kernel.newFifo()
|
||||
|
||||
kernel.processes.keventd = function()
|
||||
while true do
|
||||
@@ -13,9 +12,7 @@ kernel.processes.keventd = function()
|
||||
kernel.reboot()
|
||||
end
|
||||
end
|
||||
events.push(event)
|
||||
kernel.io.pushEvent("raw", table.unpack(event))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
kernel.syscalls["IO_getEventAny"]=events.pop
|
||||
end
|
||||
@@ -16,7 +16,7 @@ function sys.spawn(func, name, envars, args, tgid)
|
||||
kernel.log("Task "..tostring(id).." exited with err: "..tostring(err), "ERROR")
|
||||
end
|
||||
tasks[tostring(id)].status="Z"
|
||||
tasks[tostring(id)].exit=tostring(err)
|
||||
tasks[tostring(id)].exit=err
|
||||
else
|
||||
if kernel.config.logTaskExit then
|
||||
if err then
|
||||
@@ -51,7 +51,10 @@ function sys.spawn(func, name, envars, args, tgid)
|
||||
timeSlice=0,
|
||||
lastTime=0,
|
||||
totalTime=0,
|
||||
numRuns=0
|
||||
numRuns=0,
|
||||
privacy=0,
|
||||
debugger=false,
|
||||
eventq=kernel.currentTask.eventq
|
||||
}
|
||||
table.insert(kernel.currentTask.children, tasks[tostring(id)])
|
||||
return id
|
||||
@@ -63,8 +66,119 @@ function sys.sleep(ms)
|
||||
coroutine.yield()
|
||||
end
|
||||
|
||||
function sys.getTaskInfo(pid)
|
||||
if tasks[tostring(pid)] then
|
||||
local task = tasks[tostring(pid)]
|
||||
local children = {}
|
||||
local siblings = {}
|
||||
for i,v in ipairs(task.children) do
|
||||
children[i]=v.pid
|
||||
end
|
||||
for i,v in ipairs(task.siblings) do
|
||||
siblings[i]=v.pid
|
||||
end
|
||||
return {
|
||||
name=task.name,
|
||||
envars=table.deepcopy(task.envars),
|
||||
args=table.deepcopy(task.args),
|
||||
status=task.status,
|
||||
pid=task.pid,
|
||||
tgid=task.tgid,
|
||||
user=task.user,
|
||||
uid=task.uid,
|
||||
exit=task.exit,
|
||||
sleep=task.sleep,
|
||||
ivs=task.ivs,
|
||||
vs=task.vs,
|
||||
children=children,
|
||||
siblings=siblings,
|
||||
parent=task.parent.pid,
|
||||
cwd=task.cwd,
|
||||
term=task.term
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
function sys.collect(pid)
|
||||
local children={}
|
||||
for i,v in ipairs(kernel.currentTask.children) do
|
||||
children[i]=v.pid
|
||||
end
|
||||
if not tasks[tostring(pid)] then
|
||||
return false, "Task does not exist"
|
||||
elseif not isEqualToAny(tasks[tostring(pid)].pid,table.unpack(children)) then
|
||||
return false, "You do not own this task"
|
||||
elseif tasks[tostring(pid)].status~="Z" then
|
||||
return false, "Task must exit to collect status"
|
||||
else
|
||||
tasks[tostring(pid)].reapTime=0
|
||||
return true, tasks[tostring(pid)].exit
|
||||
end
|
||||
end
|
||||
|
||||
function sys.kill(pid)
|
||||
local children={}
|
||||
for i,v in ipairs(kernel.currentTask.children) do
|
||||
children[i]=v.pid
|
||||
end
|
||||
if not tasks[tostring(pid)] then
|
||||
return false, "Task does not exist"
|
||||
elseif not isEqualToAny(tasks[tostring(pid)].pid,table.unpack(children)) then
|
||||
return false, "You do not own this task"
|
||||
elseif tasks[tostring(pid)].status=="Z" then
|
||||
return false, "Task is already dead"
|
||||
else
|
||||
tasks[tostring(pid)].status="Z"
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
function sys.stop(pid)
|
||||
local children={}
|
||||
for i,v in ipairs(kernel.currentTask.children) do
|
||||
children[i]=v.pid
|
||||
end
|
||||
if not tasks[tostring(pid)] then
|
||||
return false, "Task does not exist"
|
||||
elseif not isEqualToAny(tasks[tostring(pid)].pid,table.unpack(children)) then
|
||||
return false, "You do not own this task"
|
||||
elseif tasks[tostring(pid)].status~="R" then
|
||||
return false, "Cannot stop non running task"
|
||||
else
|
||||
tasks[tostring(pid)].status="T"
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
function sys.continue(pid)
|
||||
local children={}
|
||||
for i,v in ipairs(kernel.currentTask.children) do
|
||||
children[i]=v.pid
|
||||
end
|
||||
if not tasks[tostring(pid)] then
|
||||
return false, "Task does not exist"
|
||||
elseif not isEqualToAny(tasks[tostring(pid)].pid,table.unpack(children)) then
|
||||
return false, "You do not own this task"
|
||||
elseif tasks[tostring(pid)].status~="T" then
|
||||
return false, "Task is not stopped"
|
||||
else
|
||||
tasks[tostring(pid)].status="R"
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
function sys.getPid()
|
||||
return kernel.currentTask.pid
|
||||
end
|
||||
|
||||
kernel.syscalls["HPV_spawn"]=sys.spawn
|
||||
kernel.syscalls["HPV_sleep"]=sys.sleep
|
||||
kernel.syscalls["HPV_getTaskInfo"]=sys.getTaskInfo
|
||||
kernel.syscalls["HPV_collect"]=sys.collect
|
||||
kernel.syscalls["HPV_kill"]=sys.kill
|
||||
kernel.syscalls["HPV_stop"]=sys.stop
|
||||
kernel.syscalls["HPV_continue"]=sys.continue
|
||||
kernel.syscalls["HPV_getPid"]=sys.getPid
|
||||
kernel._G.sleep=function(...)coroutine.yield("syscall","HPV_sleep",...)end
|
||||
|
||||
local function reapDeadTasks()
|
||||
@@ -87,8 +201,10 @@ local function reapDeadTasks()
|
||||
kernel.vfs.close(v)
|
||||
end
|
||||
task.fd = nil
|
||||
task.debugger=nil
|
||||
task.privacy=nil
|
||||
task.reapTime = kernel.computer:time() + 30000
|
||||
elseif task.reapTime and kernel.computer:time() > task.reapTime then
|
||||
elseif task.reapTime and kernel.computer:time() > task.reapTime and task.status=="Z" then
|
||||
for _,child in ipairs(task.children) do
|
||||
child.parent = tasks["1"]
|
||||
child.siblings = tasks["1"].children
|
||||
@@ -175,6 +291,9 @@ function kernel.main()
|
||||
if kernel.syscalls[ret[3]] then
|
||||
if kernel.config.debugSyscalls then
|
||||
kernel.log("Task "..task.pid.." invoking syscall: "..ret[3], "DBUG")
|
||||
for i=4,#ret do
|
||||
kernel.log(" inval["..tostring(i-3).."] = "..tostring(ret[i]), "DBUG")
|
||||
end
|
||||
end
|
||||
local sysret = {xpcall(kernel.syscalls[ret[3]], debug.traceback, table.unpack(ret, 4))}
|
||||
if kernel.config.debugSyscalls then
|
||||
@@ -183,7 +302,11 @@ function kernel.main()
|
||||
else
|
||||
kernel.log("Task "..task.pid.." syscall "..ret[3].." completed returning "..tostring(#sysret-1).." values", "DBUG")
|
||||
for i=2,#sysret do
|
||||
kernel.log(" retval["..tostring(i-1).."] = "..tostring(sysret[i]), "DBUG")
|
||||
if type(sysret[i])=="table" then
|
||||
kernel.log(" retval["..tostring(i-1).."] = "..table.serialize(sysret[i]), "DBUG")
|
||||
else
|
||||
kernel.log(" retval["..tostring(i-1).."] = "..tostring(sysret[i]), "DBUG")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user