Bubble bug (#2405)

* better ls failure check

* always yield from sh threads, do not call event.pull directly

* load env wrapping and some bug fixes
This commit is contained in:
payonel 2017-05-26 07:22:45 -07:00 committed by GitHub
parent fcb9122d63
commit e3ab7fc868
15 changed files with 50 additions and 76 deletions

View File

@ -5,10 +5,13 @@ local ok, why = pcall(function(...)
end, ...)
if not ok then
if type(why) == "table" and why.code == 0 then
return
if type(why) == "table" then
if why.code == 0 then
return
end
why = why.reason
end
io.stderr:write((why or "") .. "\nFor low memory systems, try using `list` instead\n")
io.stderr:write(tostring(why) .. "\nFor low memory systems, try using `list` instead\n")
return 1
end

View File

@ -23,13 +23,18 @@ for key,value in pairs(_coroutine) do
end
end
local init_thread = _coroutine.running()
local init_load = _G.load
_G.load = function(ld, source, mode, env)
env = env or select(2, process.running())
return init_load(ld, source, mode, env)
local kernel_load = _G.load
local intercept_load
intercept_load = function(source, label, mode, env)
if env then
env.load = kernel_load([[
local source, label, mode, env = ...
return load(source, label, mode, env or fenv)
]], "=load", "t", {fenv=env, load=intercept_load})
end
return kernel_load(source, label, mode, env or process.info().env)
end
_G.load = intercept_load
local kernel_create = _coroutine.create
_coroutine.create = function(f,standAlone)
@ -50,6 +55,7 @@ _coroutine.wrap = function(f)
end
end
local init_thread = _coroutine.running()
process.list[init_thread] = {
path = "/init.lua",
command = "init",

View File

@ -3,7 +3,6 @@ local computer = require("computer")
local event = require("event")
local adding = {}
local removing = {}
local primaries = {}
-------------------------------------------------------------------------------

View File

@ -2,9 +2,8 @@ local component = require("component")
local computer = require("computer")
local event = require("event")
local tty = require("tty")
local process = require("process")
event.listen("gpu_bound", function(ename, gpu)
event.listen("gpu_bound", function(_, gpu)
gpu = component.proxy(gpu)
tty.bind(gpu)
computer.pushSignal("term_available")

View File

@ -98,7 +98,7 @@ function buffer:readLine(chop, timeout)
if reason then
return nil, reason
else -- eof
local result = #self.bufferRead > 0 and self.bufferRead or nil
result = #self.bufferRead > 0 and self.bufferRead or nil
self.bufferRead = ""
return result
end

View File

@ -117,16 +117,16 @@ local function dynamic_list(path, fsnode)
local nodes, links, dirs = {}, {}, {}
local node = findNode(path)
if node then
for name,node in child_iterator(node) do
if node.proxy and node.proxy.link then
links[name] = node.proxy.link
elseif node.proxy and node.proxy.list then
for name,cnode in child_iterator(node) do
if cnode.proxy and cnode.proxy.link then
links[name] = cnode.proxy.link
elseif cnode.proxy and cnode.proxy.list then
local child = {name=name,parent=fsnode}
local child_path = path .. "/" .. name
inject_dynamic_pairs(child, child_path, true)
dirs[name] = child
else
nodes[name] = node
nodes[name] = cnode
end
end
end
@ -143,7 +143,7 @@ inject_dynamic_pairs = function(fsnode, path, bStoreUse)
local bLinks = key == "links"
local bChildren = key == "children"
if not bLinks and not bChildren then return end
local nodes, links, dirs = dynamic_list(path, tbl)
local _, links, dirs = dynamic_list(path, tbl)
if bStoreUse then
tbl.children = dirs
tbl.links = links
@ -182,7 +182,7 @@ end
function api.proxy.list(path)
local result = {}
for name,node in pairs(dynamic_list(path, false, false)) do
for name in pairs(dynamic_list(path, false, false)) do
table.insert(result, name)
end
return result
@ -195,7 +195,7 @@ end
function api.proxy.size(path)
checkArg(1, path, "string")
local node, why = findNode(path)
local node = findNode(path)
if not node or not node.proxy then
return 0
end

View File

@ -47,7 +47,7 @@ function pipeStream:close()
local pco_root = self.pm.threads[1]
if co.status(pco_root) == "dead" then
-- I would have liked the pco stack to unwind itself for dead coroutines
-- maybe I haven't handled aborts corrects
-- maybe I haven't handled aborts correctly
return
end
@ -268,7 +268,7 @@ function pipeManager.reader(pm,...)
-- if we are a reader pipe, we leave the buffer alone and yield to previous
if pm.pco.status(pm.threads[pm.prog_id]) ~= "dead" then
pm.pco.yield()
pm.pco.yield(...)
end
end
pm.dead = true
@ -308,8 +308,7 @@ function pipeManager.new(prog, mode, env)
return nil, "bad argument #2: invalid mode " .. tostring(mode) .. " must be r or w"
end
local shellPath = os.getenv("SHELL") or "/bin/sh"
local shellPath, reason = shell.resolve(shellPath, "lua")
local shellPath, reason = shell.resolve(os.getenv("SHELL") or "/bin/sh", "lua")
if not shellPath then
return nil, reason
end
@ -361,7 +360,7 @@ function plib.popen(prog, mode, env)
return false, reason
end
pm.pco=plib.internal.create(pm.root)
pm.pco = plib.internal.create(pm.root)
local pfd = require("buffer").new(mode, pipeStream.new(pm))
pfd:setvbuf("no", 0) -- 2nd are to read chunk size
@ -372,4 +371,11 @@ function plib.popen(prog, mode, env)
return pfd
end
function plib.create(fp, name)
checkArg(1, fp, "function")
checkArg(2, name, "string", "nil")
local pco = plib.internal.create(fp, nil, name)
return pco.stack[1]
end
return plib

View File

@ -30,10 +30,7 @@ function process.load(path, env, init, name)
name = name or ""
local p = process.findProcess()
if p then
env = env or p.env
end
env = setmetatable({}, {__index=env or _G})
env = env or p.env
local code
if type(path) == 'string' then
code = function(...)

View File

@ -297,11 +297,7 @@ function sh.internal.runThreads(threads)
while coroutine.status(thread) ~= "dead" do
result = table.pack(coroutine.resume(thread, table.unpack(args)))
if coroutine.status(thread) ~= "dead" then
args = sh.internal.handleThreadYield(result)
if table.remove(args, 1) then
-- in case this was the end of the line, args is returned
return args[2]
end
args = table.pack(coroutine.yield(table.unpack(result, 2, result.n)))
elseif not result[1] then
io.stderr:write(result[2])
end

View File

@ -1,6 +1,5 @@
local unicode = require("unicode")
local event = require("event")
local process = require("process")
local kb = require("keyboard")
local component = require("component")
local computer = require("computer")
@ -58,15 +57,13 @@ local function tab_handler(handler, cursor)
end
local cache = handler.cache
local cache_size = #cache
if cache_size == 1 and cache.i == 0 then
if #cache == 1 and cache.i == 0 then
-- there was only one solution, and the user is asking for the next
handler.cache = hints(cache[1], cursor.index + 1)
if not handler.cache then return end
handler.cache.i = -1
cache = handler.cache
cache_size = #cache
end
local change = kb.isShiftDown(main_kb) and -1 or 1
@ -107,7 +104,7 @@ local function key_down_handler(handler, cursor, char, code)
elseif code == keys["end"] then cursor:move( math.huge)
elseif code == keys.back then c = -1
elseif code == keys.delete then c = 1
elseif ctrl and char == "w"then -- TODO: cut word
--elseif ctrl and char == "w"then -- TODO: cut word
elseif char >= 32 then c = unicode.char(char)
else handler.cache = backup_cache -- ignored chars shouldn't clear hint cache
end
@ -359,7 +356,7 @@ function tty.write(value, wrap)
stream.nowrap = wrap == false
stdout:write(value)
stdout:flush()
stream.nowrap = previous_wrap
stream.nowrap = previous_nowrap
end
function tty.getCursor()

View File

@ -6,7 +6,6 @@ function uuid.next()
local sets = {4, 2, 2, 2, 6}
local result = ""
local i
for _,set in ipairs(sets) do
if result:len() > 0 then
result = result .. "-"

View File

@ -21,10 +21,10 @@ function lib.loadRules(root_dir)
for file in fs.list(root_dir) do
if file:match("%.lua$") then
local path = fs_key(root_dir, file)
local file = io.open(path)
if file then
local load_rule = load("return {" .. file:read("*a") .. "}")
file:close()
local file_handle = io.open(path)
if file_handle then
local load_rule = load("return {" .. file_handle:read("*a") .. "}")
file_handle:close()
if load_rule then
local ok, rule = pcall(load_rule)
if ok and type(rule) == "table" then
@ -54,7 +54,7 @@ function lib.saveRule(rule_set, path)
file:close()
end
function lib.saveRules()
function lib.saveRules(rules)
for path, rule_set in pairs(rules) do
lib.saveRule(rule_set, path)
end

View File

@ -163,7 +163,7 @@ local function pad(txt)
end
local function formatDate(epochms)
local day_names={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"}
--local day_names={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"}
local month_names={"January","February","March","April","May","June","July","August","September","October","November","December"}
if epochms == 0 then return "" end
local d = os.date("*t", epochms)
@ -336,21 +336,6 @@ if #dirsArg > 1 or ops.R then
io.write(path,":\n")
end
end
local function splitDirsFromFileArgs(dirs)
local trimmed = {}
local files = {}
for _,dir in ipairs(dirs) do
local path = shell.resolve(dir)
if not fs.exists(path) then
perr("cannot access " .. tostring(path) .. ": No such file or directory")
elseif fs.isDirectory(path) then
table.insert(trimmed, dir)
else -- file or link
table.insert(files, dir)
end
end
return files, trimmed
end
local function displayDirList(dirs)
while #dirs > 0 do
local dir = table.remove(dirs, 1)

View File

@ -1,4 +1,3 @@
local event = require("event")
local fs = require("filesystem")
local process = require("process")
local shell = require("shell")
@ -12,15 +11,6 @@ local isWordOf = sh.internal.isWordOf
-------------------------------------------------------------------------------
function sh.internal.handleThreadYield(result)
local action = result[2]
if action == nil or type(action) == "number" then
return table.pack(pcall(event.pull, table.unpack(result, 2, result.n)))
else
return table.pack(coroutine.yield(table.unpack(result, 2, result.n)))
end
end
function sh.internal.buildCommandRedirects(args, thread)
local data = process.info(thread).data
local tokens, ios, handles = args, data.io, data.handles

View File

@ -32,9 +32,6 @@ env = setmetatable({}, {
return k, v
end
end,
__newindex = function(_, k, v)
process.info().env[k] = v
end
})
env._PROMPT = tostring(env._PROMPT or "lua> ")