This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
The Crazy Phoenix's profile picture

Changes to FS do not affect IO

Started by The Crazy Phoenix, 20 June 2015 - 07:34 AM
The Crazy Phoenix #1
Posted 20 June 2015 - 09:34 AM
I'm working on a VFS, but any change I make to the FS API does not affect the IO API, yet I'm overwriting _G.fs

Why do the changes not affect IO?
Edited on 20 June 2015 - 08:02 AM
Creator #2
Posted 20 June 2015 - 09:42 AM
It should affect it, except if IO makes a backup of fs, when loaded.
The Crazy Phoenix #3
Posted 20 June 2015 - 09:49 AM
Even if it did backup FS, my changes would take effect since after starting the VFS, I call "/rom/programs/shell" in an environment where shell is nil.

Btw it doesn't backup anyway
Edited on 20 June 2015 - 07:49 AM
InDieTasten #4
Posted 20 June 2015 - 09:57 AM
The fs api is kinda complicated. some of the functions depend on io, and some others are registered from java I think. Not entirely sure though.

But I'm pretty pretty sure, that io does not depend on fs, which is why your changes do not effect the io functions AFAIK


I was wrong with that^^
Edited on 20 June 2015 - 08:00 AM
Creator #5
Posted 20 June 2015 - 09:57 AM
IO is a wrapper for FS, not the other way around.
InDieTasten #6
Posted 20 June 2015 - 09:58 AM
I will take a look into the mod archive
The Crazy Phoenix #7
Posted 20 June 2015 - 10:04 AM
When the IO API is loaded, "_G.fs" is equal to my VFS API. Yet the IO API seems to still be able to call the native FS API.
InDieTasten #8
Posted 20 June 2015 - 10:10 AM
When the IO API is loaded, "_G.fs" is equal to my VFS API. Yet the IO API seems to still be able to call the native FS API.
You could try to set the fenv of io.open to conatain your vfs. That might work. But again, not sure

Otherwise you may want to just override IO too.
dan200 #9
Posted 20 June 2015 - 10:11 AM
The io API only calls the global "fs" table, and it doesn't cache any of the values. Perhaps you're running in an environ where "_G" has been replaced ?
Bomb Bloke #10
Posted 20 June 2015 - 10:11 AM
Er, where's the code we're supposed to be commenting on…?
InDieTasten #11
Posted 20 June 2015 - 10:11 AM
But yeah, I think theres something we are missing. I'm sure at some point a genious comes along, that has already done this before in the past and will post the solution in here. In the meanwhile you may want to post your source, so that this genious can tell exactly whats missing.

Ninja'd by dan200: Achievement get! :ph34r:/>
Edited on 20 June 2015 - 08:12 AM
The Crazy Phoenix #12
Posted 20 June 2015 - 10:59 AM
Here's the code I'm using.

Pastebin: fdKdmv13

Note: config is nil because it's set in another program.
Bomb Bloke #13
Posted 20 June 2015 - 11:27 AM
When the IO API is loaded, "_G.fs" is equal to my VFS API. Yet the IO API seems to still be able to call the native FS API.

The io API isn't loaded when you run "shell", if that's what you're thinking. It's loaded when bios.lua executes, back when the computer very first boots up. It isn't loaded again unless you specifically request it, which you don't.

I sorta get the impression you're thinking this:

local env = setmetatable({
  shell = nil,
  io = nil,
  -- etc

… somehow "unloads" shell and io from your resulting "env" table. Unfortunately, that won't work - these lines are attempting to unset values that were never set in the first place, so the resulting metatable will simply allow you to pull the original io table from _G, same as it would anyway. And the functions in that original io table are rigged to pull fs from the original _G, which is not where you're placing your custom fs table (as Dan correctly guessed).

(Also, bear in mind the "shell" table is never loaded into _G anyway - it's simply placed into the global table bios.lua used to os.run() shell when the computer booted up, by the shell script itself.)
MKlegoman357 #14
Posted 20 June 2015 - 11:28 AM
The problem is that you don't override the io API in any way, so it still uses the fs API it gets from the _G table. When you set an environment of a program to your custom environment it doesn't overwrite the _G table, thus _G.fs is not overriden. If you don't want to be overwriting the _G.fs table (so other programs would not be affected by the change) you can load the io API with the custom environment. os.loadAPI would not work here, so you'd need a custom version of it. If you open the bios.lua file you'll find the source code of os.loadAPI and can simply copy/paste and change it to use your custom environment.
Edited on 20 June 2015 - 09:30 AM
The Crazy Phoenix #15
Posted 20 June 2015 - 11:31 AM
MKlegoman read the os.run line in the program, you'll notice I set the environment of that program to env.

So, should I just os.loadAPI the IO API inside the VFS' rom?
Edit: Calling os.loadAPI("/rom/apis/io") at the start of "shell" doesn't work.
Edited on 20 June 2015 - 09:35 AM
MKlegoman357 #16
Posted 20 June 2015 - 11:34 AM
I did notice that, but you should be re-loading the io API with a custom os.loadAPI function to set the APIs environment to your custom 'env'.
The Crazy Phoenix #17
Posted 20 June 2015 - 11:37 AM
I don't need to create a custom os.loadAPI function since I can edit the rom in the VFS (as long as I'm outside of the VFS)

Also, reloading the IO API inside the VFS didn't work.
Bomb Bloke #18
Posted 20 June 2015 - 11:49 AM
Because the os.loadAPI() function is also rigged to use the original _G, as MKlegoman357 pointed out. It's defined by bios.lua, which, by the way, isn't present in the ROM directory structure - it's in assets/computercraft/lua, within the ComputerCraft mod archive.

Edit:

I've got a hunch that it might be easier to copy the pre-loaded io table's pointer, os.loadAPI() another copy (with the original copy of the os.loadAPI() function, don't worry about modifying it), then setfenv()'ing all the functions in the "backed up" io table to use your new environment. You could then include said io table in your new env table.

At least, I think that should work. I've not tried that sort of thing myself.
Edited on 20 June 2015 - 09:57 AM
The Crazy Phoenix #19
Posted 20 June 2015 - 12:17 PM
Actually Bomb Bloke, that's a good idea. I'm going to recursively set the environment of the os.loadAPI function

It worked! Thanks
Edited on 20 June 2015 - 10:37 AM