Compare commits
3 Commits
9022bfce78
...
0ced41b897
Author | SHA1 | Date | |
---|---|---|---|
0ced41b897 | |||
346c6bcf29 | |||
408e9600b7 |
@ -1,8 +1,16 @@
|
|||||||
xpcall(function()
|
xpcall(function()
|
||||||
io.input("/dev/tty0")
|
os.spawnfile("/boot/service/getty.lua")
|
||||||
io.output("/dev/tty0")
|
coroutine.yield()
|
||||||
os.setenv("PWD","/boot")
|
for k,v in pairs(fs.list("/dev/")) do
|
||||||
io.write("PsychOS v2.0a1 - ")
|
if v:sub(1,3) == "tty" then
|
||||||
print(tostring(math.floor(computer.totalMemory()/1024)).."K RAM")
|
dprint(tostring(io.input("/dev/"..v)))
|
||||||
os.spawnfile("/boot/exec/shell.lua")
|
dprint(tostring(io.output("/dev/"..v)))
|
||||||
end,function(e) dprint(e) end,"init test")
|
io.write("PsychOS v2.0a1 - ")
|
||||||
|
print(tostring(math.floor(computer.totalMemory()/1024)).."K RAM")
|
||||||
|
os.spawnfile("/boot/exec/shell.lua")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
while true do
|
||||||
|
coroutine.yield()
|
||||||
|
end
|
||||||
|
end,function(e) dprint(e) end,"init")
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
print("PID# Parent Name")
|
print("PID# Parent | Name")
|
||||||
for k,v in pairs(os.tasks()) do
|
for k,v in pairs(os.tasks()) do
|
||||||
local t = os.taskInfo(v)
|
local t = os.taskInfo(v)
|
||||||
print(string.format("%4d %4d %s",k,v.parent,v.name))
|
print(string.format("%4d %4d | %s",k,t.parent,t.name))
|
||||||
end
|
end
|
||||||
|
@ -26,6 +26,7 @@ setmetatable(shenv,{__index=function(_,k)
|
|||||||
if _G[k] then
|
if _G[k] then
|
||||||
return _G[k]
|
return _G[k]
|
||||||
elseif fs.exists("/boot/exec/"..k..".lua") then
|
elseif fs.exists("/boot/exec/"..k..".lua") then
|
||||||
|
--[[
|
||||||
local rqid = string.format("shell-%d",math.random(1,99999))
|
local rqid = string.format("shell-%d",math.random(1,99999))
|
||||||
return function(...)
|
return function(...)
|
||||||
local tA = {...}
|
local tA = {...}
|
||||||
@ -42,6 +43,8 @@ setmetatable(shenv,{__index=function(_,k)
|
|||||||
end
|
end
|
||||||
until tTasks[pid] == nil
|
until tTasks[pid] == nil
|
||||||
end
|
end
|
||||||
|
]]--
|
||||||
|
return loadfile("/boot/exec/"..k..".lua")
|
||||||
end
|
end
|
||||||
end})
|
end})
|
||||||
print(_VERSION)
|
print(_VERSION)
|
||||||
|
@ -1,171 +0,0 @@
|
|||||||
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
|
|
7
module/chatbox-dprint.lua
Normal file
7
module/chatbox-dprint.lua
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
if component.list("chat_box")() then
|
||||||
|
function dprint(...)
|
||||||
|
for k,v in pairs({...}) do
|
||||||
|
component.invoke(component.list("chat_box")(),"say",v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -1,12 +1,12 @@
|
|||||||
|
--#include "module/chatbox-dprint.lua"
|
||||||
--#include "module/syslog.lua"
|
--#include "module/syslog.lua"
|
||||||
--#include "module/sched.lua"
|
--#include "module/sched.lua"
|
||||||
--#include "module/buffer.lua"
|
|
||||||
--#include "module/fs.lua"
|
--#include "module/fs.lua"
|
||||||
--#include "module/io.lua"
|
--#include "module/newio.lua"
|
||||||
--#include "module/devfs.lua"
|
--#include "module/devfs.lua"
|
||||||
--#include "module/devfs/syslog.lua"
|
--#include "module/devfs/syslog.lua"
|
||||||
|
--#include "module/vt-task.lua"
|
||||||
--#include "module/loadfile.lua"
|
--#include "module/loadfile.lua"
|
||||||
--#include "module/term.lua"
|
os.spawnfile("/boot/exec/init.lua")
|
||||||
os.spawnfile("/boot/exec/init.lua","init")
|
|
||||||
|
|
||||||
os.sched()
|
os.sched()
|
||||||
|
116
module/io.lua
116
module/io.lua
@ -1,116 +0,0 @@
|
|||||||
do
|
|
||||||
io = {}
|
|
||||||
|
|
||||||
function io.close(file)
|
|
||||||
return (file or io.output()):close()
|
|
||||||
end
|
|
||||||
|
|
||||||
function io.flush()
|
|
||||||
return io.output():flush()
|
|
||||||
end
|
|
||||||
|
|
||||||
function io.lines(filename, ...)
|
|
||||||
if filename then
|
|
||||||
local file, reason = io.open(filename)
|
|
||||||
if not file then
|
|
||||||
error(reason, 2)
|
|
||||||
end
|
|
||||||
local args = table.pack(...)
|
|
||||||
return function()
|
|
||||||
local result = table.pack(file:read(table.unpack(args, 1, args.n)))
|
|
||||||
if not result[1] then
|
|
||||||
if result[2] then
|
|
||||||
error(result[2], 2)
|
|
||||||
else -- eof
|
|
||||||
file:close()
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return table.unpack(result, 1, result.n)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
return io.input():lines()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function io.open(path, mode)
|
|
||||||
local stream, result = fs.open(path, mode)
|
|
||||||
if stream then
|
|
||||||
return buffer.new(mode, stream)
|
|
||||||
else
|
|
||||||
return nil, result
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local fdt = {[0]="STDIN","STDOUT","STDERR"}
|
|
||||||
local function getfh(fd)
|
|
||||||
return os.getenv(fdt[fd] or "FILE"..tostring(fd))
|
|
||||||
end
|
|
||||||
local function setfh(fd,fh)
|
|
||||||
os.setenv(fdt[fd] or "FILE"..tostring(fd),fh)
|
|
||||||
end
|
|
||||||
|
|
||||||
function io.stream(fd,file,mode)
|
|
||||||
checkArg(1,fd,'number')
|
|
||||||
assert(fd>=0,'fd must be >= 0. 0 is input, 1 is stdout, 2 is stderr')
|
|
||||||
if file then
|
|
||||||
if type(file) == "string" then
|
|
||||||
local result, reason = io.open(file, mode)
|
|
||||||
if not result then
|
|
||||||
error(reason, 2)
|
|
||||||
end
|
|
||||||
file = result
|
|
||||||
elseif not io.type(file) then
|
|
||||||
error("bad argument #1 (string or file expected, got " .. type(file) .. ")", 2)
|
|
||||||
end
|
|
||||||
setfh(fd,file)
|
|
||||||
end
|
|
||||||
return getfh(fd)
|
|
||||||
end
|
|
||||||
|
|
||||||
function io.input(file)
|
|
||||||
return io.stream(0, file, 'r')
|
|
||||||
end
|
|
||||||
|
|
||||||
function io.output(file)
|
|
||||||
return io.stream(1, file,'w')
|
|
||||||
end
|
|
||||||
|
|
||||||
function io.error(file)
|
|
||||||
return io.stream(2, file,'w')
|
|
||||||
end
|
|
||||||
|
|
||||||
function io.read(...)
|
|
||||||
return io.input():read(...)
|
|
||||||
end
|
|
||||||
|
|
||||||
function io.tmpfile()
|
|
||||||
local name = os.tmpname()
|
|
||||||
if name then
|
|
||||||
return io.open(name, "a")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function io.type(object)
|
|
||||||
if type(object) == "table" then
|
|
||||||
if getmetatable(object) == "file" then
|
|
||||||
if object.stream.handle then
|
|
||||||
return "file"
|
|
||||||
else
|
|
||||||
return "closed file"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
function io.write(...)
|
|
||||||
return io.output():write(...)
|
|
||||||
end
|
|
||||||
|
|
||||||
function print(...)
|
|
||||||
for k,v in ipairs({...}) do
|
|
||||||
io.write(tostring(v).."\n")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
@ -8,7 +8,8 @@ function runfile(p,...) -- runs file *p* with arbitrary arguments in the current
|
|||||||
return loadfile(p)(...)
|
return loadfile(p)(...)
|
||||||
end
|
end
|
||||||
function os.spawnfile(p,n) -- spawns a new process from file *p* with name *n*
|
function os.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)
|
dprint(p,n)
|
||||||
|
return os.spawn(function() xpcall(loadfile(p),function(e) dprint(e.."\n"..debug.traceback()) end) end,n or p)
|
||||||
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"
|
||||||
|
34
module/newio.lua
Normal file
34
module/newio.lua
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
io = {}
|
||||||
|
function io.input(fd)
|
||||||
|
if type(fd) == "string" then
|
||||||
|
fd=fs.open(fd,"rb")
|
||||||
|
end
|
||||||
|
if fd then
|
||||||
|
os.setenv("STDIN",fd)
|
||||||
|
end
|
||||||
|
return os.getenv("STDIN")
|
||||||
|
end
|
||||||
|
function io.output(fd)
|
||||||
|
if type(fd) == "string" then
|
||||||
|
fd=fs.open(fd,"wb")
|
||||||
|
end
|
||||||
|
if fd then
|
||||||
|
os.setenv("STDOUT",fd)
|
||||||
|
end
|
||||||
|
return os.getenv("STDOUT")
|
||||||
|
end
|
||||||
|
|
||||||
|
io.open = fs.open
|
||||||
|
|
||||||
|
function io.read(...)
|
||||||
|
return io.input():read()
|
||||||
|
end
|
||||||
|
function io.write(...)
|
||||||
|
io.output():write(...)
|
||||||
|
end
|
||||||
|
|
||||||
|
function print(...)
|
||||||
|
for k,v in ipairs({...}) do
|
||||||
|
io.write(tostring(v).."\n")
|
||||||
|
end
|
||||||
|
end
|
@ -1,5 +1,5 @@
|
|||||||
do
|
do
|
||||||
local tTasks,nPid,nTimeout,cPid = {},1,0,0 -- table of tasks, next process ID, event timeout, current PID
|
local tTasks,nPid,nTimeout,cPid = {},1,1,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), -- actual coroutine
|
c=coroutine.create(f), -- actual coroutine
|
||||||
|
@ -27,9 +27,12 @@ function vtemu(gpua,scra)
|
|||||||
end
|
end
|
||||||
end)) end,string.format("ttyd[%s:%s]",gpua:sub(1,8),scra:sub(1,8)))
|
end)) end,string.format("ttyd[%s:%s]",gpua:sub(1,8),scra:sub(1,8)))
|
||||||
local function bread()
|
local function bread()
|
||||||
|
while not buf:find("\n") do
|
||||||
|
coroutine.yield()
|
||||||
|
end
|
||||||
local n = buf:find("\n")
|
local n = buf:find("\n")
|
||||||
if not n then return nil end
|
|
||||||
r, buf = buf:sub(1,n), buf:sub(n+1)
|
r, buf = buf:sub(1,n), buf:sub(n+1)
|
||||||
|
dprint("bread",r)
|
||||||
return r
|
return r
|
||||||
end
|
end
|
||||||
return bread, write, function() io.write("\27[2J\27[H") end
|
return bread, write, function() io.write("\27[2J\27[H") end
|
||||||
|
50
service/getty.lua
Normal file
50
service/getty.lua
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
local gpus,screens,ttyn = {}, {}, 0
|
||||||
|
local function scan()
|
||||||
|
local w,di = pcall(computer.getDeviceInfo)
|
||||||
|
if w then
|
||||||
|
for a,t in pairs(component.list()) do
|
||||||
|
if t == "gpu" then
|
||||||
|
gpus[a] = gpus[a] or {false, tonumber(di[a].capacity)}
|
||||||
|
elseif t == "screen" then
|
||||||
|
screens[a] = screens[a] or {false, tonumber(di[a].capacity)}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
dprint("no getDevInfo")
|
||||||
|
for a,t in pairs(component.list()) do
|
||||||
|
if t == "gpu" then
|
||||||
|
gpus[a] = gpus[a] or {false, 8000}
|
||||||
|
elseif t == "screen" then
|
||||||
|
screens[a] = screens[a] or {false, 8000}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local function nextScreen(n)
|
||||||
|
local rt = {}
|
||||||
|
for k,v in pairs(screens) do
|
||||||
|
if not v[1] then
|
||||||
|
rt[v[2]] = rt[v[2]] or k
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return rt[n] or rt[8000] or rt[2000] or rt[600]
|
||||||
|
end
|
||||||
|
local function allocate()
|
||||||
|
for k,v in pairs(gpus) do
|
||||||
|
dprint(k)
|
||||||
|
local sA = nextScreen(v[2])
|
||||||
|
if v[1] == false and sA then
|
||||||
|
local r,w = vtemu(k,sA)
|
||||||
|
devfs.register("tty"..tostring(ttyn), function() return r,w,function() end end)
|
||||||
|
gpus[k][1] = true
|
||||||
|
screens[sA][1] = true
|
||||||
|
ttyn = ttyn + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
scan()
|
||||||
|
allocate()
|
||||||
|
dprint("screens ready")
|
||||||
|
while true do
|
||||||
|
coroutine.yield()
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user