475 posts
Posted 18 July 2013 - 07:06 PM
Hi everyone! :D/>
I'm trying to create a function that replaces fs.open but even if I strip it down to very basic code, it still doesn't work. After running this, when I use any FS function it has a java out of bounds error.
old = fs
function test(path, mode)
han = old.open(path, mode)
return han
end
fs.open = test
Any help is appreciated! Thank you in advanced :)/>
1522 posts
Location
The Netherlands
Posted 18 July 2013 - 07:21 PM
However I cant seem to reproduce, I suggest 'direct overwriting'
For example:
local _fs.open = fs.open
fs.open = function( path, mode )
local han = _fs.open( path, mode )
return han
end
I know it! You are creating a pointer to fs, not the actual table. So you are actually doing recursion.
I figured out a way how to avoid it:
local test = {}
for k, v in pairs( _G["fs"] ) do
test[k] = v
end
fs.open = function( mode, path )
local han = test.open( mode, path )
return han
end
print( fs.isDir("rom") )
local t = fs.open( "test", "w")
t.write( "qw" )
t.close()
475 posts
Posted 18 July 2013 - 07:29 PM
However I cant seem to reproduce, I suggest 'direct overwriting'
For example:
local _fs.open = fs.open
fs.open = function( path, mode )
local han = _fs.open( path, mode )
return han
end
I know it! You are creating a pointer to fs, not the actual table. So you are actually doing recursion.
I figured out a way how to avoid it:
local test = {}
for k, v in pairs( _G["fs"] ) do
test[k] = v
end
fs.open = function( mode, path )
local han = test.open( mode, path )
return han
end
print( fs.isDir("rom") )
local t = fs.open( "test", "w")
t.write( "qw" )
t.close()
Ah ok I see. Thanks a lot! :)/>
475 posts
Posted 19 July 2013 - 06:17 PM
Ok so I tried the code again this time modifying somethings but I keep getting the Java out of bounds error. The full code had some other things but I stripped it down to basic idea but it doesn't work
oldFS = {}
for k, v in pairs(_G["fs"]) do
oldFS[k] = v
end
fs.open = function(path, mode)
local fsHandle = oldFS.open(path, mode)
local fsClose = fsHandle.close
local function close()
return fsHandle.close()
end
fsHandle["close"] = close
return fsHandle
end
print( fs.isDir("rom") )
local t = fs.open( "test", "w")
t.write( "qw" )
t.close()
504 posts
Location
Seattle, WA
Posted 19 July 2013 - 07:09 PM
You're calling close recursively on the handle you're returning.
You define the function close to call fsHandle.close, then set the close function to the one you just defined, thus overwriting the original close function. Once you call close, it will keep trying to call itself and create a call stack which overflows because there are too many levels (never ending).
Try this:
local oldFs = {}
for functionName, _function in pairs (_G["fs"]) do
oldFs[functionName] = _function
end
function _G["fs"].open (path, mode)
-- Insert your other code here, if you want.
-- Here is a test: if the file is a directory, then
-- throw a huge fit about it... Hehe...
if oldFs.isDir (path) then
error ("What the hell are you thinking? Trying to open a directory... Dumbass...")
end
-- Things worked out? Return a handle using the original fs API.
return oldFs.open (path, mode)
end
1604 posts
Posted 19 July 2013 - 07:23 PM
You don't need to copy the whole fs api, just the open function:
local oldFsOpen = fs.open
function fs.open(path, mode)
local handle = oldFsOpen(path, mode)
-- do whatever you want now
return handle
end
475 posts
Posted 19 July 2013 - 08:18 PM
So how can I override the close function in fs.open without causing stack overflow?
EDIT: Never mind figured it out. Thanks for the help guys! :)/>
1522 posts
Location
The Netherlands
Posted 21 July 2013 - 07:02 AM
However this is solved and such, I want to point out that there is another where to back-up some API's. It is very easy:
local oldFS = setmetatable( {}, { __index = _G["fs"] } )
It is way quicker and just one line :)/>
The only thing is, you cant loop through the table and get the keys, because it is a metatable.