Compare commits
No commits in common. "eb95f9715e78fa83da7325f173e7f79019eb651a" and "1ef6d5db9687886dad4fc8dbdcdd30c03cff2d21" have entirely different histories.
eb95f9715e
...
1ef6d5db96
@ -21,29 +21,24 @@ end
|
|||||||
function shell.interactive()
|
function shell.interactive()
|
||||||
local shenv = setmetatable({}, {__index=shindex})
|
local shenv = setmetatable({}, {__index=shindex})
|
||||||
local run = true
|
local run = true
|
||||||
os.setenv("PATH",{"/boot/exec","/pkg/exec"})
|
|
||||||
function shenv.quit()
|
function shenv.quit()
|
||||||
run = false
|
run = false
|
||||||
end
|
end
|
||||||
while run do
|
while run do
|
||||||
io.write(string.format("\27[32m%s:%s>\27[0m ",os.getenv("HOSTNAME") or "localhost",(os.getenv("PWD") or _VERSION)))
|
io.write(string.format("\27[32m%s:%s>\27[0m ",os.getenv("HOSTNAME") or "localhost",(os.getenv("PWD") or _VERSION)))
|
||||||
local w,input = pcall(io.read)
|
local input = io.read()
|
||||||
if not w then
|
if input:sub(1,1) == "=" then
|
||||||
print("\27[31m^C")
|
input = "return "..input:sub(2)
|
||||||
|
end
|
||||||
|
local f, r = load(input, "shell", "t", shenv)
|
||||||
|
if not f then
|
||||||
|
print("\27[31m"..r)
|
||||||
else
|
else
|
||||||
if input:sub(1,1) == "=" then
|
local rt = {pcall(f)}
|
||||||
input = "return "..input:sub(2)
|
local rs = table.remove(rt,1)
|
||||||
end
|
if not rs then io.write("\27[31m") end
|
||||||
local f, r = load(input, "shell", "t", shenv)
|
for k,v in pairs(rt) do
|
||||||
if not f then
|
print(formatValue(v))
|
||||||
print("\27[31m"..r)
|
|
||||||
else
|
|
||||||
local rt = {pcall(f)}
|
|
||||||
local rs = table.remove(rt,1)
|
|
||||||
if not rs then io.write("\27[31m") end
|
|
||||||
for k,v in pairs(rt) do
|
|
||||||
print(formatValue(v))
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -119,49 +119,9 @@ function shutil.free() -- Displays used and free memory.
|
|||||||
print(string.format("%5s %5s %5s",wrapUnits(computer.totalMemory()),wrapUnits(computer.totalMemory()-computer.freeMemory()),wrapUnits(computer.freeMemory())))
|
print(string.format("%5s %5s %5s",wrapUnits(computer.totalMemory()),wrapUnits(computer.totalMemory()-computer.freeMemory()),wrapUnits(computer.freeMemory())))
|
||||||
end
|
end
|
||||||
|
|
||||||
local function pread(self,len)
|
|
||||||
syslog(tostring(self))
|
|
||||||
syslog(tostring(len))
|
|
||||||
io.input(self.input)
|
|
||||||
local b = io.read(len)
|
|
||||||
io.input(self)
|
|
||||||
if b:match("\3") then
|
|
||||||
error("terminated")
|
|
||||||
end
|
|
||||||
return b
|
|
||||||
end
|
|
||||||
|
|
||||||
function shutil.which(name)
|
|
||||||
local fpath
|
|
||||||
for _,dir in ipairs(os.getenv("PATH")) do
|
|
||||||
fpath = fpath or fs.exists(string.format("%s/%s.lua",dir,name)) and string.format("%s/%s.lua",dir,name) or fs.exists(string.format("%s/%s",dir,name)) and string.format("%s/%s",dir,name)
|
|
||||||
end
|
|
||||||
return fpath
|
|
||||||
end
|
|
||||||
|
|
||||||
shutil.cd = os.chdir
|
shutil.cd = os.chdir
|
||||||
shutil.mkdir = fs.makeDirectory
|
shutil.mkdir = fs.makeDirectory
|
||||||
shutil.cp = fs.copy
|
shutil.cp = fs.copy
|
||||||
shutil.rm = fs.remove
|
shutil.rm = fs.remove
|
||||||
|
|
||||||
return setmetatable({}, {__index = function(t,k)
|
return shutil
|
||||||
if shutil[k] then
|
|
||||||
return shutil[k]
|
|
||||||
end
|
|
||||||
local path = shutil.which(k)
|
|
||||||
if path then
|
|
||||||
local fn, e = loadfile(path)
|
|
||||||
if not fn then error(string.format("\n - %s",e)) end
|
|
||||||
return function()
|
|
||||||
local pid = os.spawn(fn,path)
|
|
||||||
local ret = {require("event").pull("process_finished",pid)}
|
|
||||||
if not ret[3] then
|
|
||||||
error(string.format("\n - %s",ret[4]))
|
|
||||||
end
|
|
||||||
for i = 1, 3 do
|
|
||||||
table.remove(ret,1)
|
|
||||||
end
|
|
||||||
return table.unpack(ret)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end})
|
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
local vtansi = {}
|
local vtansi = {}
|
||||||
local keyboardIgnore = {}
|
|
||||||
vtansi.activeBuffers = {}
|
|
||||||
vtansi.sequences = {
|
vtansi.sequences = {
|
||||||
[28] = "\n", -- newline
|
[28] = "\n", -- newline
|
||||||
[200] = "\27[A", -- up
|
[200] = "\27[A", -- up
|
||||||
@ -10,26 +8,9 @@ vtansi.sequences = {
|
|||||||
[201] = "\27[5~", -- page up
|
[201] = "\27[5~", -- page up
|
||||||
[209] = "\27[6~" -- page down
|
[209] = "\27[6~" -- page down
|
||||||
}
|
}
|
||||||
vtansi.keys = {}
|
function vtansi.vtemu(gpu) -- table -- function -- takes GPU component proxy *gpu* and returns a function to write to it in a manner like an ANSI terminal
|
||||||
vtansi.keys[0x38] = "lalt"
|
|
||||||
vtansi.keys[0xB8] = "ralt"
|
|
||||||
function vtansi.saveToBuffer(gpu,idx)
|
|
||||||
gpu.bitblt(idx, nil, nil, nil, nil, 0)
|
|
||||||
end
|
|
||||||
function vtansi.loadFromBuffer(gpu,idx)
|
|
||||||
gpu.bitblt(0, nil, nil, nil, nil, idx)
|
|
||||||
end
|
|
||||||
function vtansi.switchToBuffer(gpu,idx)
|
|
||||||
-- copy screen to the active buffer
|
|
||||||
vtansi.saveToBuffer(gpu,vtansi.activeBuffers[gpu.address])
|
|
||||||
-- copy the new buffer to the screen
|
|
||||||
vtansi.loadFromBuffer(gpu,idx)
|
|
||||||
vtansi.activeBuffers[gpu.address] = idx
|
|
||||||
end
|
|
||||||
function vtansi.vtemu(gpu,bn) -- table number -- function -- takes GPU component proxy *gpu* and returns a function to write to it in a manner like an ANSI terminal, either allocating a new buffer or using *bn*.
|
|
||||||
local colours = {0x0,0xFF0000,0x00FF00,0xFFFF00,0x0000FF,0xFF00FF,0x00B6FF,0xFFFFFF}
|
local colours = {0x0,0xFF0000,0x00FF00,0xFFFF00,0x0000FF,0xFF00FF,0x00B6FF,0xFFFFFF}
|
||||||
local mx, my = gpu.maxResolution()
|
local mx, my = gpu.maxResolution()
|
||||||
local buffer = nil
|
|
||||||
local cx, cy = 1, 1
|
local cx, cy = 1, 1
|
||||||
local pc = " "
|
local pc = " "
|
||||||
local lc = ""
|
local lc = ""
|
||||||
@ -40,19 +21,8 @@ function vtansi.vtemu(gpu,bn) -- table number -- function -- takes GPU component
|
|||||||
local bg, fg = 0, 0xFFFFFF
|
local bg, fg = 0, 0xFFFFFF
|
||||||
|
|
||||||
-- setup
|
-- setup
|
||||||
if gpu.getActiveBuffer then
|
gpu.setResolution(mx,my)
|
||||||
buffer = bn or gpu.allocateBuffer(mx,my)
|
gpu.fill(1,1,mx,my," ")
|
||||||
vtansi.activeBuffers[gpu.address] = vtansi.activeBuffers[gpu.address] or buffer
|
|
||||||
local oldActiveBuffer = vtansi.activeBuffers[gpu.address]
|
|
||||||
gpu.setActiveBuffer(buffer)
|
|
||||||
gpu.setResolution(mx,my)
|
|
||||||
gpu.fill(1,1,mx,my," ")
|
|
||||||
gpu.setActiveBuffer(oldActiveBuffer)
|
|
||||||
else
|
|
||||||
gpu.setResolution(mx,my)
|
|
||||||
gpu.fill(1,1,mx,my," ")
|
|
||||||
end
|
|
||||||
|
|
||||||
local function checkCursor()
|
local function checkCursor()
|
||||||
if cx > mx and lw then
|
if cx > mx and lw then
|
||||||
cx, cy = 1, cy+1
|
cx, cy = 1, cy+1
|
||||||
@ -67,13 +37,6 @@ function vtansi.vtemu(gpu,bn) -- table number -- function -- takes GPU component
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function termwrite(s)
|
local function termwrite(s)
|
||||||
if buffer then
|
|
||||||
if vtansi.activeBuffers[gpu.address] == buffer then
|
|
||||||
gpu.setActiveBuffer(0)
|
|
||||||
else
|
|
||||||
gpu.setActiveBuffer(buffer)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local wb = ""
|
local wb = ""
|
||||||
local lb, ec = nil, nil
|
local lb, ec = nil, nil
|
||||||
local function flushwb()
|
local function flushwb()
|
||||||
@ -198,14 +161,13 @@ function vtansi.vtemu(gpu,bn) -- table number -- function -- takes GPU component
|
|||||||
return rs, lb, ec
|
return rs, lb, ec
|
||||||
end
|
end
|
||||||
|
|
||||||
return termwrite, buffer
|
return termwrite
|
||||||
end
|
end
|
||||||
|
|
||||||
function vtansi.vtsession(gpua,scra,bn) -- string string number -- function function function -- creates a process to handle the GPU and screen address combination *gpua*/*scra*, optionally using buffer number *bn* specifically. Returns read, write and "close" functions.
|
function vtansi.vtsession(gpua,scra) -- string string -- table -- creates a process to handle the GPU and screen address combination *gpua*/*scra*. Returns read, write and "close" functions.
|
||||||
local modifiers = {}
|
|
||||||
local gpu = component.proxy(gpua)
|
local gpu = component.proxy(gpua)
|
||||||
-- gpu.bind(scra)
|
gpu.bind(scra)
|
||||||
local write, bn = vtansi.vtemu(gpu,bn)
|
local write = vtansi.vtemu(gpu)
|
||||||
local kba = {}
|
local kba = {}
|
||||||
for k,v in ipairs(component.invoke(scra,"getKeyboards")) do
|
for k,v in ipairs(component.invoke(scra,"getKeyboards")) do
|
||||||
kba[v]=true
|
kba[v]=true
|
||||||
@ -214,45 +176,19 @@ function vtansi.vtsession(gpua,scra,bn) -- string string number -- function func
|
|||||||
os.spawn(function()
|
os.spawn(function()
|
||||||
while true do
|
while true do
|
||||||
local ty,ka,ch,kc = coroutine.yield()
|
local ty,ka,ch,kc = coroutine.yield()
|
||||||
if kba[ka] and keyboardIgnore[ka] == bn then
|
if ty == "key_down" and kba[ka] then
|
||||||
keyboardIgnore[ka] = nil
|
local outs
|
||||||
end
|
if ch > 0 then
|
||||||
if kba[ka] and vtansi.keys[kc] then
|
outs = string.char(ch)
|
||||||
modifiers[vtansi.keys[kc]] = ty == "key_down"
|
end
|
||||||
end
|
outs = vtansi.sequences[kc] or outs
|
||||||
if ty == "key_down" and kba[ka] and (bn == nil or vtansi.activeBuffers[gpua] == bn) then
|
if outs then
|
||||||
if bn and ty == "key_down" and kba[ka] and ch == 46 and kc == 52 and (modifiers.lalt or modifiers.ralt) then
|
if echo then write(outs) end
|
||||||
-- next buffer
|
buf=buf..outs
|
||||||
local allBuffers = gpu.buffers()
|
|
||||||
for k,v in ipairs(allBuffers) do
|
|
||||||
if v == vtansi.activeBuffers[gpu.address] and allBuffers[k+1] and not keyboardIgnore[ka] then
|
|
||||||
keyboardIgnore[ka] = bn
|
|
||||||
vtansi.switchToBuffer(gpu,allBuffers[k+1])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
elseif bn and ty == "key_down" and kba[ka] and ch == 44 and kc == 51 and (modifiers.lalt or modifiers.ralt) then
|
|
||||||
-- previous buffer
|
|
||||||
local allBuffers = gpu.buffers()
|
|
||||||
for k,v in ipairs(allBuffers) do
|
|
||||||
if v == vtansi.activeBuffers[gpu.address] and allBuffers[k-1] and not keyboardIgnore[ka] then
|
|
||||||
keyboardIgnore[ka] = bn
|
|
||||||
vtansi.switchToBuffer(gpu,allBuffers[k-1])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
local outs
|
|
||||||
if ch > 0 then
|
|
||||||
outs = string.char(ch)
|
|
||||||
end
|
|
||||||
outs = vtansi.sequences[kc] or outs
|
|
||||||
if outs then
|
|
||||||
if echo then write(outs) end
|
|
||||||
buf=buf..outs
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end,string.format("ttyd[%s:%s/%i]",gpua:sub(1,8),scra:sub(1,8),tonumber(bn) or 0))
|
end,string.format("ttyd[%s:%s]",gpua:sub(1,8),scra:sub(1,8)))
|
||||||
local function bread(n)
|
local function bread(n)
|
||||||
coroutine.yield()
|
coroutine.yield()
|
||||||
local r = buf
|
local r = buf
|
||||||
|
@ -307,8 +307,6 @@ function buffer:read(...)
|
|||||||
if #buffer > 0 and pos <= #buffer then
|
if #buffer > 0 and pos <= #buffer then
|
||||||
buffer = buffer:sub(1, (#buffer - pos)) .. buffer:sub((#buffer - pos) + 2)
|
buffer = buffer:sub(1, (#buffer - pos)) .. buffer:sub((#buffer - pos) + 2)
|
||||||
end
|
end
|
||||||
elseif char == "\3" then -- ^C, error
|
|
||||||
error("terminated")
|
|
||||||
elseif char == "\1" then -- ^A, go to start of line
|
elseif char == "\1" then -- ^A, go to start of line
|
||||||
pos = buffer:len()+1
|
pos = buffer:len()+1
|
||||||
elseif char == "\5" then -- ^E, go to end of line
|
elseif char == "\5" then -- ^E, go to end of line
|
||||||
|
@ -54,7 +54,7 @@ function fs.open(path,mode) -- string string -- table -- Opens file *path* with
|
|||||||
if mode:find("r") then
|
if mode:find("r") then
|
||||||
fobj.read = fread
|
fobj.read = fread
|
||||||
end
|
end
|
||||||
if mode:find("w") or mode:find("a") then
|
if mode:find("w") then
|
||||||
fobj.write = fwrite
|
fobj.write = fwrite
|
||||||
end
|
end
|
||||||
return fobj
|
return fobj
|
||||||
|
@ -37,32 +37,20 @@ local function spawnShell(fin,fout)
|
|||||||
io.input(fin)
|
io.input(fin)
|
||||||
io.output(fout):setvbuf("no")
|
io.output(fout):setvbuf("no")
|
||||||
print(_OSVERSION.." - "..tostring(math.floor(computer.totalMemory()/1024)).."K RAM")
|
print(_OSVERSION.." - "..tostring(math.floor(computer.totalMemory()/1024)).."K RAM")
|
||||||
print((os.getenv("HOSTNAME") or "unknown") .. " on " .. fin)
|
return os.spawn(function() local w,r = pcall(shell.interactive) if not w then syslog(r) end end, "shell: "..tostring(fin))
|
||||||
-- return os.spawn(function() local w,r = pcall(shell.interactive) if not w then syslog(r) end end, "shell: "..tostring(fin))
|
|
||||||
return os.spawn(shell.interactive, "shell: "..tostring(fin))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function allocate()
|
local function allocate()
|
||||||
for k,v in pairs(gpus) do
|
for k,v in pairs(gpus) do
|
||||||
dprint("Setting up display "..k)
|
dprint(k)
|
||||||
local sA = nextScreen(v[2])
|
local sA = nextScreen(v[2])
|
||||||
if v[1] == false and sA then
|
if v[1] == false and sA then
|
||||||
local terminals = 1
|
local r,w = vtansi.vtsession(k,sA)
|
||||||
local gpu = component.proxy(k)
|
devfs.register("tty"..tostring(ttyn), function() return r,w,function() end end)
|
||||||
gpu.bind(sA)
|
|
||||||
if gpu.buffers then
|
|
||||||
gpu.freeAllBuffers()
|
|
||||||
local mw, mh = gpu.maxResolution()
|
|
||||||
terminals = math.floor(gpu.freeMemory() / (mw * mh))
|
|
||||||
end
|
|
||||||
for i = 1, terminals do
|
|
||||||
local r,w = vtansi.vtsession(k,sA)
|
|
||||||
devfs.register("tty"..tostring(ttyn), function() return r,w,function() end end)
|
|
||||||
pids["tty"..tostring(ttyn)] = {-1}
|
|
||||||
ttyn = ttyn + 1
|
|
||||||
end
|
|
||||||
gpus[k][1] = true
|
gpus[k][1] = true
|
||||||
screens[sA][1] = true
|
screens[sA][1] = true
|
||||||
|
pids["tty"..tostring(ttyn)] = {-1}
|
||||||
|
ttyn = ttyn + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -71,15 +59,14 @@ function start()
|
|||||||
basepid = os.spawn(function()
|
basepid = os.spawn(function()
|
||||||
scan()
|
scan()
|
||||||
allocate()
|
allocate()
|
||||||
dprint("Display setup complete.")
|
dprint("screens ready")
|
||||||
while true do
|
while true do
|
||||||
coroutine.yield()
|
coroutine.yield()
|
||||||
for k,v in pairs(pids) do
|
for k,v in pairs(pids) do
|
||||||
if not os.taskInfo(v[1]) then
|
if not os.taskInfo(v[1]) then
|
||||||
dprint("Spawning new shell for "..k)
|
dprint("Spawning new shell for "..k)
|
||||||
pids[k][1] = spawnShell(v[2] or "/dev/"..k, v[3] or "/dev/"..k)
|
pids[k][1] = spawnShell(v[2] or "/dev/"..k, v[3] or "/dev/"..k)
|
||||||
pids[k][2], pids[k][3] = pids[k][2] or "/dev/"..k, pids[k][3] or "/dev/"..k
|
pids[k][2], pids[k][3] = pids[k][2] or io.input(), pids[k][3] or io.output()
|
||||||
coroutine.yield()
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user