From 367f268662658e3d80bccd325f58fe7e9f1a6698 Mon Sep 17 00:00:00 2001 From: payonel Date: Sun, 24 Jul 2016 21:22:54 -0700 Subject: [PATCH 1/5] reduce RAM costs by delaying part of /lib/buffer --- .../opencomputers/loot/openos/lib/buffer.lua | 128 +---------------- .../openos/lib/tools/advanced-buffering.lua | 132 ++++++++++++++++++ 2 files changed, 133 insertions(+), 127 deletions(-) create mode 100644 src/main/resources/assets/opencomputers/loot/openos/lib/tools/advanced-buffering.lua diff --git a/src/main/resources/assets/opencomputers/loot/openos/lib/buffer.lua b/src/main/resources/assets/opencomputers/loot/openos/lib/buffer.lua index 233a62505..1a7595267 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/lib/buffer.lua +++ b/src/main/resources/assets/opencomputers/loot/openos/lib/buffer.lua @@ -111,132 +111,6 @@ function buffer:read(...) return buffer end - local function readNumber() - local len, sub - if self.mode.b then - len = rawlen - sub = string.sub - else - len = unicode.len - sub = unicode.sub - end - local buffer = "" - local first = true - local decimal = false - local last = false - local hex = false - local pat = "^[0-9]+" - local minbuf = 3 -- "+0x" (sign + hexadecimal tag) - -- this function is used to read trailing numbers (1e2, 0x1p2, etc) - local function readnum(checksign) - local _buffer = "" - local sign = "" - while true do - if len(self.bufferRead) == 0 then - local result, reason = readChunk() - if not result then - if reason then - return nil, reason - else -- eof - return #_buffer > 0 and (sign .. _buffer) or nil - end - end - end - if checksign then - local _sign = sub(self.bufferRead, 1, 1) - if _sign == "+" or _sign == "-" then - -- "eat" the sign (Rio Lua behaviour) - sign = sub(self.bufferRead, 1, 1) - self.bufferRead = sub(self.bufferRead, 2) - end - checksign = false - else - local x,y = string.find(self.bufferRead, pat) - if not x then - break - else - _buffer = _buffer .. sub(self.bufferRead, 1, y) - self.bufferRead = sub(self.bufferRead, y + 1) - end - end - end - return #_buffer > 0 and (sign .. _buffer) or nil - end - while true do - if len(self.bufferRead) == 0 or len(self.bufferRead) < minbuf then - local result, reason = readChunk() - if not result then - if reason then - return nil, reason - else -- eof - return #buffer > 0 and tonumber(buffer) or nil - end - end - end - -- these ifs are here so we run the buffer check above - if first then - local sign = sub(self.bufferRead, 1, 1) - if sign == "+" or sign == "-" then - -- "eat" the sign (Rio Lua behaviour) - buffer = buffer .. sub(self.bufferRead, 1, 1) - self.bufferRead = sub(self.bufferRead, 2) - end - local hextag = sub(self.bufferRead, 1, 2) - if hextag == "0x" or hextag == "0X" then - pat = "^[0-9A-Fa-f]+" - -- "eat" the 0x, see https://gist.github.com/SoniEx2/570a363d81b743353151 - buffer = buffer .. sub(self.bufferRead, 1, 2) - self.bufferRead = sub(self.bufferRead, 3) - hex = true - end - minbuf = 0 - first = false - elseif decimal then - local sep = sub(self.bufferRead, 1, 1) - if sep == "." then - buffer = buffer .. sep - self.bufferRead = sub(self.bufferRead, 2) - local temp = readnum(false) -- no sign - if temp then - buffer = buffer .. temp - end - end - if not tonumber(buffer) then break end - decimal = false - last = true - minbuf = 1 - elseif last then - local tag = sub(self.bufferRead, 1, 1) - if hex and (tag == "p" or tag == "P") then - local temp = sub(self.bufferRead, 1, 1) - self.bufferRead = sub(self.bufferRead, 2) - local temp2 = readnum(true) -- this eats the next sign if any - if temp2 then - buffer = buffer .. temp .. temp2 - end - elseif tag == "e" or tag == "E" then - local temp = sub(self.bufferRead, 1, 1) - self.bufferRead = sub(self.bufferRead, 2) - local temp2 = readnum(true) -- this eats the next sign if any - if temp2 then - buffer = buffer .. temp .. temp2 - end - end - break - else - local x,y = string.find(self.bufferRead, pat) - if not x then - minbuf = 1 - decimal = true - else - buffer = buffer .. sub(self.bufferRead, 1, y) - self.bufferRead = sub(self.bufferRead, y + 1) - end - end - end - return tonumber(buffer) - end - local function readLine(chop) local start = 1 while true do @@ -289,7 +163,7 @@ function buffer:read(...) end format = unicode.sub(format, 2, 2) if format == "n" then - return readNumber() + return require("tools/advanced-buffering").readNumber(self, readChunk) elseif format == "l" then return readLine(true) elseif format == "L" then diff --git a/src/main/resources/assets/opencomputers/loot/openos/lib/tools/advanced-buffering.lua b/src/main/resources/assets/opencomputers/loot/openos/lib/tools/advanced-buffering.lua new file mode 100644 index 000000000..405a5158a --- /dev/null +++ b/src/main/resources/assets/opencomputers/loot/openos/lib/tools/advanced-buffering.lua @@ -0,0 +1,132 @@ +local unicode = require("unicode") + +--for k in pairs(buffer.reads) do print(k, #buffer.reads[k]) end +local adv_buf = {} + +function adv_buf.readNumber(self, readChunk) + local len, sub + if self.mode.b then + len = rawlen + sub = string.sub + else + len = unicode.len + sub = unicode.sub + end + local buffer = "" + local first = true + local decimal = false + local last = false + local hex = false + local pat = "^[0-9]+" + local minbuf = 3 -- "+0x" (sign + hexadecimal tag) + -- this function is used to read trailing numbers (1e2, 0x1p2, etc) + local function readnum(checksign) + local _buffer = "" + local sign = "" + while true do + if len(self.bufferRead) == 0 then + local result, reason = readChunk() + if not result then + if reason then + return nil, reason + else -- eof + return #_buffer > 0 and (sign .. _buffer) or nil + end + end + end + if checksign then + local _sign = sub(self.bufferRead, 1, 1) + if _sign == "+" or _sign == "-" then + -- "eat" the sign (Rio Lua behaviour) + sign = sub(self.bufferRead, 1, 1) + self.bufferRead = sub(self.bufferRead, 2) + end + checksign = false + else + local x,y = string.find(self.bufferRead, pat) + if not x then + break + else + _buffer = _buffer .. sub(self.bufferRead, 1, y) + self.bufferRead = sub(self.bufferRead, y + 1) + end + end + end + return #_buffer > 0 and (sign .. _buffer) or nil + end + while true do + if len(self.bufferRead) == 0 or len(self.bufferRead) < minbuf then + local result, reason = readChunk() + if not result then + if reason then + return nil, reason + else -- eof + return #buffer > 0 and tonumber(buffer) or nil + end + end + end + -- these ifs are here so we run the buffer check above + if first then + local sign = sub(self.bufferRead, 1, 1) + if sign == "+" or sign == "-" then + -- "eat" the sign (Rio Lua behaviour) + buffer = buffer .. sub(self.bufferRead, 1, 1) + self.bufferRead = sub(self.bufferRead, 2) + end + local hextag = sub(self.bufferRead, 1, 2) + if hextag == "0x" or hextag == "0X" then + pat = "^[0-9A-Fa-f]+" + -- "eat" the 0x, see https://gist.github.com/SoniEx2/570a363d81b743353151 + buffer = buffer .. sub(self.bufferRead, 1, 2) + self.bufferRead = sub(self.bufferRead, 3) + hex = true + end + minbuf = 0 + first = false + elseif decimal then + local sep = sub(self.bufferRead, 1, 1) + if sep == "." then + buffer = buffer .. sep + self.bufferRead = sub(self.bufferRead, 2) + local temp = readnum(false) -- no sign + if temp then + buffer = buffer .. temp + end + end + if not tonumber(buffer) then break end + decimal = false + last = true + minbuf = 1 + elseif last then + local tag = sub(self.bufferRead, 1, 1) + if hex and (tag == "p" or tag == "P") then + local temp = sub(self.bufferRead, 1, 1) + self.bufferRead = sub(self.bufferRead, 2) + local temp2 = readnum(true) -- this eats the next sign if any + if temp2 then + buffer = buffer .. temp .. temp2 + end + elseif tag == "e" or tag == "E" then + local temp = sub(self.bufferRead, 1, 1) + self.bufferRead = sub(self.bufferRead, 2) + local temp2 = readnum(true) -- this eats the next sign if any + if temp2 then + buffer = buffer .. temp .. temp2 + end + end + break + else + local x,y = string.find(self.bufferRead, pat) + if not x then + minbuf = 1 + decimal = true + else + buffer = buffer .. sub(self.bufferRead, 1, y) + self.bufferRead = sub(self.bufferRead, y + 1) + end + end + end + return tonumber(buffer) +end + +return adv_buf From aa422bf21aa4a2293eec4798c3adbb090e4701ed Mon Sep 17 00:00:00 2001 From: payonel Date: Sun, 24 Jul 2016 21:37:40 -0700 Subject: [PATCH 2/5] fix /bin/touch --- .../resources/assets/opencomputers/loot/openos/bin/touch.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/assets/opencomputers/loot/openos/bin/touch.lua b/src/main/resources/assets/opencomputers/loot/openos/bin/touch.lua index 7de1591a8..e88ee44de 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/bin/touch.lua +++ b/src/main/resources/assets/opencomputers/loot/openos/bin/touch.lua @@ -31,7 +31,7 @@ for _,arg in ipairs(args) do if fs.isDirectory(path) then io.stderr:write(string.format("`%s' ignored: directories not supported\n", arg)) elseif fs.exists(path) or not options.c then - local f, reason = io.open(path, "w") + local f, reason = io.open(path, "a") if not f then io.stderr:write(string.format("touch: cannot touch `%s': permission denied\n", arg)) errors = 1 From a4850a5ff16a2c42c2435a735c82c3782fec2125 Mon Sep 17 00:00:00 2001 From: payonel Date: Sun, 24 Jul 2016 21:55:10 -0700 Subject: [PATCH 3/5] allow soft interrupts to stop cp --- src/main/resources/assets/opencomputers/loot/openos/bin/cp.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/resources/assets/opencomputers/loot/openos/bin/cp.lua b/src/main/resources/assets/opencomputers/loot/openos/bin/cp.lua index 1fa0fe20b..6d5aaad17 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/bin/cp.lua +++ b/src/main/resources/assets/opencomputers/loot/openos/bin/cp.lua @@ -31,6 +31,9 @@ local result, reason local function prompt(message) io.write(message .. " [Y/n] ") local result = io.read() + if not result then -- closed pipe + os.exit(1) + end return result and (result == "" or result:sub(1, 1):lower() == "y") end From 49666dee0ca7ce2f22f22a607d63c4993f11e132 Mon Sep 17 00:00:00 2001 From: payonel Date: Mon, 25 Jul 2016 23:32:41 -0700 Subject: [PATCH 4/5] safer install on low memory --- .../assets/opencomputers/loot/openos/bin/install.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/resources/assets/opencomputers/loot/openos/bin/install.lua b/src/main/resources/assets/opencomputers/loot/openos/bin/install.lua index 482395b76..60ab9cb53 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/bin/install.lua +++ b/src/main/resources/assets/opencomputers/loot/openos/bin/install.lua @@ -4,7 +4,11 @@ local shell = require("shell") local options do - local basic = loadfile(package.searchpath("tools/install_basics", package.path), "bt", _G) + local basic, reason = loadfile(package.searchpath("tools/install_basics", package.path), "bt", _G) + if not basic then + io.stderr:write("failed to load install: " .. tostring(reason) .. "\n") + return 1 + end options = basic(...) end From aa103349d07f96a093d7ff6463ae9c91c10e9077 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Wed, 27 Jul 2016 20:43:27 +0200 Subject: [PATCH 5/5] Try to prevent nodes loading into an illegal state. --- src/main/scala/li/cil/oc/server/network/Node.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/scala/li/cil/oc/server/network/Node.scala b/src/main/scala/li/cil/oc/server/network/Node.scala index de8100c0b..9aa34ea99 100644 --- a/src/main/scala/li/cil/oc/server/network/Node.scala +++ b/src/main/scala/li/cil/oc/server/network/Node.scala @@ -1,5 +1,6 @@ package li.cil.oc.server.network +import com.google.common.base.Strings import li.cil.oc.OpenComputers import li.cil.oc.api import li.cil.oc.api.network.Environment @@ -67,7 +68,7 @@ trait Node extends ImmutableNode { def load(nbt: NBTTagCompound) = { if (nbt.hasKey("address")) { val newAddress = nbt.getString("address") - if (newAddress != address) network match { + if (!Strings.isNullOrEmpty(newAddress) && newAddress != address) network match { case wrapper: Network.Wrapper => wrapper.network.remap(this, newAddress) case _ => address = newAddress }