kernel improvements

This commit is contained in:
kepler155c@gmail.com 2020-05-08 22:32:44 -06:00
parent 71bbd2d457
commit b0db0b86bd
7 changed files with 87 additions and 83 deletions

View File

@ -42,17 +42,16 @@ local function telnetHost(socket, mode)
end end
local shellThread = kernel.run({ local shellThread = kernel.run({
terminal = win,
window = win, window = win,
title = mode .. ' client', title = mode .. ' client',
hidden = true, hidden = true,
co = coroutine.create(function() fn = function()
Util.run(_ENV, Alt.get('shell'), table.unpack(termInfo.program)) Util.run(kernel.makeEnv(), Alt.get('shell'), table.unpack(termInfo.program))
if socket.queue then if socket.queue then
socket:write(socket.queue) socket:write(socket.queue)
end end
socket:close() socket:close()
end) end,
}) })
Event.addRoutine(function() Event.addRoutine(function()

View File

@ -26,7 +26,7 @@ local function systemLog()
if y > 1 then if y > 1 then
local currentTab = kernel.getFocused() local currentTab = kernel.getFocused()
if currentTab == routine then if currentTab == routine then
if currentTab.terminal.scrollUp and not currentTab.terminal.noAutoScroll then if currentTab.terminal.scrollUp then
if dir == -1 then if dir == -1 then
currentTab.terminal.scrollUp() currentTab.terminal.scrollUp()
else else

View File

@ -104,12 +104,12 @@ function nativefs.delete(node, dir)
-- if a file is mounted over an existing directory -- if a file is mounted over an existing directory
-- ie. sys/apps/MOUNT.LUA -- ie. sys/apps/MOUNT.LUA
-- then sys and sys/apps are created as temp nodes -- then sys and sys/apps are created as temp nodes
-- therefore, trying to delete sys will was only -- therefore, trying to delete sys was only
-- removing the node and not deleting the directory -- removing the node and not deleting the directory
-- Need a better way to backfill nodes in a way -- Need a better way to backfill nodes in a way
-- that preserves the vfs functionality -- that preserves the vfs functionality
-- perhaps a flag that denotes that this is a -- perhaps a flag that denotes that this
-- file/directory is the actual mount -- file/directory is the actual mount
-- this hack will not fix -- this hack will not fix

View File

@ -1,6 +1,5 @@
local Blit = require('opus.ui.blit') local Blit = require('opus.ui.blit')
local Config = require('opus.config') local Config = require('opus.config')
local trace = require('opus.trace')
local Util = require('opus.util') local Util = require('opus.util')
local colors = _G.colors local colors = _G.colors
@ -103,48 +102,25 @@ function multishell.launch( tProgramEnv, sProgramPath, ... )
}) })
end end
local function xprun(env, path, ...)
setmetatable(env, { __index = _G })
local fn, m = loadfile(path, env)
if fn then
return trace(fn, ...)
end
return fn, m
end
function multishell.openTab(tab) function multishell.openTab(tab)
if not tab.title and tab.path then if not tab.title and tab.path then
tab.title = fs.getName(tab.path):match('([^%.]+)') tab.title = fs.getName(tab.path):match('([^%.]+)')
end end
tab.title = tab.title or 'untitled' tab.title = tab.title or 'untitled'
tab.window = tab.window or window.create(parentTerm, 1, 2, w, h - 1, false) tab.window = tab.window or window.create(parentTerm, 1, 2, w, h - 1, false)
tab.terminal = tab.terminal or tab.window tab.onExit = function(self, result, err)
local routine = kernel.newRoutine(tab)
routine.co = coroutine.create(function()
local result, err
if tab.fn then
result, err = Util.runFunction(routine.env, tab.fn, table.unpack(tab.args or { } ))
elseif tab.path then
result, err = xprun(routine.env, tab.path, table.unpack(tab.args or { } ))
else
err = 'multishell: invalid tab'
end
if not result and err and err ~= 'Terminated' or (err and err ~= 0) then if not result and err and err ~= 'Terminated' or (err and err ~= 0) then
tab.terminal.setBackgroundColor(colors.black) self.terminal.setBackgroundColor(colors.black)
if tonumber(err) then if tonumber(err) then
tab.terminal.setTextColor(colors.orange) self.terminal.setTextColor(colors.orange)
print('Process exited with error code: ' .. err) print('Process exited with error code: ' .. err)
elseif err then elseif err then
printError(tostring(err)) printError(tostring(err))
end end
tab.terminal.setTextColor(colors.white) self.terminal.setTextColor(colors.white)
print('\nPress enter to close') print('\nPress enter to close')
routine.isDead = true self.isDead = true
routine.hidden = false self.hidden = false
redrawMenu() redrawMenu()
while true do while true do
local e, code = os.pullEventRaw('key') local e, code = os.pullEventRaw('key')
@ -153,9 +129,9 @@ function multishell.openTab(tab)
end end
end end
end end
end) end
kernel.launch(routine) local routine = kernel.run(tab)
if tab.focused then if tab.focused then
multishell.setFocus(routine.uid) multishell.setFocus(routine.uid)
@ -256,9 +232,10 @@ kernel.hook('multishell_redraw', function()
if currentTab then if currentTab then
if currentTab.sx then if currentTab.sx then
local textColor = currentTab.isDead and _colors.errorColor or _colors.focusTextColor
blit:write(currentTab.sx - 1, blit:write(currentTab.sx - 1,
' ' .. currentTab.title:sub(1, currentTab.width - 1) .. ' ', ' ' .. currentTab.title:sub(1, currentTab.width - 1) .. ' ',
_colors.focusBackgroundColor, _colors.focusTextColor) _colors.focusBackgroundColor, textColor)
end end
if not currentTab.noTerminate then if not currentTab.noTerminate then
blit:write(w, closeInd, nil, _colors.focusTextColor) blit:write(w, closeInd, nil, _colors.focusTextColor)

View File

@ -1,5 +1,6 @@
local Array = require('opus.array') local Array = require('opus.array')
local Terminal = require('opus.terminal') local Terminal = require('opus.terminal')
local trace = require('opus.trace')
local Util = require('opus.util') local Util = require('opus.util')
_G.kernel = { _G.kernel = {
@ -67,8 +68,6 @@ function kernel.unhook(event, fn)
end end
end end
local Routine = { }
local function switch(routine, previous) local function switch(routine, previous)
if routine then if routine then
if previous and previous.window then if previous and previous.window then
@ -86,6 +85,8 @@ local function switch(routine, previous)
end end
end end
local Routine = { }
function Routine:resume(event, ...) function Routine:resume(event, ...)
if not self.co or coroutine.status(self.co) == 'dead' then if not self.co or coroutine.status(self.co) == 'dead' then
return return
@ -95,38 +96,33 @@ function Routine:resume(event, ...)
local previousTerm = term.redirect(self.terminal) local previousTerm = term.redirect(self.terminal)
local previous = kernel.running local previous = kernel.running
kernel.running = self -- stupid shell set title kernel.running = self
local ok, result = coroutine.resume(self.co, event, ...) local ok, result = coroutine.resume(self.co, event, ...)
kernel.running = previous kernel.running = previous
if ok then self.filter = result
self.filter = result
else
_G.printError(result)
end
self.terminal = term.current() self.terminal = term.current()
term.redirect(previousTerm) term.redirect(previousTerm)
if not ok and self.haltOnError then
error(result, -1)
end
if coroutine.status(self.co) == 'dead' then
Array.removeByValue(kernel.routines, self)
if self.onDestroy then
pcall(self.onDestroy, self)
end
if #kernel.routines > 0 then
switch(kernel.routines[1])
end
if self.haltOnExit then
kernel.halt()
end
end
return ok, result return ok, result
end end
end end
-- override if any post processing is required
-- routine:cleanup must be called explicitly if overridden
function Routine:onExit(status, message) -- self, status, message
if not status and message ~= 'Terminated' then
_G.printError(message)
end
end
function Routine:cleanup()
Array.removeByValue(kernel.routines, self)
if #kernel.routines > 0 then
switch(kernel.routines[1])
end
end
function kernel.getFocused() function kernel.getFocused()
return kernel.routines[1] return kernel.routines[1]
end end
@ -147,17 +143,26 @@ function kernel.newRoutine(args)
local routine = setmetatable({ local routine = setmetatable({
uid = kernel.UID, uid = kernel.UID,
timestamp = os.clock(), timestamp = os.clock(),
terminal = kernel.window,
window = kernel.window, window = kernel.window,
title = 'untitled', title = 'untitled',
}, { __index = Routine }) }, { __index = Routine })
Util.merge(routine, args) Util.merge(routine, args)
routine.env = args.env or shell.makeEnv() routine.env = args.env or shell.makeEnv()
routine.terminal = routine.terminal or routine.window
return routine return routine
end end
local function xprun(env, path, ...)
setmetatable(env, { __index = _G })
local fn, m = loadfile(path, env)
if fn then
return trace(fn, ...)
end
return fn, m
end
function kernel.launch(routine) function kernel.launch(routine)
routine.co = routine.co or coroutine.create(function() routine.co = routine.co or coroutine.create(function()
local result, err local result, err
@ -165,14 +170,13 @@ function kernel.launch(routine)
if routine.fn then if routine.fn then
result, err = Util.runFunction(routine.env, routine.fn, table.unpack(routine.args or { } )) result, err = Util.runFunction(routine.env, routine.fn, table.unpack(routine.args or { } ))
elseif routine.path then elseif routine.path then
result, err = Util.run(routine.env, routine.path, table.unpack(routine.args or { } )) result, err = xprun(routine.env, routine.path, table.unpack(routine.args or { } ))
else else
err = 'kernel: invalid routine' err = 'kernel: invalid routine'
end end
if not result and err ~= 'Terminated' then pcall(routine.onExit, routine, result, err)
error(err or 'Error occurred', 2) routine:cleanup()
end
end) end)
table.insert(kernel.routines, routine) table.insert(kernel.routines, routine)
@ -203,8 +207,6 @@ function kernel.raise(uid)
end end
switch(routine, previous) switch(routine, previous)
-- local previous = eventData[2]
-- local routine = kernel.find(previous)
return true return true
end end
return false return false
@ -232,8 +234,8 @@ function kernel.find(uid)
return Util.find(kernel.routines, 'uid', uid) return Util.find(kernel.routines, 'uid', uid)
end end
function kernel.halt() function kernel.halt(status, message)
os.queueEvent('kernel_halt') os.queueEvent('kernel_halt', status, message)
end end
function kernel.event(event, eventData) function kernel.event(event, eventData)
@ -275,15 +277,20 @@ function kernel.event(event, eventData)
end end
function kernel.start() function kernel.start()
local s, m = pcall(function() local s, m
pcall(function()
repeat repeat
local eventData = { os.pullEventRaw() } local eventData = { os.pullEventRaw() }
local event = table.remove(eventData, 1) local event = table.remove(eventData, 1)
kernel.event(event, eventData) kernel.event(event, eventData)
if event == 'kernel_halt' then
s = eventData[1]
m = eventData[2]
end
until event == 'kernel_halt' until event == 'kernel_halt'
end) end)
if not s then if not s and m then
kernel.window.setVisible(true) kernel.window.setVisible(true)
term.redirect(kernel.window) term.redirect(kernel.window)
print('\nCrash detected\n') print('\nCrash detected\n')
@ -320,15 +327,15 @@ local function init(...)
term.redirect(kernel.window) term.redirect(kernel.window)
shell.run('sys/apps/autorun.lua') shell.run('sys/apps/autorun.lua')
local shellWindow = window.create(kernel.terminal, 1, 1, w, h, false) local win = window.create(kernel.terminal, 1, 1, w, h, true)
local s, m = kernel.run({ local s, m = kernel.run({
title = args[1], title = args[1],
path = 'sys/apps/shell.lua', path = 'sys/apps/shell.lua',
args = args, args = args,
haltOnExit = true, window = win,
haltOnError = true, onExit = function(_, s, m)
terminal = shellWindow, kernel.halt(s, m)
window = shellWindow, end,
}) })
if s then if s then
kernel.raise(s.uid) kernel.raise(s.uid)
@ -342,8 +349,12 @@ end
kernel.run({ kernel.run({
fn = init, fn = init,
title = 'init', title = 'init',
haltOnError = true,
args = { ... }, args = { ... },
onExit = function(_, status, message)
if not status then
kernel.halt(status, message)
end
end,
}) })
kernel.start() kernel.start()

View File

@ -79,7 +79,7 @@ return function(env)
-- place package and require function into env -- place package and require function into env
env.package = { env.package = {
path = env.LUA_PATH or _G.LUA_PATH or DEFAULT_PATH, path = env.LUA_PATH or _G.LUA_PATH or DEFAULT_PATH,
config = '/\n:\n?\n!\n-', config = '/\n:\n?\n!\n-',
preload = { }, preload = { },
loaded = { loaded = {

View File

@ -37,6 +37,22 @@ local function trim_traceback(target, marker)
for line in target:gmatch("([^\n]*)\n?") do ttarget[#ttarget + 1] = line end for line in target:gmatch("([^\n]*)\n?") do ttarget[#ttarget + 1] = line end
for line in marker:gmatch("([^\n]*)\n?") do tmarker[#tmarker + 1] = line end for line in marker:gmatch("([^\n]*)\n?") do tmarker[#tmarker + 1] = line end
--[[
TODO : fix this trace
Anavrins - if you could take a look, it would be appreciated
-- basically i want the stack logged in a more readable
-- format and the normal code/error message to be returned
-- unsure why the traceback method concatenates the stack
-- when it can just be returned as a table - would make
-- filtering much simpler
-- the following seems to reduce the stacktrace way too
-- much - losing most of the relevant call stack
-- i have modified this a bit from the original - not sure
-- if my changes are causing the issues or not
-- Trim identical suffixes -- Trim identical suffixes
local t_len, m_len = #ttarget, #tmarker local t_len, m_len = #ttarget, #tmarker
while t_len >= 3 and ttarget[t_len] == tmarker[m_len] do while t_len >= 3 and ttarget[t_len] == tmarker[m_len] do
@ -50,7 +66,7 @@ local function trim_traceback(target, marker)
table.remove(ttarget, t_len) table.remove(ttarget, t_len)
t_len = t_len - 1 t_len = t_len - 1
end end
]]
ttarget[#ttarget] = nil -- remove 2 calls added by the added xpcall ttarget[#ttarget] = nil -- remove 2 calls added by the added xpcall
ttarget[#ttarget] = nil ttarget[#ttarget] = nil
@ -84,6 +100,7 @@ return function (fn, ...)
if trace[i] == "stack traceback:" then trace_starts = i; break end if trace[i] == "stack traceback:" then trace_starts = i; break end
end end
_G._syslog('')
for _, line in pairs(trace) do for _, line in pairs(trace) do
_G._syslog(line) _G._syslog(line)
end end