Compare commits
No commits in common. "aaccc053d31d652b127b03c0e59f60984e33e639" and "2e3907abd3d3220d4a6301a248ffd871b74c256f" have entirely different histories.
aaccc053d3
...
2e3907abd3
@ -1,8 +0,0 @@
|
|||||||
xpcall(function()
|
|
||||||
io.input("/dev/tty0")
|
|
||||||
io.output("/dev/tty0")
|
|
||||||
os.setenv("PWD","/boot")
|
|
||||||
io.write("PsychOS v2.0a1 - ")
|
|
||||||
print(tostring(math.floor(computer.totalMemory()/1024)).."K RAM")
|
|
||||||
os.spawnfile("/boot/exec/shell.lua")
|
|
||||||
end,function(e) dprint(e) end,"init test")
|
|
@ -1,5 +1,4 @@
|
|||||||
print("PID# Parent Name")
|
print("PID# VTY# Name")
|
||||||
for k,v in pairs(os.tasks()) do
|
for k,v in pairs(tTasks) do
|
||||||
local t = os.taskInfo(v)
|
print(string.format("%4d %4d %s",k,v.e.t or 0,v.n))
|
||||||
print(string.format("%4d %4d %s",k,v.parent,v.name))
|
|
||||||
end
|
end
|
||||||
|
@ -1,171 +0,0 @@
|
|||||||
local buffer = {}
|
|
||||||
local metatable = {
|
|
||||||
__index = buffer,
|
|
||||||
__metatable = "file",
|
|
||||||
__close = buffer.close
|
|
||||||
}
|
|
||||||
|
|
||||||
function buffer.new(mode, stream)
|
|
||||||
local result = {
|
|
||||||
closed = false,
|
|
||||||
tty = false,
|
|
||||||
mode = {},
|
|
||||||
stream = stream,
|
|
||||||
bufferRead = "",
|
|
||||||
bufferWrite = "",
|
|
||||||
bufferSize = math.max(512, math.min(8 * 1024, computer.freeMemory() / 8)),
|
|
||||||
bufferMode = "full",
|
|
||||||
readTimeout = math.huge,
|
|
||||||
}
|
|
||||||
mode = mode or "r"
|
|
||||||
for i = 1, mode:len() do
|
|
||||||
result.mode[mode:sub(i, i)] = true
|
|
||||||
end
|
|
||||||
-- when stream closes, result should close first
|
|
||||||
-- when result closes, stream should close after
|
|
||||||
-- when stream closes, it is removed from the proc
|
|
||||||
stream.close = setmetatable({close = stream.close,parent = result},{__call = buffer.close})
|
|
||||||
return setmetatable(result, metatable)
|
|
||||||
end
|
|
||||||
|
|
||||||
function buffer:close()
|
|
||||||
-- self is either the buffer, or the stream.close callable
|
|
||||||
local meta = getmetatable(self)
|
|
||||||
if meta == metatable.__metatable then
|
|
||||||
return self.stream:close()
|
|
||||||
end
|
|
||||||
local parent = self.parent
|
|
||||||
|
|
||||||
if parent.mode.w or parent.mode.a then
|
|
||||||
parent:flush()
|
|
||||||
end
|
|
||||||
parent.closed = true
|
|
||||||
return self.close(parent.stream)
|
|
||||||
end
|
|
||||||
|
|
||||||
function buffer:flush()
|
|
||||||
if #self.bufferWrite > 0 then
|
|
||||||
local tmp = self.bufferWrite
|
|
||||||
self.bufferWrite = ""
|
|
||||||
local result, reason = self.stream:write(tmp)
|
|
||||||
if not result then
|
|
||||||
return nil, reason or "bad file descriptor"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
function buffer:lines(...)
|
|
||||||
local args = table.pack(...)
|
|
||||||
return function()
|
|
||||||
local result = table.pack(self:read(table.unpack(args, 1, args.n)))
|
|
||||||
if not result[1] and result[2] then
|
|
||||||
error(result[2])
|
|
||||||
end
|
|
||||||
return table.unpack(result, 1, result.n)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function readChunk(self)
|
|
||||||
if computer.uptime() > self.timeout then
|
|
||||||
error("timeout")
|
|
||||||
end
|
|
||||||
local result, reason = self.stream:read(math.max(1,self.bufferSize))
|
|
||||||
if result then
|
|
||||||
self.bufferRead = self.bufferRead .. result
|
|
||||||
return self
|
|
||||||
else -- error or eof
|
|
||||||
return result, reason
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function buffer:readLine(chop, timeout)
|
|
||||||
self.timeout = timeout or (computer.uptime() + self.readTimeout)
|
|
||||||
local start = 1
|
|
||||||
while true do
|
|
||||||
local buf = self.bufferRead
|
|
||||||
local i = buf:find("[\r\n]", start)
|
|
||||||
local c = i and buf:sub(i,i)
|
|
||||||
local is_cr = c == "\r"
|
|
||||||
if i and (not is_cr or i < #buf) then
|
|
||||||
local n = buf:sub(i+1,i+1)
|
|
||||||
if is_cr and n == "\n" then
|
|
||||||
c = c .. n
|
|
||||||
end
|
|
||||||
local result = buf:sub(1, i - 1) .. (chop and "" or c)
|
|
||||||
self.bufferRead = buf:sub(i + #c)
|
|
||||||
return result
|
|
||||||
else
|
|
||||||
start = #self.bufferRead - (is_cr and 1 or 0)
|
|
||||||
local result, reason = readChunk(self)
|
|
||||||
if not result then
|
|
||||||
if reason then
|
|
||||||
return result, reason
|
|
||||||
else -- eof
|
|
||||||
result = #self.bufferRead > 0 and self.bufferRead or nil
|
|
||||||
self.bufferRead = ""
|
|
||||||
return result
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
coroutine.yield()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function buffer:read(...)
|
|
||||||
if not self.mode.r then
|
|
||||||
return nil, "read mode was not enabled for this stream"
|
|
||||||
end
|
|
||||||
|
|
||||||
if self.mode.w or self.mode.a then
|
|
||||||
self:flush()
|
|
||||||
end
|
|
||||||
|
|
||||||
if select("#", ...) == 0 then
|
|
||||||
return self:readLine(true)
|
|
||||||
end
|
|
||||||
return self:formatted_read(readChunk, ...)
|
|
||||||
end
|
|
||||||
|
|
||||||
function buffer:setvbuf(mode, size)
|
|
||||||
mode = mode or self.bufferMode
|
|
||||||
size = size or self.bufferSize
|
|
||||||
|
|
||||||
assert(mode == "no" or mode == "full" or mode == "line",
|
|
||||||
"bad argument #1 (no, full or line expected, got " .. tostring(mode) .. ")")
|
|
||||||
assert(mode == "no" or type(size) == "number",
|
|
||||||
"bad argument #2 (number expected, got " .. type(size) .. ")")
|
|
||||||
|
|
||||||
self.bufferMode = mode
|
|
||||||
self.bufferSize = size
|
|
||||||
|
|
||||||
return self.bufferMode, self.bufferSize
|
|
||||||
end
|
|
||||||
|
|
||||||
function buffer:write(...)
|
|
||||||
if self.closed then
|
|
||||||
return nil, "bad file descriptor"
|
|
||||||
end
|
|
||||||
if not self.mode.w and not self.mode.a then
|
|
||||||
return nil, "write mode was not enabled for this stream"
|
|
||||||
end
|
|
||||||
local args = table.pack(...)
|
|
||||||
for i = 1, args.n do
|
|
||||||
if type(args[i]) == "number" then
|
|
||||||
args[i] = tostring(args[i])
|
|
||||||
end
|
|
||||||
checkArg(i, args[i], "string")
|
|
||||||
end
|
|
||||||
|
|
||||||
for i = 1, args.n do
|
|
||||||
local arg = args[i]
|
|
||||||
local result, reason
|
|
||||||
result, reason = self.stream:write(arg)
|
|
||||||
if not result then
|
|
||||||
return nil, reason
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return self
|
|
||||||
end
|
|
19
module/createterms.lua
Normal file
19
module/createterms.lua
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
local ts = {}
|
||||||
|
for a,_ in component.list("screen") do
|
||||||
|
ts[#ts+1] = a
|
||||||
|
end
|
||||||
|
local ttyn = 0
|
||||||
|
for a,_ in component.list("gpu") do
|
||||||
|
local r,w = vtemu(a,table.remove(ts,1))
|
||||||
|
-- fd[#fd+1] = {["read"]=r,["write"]=w,["close"]=function() w("\27[2J\27[H") end,["t"]="t"}
|
||||||
|
iofs.register("tty"..tostring(ttyn),function() return r,w,function() w("\27[2J\27[H") end end)
|
||||||
|
local f = io.open("/iofs/tty"..tostring(ttyn),"rw")
|
||||||
|
fd[f.fd].t = "t"
|
||||||
|
ttyn = ttyn + 1
|
||||||
|
end
|
||||||
|
do
|
||||||
|
iofs.register("syslog",function() return function() return "" end, function(msg) syslog(msg,nil,tTasks[cPid].n) end, function() return true end end)
|
||||||
|
end
|
||||||
|
if #fd < 1 then
|
||||||
|
io.open("/iofs/syslog","rw")
|
||||||
|
end
|
@ -1,68 +0,0 @@
|
|||||||
devfs = {}
|
|
||||||
devfs.files = {}
|
|
||||||
devfs.fds = {}
|
|
||||||
devfs.nextfd = 0
|
|
||||||
devfs.component = {}
|
|
||||||
|
|
||||||
local function rfalse()
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
function devfs.component.getLabel()
|
|
||||||
return "devfs"
|
|
||||||
end
|
|
||||||
devfs.component.spaceUsed, devfs.component.spaceTotal, devfs.component.isReadOnly, devfs.component.isDirectory,devfs.component.size, devfs.component.setLabel = function() return computer.totalMemory()-computer.freeMemory() end, computer.totalMemory, rfalse, rfalse, rfalse, rfalse
|
|
||||||
|
|
||||||
function devfs.component.exists(fname)
|
|
||||||
return devfs.files[fname] ~= nil
|
|
||||||
end
|
|
||||||
|
|
||||||
function devfs.component.list()
|
|
||||||
local t = {}
|
|
||||||
for k,v in pairs(devfs.files) do
|
|
||||||
t[#t+1] = k
|
|
||||||
end
|
|
||||||
return t
|
|
||||||
end
|
|
||||||
|
|
||||||
function devfs.component.open(fname, mode)
|
|
||||||
fname=fname:gsub("/","")
|
|
||||||
if devfs.files[fname] then
|
|
||||||
local r,w,c,s = devfs.files[fname](mode)
|
|
||||||
devfs.fds[devfs.nextfd] = {["read"]=r or rfalse,["write"]=w or rfalse,["seek"]=s or rfalse,["close"]=c or rfalse}
|
|
||||||
devfs.nextfd = devfs.nextfd + 1
|
|
||||||
return devfs.nextfd - 1
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
function devfs.component.read(fd,count)
|
|
||||||
if devfs.fds[fd] then
|
|
||||||
return devfs.fds[fd].read(count)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function devfs.component.write(fd,data)
|
|
||||||
if devfs.fds[fd] then
|
|
||||||
return devfs.fds[fd].write(data)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function devfs.component.close(fd)
|
|
||||||
if devfs.fds[fd] then
|
|
||||||
devfs.fds[fd].close()
|
|
||||||
end
|
|
||||||
devfs.fds[fd] = nil
|
|
||||||
end
|
|
||||||
function devfs.component.seek(fd,...)
|
|
||||||
if devfs.fds[fd] then
|
|
||||||
return devfs.fds[fd].seek(...)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function devfs.component.remove(fname)
|
|
||||||
end
|
|
||||||
|
|
||||||
function devfs.register(fname,fopen) -- Register a new devfs node with the name *fname* that will run the function *fopen* when opened. This function should return a function for read, a function for write, function for close, and optionally, a function for seek, in that order.
|
|
||||||
devfs.files[fname] = fopen
|
|
||||||
end
|
|
||||||
|
|
||||||
fs.mounts.dev = devfs.component
|
|
||||||
|
|
||||||
--#include "module/devfs/null.lua"
|
|
@ -1,8 +0,0 @@
|
|||||||
devfs.register("cons",function()
|
|
||||||
return function()
|
|
||||||
end,
|
|
||||||
function()
|
|
||||||
end,
|
|
||||||
function()
|
|
||||||
end
|
|
||||||
end)
|
|
@ -1,3 +0,0 @@
|
|||||||
devfs.register("null",function()
|
|
||||||
return function() end, function() end, function() end
|
|
||||||
end)
|
|
@ -1,2 +0,0 @@
|
|||||||
devfs.register("syslog",function()
|
|
||||||
return function() end, syslog, function() end end)
|
|
51
module/dispmanager.lua
Normal file
51
module/dispmanager.lua
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
do
|
||||||
|
local tG,ttyn = {}, 0
|
||||||
|
|
||||||
|
local function checkUnused(addr) -- returns false if a screen *addr* is already allocated to a GPU
|
||||||
|
for k,v in pairs(tG) do
|
||||||
|
if v == addr then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
local function findNextDisplay() -- finds the next available screen, or nil if there are no available screens
|
||||||
|
for a,_ in component.list("screen") do
|
||||||
|
if checkUnused(a) then
|
||||||
|
return a
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
for file in ipairs(fs.list("/boot/cfg/disp/") or {}) do -- allows files in /boot/cfg/disp with filenames as GPU addresses to bind to specific screens
|
||||||
|
if component.proxy(file) then
|
||||||
|
local f = io.open("/boot/cfg/disp/"..file)
|
||||||
|
if f then
|
||||||
|
local sA = file:read()
|
||||||
|
if checkUnused(sA) then
|
||||||
|
tG[file] = sA
|
||||||
|
end
|
||||||
|
f:close()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for a,_ in component.list("gpu") do -- allocate a screen to every unused GPU
|
||||||
|
tG[a] = findNextDisplay()
|
||||||
|
end
|
||||||
|
|
||||||
|
for gpu,screen in pairs(tG) do
|
||||||
|
local r,w = vtemu(gpu,screen)
|
||||||
|
iofs.register("tty"..tostring(ttyn),function() return r,w,function() w("\27[2J\27[H") end end)
|
||||||
|
local f = io.open("/iofs/tty"..tostring(ttyn),"rw")
|
||||||
|
fd[f.fd].t = "t"
|
||||||
|
ttyn = ttyn + 1
|
||||||
|
end
|
||||||
|
do
|
||||||
|
iofs.register("syslog",function() return function() return "" end, function(msg) syslog(msg,nil,tTasks[cPid].n) end, function() return true end end)
|
||||||
|
end
|
||||||
|
if #fd < 1 then
|
||||||
|
io.open("/iofs/syslog","rw")
|
||||||
|
end
|
||||||
|
end
|
@ -1,12 +1,20 @@
|
|||||||
--#include "module/syslog.lua"
|
os.spawn(function() print(pcall(function()
|
||||||
--#include "module/sched.lua"
|
print(_OSVERSION,tostring(math.floor(computer.totalMemory()/1024)).."K memory")
|
||||||
--#include "module/buffer.lua"
|
os.setenv("PWD","/boot")
|
||||||
--#include "module/fs.lua"
|
local f = fs.open("/boot/init.txt","rb")
|
||||||
--#include "module/io.lua"
|
if f then
|
||||||
--#include "module/devfs.lua"
|
local fc = f:read("*a")
|
||||||
--#include "module/devfs/syslog.lua"
|
f:close()
|
||||||
--#include "module/loadfile.lua"
|
for line in fc:gmatch("[^\n]+") do
|
||||||
--#include "module/term.lua"
|
print("Starting service "..line)
|
||||||
os.spawnfile("/boot/exec/init.lua","init")
|
spawnfile("/boot/service/"..line,line)
|
||||||
|
end
|
||||||
os.sched()
|
end
|
||||||
|
for k,v in pairs(fd) do
|
||||||
|
if v.t == "t" then
|
||||||
|
os.setenv("t",k)
|
||||||
|
print("Spawning a shell for terminal #"..tostring(k))
|
||||||
|
spawnfile("/boot/exec/shell.lua","shell [local:"..tostring(k).."]")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)) end,"init")
|
||||||
|
65
module/io.lua
Normal file
65
module/io.lua
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
do
|
||||||
|
_G.fd,_G.io = {},{}
|
||||||
|
function io.write(d) -- writes *d* to stdout
|
||||||
|
fd[os.getenv("t") or 1].write(d)
|
||||||
|
end
|
||||||
|
function io.read(d,b) -- reads *d* from stdin, until something is returned, or b is true
|
||||||
|
local r = ""
|
||||||
|
repeat
|
||||||
|
r=fd[os.getenv("t") or 1].read(d)
|
||||||
|
coroutine.yield()
|
||||||
|
until r or b
|
||||||
|
return r
|
||||||
|
end
|
||||||
|
function print(...) -- outputs its arguments to stdout, separated by newlines
|
||||||
|
for k,v in pairs({...}) do
|
||||||
|
io.write(tostring(v).."\n")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local function fdw(f,d)
|
||||||
|
fd[f.fd].write(d)
|
||||||
|
end
|
||||||
|
local function fdr(f,d)
|
||||||
|
return fd[f.fd].read(d)
|
||||||
|
end
|
||||||
|
local function fdc(f)
|
||||||
|
fd[f.fd].close()
|
||||||
|
fd[f.fd] = nil
|
||||||
|
end
|
||||||
|
function io.newfd() -- creates a new file descriptor and returns it plus its ID
|
||||||
|
local nfd=#fd+1
|
||||||
|
fd[nfd] = {}
|
||||||
|
return nfd,fd[nfd]
|
||||||
|
end
|
||||||
|
local function fdfile(f,m) -- create a fd from a file
|
||||||
|
local e,fobj = pcall(fs.open,f,m)
|
||||||
|
if e and fobj then
|
||||||
|
local fdi, fdo =io.newfd()
|
||||||
|
if fobj.read then
|
||||||
|
function fdo.read(d)
|
||||||
|
return fobj:read(d)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if fobj.write then
|
||||||
|
function fdo.write(d)
|
||||||
|
return fobj:write(d)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function fdo.close()
|
||||||
|
fobj:close()
|
||||||
|
end
|
||||||
|
return fdi
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
function io.open(f,m) -- opens file or file descriptor *f* with mode *m*
|
||||||
|
if type(f) == "string" then
|
||||||
|
f = fdfile(f,m)
|
||||||
|
end
|
||||||
|
if fd[f] then
|
||||||
|
local t = {["close"]=fdc,["read"]=fdr,["write"]=fdw,["fd"]=f,["mode"]=m}
|
||||||
|
return t
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
64
module/iofs.lua
Normal file
64
module/iofs.lua
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
iofs = {}
|
||||||
|
iofs.files = {}
|
||||||
|
iofs.fds = {}
|
||||||
|
iofs.nextfd = 0
|
||||||
|
iofs.component = {}
|
||||||
|
|
||||||
|
local function rfalse()
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
function iofs.component.getLabel()
|
||||||
|
return "iofs"
|
||||||
|
end
|
||||||
|
iofs.component.spaceUsed, iofs.component.spaceTotal, iofs.component.isReadOnly, iofs.component.isDirectory,iofs.component.size, iofs.component.setLabel = function() return computer.totalMemory()-computer.freeMemory() end, computer.totalMemory, rfalse, rfalse, rfalse, rfalse
|
||||||
|
|
||||||
|
function iofs.component.exists(fname)
|
||||||
|
return iofs.files[fname] ~= nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function iofs.component.list()
|
||||||
|
local t = {}
|
||||||
|
for k,v in pairs(iofs.files) do
|
||||||
|
t[#t+1] = k
|
||||||
|
end
|
||||||
|
return t
|
||||||
|
end
|
||||||
|
|
||||||
|
function iofs.component.open(fname, mode)
|
||||||
|
fname=fname:gsub("/","")
|
||||||
|
if iofs.files[fname] then
|
||||||
|
local r,w,c,s = iofs.files[fname](mode)
|
||||||
|
iofs.fds[iofs.nextfd] = {["read"]=r or rfalse,["write"]=w or rfalse,["seek"]=s or rfalse,["close"]=c or rfalse}
|
||||||
|
iofs.nextfd = iofs.nextfd + 1
|
||||||
|
return iofs.nextfd - 1
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
function iofs.component.read(fd,count)
|
||||||
|
if iofs.fds[fd] then
|
||||||
|
return iofs.fds[fd].read(count)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function iofs.component.write(fd,data)
|
||||||
|
if iofs.fds[fd] then
|
||||||
|
return iofs.fds[fd].write(data)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function iofs.component.close(fd)
|
||||||
|
if iofs.fds[fd] then
|
||||||
|
iofs.fds[fd].close()
|
||||||
|
end
|
||||||
|
iofs.fds[fd] = nil
|
||||||
|
end
|
||||||
|
function iofs.component.seek(fd,...)
|
||||||
|
if iofs.fds[fd] then
|
||||||
|
return iofs.fds[fd].seek(...)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function iofs.register(fname,fopen) -- Register a new iofs node with the name *fname* that will run the function *fopen* when opened. This function should return a function for read, a function for write, function for close, and optionally, a function for seek, in that order.
|
||||||
|
iofs.files[fname] = fopen
|
||||||
|
end
|
||||||
|
|
||||||
|
fs.mounts.iofs = iofs.component
|
@ -7,8 +7,8 @@ end
|
|||||||
function runfile(p,...) -- runs file *p* with arbitrary arguments in the current thread
|
function runfile(p,...) -- runs file *p* with arbitrary arguments in the current thread
|
||||||
return loadfile(p)(...)
|
return loadfile(p)(...)
|
||||||
end
|
end
|
||||||
function os.spawnfile(p,n) -- spawns a new process from file *p* with name *n*
|
function spawnfile(p,n) -- spawns a new process from file *p* with name *n*
|
||||||
return os.spawn(function() xpcall(loadfile(p),function(e) dprint(e.."\n"..debug.traceback) end) end,n)
|
return os.spawn(function() print(pcall(loadfile(p))) end,n)
|
||||||
end
|
end
|
||||||
function require(f) -- searches for a library with name *f* and returns what the library returns, if possible
|
function require(f) -- searches for a library with name *f* and returns what the library returns, if possible
|
||||||
local lib = os.getenv("LIB") or "/boot/lib"
|
local lib = os.getenv("LIB") or "/boot/lib"
|
||||||
|
@ -1,82 +0,0 @@
|
|||||||
do
|
|
||||||
io = {}
|
|
||||||
|
|
||||||
function io.type(fh)
|
|
||||||
if type(fh) ~= "table" then return nil end
|
|
||||||
if fh.state == "open" then
|
|
||||||
return "file"
|
|
||||||
elseif fh.state == "closed" then
|
|
||||||
return "closed file"
|
|
||||||
end
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
function io.read(buf, n)
|
|
||||||
n = n or buf
|
|
||||||
buf = buf or io.input()
|
|
||||||
print("bread",type(buf),n)
|
|
||||||
if not buf.aread then return nil end
|
|
||||||
if not buf.abmode then
|
|
||||||
buffer.write(buf,buf.fh:read(buf.m - buf.b:len()))
|
|
||||||
end
|
|
||||||
local rv = buffer.read(buf,n)
|
|
||||||
buffer.write(buf,buf.fh:read(buf.m - buf.b:len()))
|
|
||||||
return rv
|
|
||||||
end
|
|
||||||
function io.write(buf, d)
|
|
||||||
d = d or buf
|
|
||||||
buf = buf or io.output()
|
|
||||||
print("bwrite",type(buf),d)
|
|
||||||
if not buf.awrite then return nil end
|
|
||||||
if buf.b:len() + d:len() > buf.m then
|
|
||||||
buf.fh:write(buffer.read(buf,buf.m))
|
|
||||||
end
|
|
||||||
local rv = buffer.write(buf,d)
|
|
||||||
if not buf.abmode then
|
|
||||||
buf.fh:write(buffer.read(buf,buf.m))
|
|
||||||
end
|
|
||||||
return rv
|
|
||||||
end
|
|
||||||
|
|
||||||
function io.close(fh)
|
|
||||||
fh.fh.close()
|
|
||||||
fh.state = "closed"
|
|
||||||
end
|
|
||||||
|
|
||||||
function io.flush()
|
|
||||||
end
|
|
||||||
|
|
||||||
function io.open(fname,mode)
|
|
||||||
mode=mode or "r"
|
|
||||||
local buf = buffer.new()
|
|
||||||
buf.fh, er = fs.open(fname,mode)
|
|
||||||
if not buf.fh then
|
|
||||||
error(er)
|
|
||||||
end
|
|
||||||
buf.state = "open"
|
|
||||||
buf.aread = mode:match("r")
|
|
||||||
buf.awrite = mode:match("w") or mode:match("a")
|
|
||||||
setmetatable(buf,{__index=io})
|
|
||||||
return buf
|
|
||||||
end
|
|
||||||
|
|
||||||
function print(...)
|
|
||||||
for k,v in ipairs({...}) do
|
|
||||||
io.write(string.format("%s\n",tostring(v)))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
io.stdin = io.open("/dev/null")
|
|
||||||
io.stdout = io.open("/dev/null","w")
|
|
||||||
|
|
||||||
function io.input(fname)
|
|
||||||
if not fname then return os.getenv("STDIN") or io.stdin end
|
|
||||||
os.setenv("STDIN",io.open(fname))
|
|
||||||
end
|
|
||||||
|
|
||||||
function io.output(fname)
|
|
||||||
if not fname then return os.getenv("STDOUT") or io.stdout end
|
|
||||||
os.setenv("STDOUT",io.open(fname,"w"))
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
@ -1,13 +1,7 @@
|
|||||||
do
|
do
|
||||||
local tTasks,nPid,nTimeout,cPid = {},1,0,0 -- table of tasks, next process ID, event timeout, current PID
|
tTasks,nPid,nTimeout,cPid = {},1,0,0 -- table of tasks, next process ID, event timeout, current PID
|
||||||
function os.spawn(f,n) -- creates a process from function *f* with name *n*
|
function os.spawn(f,n) -- creates a process from function *f* with name *n*
|
||||||
tTasks[nPid] = {
|
tTasks[nPid] = {["c"]=coroutine.create(f),["n"]=n,["p"]=nPid,e={}}
|
||||||
c=coroutine.create(f), -- actual coroutine
|
|
||||||
n=n, -- process name
|
|
||||||
p=nPid, -- process PID
|
|
||||||
P=cPid, -- parent PID
|
|
||||||
e={} -- environment variables
|
|
||||||
}
|
|
||||||
if tTasks[cPid] then
|
if tTasks[cPid] then
|
||||||
for k,v in pairs(tTasks[cPid].e) do
|
for k,v in pairs(tTasks[cPid].e) do
|
||||||
tTasks[nPid].e[k] = tTasks[nPid].e[k] or v
|
tTasks[nPid].e[k] = tTasks[nPid].e[k] or v
|
||||||
@ -19,21 +13,7 @@ end
|
|||||||
function os.kill(pid) -- removes process *pid* from the task list
|
function os.kill(pid) -- removes process *pid* from the task list
|
||||||
tTasks[pid] = nil
|
tTasks[pid] = nil
|
||||||
end
|
end
|
||||||
function os.pid()
|
function sched() -- the actual scheduler function
|
||||||
return cPid
|
|
||||||
end
|
|
||||||
function os.tasks()
|
|
||||||
local rt = {}
|
|
||||||
for k,v in pairs(tTasks) do
|
|
||||||
rt[#rt+1] = k
|
|
||||||
end
|
|
||||||
return rt
|
|
||||||
end
|
|
||||||
function os.taskInfo(pid)
|
|
||||||
return {name=tTasks[pid].n,parent=tTasks[pid].P}
|
|
||||||
end
|
|
||||||
function os.sched() -- the actual scheduler function
|
|
||||||
os.sched = nil
|
|
||||||
while #tTasks > 0 do
|
while #tTasks > 0 do
|
||||||
local tEv = {computer.pullSignal(nTimeout)}
|
local tEv = {computer.pullSignal(nTimeout)}
|
||||||
for k,v in pairs(tTasks) do
|
for k,v in pairs(tTasks) do
|
||||||
|
16
module/spawnprompt.lua
Normal file
16
module/spawnprompt.lua
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
os.spawn(function()
|
||||||
|
print(_OSVERSION,tostring(computer.totalMemory()/1024).."K memory")
|
||||||
|
for k,v in pairs(fd) do
|
||||||
|
if v.t == "t" then
|
||||||
|
os.setenv("t") = k
|
||||||
|
print("Spawning Lua prompt for "..tostring(k))
|
||||||
|
os.setenv("PWD","/boot")
|
||||||
|
os.spawn(function() print(pcall(function() while true do
|
||||||
|
io.write(_VERSION.."> ")
|
||||||
|
tResult = {pcall(load(io.read()))}
|
||||||
|
for k,v in pairs(tResult) do
|
||||||
|
print(v)
|
||||||
|
end
|
||||||
|
end end)) end,"lua prompt")
|
||||||
|
end
|
||||||
|
end end,"init")
|
@ -1,5 +1,3 @@
|
|||||||
dprint=dprint or function() end
|
|
||||||
|
|
||||||
syslog = {}
|
syslog = {}
|
||||||
syslog.emergency = 0
|
syslog.emergency = 0
|
||||||
syslog.alert = 1
|
syslog.alert = 1
|
||||||
@ -11,7 +9,6 @@ syslog.info = 6
|
|||||||
syslog.debug = 7
|
syslog.debug = 7
|
||||||
|
|
||||||
setmetatable(syslog,{__call = function(_,msg, level, service)
|
setmetatable(syslog,{__call = function(_,msg, level, service)
|
||||||
level, service = level or syslog.info, service or os.taskInfo(os.pid()).name or "unknown"
|
level, service = level or syslog.info, service or process.info().path
|
||||||
dprint(string.format("syslog: [%s:%d/%d] %s",service,os.pid(),level,msg))
|
|
||||||
computer.pushSignal("syslog",msg, level, service)
|
computer.pushSignal("syslog",msg, level, service)
|
||||||
end})
|
end})
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
--#include "module/vt-task.lua"
|
|
||||||
do
|
|
||||||
local r,w = vtemu(component.list("gpu")(),component.list("screen")())
|
|
||||||
devfs.register("tty0", function() return r,w,function() end end)
|
|
||||||
end
|
|
@ -1,15 +1,13 @@
|
|||||||
do
|
|
||||||
--#include "module/vt100.lua"
|
|
||||||
function vtemu(gpua,scra)
|
function vtemu(gpua,scra)
|
||||||
local gpu = component.proxy(gpua)
|
local gpu,scr = component.proxy(gpua),component.proxy(scra)
|
||||||
gpu.bind(scra)
|
gpu.bind(scra)
|
||||||
local write = vt100emu(gpu)
|
local write = vt100emu(gpu)
|
||||||
local kba = {}
|
local kba = {}
|
||||||
for k,v in ipairs(component.invoke(scra,"getKeyboards")) do
|
for k,v in ipairs(scr.getKeyboards()) do
|
||||||
kba[v]=true
|
kba[v]=true
|
||||||
end
|
end
|
||||||
local buf = ""
|
local buf = ""
|
||||||
os.spawn(function() dprint(pcall(function()
|
os.spawn(function()
|
||||||
while true do
|
while true do
|
||||||
local ty,ka,ch = coroutine.yield()
|
local ty,ka,ch = coroutine.yield()
|
||||||
if ty == "key_down" and kba[ka] then
|
if ty == "key_down" and kba[ka] then
|
||||||
@ -21,17 +19,27 @@ function vtemu(gpua,scra)
|
|||||||
end
|
end
|
||||||
elseif ch > 0 then
|
elseif ch > 0 then
|
||||||
write(string.char(ch))
|
write(string.char(ch))
|
||||||
buf=buf..string.char(ch)
|
buf = buf .. string.char(ch)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)) end,string.format("ttyd[%s:%s]",gpua:sub(1,8),scra:sub(1,8)))
|
end,"keyboard daemon for "..gpua:sub(1,8)..":"..scra:sub(1,8))
|
||||||
local function bread()
|
local function read(n)
|
||||||
local n = buf:find("\n")
|
n = n or "\n"
|
||||||
if not n then return nil end
|
local rdata = ""
|
||||||
r, buf = buf:sub(1,n), buf:sub(n+1)
|
if type(n) == "number" then
|
||||||
return r
|
rdata = buf:sub(1,n)
|
||||||
|
return rdata
|
||||||
|
else
|
||||||
|
if n == "*a" then
|
||||||
|
rdata = buf
|
||||||
|
buf = ""
|
||||||
|
return rdata
|
||||||
|
end
|
||||||
|
local pr,po = buf:match("(.-)"..n.."(.*)")
|
||||||
|
buf = po or buf
|
||||||
|
return pr
|
||||||
|
end
|
||||||
end
|
end
|
||||||
return bread, write, function() io.write("\27[2J\27[H") end
|
return read,write
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
@ -58,9 +58,9 @@ function vt100emu(gpu) -- takes GPU component proxy *gpu* and returns a function
|
|||||||
cx, cy = sx, sy
|
cx, cy = sx, sy
|
||||||
mode = "n"
|
mode = "n"
|
||||||
elseif cc == "H" then -- cursor home or to
|
elseif cc == "H" then -- cursor home or to
|
||||||
local tx, ty = cs:match("(.-);(.-)")
|
local tx, ty = cs:match("(.);(.)")
|
||||||
tx, ty = tx or "1", ty or "1"
|
tx, ty = tx or "\1", ty or "\1"
|
||||||
cx, cy = tonumber(tx), tonumber(ty)
|
cx, cy = string.byte(tx), string.byte(ty)
|
||||||
mode = "n"
|
mode = "n"
|
||||||
elseif cc == "A" then -- cursor up
|
elseif cc == "A" then -- cursor up
|
||||||
cy = cy - string.byte(n)
|
cy = cy - string.byte(n)
|
||||||
|
Loading…
Reference in New Issue
Block a user