mirror of
https://git.shadowkat.net/izaya/OC-PsychOS2.git
synced 2024-11-25 12:42:10 -05:00
Compare commits
21 Commits
b2d1379127
...
180a5a9a78
Author | SHA1 | Date | |
---|---|---|---|
|
180a5a9a78 | ||
|
37df78ffed | ||
|
80eea7142d | ||
|
256e05233a | ||
|
a219b5603e | ||
|
a97e3c93ee | ||
|
ec699518b5 | ||
|
faca451c57 | ||
|
aed9278433 | ||
|
6ad6880a6d | ||
|
1bd18f45b3 | ||
|
d23a25613d | ||
|
ac98d09b93 | ||
|
a335ff5c87 | ||
|
e9aac95dd7 | ||
|
150541d91b | ||
|
6b5677b870 | ||
|
5f8e4efe33 | ||
|
98e3581e6e | ||
|
23680afd75 | ||
|
69eae00ec1 |
4
build.sh
4
build.sh
@ -1,9 +1,11 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
rm -r target/*
|
rm -r target/*
|
||||||
mkdir target
|
mkdir target &>/dev/null
|
||||||
|
mkdir target/cfg
|
||||||
lua luapreproc.lua module/init.lua target/init.lua
|
lua luapreproc.lua module/init.lua target/init.lua
|
||||||
echo _OSVERSION=\"PsychOS 2.0a1-$(git rev-parse --short HEAD)\" > target/version.lua
|
echo _OSVERSION=\"PsychOS 2.0a1-$(git rev-parse --short HEAD)\" > target/version.lua
|
||||||
cat target/version.lua target/init.lua > target/tinit.lua
|
cat target/version.lua target/init.lua > target/tinit.lua
|
||||||
mv target/tinit.lua target/init.lua
|
mv target/tinit.lua target/init.lua
|
||||||
cp -r exec/ service/ lib/ target/
|
cp -r exec/ service/ lib/ target/
|
||||||
|
cp default-init.txt target/cfg/
|
||||||
lua finddesc.lua $(find module/ -type f) $(find lib/ -type f) > apidoc.md
|
lua finddesc.lua $(find module/ -type f) $(find lib/ -type f) > apidoc.md
|
||||||
|
@ -1,3 +1,2 @@
|
|||||||
minitel.lua
|
getty.lua
|
||||||
tape-iofs.lua
|
fsmanager.lua
|
||||||
fsmanager.service
|
|
||||||
|
23
exec/df.lua
Normal file
23
exec/df.lua
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
local mt = fs.mounts()
|
||||||
|
local ml = 0
|
||||||
|
for k,v in pairs(mt) do
|
||||||
|
if v:len() > ml then
|
||||||
|
ml = v:len()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local scale = {"K","M","G","T","P"}
|
||||||
|
local function wrapUnits(n)
|
||||||
|
local count = 0
|
||||||
|
while n > 1024 do
|
||||||
|
count = count + 1
|
||||||
|
if not scale[count] then return "inf" end
|
||||||
|
n = n / 1024
|
||||||
|
end
|
||||||
|
return tostring(math.floor(n))..(scale[count] or "")
|
||||||
|
end
|
||||||
|
local fstr = "%-"..tostring(ml).."s %5s %5s"
|
||||||
|
print("fs"..(" "):rep(ml-2).." size used")
|
||||||
|
for k,v in pairs(mt) do
|
||||||
|
local st, su = fs.spaceTotal(v), fs.spaceUsed(v)
|
||||||
|
print(string.format(fstr,v,wrapUnits(st),wrapUnits(su)))
|
||||||
|
end
|
@ -63,6 +63,7 @@ end
|
|||||||
function ct.append(np)
|
function ct.append(np)
|
||||||
ct.sp(np)
|
ct.sp(np)
|
||||||
p=p+1
|
p=p+1
|
||||||
|
if #ft < 1 then p = 1 end
|
||||||
ct.insert()
|
ct.insert()
|
||||||
end
|
end
|
||||||
function ct.delete(np,n)
|
function ct.delete(np,n)
|
||||||
|
@ -1,16 +1,25 @@
|
|||||||
xpcall(function()
|
if os.taskInfo(1) and os.pid() ~= 1 then
|
||||||
os.setenv("PWD","/boot")
|
return false, "init already started"
|
||||||
os.spawnfile("/boot/service/getty.lua")
|
|
||||||
coroutine.yield()
|
|
||||||
for k,v in pairs(fs.list("/dev/")) do
|
|
||||||
if v:sub(1,3) == "tty" then
|
|
||||||
dprint(tostring(io.input("/dev/"..v)))
|
|
||||||
dprint(tostring(io.output("/dev/"..v)))
|
|
||||||
print(_OSVERSION.." - "..tostring(math.floor(computer.totalMemory()/1024)).."K RAM")
|
|
||||||
os.spawnfile("/boot/exec/shell.lua")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
os.setenv("PWD","/boot")
|
||||||
|
io.input("/dev/null")
|
||||||
|
io.output("/dev/syslog")
|
||||||
|
local pids = {}
|
||||||
|
local function loadlist()
|
||||||
|
local f = io.open("/boot/cfg/init.txt","rb")
|
||||||
|
if not f then return false end
|
||||||
|
for line in f:read("*a"):gmatch("[^\r\n]+") do
|
||||||
|
pids[line] = -1
|
||||||
|
end
|
||||||
|
f:close()
|
||||||
|
end
|
||||||
|
loadlist()
|
||||||
while true do
|
while true do
|
||||||
|
for k,v in pairs(pids) do
|
||||||
|
if not os.taskInfo(v) then
|
||||||
|
syslog("Starting service "..k)
|
||||||
|
pids[k] = os.spawnfile("/boot/service/"..k)
|
||||||
|
end
|
||||||
|
end
|
||||||
coroutine.yield()
|
coroutine.yield()
|
||||||
end
|
end
|
||||||
end,function(e) dprint(e) end,"init")
|
|
||||||
|
24
exec/mount.lua
Normal file
24
exec/mount.lua
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
local tA = {...}
|
||||||
|
if #tA < 1 then
|
||||||
|
local mt = fs.mounts()
|
||||||
|
for k,v in pairs(mt) do
|
||||||
|
print(tostring(fs.address(v)).." on "..tostring(v).." type "..fs.type(v))
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local addr,path = tA[1],tA[2]
|
||||||
|
local fscomp = component.list("filesystem")
|
||||||
|
if not fscomp[addr] then
|
||||||
|
for k,v in pairs(fscomp) do
|
||||||
|
if k:find(addr) then
|
||||||
|
print(tostring(addr).." not found, assuming you meant "..k)
|
||||||
|
addr = k
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local proxy = component.proxy(addr)
|
||||||
|
if not proxy then
|
||||||
|
return false, "no such filesystem component"
|
||||||
|
end
|
||||||
|
print(fs.mount(path,proxy))
|
||||||
|
end
|
@ -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,t.parent,t.name))
|
print(string.format("%4d %4d | %s",v,t.parent,t.name))
|
||||||
end
|
end
|
||||||
|
@ -4,6 +4,7 @@ function shenv.quit()
|
|||||||
os.setenv("run",nil)
|
os.setenv("run",nil)
|
||||||
end
|
end
|
||||||
shenv.cd = os.chdir
|
shenv.cd = os.chdir
|
||||||
|
shenv.mkdir = fs.makeDirectory
|
||||||
setmetatable(shenv,{__index=function(_,k)
|
setmetatable(shenv,{__index=function(_,k)
|
||||||
if _G[k] then
|
if _G[k] then
|
||||||
return _G[k]
|
return _G[k]
|
||||||
|
@ -23,16 +23,13 @@ function event.pull(t,...) -- return an event, optionally with timeout *t* and f
|
|||||||
end
|
end
|
||||||
|
|
||||||
function event.listen(e,f) -- run function *f* for every occurance of event *e*
|
function event.listen(e,f) -- run function *f* for every occurance of event *e*
|
||||||
local op = os.getenv("parent")
|
|
||||||
os.setenv("parent",cPid)
|
|
||||||
os.spawn(function() while true do
|
os.spawn(function() while true do
|
||||||
local tEv = {coroutine.yield()}
|
local tEv = {coroutine.yield()}
|
||||||
if tEv[1] == e then
|
if tEv[1] == e then
|
||||||
f(table.unpack(tEv))
|
f(table.unpack(tEv))
|
||||||
end
|
end
|
||||||
if not tTasks[os.getenv("parent")] or (tEv[1] == "unlisten" and tEv[2] == e and tEv[3] == tostring(f)) then break end
|
if not os.taskInfo(os.taskInfo().parent) or (tEv[1] == "unlisten" and tEv[2] == e and tEv[3] == tostring(f)) then break end
|
||||||
end end,string.format("[%d] %s listener",cPid,e))
|
end end,string.format("[%d] %s listener",os.pid(),e))
|
||||||
os.setenv("parent",op)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function event.ignore(e,f) -- stop function *f* running for every occurance of event *e*
|
function event.ignore(e,f) -- stop function *f* running for every occurance of event *e*
|
||||||
|
@ -1,145 +1,49 @@
|
|||||||
-- serialization lib borrowed from OpenOS
|
local serial = {}
|
||||||
local serialization = {}
|
local local_pairs=function(tbl)
|
||||||
|
local mt=getmetatable(tbl)
|
||||||
-- delay loaded tables fail to deserialize cross [C] boundaries (such as when having to read files that cause yields)
|
return (mt and mt.__pairs or pairs)(tbl)
|
||||||
local local_pairs = function(tbl)
|
|
||||||
local mt = getmetatable(tbl)
|
|
||||||
return (mt and mt.__pairs or pairs)(tbl)
|
|
||||||
end
|
end
|
||||||
|
function serial.serialize(value)
|
||||||
-- Important: pretty formatting will allow presenting non-serializable values
|
local kw={["and"]=true,["break"]=true,["do"]=true,["else"]=true,["elseif"]=true,["end"]=true,["false"]=true,["for"]=true,["function"]=true,["goto"]=true,["if"]=true,["in"]=true,["local"]=true,["nil"]=true,["not"]=true,["or"]=true,["repeat"]=true,["return"]=true,["then"]=true,["true"]=true,["until"]=true,["while"]=true}
|
||||||
-- but may generate output that cannot be unserialized back.
|
local id="^[%a_][%w_]*$"
|
||||||
function serialization.serialize(value, pretty) -- serialize *value* into a string, optionally in a nicely formatted manner when *pretty* is set
|
local ts={}
|
||||||
local kw = {["and"]=true, ["break"]=true, ["do"]=true, ["else"]=true,
|
local function s(v,l)
|
||||||
["elseif"]=true, ["end"]=true, ["false"]=true, ["for"]=true,
|
local t=type(v)
|
||||||
["function"]=true, ["goto"]=true, ["if"]=true, ["in"]=true,
|
if t=="nil" then return "nil"
|
||||||
["local"]=true, ["nil"]=true, ["not"]=true, ["or"]=true,
|
elseif t=="boolean" then return v and "true" or "false"
|
||||||
["repeat"]=true, ["return"]=true, ["then"]=true, ["true"]=true,
|
elseif t=="number" then
|
||||||
["until"]=true, ["while"]=true}
|
if v~=v then return "0/0"
|
||||||
local id = "^[%a_][%w_]*$"
|
elseif v==math.huge then return "math.huge"
|
||||||
local ts = {}
|
elseif v==-math.huge then return "-math.huge"
|
||||||
local result_pack = {}
|
else return tostring(v) end
|
||||||
local function recurse(current_value, depth)
|
elseif t=="string" then return string.format("%q",v):gsub("\\\n","\\n")
|
||||||
local t = type(current_value)
|
elseif t=="table" then
|
||||||
if t == "number" then
|
if ts[v] then error("tcyc") end
|
||||||
if current_value ~= current_value then
|
ts[v]=true
|
||||||
table.insert(result_pack, "0/0")
|
local i,r=1, nil
|
||||||
elseif current_value == math.huge then
|
local f=table.pack(local_pairs(v))
|
||||||
table.insert(result_pack, "math.huge")
|
for k,v in table.unpack(f) do
|
||||||
elseif current_value == -math.huge then
|
if r then r=r..","..(("\n"..string.rep(" ",l)) or "")
|
||||||
table.insert(result_pack, "-math.huge")
|
else r="{" end
|
||||||
else
|
local tk=type(k)
|
||||||
table.insert(result_pack, tostring(current_value))
|
if tk=="number" and k==i then
|
||||||
end
|
i=i+1
|
||||||
elseif t == "string" then
|
r=r..s(v,l+1)
|
||||||
table.insert(result_pack, (string.format("%q", current_value):gsub("\\\n","\\n")))
|
|
||||||
elseif
|
|
||||||
t == "nil" or
|
|
||||||
t == "boolean" or
|
|
||||||
pretty and (t ~= "table" or (getmetatable(current_value) or {}).__tostring) then
|
|
||||||
table.insert(result_pack, tostring(current_value))
|
|
||||||
elseif t == "table" then
|
|
||||||
if ts[current_value] then
|
|
||||||
if pretty then
|
|
||||||
table.insert(result_pack, "recursion")
|
|
||||||
return
|
|
||||||
else
|
|
||||||
error("tables with cycles are not supported")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
ts[current_value] = true
|
|
||||||
local f
|
|
||||||
if pretty then
|
|
||||||
local ks, sks, oks = {}, {}, {}
|
|
||||||
for k in local_pairs(current_value) do
|
|
||||||
if type(k) == "number" then
|
|
||||||
table.insert(ks, k)
|
|
||||||
elseif type(k) == "string" then
|
|
||||||
table.insert(sks, k)
|
|
||||||
else
|
|
||||||
table.insert(oks, k)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
table.sort(ks)
|
|
||||||
table.sort(sks)
|
|
||||||
for _, k in ipairs(sks) do
|
|
||||||
table.insert(ks, k)
|
|
||||||
end
|
|
||||||
for _, k in ipairs(oks) do
|
|
||||||
table.insert(ks, k)
|
|
||||||
end
|
|
||||||
local n = 0
|
|
||||||
f = table.pack(function()
|
|
||||||
n = n + 1
|
|
||||||
local k = ks[n]
|
|
||||||
if k ~= nil then
|
|
||||||
return k, current_value[k]
|
|
||||||
else
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
else
|
|
||||||
f = table.pack(local_pairs(current_value))
|
|
||||||
end
|
|
||||||
local i = 1
|
|
||||||
local first = true
|
|
||||||
table.insert(result_pack, "{")
|
|
||||||
for k, v in table.unpack(f) do
|
|
||||||
if not first then
|
|
||||||
table.insert(result_pack, ",")
|
|
||||||
if pretty then
|
|
||||||
table.insert(result_pack, "\n" .. string.rep(" ", depth))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
first = nil
|
|
||||||
local tk = type(k)
|
|
||||||
if tk == "number" and k == i then
|
|
||||||
i = i + 1
|
|
||||||
recurse(v, depth + 1)
|
|
||||||
else
|
|
||||||
if tk == "string" and not kw[k] and string.match(k, id) then
|
|
||||||
table.insert(result_pack, k)
|
|
||||||
else
|
|
||||||
table.insert(result_pack, "[")
|
|
||||||
recurse(k, depth + 1)
|
|
||||||
table.insert(result_pack, "]")
|
|
||||||
end
|
|
||||||
table.insert(result_pack, "=")
|
|
||||||
recurse(v, depth + 1)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
ts[current_value] = nil -- allow writing same table more than once
|
|
||||||
table.insert(result_pack, "}")
|
|
||||||
else
|
else
|
||||||
error("unsupported type: " .. t)
|
if tk == "string" and not kw[k] and string.match(k,id) then r=r..k
|
||||||
end
|
else r=r.."["..s(k,l+1).."]" end
|
||||||
end
|
r=r.."="..s(v,l+1) end end
|
||||||
recurse(value, 1)
|
ts[v]=nil
|
||||||
local result = table.concat(result_pack)
|
return (r or "{").."}"
|
||||||
if pretty then
|
else error("ut "..t) end end
|
||||||
local limit = type(pretty) == "number" and pretty or 10
|
return s(value, 1)
|
||||||
local truncate = 0
|
|
||||||
while limit > 0 and truncate do
|
|
||||||
truncate = string.find(result, "\n", truncate + 1, true)
|
|
||||||
limit = limit - 1
|
|
||||||
end
|
|
||||||
if truncate then
|
|
||||||
return result:sub(1, truncate) .. "..."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return result
|
|
||||||
end
|
end
|
||||||
|
function serial.unserialize(data)
|
||||||
function serialization.unserialize(data) -- returns the data contained in serialized string *data*
|
checkArg(1, data, "string")
|
||||||
local result, reason = load("return " .. data, "=data", nil, {math={huge=math.huge}})
|
local result, reason = load("return " .. data, "=data", _, {math={huge=math.huge}})
|
||||||
if not result then
|
if not result then return nil, reason end
|
||||||
return nil, reason
|
local ok, output = pcall(result)
|
||||||
end
|
if not ok then return nil, output end
|
||||||
local ok, output = pcall(result)
|
return output
|
||||||
if not ok then
|
|
||||||
return nil, output
|
|
||||||
end
|
|
||||||
return output
|
|
||||||
end
|
end
|
||||||
|
return serial
|
||||||
return serialization
|
|
||||||
|
@ -7,10 +7,13 @@ devfs.component = {}
|
|||||||
local function rfalse()
|
local function rfalse()
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
local function rzero()
|
||||||
|
return 0
|
||||||
|
end
|
||||||
function devfs.component.getLabel()
|
function devfs.component.getLabel()
|
||||||
return "devfs"
|
return "devfs"
|
||||||
end
|
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
|
devfs.component.spaceUsed, devfs.component.spaceTotal, devfs.component.isReadOnly, devfs.component.isDirectory,devfs.component.size, devfs.component.setLabel = rzero, rzero, rfalse, rfalse, rzero, rfalse
|
||||||
|
|
||||||
function devfs.component.exists(fname)
|
function devfs.component.exists(fname)
|
||||||
return devfs.files[fname] ~= nil
|
return devfs.files[fname] ~= nil
|
||||||
|
@ -15,11 +15,8 @@ function fs.resolve(path) -- resolves *path* to a specific filesystem mount and
|
|||||||
if path:sub(1,1) ~= "/" then path=(os.getenv("PWD") or "").."/"..path end
|
if path:sub(1,1) ~= "/" then path=(os.getenv("PWD") or "").."/"..path end
|
||||||
local segments, rpath, rfs= fs.segments(path)
|
local segments, rpath, rfs= fs.segments(path)
|
||||||
local rc = #segments
|
local rc = #segments
|
||||||
dprint(rc)
|
|
||||||
for i = #segments, 1, -1 do
|
for i = #segments, 1, -1 do
|
||||||
dprint("testing "..table.concat(segments, "/", 1, i),tostring(fsmounts[table.concat(segments, "/", 1, i)]))
|
|
||||||
if fsmounts[table.concat(segments, "/", 1, i)] ~= nil then
|
if fsmounts[table.concat(segments, "/", 1, i)] ~= nil then
|
||||||
dprint("ret",table.concat(segments, "/", 1, i), table.concat(segments, "/", i+1))
|
|
||||||
return table.concat(segments, "/", 1, i), table.concat(segments, "/", i+1)
|
return table.concat(segments, "/", 1, i), table.concat(segments, "/", i+1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -27,7 +24,7 @@ function fs.resolve(path) -- resolves *path* to a specific filesystem mount and
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- generate some simple functions
|
-- generate some simple functions
|
||||||
for k,v in pairs({"makeDirectory","exists","isDirectory","list","lastModified","remove","size","spaceUsed","isReadOnly","getLabel"}) do
|
for k,v in pairs({"makeDirectory","exists","isDirectory","list","lastModified","remove","size","spaceUsed","spaceTotal","isReadOnly","getLabel"}) do
|
||||||
fs[v] = function(path)
|
fs[v] = function(path)
|
||||||
local fsi,path = fs.resolve(path)
|
local fsi,path = fs.resolve(path)
|
||||||
return fsmounts[fsi][v](path)
|
return fsmounts[fsi][v](path)
|
||||||
@ -99,13 +96,34 @@ function fs.rename(from,to) -- moves file *from* to *to*
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
function fs.mount(path,proxy)
|
function fs.mount(path,proxy) -- mounts the filesystem *proxy* to the mount point *path* if it is a directory. BYO proxy.
|
||||||
if fs.isDirectory(path) then
|
if fs.isDirectory(path) and not fsmounts[table.concat(fs.segments(path),"/")] then
|
||||||
fsmounts[table.concat(fs.segments(path),"/")] = proxy
|
fsmounts[table.concat(fs.segments(path),"/")] = proxy
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
return false, "path is not a directory"
|
return false, "path is not a directory"
|
||||||
end
|
end
|
||||||
|
function fs.umount(path)
|
||||||
|
local fsi,_ = fs.resolve(path)
|
||||||
|
fsmounts[fsi] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function fs.mounts() -- returns a table containing the mount points of all mounted filesystems
|
||||||
|
local rt = {}
|
||||||
|
for k,v in pairs(fsmounts) do
|
||||||
|
rt[#rt+1] = k,v.address or "unknown"
|
||||||
|
end
|
||||||
|
return rt
|
||||||
|
end
|
||||||
|
|
||||||
|
function fs.address(path) -- returns the address of the filesystem at a given path, if applicable
|
||||||
|
local fsi,_ = fs.resolve(path)
|
||||||
|
return fsmounts[fsi].address
|
||||||
|
end
|
||||||
|
function fs.type(path) -- returns the component type of the filesystem at a given path, if applicable
|
||||||
|
local fsi,_ = fs.resolve(path)
|
||||||
|
return fsmounts[fsi].type
|
||||||
|
end
|
||||||
|
|
||||||
fsmounts["/"] = component.proxy(computer.tmpAddress())
|
fsmounts["/"] = component.proxy(computer.tmpAddress())
|
||||||
fs.makeDirectory("temp")
|
fs.makeDirectory("temp")
|
||||||
@ -113,9 +131,5 @@ if computer.getBootAddress then
|
|||||||
fs.makeDirectory("boot")
|
fs.makeDirectory("boot")
|
||||||
fs.mount("boot",component.proxy(computer.getBootAddress()))
|
fs.mount("boot",component.proxy(computer.getBootAddress()))
|
||||||
end
|
end
|
||||||
for addr, _ in component.list("filesystem") do
|
|
||||||
fs.makeDirectory(addr:sub(1,3))
|
|
||||||
fs.mount(addr:sub(1,3),component.proxy(addr))
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -8,7 +8,6 @@ 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*
|
||||||
dprint(p,n)
|
|
||||||
return os.spawn(function() xpcall(loadfile(p),function(e) dprint(e.."\n"..debug.traceback()) end) end,n or p)
|
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
|
||||||
|
@ -30,6 +30,8 @@ function os.tasks()
|
|||||||
return rt
|
return rt
|
||||||
end
|
end
|
||||||
function os.taskInfo(pid)
|
function os.taskInfo(pid)
|
||||||
|
pid = pid or os.pid()
|
||||||
|
if not tTasks[pid] then return false end
|
||||||
return {name=tTasks[pid].n,parent=tTasks[pid].P}
|
return {name=tTasks[pid].n,parent=tTasks[pid].P}
|
||||||
end
|
end
|
||||||
function os.sched() -- the actual scheduler function
|
function os.sched() -- the actual scheduler function
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
dprint=dprint or function() end
|
do
|
||||||
|
|
||||||
syslog = {}
|
syslog = {}
|
||||||
syslog.emergency = 0
|
syslog.emergency = 0
|
||||||
syslog.alert = 1
|
syslog.alert = 1
|
||||||
@ -10,8 +9,15 @@ syslog.notice = 5
|
|||||||
syslog.info = 6
|
syslog.info = 6
|
||||||
syslog.debug = 7
|
syslog.debug = 7
|
||||||
|
|
||||||
|
local rdprint=dprint or function() end
|
||||||
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 (os.taskInfo(os.pid()) or {}).name or "unknown"
|
||||||
dprint(string.format("syslog: [%s:%d/%d] %s",service,os.pid(),level,msg))
|
rdprint(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})
|
||||||
|
function dprint(...)
|
||||||
|
for k,v in pairs({...}) do
|
||||||
|
syslog(v,syslog.debug)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@ -31,8 +31,7 @@ function vtemu(gpua,scra) -- creates a process to handle the GPU and screen addr
|
|||||||
coroutine.yield()
|
coroutine.yield()
|
||||||
end
|
end
|
||||||
local n = buf:find("\n")
|
local n = buf:find("\n")
|
||||||
r, buf = buf:sub(1,n), buf:sub(n+1)
|
r, buf = buf:sub(1,n-1), 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
|
||||||
|
@ -1,11 +1,21 @@
|
|||||||
|
local function mount(addr)
|
||||||
|
dest = component.invoke(addr,"getLabel") or "mnt/"..addr:sub(1,3)
|
||||||
|
dest = "/"..dest
|
||||||
|
syslog("Mounting "..addr.." to "..dest)
|
||||||
|
fs.makeDirectory(dest)
|
||||||
|
local w,r = fs.mount(dest,component.proxy(addr))
|
||||||
|
if not w then
|
||||||
|
syslog("Failed to mount: "..r)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for addr, _ in component.list("filesystem") do
|
||||||
|
mount(addr)
|
||||||
|
end
|
||||||
while true do
|
while true do
|
||||||
local tE = {coroutine.yield()}
|
local tE = {coroutine.yield()}
|
||||||
if tE[1] == "component_added" and tE[3] == "filesystem" then
|
if tE[1] == "component_added" and tE[3] == "filesystem" then
|
||||||
local w, doesExist = pcall(fs.exists,"/"..tE[2]:sub(1,3))
|
mount(tE[2])
|
||||||
if not w or not doesExist then
|
|
||||||
fs.mounts[tE[2]:sub(1,3)] = component.proxy(tE[2])
|
|
||||||
end
|
|
||||||
elseif tE[1] == "component_removed" and tE[3] == "filesystem" then
|
elseif tE[1] == "component_removed" and tE[3] == "filesystem" then
|
||||||
fs.mounts[tE[2]:sub(1,3)] = nil
|
fs.umount("/mnt/"..tE[2]:sub(1,3))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
local gpus,screens,ttyn = {}, {}, 0
|
local gpus,screens,ttyn,pids = {}, {}, 0, {}
|
||||||
local function scan()
|
local function scan()
|
||||||
local w,di = pcall(computer.getDeviceInfo)
|
local w,di = pcall(computer.getDeviceInfo)
|
||||||
if w then
|
if w then
|
||||||
@ -29,6 +29,14 @@ local function nextScreen(n)
|
|||||||
end
|
end
|
||||||
return rt[n] or rt[8000] or rt[2000] or rt[600]
|
return rt[n] or rt[8000] or rt[2000] or rt[600]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function spawnShell(fin,fout)
|
||||||
|
io.input(fin)
|
||||||
|
io.output(fout)
|
||||||
|
print(_OSVERSION.." - "..tostring(math.floor(computer.totalMemory()/1024)).."K RAM")
|
||||||
|
return os.spawnfile("/boot/exec/shell.lua")
|
||||||
|
end
|
||||||
|
|
||||||
local function allocate()
|
local function allocate()
|
||||||
for k,v in pairs(gpus) do
|
for k,v in pairs(gpus) do
|
||||||
dprint(k)
|
dprint(k)
|
||||||
@ -38,13 +46,22 @@ local function allocate()
|
|||||||
devfs.register("tty"..tostring(ttyn), function() return r,w,function() end end)
|
devfs.register("tty"..tostring(ttyn), function() return r,w,function() end 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
|
ttyn = ttyn + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
scan()
|
scan()
|
||||||
allocate()
|
allocate()
|
||||||
dprint("screens ready")
|
dprint("screens ready")
|
||||||
while true do
|
while true do
|
||||||
coroutine.yield()
|
coroutine.yield()
|
||||||
|
for k,v in pairs(pids) do
|
||||||
|
if not os.taskInfo(v[1]) then
|
||||||
|
dprint("Spawning new shell for "..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 io.input(), pids[k][3] or io.output()
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user