added more hpv funcs and made primshell

This commit is contained in:
2026-01-16 14:17:28 -05:00
parent bd8fe50770
commit 70532f6e2c
14 changed files with 321 additions and 121 deletions

View File

@@ -1,18 +1,78 @@
--:Minify:--
syscall.TTY_clear() syscall.TTY_clear()
syscall.TTY_setTextColor(1) syscall.TTY_setTextColor(1)
syscall.TTY_setCursorPos(1, 1) syscall.TTY_setCursorPos(1, 1)
syscall.TTY_print("HyperionOS Bash Shell") syscall.TTY_print("HyperionOS Bash Shell")
local str="" local str=""
local stopInput=false
local inputIO=syscall.IO_getBoundQueue()
local pid=syscall.HPV_getPid()
local proc=0
local fs=require("sys.fs")
printInline("> ")
while true do while true do
local event = syscall.IO_getEventAny() local event = {syscall.IO_pullEvent()}
if event then if event[1] then
if event[1]=="keyTyped" then if not stopInput then
if event[3]=="\b" then if event[1]=="keyTyped" then
str=str:sub(1,#str-1) if event[3]=="\b" then
printInline("\b") if #str>0 then
else str=str:sub(1,#str-1)
str=str..event[3] printInline("\b")
printInline(event[3]) end
elseif event[3]=="\n" then
print("")
stopInput=true
if str == "" then
printInline("> ")
stopInput=false
else
local path=nil
if fs.exists("/bin/"..str) then
path="/bin/"..str
elseif fs.exists("/bin/"..str..".lua") then
path="/bin/"..str..".lua"
end
if not path then
print("Program not found")
printInline("> ")
stopInput=false
else
local text = fs.readAllText(path)
local program, err = load(text, path)
if not program then
print(err)
printInline("> ")
end
syscall.IO_bind("bash:"..tostring(pid))
proc = syscall.HPV_spawn(program, path)
syscall.IO_bind(inputIO)
end
str=""
end
else
str=str..event[3]
printInline(event[3])
end
end
end
end
if stopInput then
local exited, code = syscall.HPV_collect(proc)
if exited then
print("\nTask exited with code:\n"..tostring(code))
printInline("> ")
stopInput=false
else
if event[1] then
if event[1]=="keyTyped" and event[3]=="^c" then
syscall.HPV_kill(proc)
print("Terminated")
printInline("> ")
stopInput=false
else
syscall.IO_pushEvent("bash:"..tostring(pid), table.unpack(event))
end
end end
end end
end end

View File

@@ -0,0 +1,9 @@
local fs = require("sys.fs")
local stuff = fs.list("")
for i,v in ipairs(stuff) do
if fs.isDir(v) then
print(v.."/")
else
print(v)
end
end

View File

@@ -1,6 +1,4 @@
-- bit32.lua --:Minify:--
-- Full pure-Lua implementation of Lua 5.2 bit32 library
-- NO Lua 5.3 operators used
local bit32 = {} local bit32 = {}
@@ -136,16 +134,4 @@ function bit32.replace(x, v, field, width)
return bit32.bor(x, bit32.lshift(v, field)) return bit32.bor(x, bit32.lshift(v, field))
end end
-- ===== Test =====
function bit32.test(x, ...)
local args = {...}
for i = 1, #args do
if bit32.band(x, args[i]) ~= 0 then
return true
end
end
return false
end
return bit32 return bit32

View File

@@ -1,3 +1,4 @@
--:Minify:--
local fs={} local fs={}
-- "VFS_open" : open -- "VFS_open" : open
@@ -136,4 +137,8 @@ function fs.setcwd(path)
return syscall.VFS_setcwd(path) return syscall.VFS_setcwd(path)
end end
function fs.isDir(path)
return syscall.VFS_isDirectory(path)
end
return fs return fs

View File

@@ -1,57 +1,6 @@
local sys = {} local sys = {}
local fs = require("sys.fs") local fs = require("sys.fs")
function sys.spawn(func, name, envars, args)
return coroutine.yield(0x10, func, name, envars, args)
end
function sys.spawnFromFile(path, name, envars, args)
local data = fs.readAllText(path)
if not data then
error("File not found: "..path,2)
end
local func, err = load(data, "@"..path)
if not func then
error("Error loading file "..path..": "..tostring(err),2)
end
return coroutine.yield(0x10, func, name, envars, args)
end
function sys.spawnAndWait(func, name, envars, args)
local task = coroutine.yield(0x10, func, name, envars, args)
local oldsignal = sys.getSignalHandler(17)
local exit = false
sys.setSignalHandler(17, function()
local tasks = sys.getChildrenTasks(task)
if not tasks[task] then
exit = true
end
end)
while not exit do
coroutine.yield()
end
sys.setSignalHandler(17, oldsignal)
return task
end
function sys.spawnFromFileAndWait(path, name, envars, args)
local data = fs.readAllText(path)
if not data then
error("File not found: "..path,2)
end
local func, err = load(data, "@"..path)
if not func then
error("Error loading file "..path..": "..tostring(err),2)
end
return sys.spawnAndWait(func, name, envars, args)
end
function sys.exit(code)
return coroutine.yield(0x11, code)
end
function sys.getTaskInfo(task)
return coroutine.yield(0x12, task)
end
return sys return sys

View File

@@ -1,6 +1,8 @@
--:Minify:--
local kernel=... local kernel=...
local fs=require("sys.fs") local fs=require("sys.fs")
syscall.TTY_bind("tty0") syscall.TTY_bind("tty0")
syscall.IO_bind("raw")
for i,v in pairs(kernel.processes) do for i,v in pairs(kernel.processes) do
kernel.log("Spawning kernel task "..i) kernel.log("Spawning kernel task "..i)
@@ -14,6 +16,7 @@ for i,v in pairs(kernel.processes) do
end, i) end, i)
end end
local eventQueues = {}
local files = fs.list("/bin/startup") local files = fs.list("/bin/startup")
if not files then error("Failed to list /bin/startup") end if not files then error("Failed to list /bin/startup") end
for i,v in ipairs(files) do for i,v in ipairs(files) do
@@ -25,6 +28,8 @@ for i,v in ipairs(files) do
kernel.log("Error loading startup script '" .. filepath .. "': " .. err, "ERROR") kernel.log("Error loading startup script '" .. filepath .. "': " .. err, "ERROR")
else else
syscall.HPV_spawn(function() syscall.HPV_spawn(function()
syscall.IO_bind("eventQueue:"..tostring(i))
eventQueues[#eventQueues+1]="eventQueue:"..tostring(i)
local status, err = pcall(startupFunc) local status, err = pcall(startupFunc)
if not status then if not status then
kernel.log("Error executing startup script '" .. filepath .. "': " .. err, "ERROR") kernel.log("Error executing startup script '" .. filepath .. "': " .. err, "ERROR")
@@ -37,6 +42,11 @@ for i,v in ipairs(files) do
end end
while true do while true do
local event = {syscall.IO_pullEvent()}
if event[1] then
for i,v in ipairs(eventQueues) do
syscall.IO_pushEvent(v, table.unpack(event))
end
end
kernel.saveLog() kernel.saveLog()
sleep(1000)
end end

View File

@@ -38,7 +38,6 @@ end
function kernel.PANIC(msg) function kernel.PANIC(msg)
if kernel.status~="Panic" then if kernel.status~="Panic" then
kernel.exitMain = true
kernel.log("PANIC: "..msg, "PANIC") kernel.log("PANIC: "..msg, "PANIC")
pcall(kernel["saveLog"]) pcall(kernel["saveLog"])
kernel.status="Panic" kernel.status="Panic"
@@ -50,6 +49,7 @@ function kernel.PANIC(msg)
screen:print(LOG_Text) screen:print(LOG_Text)
screen:print("KERNEL PANIC!\n"..msg.."\nSystem halted.") screen:print("KERNEL PANIC!\n"..msg.."\nSystem halted.")
screen:print("Press any key to continue...") screen:print("Press any key to continue...")
kernel.exitMain = true
end end
while true do while true do
local event={computer:getMachineEvent()} local event={computer:getMachineEvent()}
@@ -250,4 +250,7 @@ end
kernel.log("Kernel initialized successfully.") kernel.log("Kernel initialized successfully.")
kernel.status="running" kernel.status="running"
kernel.main() kernel.main()
if kernel.status=="panic" then
kernel.panic()
end
kernel.PANIC("Execution complete") kernel.PANIC("Execution complete")

View File

@@ -151,45 +151,54 @@ function table.proxy(tbl)
return createProxy(tbl) return createProxy(tbl)
end 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 = "{" local output = "{"
for i,v in pairs(table) do local first = true
local coma=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 if type(i) == "string" then
output=output.."[\""..i.."\"]=" output = output .. "[\"" .. i .. "\"]="
elseif type(i) == "number" then elseif type(i) == "number" then
output=output.."["..tostring(i).."]=" output = output .. "[" .. tostring(i) .. "]="
end end
-- Serialize Value
if type(v) == "table" then if type(v) == "table" then
if v == table then -- Pass the 'seen' table down to the recursive call
output=string.sub(output,1,#output-(#i+1)) output = output .. serialize(v, seen)
coma=false
else
output=output..serialize(v)
end
elseif type(v) == "string" then elseif type(v) == "string" then
output=output.."[=["..v.."]=]" output = output .. "[=[" .. v .. "]=]"
elseif type(v) == "number" then elseif type(v) == "number" or type(v) == "boolean" then
output=output..tostring(v) output = output .. tostring(v)
elseif type(v) == "boolean" then
if v == true then
output=output.."true"
else
output=output.."false"
end
elseif type(v) == "function" then elseif type(v) == "function" then
output=output..tostring(v) output = output .. "\"" .. tostring(v) .. "\""
elseif type(v) == "thread" then
output = output .. "\"" .. tostring(v) .. "\""
else else
error("serialization of type \""..type(v).."\" is not supported") error("serialization of type \"" .. type(v) .. "\" is not supported")
end
if coma then
output=output..","
end end
end end
if #table>0 or string.sub(output,#output,#output) == "," then
output=string.sub(output,1,#output-1) seen[tbl] = nil
end
output=output.."}" output = output .. "}"
return output return output
end end

View 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")

View File

@@ -71,13 +71,9 @@ local function allocFD(task)
return fd return fd
end end
local total=0
local function checkSystemLimit() local function checkSystemLimit()
-- enforce system-wide limit if total >= kernel.config.maxOpenFiles-16 then
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
error("ENFILE") -- Too many open files in the system error("ENFILE") -- Too many open files in the system
end end
end end
@@ -100,6 +96,7 @@ function vfs.open(path, mode)
local file = newFileObject(disk.address, handle, mode, path) local file = newFileObject(disk.address, handle, mode, path)
local fd = allocFD(task) local fd = allocFD(task)
task.fd[fd] = file task.fd[fd] = file
total=total+1
return fd return fd
end end
@@ -114,6 +111,7 @@ function vfs.close(fd)
if file.refcount == 0 then if file.refcount == 0 then
file.handle.close() file.handle.close()
end end
total=total-1
return true return true
end end
@@ -184,6 +182,12 @@ function vfs.type(path)
return disk:type(diskPath) return disk:type(diskPath)
end end
function vfs.isDirectory(path)
local disk, diskPath = resolvePath(path)
if not disk then return false end
return disk:directoryExists(diskPath)
end
-- CWD -- CWD
function vfs.getcwd() function vfs.getcwd()
return kernel.currentTask.cwd return kernel.currentTask.cwd
@@ -274,5 +278,6 @@ kernel.syscalls["VFS_setcwd"] = vfs.setcwd
kernel.syscalls["VFS_whereis"] = vfs.whereis kernel.syscalls["VFS_whereis"] = vfs.whereis
kernel.syscalls["VFS_dup"] = vfs.dup kernel.syscalls["VFS_dup"] = vfs.dup
kernel.syscalls["VFS_dup2"] = vfs.dup2 kernel.syscalls["VFS_dup2"] = vfs.dup2
kernel.syscalls["VFS_isDirectory"]= vfs.isDirectory
kernel.log("VFS module loaded") kernel.log("VFS module loaded")

View File

@@ -1,6 +1,5 @@
--:Minify:-- --:Minify:--
local kernel = ... local kernel = ...
local events = kernel.newFifo()
kernel.processes.keventd = function() kernel.processes.keventd = function()
while true do while true do
@@ -13,9 +12,7 @@ kernel.processes.keventd = function()
kernel.reboot() kernel.reboot()
end end
end end
events.push(event) kernel.io.pushEvent("raw", table.unpack(event))
end end
end end
end end
kernel.syscalls["IO_getEventAny"]=events.pop

View File

@@ -16,7 +16,7 @@ function sys.spawn(func, name, envars, args, tgid)
kernel.log("Task "..tostring(id).." exited with err: "..tostring(err), "ERROR") kernel.log("Task "..tostring(id).." exited with err: "..tostring(err), "ERROR")
end end
tasks[tostring(id)].status="Z" tasks[tostring(id)].status="Z"
tasks[tostring(id)].exit=tostring(err) tasks[tostring(id)].exit=err
else else
if kernel.config.logTaskExit then if kernel.config.logTaskExit then
if err then if err then
@@ -51,7 +51,10 @@ function sys.spawn(func, name, envars, args, tgid)
timeSlice=0, timeSlice=0,
lastTime=0, lastTime=0,
totalTime=0, totalTime=0,
numRuns=0 numRuns=0,
privacy=0,
debugger=false,
eventq=kernel.currentTask.eventq
} }
table.insert(kernel.currentTask.children, tasks[tostring(id)]) table.insert(kernel.currentTask.children, tasks[tostring(id)])
return id return id
@@ -63,8 +66,119 @@ function sys.sleep(ms)
coroutine.yield() coroutine.yield()
end 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_spawn"]=sys.spawn
kernel.syscalls["HPV_sleep"]=sys.sleep 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 kernel._G.sleep=function(...)coroutine.yield("syscall","HPV_sleep",...)end
local function reapDeadTasks() local function reapDeadTasks()
@@ -87,8 +201,10 @@ local function reapDeadTasks()
kernel.vfs.close(v) kernel.vfs.close(v)
end end
task.fd = nil task.fd = nil
task.debugger=nil
task.privacy=nil
task.reapTime = kernel.computer:time() + 30000 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 for _,child in ipairs(task.children) do
child.parent = tasks["1"] child.parent = tasks["1"]
child.siblings = tasks["1"].children child.siblings = tasks["1"].children
@@ -175,6 +291,9 @@ function kernel.main()
if kernel.syscalls[ret[3]] then if kernel.syscalls[ret[3]] then
if kernel.config.debugSyscalls then if kernel.config.debugSyscalls then
kernel.log("Task "..task.pid.." invoking syscall: "..ret[3], "DBUG") 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 end
local sysret = {xpcall(kernel.syscalls[ret[3]], debug.traceback, table.unpack(ret, 4))} local sysret = {xpcall(kernel.syscalls[ret[3]], debug.traceback, table.unpack(ret, 4))}
if kernel.config.debugSyscalls then if kernel.config.debugSyscalls then
@@ -183,7 +302,11 @@ function kernel.main()
else else
kernel.log("Task "..task.pid.." syscall "..ret[3].." completed returning "..tostring(#sysret-1).." values", "DBUG") kernel.log("Task "..task.pid.." syscall "..ret[3].." completed returning "..tostring(#sysret-1).." values", "DBUG")
for i=2,#sysret do 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 end
end end

View File

@@ -0,0 +1,2 @@
# Task privacy
---