Filing systems and closing EXEC files

bbc micro/electron/atom/risc os coding queries and routines
Post Reply
Coeus
Posts: 1659
Joined: Mon Jul 25, 2016 12:05 pm
Contact:

Filing systems and closing EXEC files

Post by Coeus » Mon Jul 13, 2020 11:48 pm

A question about correct filing system behaviour. If an EXEC file is open and the filing system on which the file is located receives a request to close that file via OSFIND with A=0, should it be doing anything to stop the OS trying to read that file as an EXEC file, for example by calling OSBYTE A=&C6? What about ROM service call &10 - should the filing system being asked to close the file issue that or does the OS? Does it make any difference if OSFIND is called with Y set to a specific file handle or with Y=0 for close all files?

tom_seddon
Posts: 409
Joined: Tue Aug 30, 2005 12:42 am
Contact:

Re: Filing systems and closing EXEC files

Post by tom_seddon » Tue Jul 14, 2020 1:23 am

BeebLink tries to do a close spool/exec handle osbyte $77 when the spool or exec file handle is being closed: https://github.com/tom-seddon/beeblink/ ... .s65#L3123

It doesn't do this on receipt of a close #0 - pretty sure this is a bug that needs fixing...

It used to close the spool/exec handles on every CLOSE# - this is arguably wrong, but didn't cause any obvious problems with any software I've tried. Can't remember what prompted this change? - the commit message isn't as thorough as it should be (https://github.com/tom-seddon/beeblink/ ... ff3b54db6a), so I don't remember exactly what I was seeing and why I thought this might help.

EDIT: how does this even work though?! OSFIND calls OSBYTE $77, and OSBYTE $77 calls OSFIND again... to close the same handle? I wonder how/why this works. Maybe this is the Master's OS being cleverer, and maybe it won't work on a model B. Ugh. Perhaps what I should actually be doing is what you suggest - use the OSBYTEs you mention to just set the spool and/or exec handles to 0 as part of the closure.

--Tom

User avatar
sweh
Posts: 2191
Joined: Sat Mar 10, 2012 12:05 pm
Location: New York, New York
Contact:

Re: Filing systems and closing EXEC files

Post by sweh » Tue Jul 14, 2020 2:08 am

tom_seddon wrote:
Tue Jul 14, 2020 1:23 am
EDIT: how does this even work though?! OSFIND calls OSBYTE $77, and OSBYTE $77 calls OSFIND again... to close the same handle? I wonder how/why this works. Maybe this is the Master's OS being cleverer, and maybe it won't work on a model B. Ugh. Perhaps what I should actually be doing is what you suggest - use the OSBYTEs you mention to just set the spool and/or exec handles to 0 as part of the closure.
I don't think OSBYTE &77 directly closes the file handles; it tells the OS to close them, and the OS then calls OSFIND to close the filehandles it knows about; the original call to OSFIND would be to close#0 but the new call would be to close#<x> where <x> is non-zero.

I'd be worried about setting the filehandle to zero 'cos who knows what other flag the OS has open!

JGH's HostFS (and thus HostFS:UPURS) calls OSBYTE &77 when it sees a CLOSE#0 call.
Rgds
Stephen

tom_seddon
Posts: 409
Joined: Tue Aug 30, 2005 12:42 am
Contact:

Re: Filing systems and closing EXEC files

Post by tom_seddon » Tue Jul 14, 2020 2:31 am

sweh wrote:
Tue Jul 14, 2020 2:08 am
tom_seddon wrote:
Tue Jul 14, 2020 1:23 am
EDIT: how does this even work though?! OSFIND calls OSBYTE $77, and OSBYTE $77 calls OSFIND again... to close the same handle? I wonder how/why this works. Maybe this is the Master's OS being cleverer, and maybe it won't work on a model B. Ugh. Perhaps what I should actually be doing is what you suggest - use the OSBYTEs you mention to just set the spool and/or exec handles to 0 as part of the closure.
I don't think OSBYTE &77 directly closes the file handles; it tells the OS to close them, and the OS then calls OSFIND to close the filehandles it knows about.

I'd be worried about setting the filehandle to zero 'cos who knows what other flag the OS has open!

