Sometimes it is desired to take corrective action if a routine returns a particular bad status value, and section contains an example of how you might do this. Unfortunately there is a problem with testing FIO/RIO status values that does not occur with most other packages.
FIO/RIO can generate two sorts of error codes. Firstly there are internal FIO/RIO codes. There is no problem testing for these. Secondly there are codes that are a translation of a FORTRAN IOSTAT value. It is these status codes that gives rise to the problem as such values are inherently machine specific, thus making it very difficult to write portable applications that test for bad status values. It might be thought that the things that could go wrong with FORTRAN I/O were sufficiently similar from one machine to another, that a common set of error codes could be devised, but surprisingly this is not the case in practice. The list of error codes that can be returned as IOSTAT values are very different from one machine to another. Even when it looks like two errors on different machines will be equivalent in practice, this does not always turn out to be the case.
On account of these difficulties, FIO/RIO adopts the following strategy:
If the text of an error message in the computer manufacturer's documentation is the same for two different machines, then FIO/RIO will return the same status value on those two machines. Otherwise different status values are returned on the different machines.
This strategy is applied quite rigorously, even when, at first sight, it looks like two error messages might be equivalent. The only exception at present is that `Cannot stat file' (on Ultrix) and `can't stat file' (on SunOS) return the same error code. Not to do so smacks of pedantry of the highest order! This strategy has been chosen as a balance between returning unique error codes on all machines (which is barely any better than using the raw IOSTAT value) and trying to guess which error codes are equivalent to each other (with the likelihood of getting it wrong). Presumably if the text of two error messages are identical, then they are intended to apply to the same situation. Even this cannot be guaranteed, but it is the best one can do.
Occasionally, the Fortran run time system will return an IOSTAT value that corresponds to a operating system error rather than a Fortran error. In such a case, an error message describing the error will be generated and the status will be set to the value of the symbolic constant FIO__OSERR.
The strategy of only returning the same error number when the text of the message is the same definitely errs on the side of caution. It means that programs that are intended to be run on several different machines must often test for different error codes, one for each machine type. For example, it is quite common to test for FIO__FILNF (file not found) on VAX/VMS. Unfortunately, there is no error that corresponds sufficiently closely to this on SunOS. As well as being very tedious, it means that tests for bad status values in application programs probably need to be modified to run on a new computer. To minimize this problem, FIO/RIO provides the ability to test status values for classes of errors. This is best described by an example. Suppose that you have prompted a user for the name of an input file and you then try to open a file using the returned string. If the program fails to open the file, this might be for one of several reasons. It may be that the file does not exist, or that the file exists, but you do not have the right to access the file, or that the string typed in is not a valid file name (e.g. [PMA}TEST.DAT on VMS). In all of these situations, you can rely on the error reporting to tell the user what has gone wrong, but all the program cares about is that it has failed to open the file and that it should re-prompt the user. A program can test for a general class of errors by using the logical function FIO_TEST. This takes a character argument and a status value and returns TRUE if the value of STATUS is in the class of errors described by the character argument. Here is an example:
IF( FIO_TEST( 'OPEN error', STATUS ) ) THEN ... ENDIF
Note that FIO_TEST is not sensitive to the case of the character string given as its first argument. An example of attempting to open a file using FORTRAN I/O and then testing to see if this was successful is:
CALL ERR_MARK OPEN( UNIT=UNUM, FILE=FILNAM, STATUS='OLD', IOSTAT=ISTAT ) CALL FIO_REP( UNUM, FILNAM, ISTAT, ' ', STATUS ) * Test for `could not open file'. IF( FIO_TEST( 'OPEN error', STATUS ) ) THEN * Handle the error if we can. ... CALL ERR_ANNUL( STATUS ) END IF CALL ERR_RLSE
This example has used a FORTRAN OPEN statement in the application code. It is generally better to let FIO handle all file access as this makes for more portable code. (It is also less typing.) In this case, the above example would be written as:
CALL ERR_MARK CALL FIO_OPEN( FILNAM, 'UPDATE', 'LIST', 0, FD, STATUS ) IF( FIO_TEST( 'OPEN error', STATUS ) ) THEN * Handle the error if we can. ... CALL ERR_ANNUL( STATUS ) END IF CALL ERR_RLSE
A list of all the classes of errors that can be handled in this manner is given
in appendix . At present, the list of error classes is
fixed, but it is intended that users will be able to define their own error
classes in a future release of FIO/RIO.
FIO/RIO FORTRAN file I/O routines