Accessing Open Files

Although SBX routines start with a fresh memory partition, they inherit the table of open files from their parent. This allows the subroutine to read and write to files that have been opened by the calling program. However, because of this, if you want to open and close files within the subroutine independently from the calling program, then you must be careful to use different file channel numbers.

It would probably be a good idea to adopt some systematic approach to the use of file channels, such as reserving file channels 60000-65000 for use within subroutines.

For sequential files (opened for INPUT, OUTPUT, or APPEND) no special techniques are needed to access the files opened outside of the subroutine. You can use PRINT #CH and INPUT #CH statements just as if you had opened the specified file channel (#CH) within the subroutine.

For random (contiguous) and ISAM files, however, the problem is that the file number variable, which was associated with the file when the file was opened, is only accessible from within the module that opened the file (i.e. the module that owns the record number variable.) So, in the case of random files, while you could access them, you could not change the record number (and thus would only be able to read and write whatever record was last accessed in the calling module). In the case of ISAM-A files, you would be able to move around in the file because this is based on key operations, but you would not be able to get the status back for each operation. To surmount that obstacle, you can call a special MIAMEX function to associate a new record-number variable (and in the case of ISAM, a status variable) with the file:

xcall MIAMEX, MX_FLSET, ch, status, recvar'adr {,statvar'adr}

This function assigns a new (local) record number variable and optionally, ISAM-A status variable, with the file opened by the calling program on channel CH. Note that the parameters have to be mapped in a specific way; see MX_FLSET for details.

Once you successfully execute the MX_FLSET operation, you can have full access to the RANDOM, ISAM, or ISAM-A file within the subroutine.

Comments

See XREAD, XWRITE, XUNLOKR for an alternative which avoids the need for MX_FLSET.

Don’t forget that the record number and ISAM status variables to be used within the subroutines are the ones whose address(es) you pass to the MX_FLSET subroutine, and not the ones that were originally used in the calling program. Otherwise, you may appear to be reading and writing the file normally within the subroutine, but you will either be reading and writing the same record over and over again (i.e. the last one accessed by the calling program) or in the case of ISAM-A, you will be accessing the file but never getting any valid status results back. (Every key operation would return 0 for ISAM’EQ, since the real return value would be sent to the variable in the calling program.)

Also, be careful of FILEBASE. You may safely ignore this for ISAM-A files where you may never explicitly use the record number, but for RANDOM files, you would ideally want to make sure that the subroutine was written to use the same FILEBASE as the calling program. But unfortunately there is no way to guarantee this. The effective FILEBASE is the one that was in effect when the file was opened; there is no way for the subroutine to override this other than closing and reopening the file.

A-Shell automatically resets the record number and ISAM status variables to their original values on return from a subroutine call, so it is not necessary for the calling program (even if it is itself an SBX routine) to worry about what the subroutine may have done to its file control variables.