diff --git a/module/buffer.lua b/module/buffer.lua deleted file mode 100644 index 5b1e164..0000000 --- a/module/buffer.lua +++ /dev/null @@ -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 diff --git a/module/chatbox-dprint.lua b/module/chatbox-dprint.lua new file mode 100644 index 0000000..577a4fc --- /dev/null +++ b/module/chatbox-dprint.lua @@ -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 diff --git a/module/init.lua b/module/init.lua index 2855e96..0ea6a09 100644 --- a/module/init.lua +++ b/module/init.lua @@ -1,12 +1,12 @@ +--#include "module/chatbox-dprint.lua" --#include "module/syslog.lua" --#include "module/sched.lua" ---#include "module/buffer.lua" --#include "module/fs.lua" ---#include "module/io.lua" +--#include "module/newio.lua" --#include "module/devfs.lua" --#include "module/devfs/syslog.lua" +--#include "module/vt-task.lua" --#include "module/loadfile.lua" ---#include "module/term.lua" -os.spawnfile("/boot/exec/init.lua","init") +os.spawnfile("/boot/exec/init.lua") os.sched() diff --git a/module/io.lua b/module/io.lua deleted file mode 100644 index 59bf90a..0000000 --- a/module/io.lua +++ /dev/null @@ -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 diff --git a/module/loadfile.lua b/module/loadfile.lua index 6c29473..7e51efc 100644 --- a/module/loadfile.lua +++ b/module/loadfile.lua @@ -8,7 +8,8 @@ function runfile(p,...) -- runs file *p* with arbitrary arguments in the current return loadfile(p)(...) end 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 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" diff --git a/module/newio.lua b/module/newio.lua new file mode 100644 index 0000000..6c04164 --- /dev/null +++ b/module/newio.lua @@ -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 diff --git a/module/sched.lua b/module/sched.lua index 76611f9..7434a3c 100644 --- a/module/sched.lua +++ b/module/sched.lua @@ -1,5 +1,5 @@ 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* tTasks[nPid] = { c=coroutine.create(f), -- actual coroutine diff --git a/module/vt-task.lua b/module/vt-task.lua index f0032d5..83d0a58 100644 --- a/module/vt-task.lua +++ b/module/vt-task.lua @@ -27,9 +27,12 @@ function vtemu(gpua,scra) end end)) end,string.format("ttyd[%s:%s]",gpua:sub(1,8),scra:sub(1,8))) local function bread() + while not buf:find("\n") do + coroutine.yield() + end local n = buf:find("\n") - if not n then return nil end r, buf = buf:sub(1,n), buf:sub(n+1) + dprint("bread",r) return r end return bread, write, function() io.write("\27[2J\27[H") end