Made filesystem seeking more failsafe and added better log trimming.
- Trying to seek before the start of a file stream now does not cause an error - Logs are now trimmed between log entries
This commit is contained in:
+13
-11
@@ -144,6 +144,7 @@ function filesystem.makeReadStream(content)
|
|||||||
end
|
end
|
||||||
return out
|
return out
|
||||||
end
|
end
|
||||||
|
|
||||||
properHandle.readBytes = readBytes
|
properHandle.readBytes = readBytes
|
||||||
properHandle.readUnicodeChar = readUnicodeChar
|
properHandle.readUnicodeChar = readUnicodeChar
|
||||||
properHandle.iterateBytes = iterateBytes
|
properHandle.iterateBytes = iterateBytes
|
||||||
@@ -151,9 +152,11 @@ function filesystem.makeReadStream(content)
|
|||||||
function properHandle.write()
|
function properHandle.write()
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
function properHandle.close()
|
function properHandle.close()
|
||||||
content = nil
|
content = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
return properHandle
|
return properHandle
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -277,6 +280,7 @@ function filesystem.open(path, mode, buffered) -- opens a file and returns its h
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
properHandle.readBytes = readBytes
|
properHandle.readBytes = readBytes
|
||||||
properHandle.readUnicodeChar = readUnicodeChar
|
properHandle.readUnicodeChar = readUnicodeChar
|
||||||
properHandle.iterateBytes = iterateBytes
|
properHandle.iterateBytes = iterateBytes
|
||||||
@@ -309,12 +313,14 @@ function filesystem.open(path, mode, buffered) -- opens a file and returns its h
|
|||||||
return component.invoke(self.address, "write", self.handle, data)
|
return component.invoke(self.address, "write", self.handle, data)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function properHandle.close(self)
|
function properHandle.close(self)
|
||||||
if buffered then
|
if buffered then
|
||||||
content = nil
|
content = nil
|
||||||
end
|
end
|
||||||
return component.invoke(self.address, "close", self.handle)
|
return component.invoke(self.address, "close", self.handle)
|
||||||
end
|
end
|
||||||
|
|
||||||
if address == computer.getBootAddress() then
|
if address == computer.getBootAddress() then
|
||||||
local eeprom
|
local eeprom
|
||||||
pcall(function()
|
pcall(function()
|
||||||
@@ -339,6 +345,7 @@ function filesystem.open(path, mode, buffered) -- opens a file and returns its h
|
|||||||
checkArg(2, data, "string")
|
checkArg(2, data, "string")
|
||||||
content = content .. data
|
content = content .. data
|
||||||
end
|
end
|
||||||
|
|
||||||
function properHandle.close(self)
|
function properHandle.close(self)
|
||||||
return eeprom[setFunc](content)
|
return eeprom[setFunc](content)
|
||||||
end
|
end
|
||||||
@@ -359,25 +366,19 @@ function filesystem.open(path, mode, buffered) -- opens a file and returns its h
|
|||||||
end
|
end
|
||||||
|
|
||||||
if buffered then
|
if buffered then
|
||||||
-- Calculate current absolute position in file
|
|
||||||
local currentAbsolutePos = bufferOffset + readCursor - 1
|
local currentAbsolutePos = bufferOffset + readCursor - 1
|
||||||
|
-- Seek real handle position to buffer handle position
|
||||||
-- Seek the underlying file handle to the correct position
|
|
||||||
component.invoke(self.address, "seek", self.handle, "set", currentAbsolutePos)
|
component.invoke(self.address, "seek", self.handle, "set", currentAbsolutePos)
|
||||||
|
local newPos = component.invoke(self.address, "seek", self.handle, whence, math.max(offset, -currentAbsolutePos))
|
||||||
-- Now perform the actual seek
|
|
||||||
local newPos = component.invoke(self.address, "seek", self.handle, whence, offset)
|
|
||||||
|
|
||||||
-- Invalidate the buffer and reset positions
|
|
||||||
content = nil
|
content = nil
|
||||||
bufferOffset = newPos or 0
|
bufferOffset = newPos or 0
|
||||||
readCursor = 1
|
readCursor = 1
|
||||||
|
|
||||||
return newPos
|
return newPos
|
||||||
else
|
else
|
||||||
return component.invoke(self.address, "seek", self.handle, whence, offset)
|
return component.invoke(self.address, "seek", self.handle, whence, math.max(offset, -currentAbsolutePos))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return properHandle
|
return properHandle
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -561,7 +562,8 @@ function filesystem.rename(fromPath, toPath)
|
|||||||
copyRecursive(fromAddress, fromAbsPath, toAddress, toAbsPath)
|
copyRecursive(fromAddress, fromAbsPath, toAddress, toAbsPath)
|
||||||
filesystem.remove(fromPath) -- component.invoke(fromAddress,"remove", fromAbsPath)
|
filesystem.remove(fromPath) -- component.invoke(fromAddress,"remove", fromAbsPath)
|
||||||
else
|
else
|
||||||
local handle, data, tmpdata = filesystem.open(fromPath), "", nil -- component.invoke(fromAddress, "open", fromAbsPath, "r"), "", nil
|
local handle, data, tmpdata = filesystem.open(fromPath), "",
|
||||||
|
nil -- component.invoke(fromAddress, "open", fromAbsPath, "r"), "", nil
|
||||||
repeat
|
repeat
|
||||||
tmpdata = handle:read(math.huge or math.maxinteger) -- component.invoke(fromAddress, "read", handle, math.huge or math.maxinteger)
|
tmpdata = handle:read(math.huge or math.maxinteger) -- component.invoke(fromAddress, "read", handle, math.huge or math.maxinteger)
|
||||||
data = data .. (tmpdata or "")
|
data = data .. (tmpdata or "")
|
||||||
|
|||||||
+28
-14
@@ -1,4 +1,5 @@
|
|||||||
local fs, computer
|
local fs, computer
|
||||||
|
local chunkSize = 1024
|
||||||
if require then
|
if require then
|
||||||
fs = require("filesystem")
|
fs = require("filesystem")
|
||||||
computer = require("computer")
|
computer = require("computer")
|
||||||
@@ -8,7 +9,9 @@ else
|
|||||||
computer = _G.computer
|
computer = _G.computer
|
||||||
end
|
end
|
||||||
|
|
||||||
logFileSizeLimit = 16384
|
local log = {}
|
||||||
|
|
||||||
|
local logFileSizeLimit = 16384
|
||||||
|
|
||||||
local function writeToLog(path, text)
|
local function writeToLog(path, text)
|
||||||
local handle
|
local handle
|
||||||
@@ -22,20 +25,30 @@ local function writeToLog(path, text)
|
|||||||
|
|
||||||
-- Log trimming if it gets too long
|
-- Log trimming if it gets too long
|
||||||
if fs.size(path) > logFileSizeLimit then
|
if fs.size(path) > logFileSizeLimit then
|
||||||
ocelot.log("Trimming log...")
|
|
||||||
local newlineCounter = 0
|
|
||||||
local sizeCounter = 0
|
local sizeCounter = 0
|
||||||
local readHandle = fs.open(path, "r")
|
local readHandle = fs.open(path, "r")
|
||||||
local chunkSize = 1024
|
local currentChunk = ""
|
||||||
readHandle:seek("end", -chunkSize)
|
readHandle:seek("end", -chunkSize)
|
||||||
repeat
|
repeat
|
||||||
local readText = readHandle:read(chunkSize)
|
currentChunk = readHandle:read(chunkSize)
|
||||||
readHandle:seek(-chunkSize * 2)
|
readHandle:seek(-chunkSize * 2)
|
||||||
local _, newlineCount = readText:gsub("\n", "\n")
|
|
||||||
newlineCounter = newlineCounter + newlineCount
|
|
||||||
sizeCounter = sizeCounter + chunkSize
|
sizeCounter = sizeCounter + chunkSize
|
||||||
until sizeCounter >= logFileSizeLimit * 0.75
|
until sizeCounter >= logFileSizeLimit * 0.75
|
||||||
readHandle:seek(chunkSize)
|
while true do
|
||||||
|
local infoEntry = currentChunk:find("INFO [", 1, true)
|
||||||
|
local warnEntry = currentChunk:find("WARN [", 1, true)
|
||||||
|
local errorEntry = currentChunk:find("ERROR [", 1, true)
|
||||||
|
if not infoEntry and not warnEntry and not errorEntry then
|
||||||
|
readHandle:seek(-chunkSize)
|
||||||
|
else
|
||||||
|
readHandle:seek(math.min(infoEntry or math.huge or math.maxinteger, warnEntry or math.huge or math.maxinteger,
|
||||||
|
errorEntry or math.huge or math.maxinteger) - 1)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
if readHandle:seek("cur") == 0 then -- Failsafe to prevent infinite loops
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
local writeHandle = fs.open(path, "w")
|
local writeHandle = fs.open(path, "w")
|
||||||
while true do
|
while true do
|
||||||
local tmpdata = readHandle:read(math.huge or math.maxinteger)
|
local tmpdata = readHandle:read(math.huge or math.maxinteger)
|
||||||
@@ -49,20 +62,21 @@ local function writeToLog(path, text)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local log = {}
|
|
||||||
|
|
||||||
setmetatable(log, {
|
setmetatable(log, {
|
||||||
["__index"] = function(tab, index)
|
["__index"] = function(_, index)
|
||||||
return {
|
return {
|
||||||
["logpath"] = fs.concat("/halyde/logs/", index .. ".log"),
|
["logpath"] = fs.concat("/halyde/logs/", index .. ".log"),
|
||||||
["info"] = function(text)
|
["info"] = function(text)
|
||||||
writeToLog(fs.concat("/halyde/logs/", index .. ".log"), "INFO [" .. computer.uptime() .. "] " .. text)
|
writeToLog(fs.concat("/halyde/logs/", index .. ".log"),
|
||||||
|
"INFO [" .. string.format("%.2f", computer.uptime()) .. "] " .. text)
|
||||||
end,
|
end,
|
||||||
["warn"] = function(text)
|
["warn"] = function(text)
|
||||||
writeToLog(fs.concat("/halyde/logs/", index .. ".log"), "WARN [" .. computer.uptime() .. "] " .. text)
|
writeToLog(fs.concat("/halyde/logs/", index .. ".log"),
|
||||||
|
"WARN [" .. string.format("%.2f", computer.uptime()) .. "] " .. text)
|
||||||
end,
|
end,
|
||||||
["error"] = function(text)
|
["error"] = function(text)
|
||||||
writeToLog(fs.concat("/halyde/logs/", index .. ".log"), "ERROR [" .. computer.uptime() .. "] " .. text)
|
writeToLog(fs.concat("/halyde/logs/", index .. ".log"),
|
||||||
|
"ERROR [" .. string.format("%.2f", computer.uptime()) .. "] " .. text)
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
end,
|
end,
|
||||||
|
|||||||
Reference in New Issue
Block a user