JGH's HostFS (and thus HostFS:UPURS) calls OSBYTE &77 when it sees a CLOSE#0 call.
Yes, it feels like OSBYTE $77 is the better bet, as presumably that entry point is there for a reason. Shame you have to close both handles at once, though.

Regarding the closure, judging from following through the OS 1.20 disassembly, OSBYTE $77 does end up calling OSFIND on the handles as part of the call. So, if your FS calls it partway through handling OSFIND, it'll get re-entered...

After following through the OS 1.20 disassembly a bit, it looks like there'll at least be no infinite loop. The OS sets its record of each handle to 0 before closing it, so a filing system that checks (as BeebLink does) will just see it as an ordinary handle the second time round. But what an FS should do, I think, is bail out early from its OSFIND handling if it called OSBYTE $77 due to being asked to close the SPOOL or EXEC handle specifically. It shouldn't carry on with the original OSFIND request and try to close that same handle a second time!

I think I need to go over BeebLink's handling of this stuff again... #-o

--Tom

User avatar
sweh
Posts: 2191
Joined: Sat Mar 10, 2012 12:05 pm
Location: New York, New York
Contact:

Re: Filing systems and closing EXEC files

Post by sweh » Tue Jul 14, 2020 2:36 am

I think that if the OS itself called "close#0" on a OSBYTE &77 then we'd have seen problems long before now.

I agree that it's a nice sanity check, but we don't always have the space and luxury and have to trust the OS.

I think if you're calling OSBYTE &77 as part of 'CLOSE#0' then you're good enough.

You probably should call that routine _early_ in the OSFIND CLOSE call though, so any recursive call won't cause data issues. JGH does

Code: Select all

\ Precheck OSFIND for CLOSE#0
\ ---------------------------
.HostFIND
        CMP #0
        BNE TubeFind            \ Not CLOSE
        CPY #0
        BNE TubeFind            \ Not CLOSE#0
        TXA
        PHA
        LDA #&77
        JSR OSBYTE              \ Close Exec and Spool files
        PLA
        TAX
        LDA #0
        TAY                     \ Restore for CLOSE#0
.TubeFind
        JMP MyosFIND
That's right at the beginning of the OSFIND call. Ignore the "TubeFind" label; it's... a consequence of Tube calling elsewhere and re-use of labels.
Rgds
Stephen

Coeus
Posts: 1659
Joined: Mon Jul 25, 2016 12:05 pm
Contact:

Re: Filing systems and closing EXEC files

Post by Coeus » Tue Jul 14, 2020 3:31 pm

Ok, so for VDFS (B-EM) I have implemented calling OSBYTE &77 on a close#0 (OSFIND A=0, Y=0) but have not, at least at the moment, checked if any handled closed explicitly happen to be the current EXEC or SPOOL file. See: https://github.com/stardot/b-em/commit/ ... 76c9611090

Coeus
Posts: 1659
Joined: Mon Jul 25, 2016 12:05 pm
Contact:

Re: Filing systems and closing EXEC files

Post by Coeus » Wed Jul 15, 2020 5:39 pm

So to add to my previous post, the bit of limited recursion here is interesting. In VDFS I am detecting that the specified handle (in Y) is zero in C code. Fortunately I have a mechanism to execute one of a number of 6502 fragments on demand without first returning to the caller so I do that to issue the OSWORD &77. That, in turn, will call OSFIND again which will end up back in the C code but this time with Y<>0 so the recursion is not infinite. So using the example from JGH, the spool/exec handles will get closed first via OSBYTE &77 and the that code calls back to the C for the rest of close#0.

On the point of doing anything special when OSFIND is called with A=0 AND Y<>0 and the handle is a SPOOL or EXEC handle, it seems neither DFS (as of 2.45) or ADFS (as of 2.03) do anything special here:
dfs.png
adfs.png
On the other hand these don't get stuck in a loop. With VDFS, when getting that "Channel" error because VDFS has closed all files but the OS still thought it had an EXEC file open, the error would occur repeatedly, i.e. the OS would try to read the EXEC file, that would generate the error, BASIC would print the error and go to read a line and the OS would then try to read the exec file again. I am beginning to wonder if there is a subtlety here like an EOF test on an invalid handle returning true rather than generating the "Channel" error?

Post Reply

Return to “programming”