Compaq Fortran
User Manual for
Tru64 UNIX and Linux Alpha Systems


Previous Contents Index

7.7 User-Supplied OPEN Procedures: the USEROPEN Specifier

You can use the USEROPEN specifier in a Compaq Fortran OPEN statement to pass control to a routine that directly opens a file. The called routine can use system calls or library routines to open the file and establish special context that changes the effect of subsequent Compaq Fortran I/O statements.

The Compaq Fortran Run-Time Library (RTL) I/O support routines call the USEROPEN function in place of the system calls usually used when the file is first opened for I/O. The USEROPEN specifier in an OPEN statement specifies the name of a function to receive control. The called function must open the file (or pipe) and return the file descriptor of the file when it returns control to the calling Compaq Fortran program.

When opening the file, the called function usually specifies options different from those provided by a normal OPEN statement.

You can obtain the file descriptor from the Compaq Fortran Run-Time Library (RTL) for a specific unit number with the getfd routine, described in getfd(3f).

Although the called function can be written in other languages (such as Fortran), C is usually the best choice for making system calls, such as open or create .

The USEROPEN specifier for the OPEN statement has the form:

USEROPEN = function-name

The function-name value represents the name of an external open function. In the calling Compaq Fortran program, the function must be declared in an EXTERNAL statement. For example, the following Compaq Fortran code might be used to call the USEROPEN procedure UOPEN (known to the linker as uopen_ ):


      EXTERNAL  UOPEN 
      INTEGER   UOPEN 
      . 
      . 
      . 
      OPEN (UNIT=10, FILE='/usr/test/data', STATUS='NEW', USEROPEN=UOPEN) 

After the OPEN statement, the uopen_ function receives control. The function opens the file, may perform other operations, and subsequently returns control (with the file descriptor) to the calling Compaq Fortran program.

If the USEROPEN function is written in C, declare it as a C function that returns a 4-byte integer (int) result to contain the file descriptor. For example:


int   uopen_ (                (1)
      char  *file_name,       (2)
      int   *open_flags,      (3)
      int   *create_mode,     (4)
      int   *lun,             (5)
      int   file_length);     (6)

The function definition and the arguments passed from the Compaq Fortran RTL are as follows:

  1. The function must be declared as a 4-byte integer (int).
  2. The first argument is the pathname (includes the file name) to be opened.
  3. The open flags are described in the header file /usr/include/sys/file.h or open(2).
  4. The create mode (protection needed when creating a file), is described in open(2).
  5. The logical unit number.
  6. The fifth (last) argument is the pathname length (hidden length argument of the pathname).

Of the arguments, the open system call (see open(2)) requires the passed pathname, the open flags (that define the type access needed, whether the file exists, and so on), and the create mode. The logical unit number specified in the Compaq Fortran OPEN statement is passed in case the called function needs it. The hidden length of the pathname is also passed.

When creating a new file, the create system call might be used in place of open (see create(2)). You can usually use other appropriate system calls or library routines within the called function; restrictions are listed in Section 7.7.1.

In most cases, the called function modifies the open flags argument passed by the Compaq Fortran RTL or uses a new value before the open (or create ) system call. After the called function opens the file, it must return control to the main Compaq Fortran program, which can do I/O with Fortran 95/90 statements to the file.

The open system call returns the file descriptor, which must be returned as a 4-byte integer to the Compaq Fortran program (and Compaq Fortran RTL). After control (and the file descriptor) is returned from the called function, the main Compaq Fortran program can perform I/O to that logical unit with Fortran 95/90 statements and eventually close it.

If the USEROPEN function is written in Fortran, declare it as a FUNCTION with an INTEGER (KIND=4) result, perhaps with an interface block. In any case, the called function must return the file descriptor as a 4-byte integer to the calling Compaq Fortran program.

If your application requires that you use C to perform the file open and close, as well as all record operations, call the appropriate C procedure from the Compaq Fortran program without using the Fortran OPEN statement. For more information on calling between Fortran and C, see Section 11.4.

7.7.1 Restrictions of Called USEROPEN Functions

The Compaq Fortran RTL uses exactly one file descriptor per logical unit, which must be returned by the called function. Because of this, only certain Compaq Tru64 UNIX system calls or library routines can be used to open the file.

System calls and library routines that do not return a file descriptor include mknod (see mknod(2)) and fopen (see fopen(3)). For example, the fopen routine returns a file pointer instead of a file descriptor.

7.7.2 Example USEROPEN Program and Function

The following Compaq Fortran code calls the USEROPEN function named UOPEN:


  EXTERNAL  UOPEN 
  INTEGER   UOPEN 
    . 
    . 
    . 
  OPEN (UNIT=1,FILE='ex1.dat',STATUS='NEW',USEROPEN=UOPEN, ERR=9,IOSTAT=errnum) 

If the default f90 options are used, the external name is passed using lowercase letters with an appended trailing underscore (_). In the preceding example, the external function UOPEN would be known as uopen_ to the linker and must be declared in C as uopen_. The function might be given the file name uopen_.c .

Compiling and Linking the C and Compaq Fortran Programs

Use a single f90 command to compile the called uopen_ C function uopen_.c and the Compaq Fortran calling program ex1.f . The same command also links both object files by using the appropriate libraries to create the file a.out file, as follows:


% f90 ex1.f uopen_.c

If appropriate for large applications, you can specify object modules ( .o files) on the f90 command line. For more information on retaining object files, see Section 2.1.6.

Source Code for the C Function and Header File

Example 7-1 shows the C language function called uopen_ and its associated header file.

Example 7-1 C Function Called by USEROPEN Procedure

/* 
** File: uopen.h -- header file for uopen_.c 
*/ 
 
#ifndef UOPEN 
#define UOPEN 1 
 
/* 
** 
**    Function Prototypes 
** 
*/ 
int   uopen_ ( 
      char  *file_name,    /* access read: name of the file to open. */ 
      int   *open_flags,   /* access read: READ/WRITE, see file.h or open(2)*/ 
      int   *create_mode,  /* access read: set if new file (to be created).*/ 
      int   *lun,          /* access read: logical unit file opened on.*/ 
      int  file_length);   /* access read: number of characters in file_name*/ 
 
#endif 
 
/* End of file uopen.h */ 
 
 
/* 
** File: uopen_.c 
*/ 
 
/* 
** This routine opens a file using data passed by Compaq Fortran RTL. 
** 
**  INCLUDE FILES 
*/ 
 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <sys/file.h> 
#include "uopen.h"/* Include file for this module */ 
 
int uopen_ (file_name, open_flags, create_mode, lun, file_length) 
 
/* 
** Open a file using the parameters passed by the calling Compaq 
**   Fortran 95/90 program. 
** 
**  Formal Parameters: 
*/ 
 
char  *file_name;    /* access read: name of the file to open. */ 
int   *open_flags;   /* access read: READ/WRITE, see file.h */ 
int   *create_mode;  /* access read: set if new file (to be created). */ 
int   *lun;          /* access read: logical unit number file opened on. */ 
int   file_length;   /* access read: number of characters in file_name. */ 
 
/* 
**  Function Value/Completion Code 
** 
** Whatever is returned by open, is immediately returned to the 
** Fortran OPEN.  the returned value is the following : 
**    value >= 0 is a valid fd. 
**    value <  0 is an error. 
** 
**  Modify open flags (logical OR) to specify the file be opened for 
**  write access only, with records appended at the end (such as 
**  writing to a shared log file). 
*/ 
 
{ 
       int    result ;           /* Function result value */ 
 
       *open_flags =                 
             O_CREAT  | 
             O_WRONLY | 
             O_APPEND; 
     
       result = open (file_name, *open_flags, *create_mode) ; 
 
       return (result) ;         /* return file descriptor or error */ 
 
       }/* End of routine uopen_ */ 
 
       /* End of file uopen_.c */ 

Source Code for the Calling Compaq Fortran Program

Example 7-2 shows the Fortran 95/90 program that calls the uopen_ C function and then performs I/O.

Example 7-2 Compaq Fortran USEROPEN Main Calling Program

 
C 
C  Program EX1 opens a file using USEROPEN and writes records to it. 
C  It closes and re-opens the file (without USEROPEN) and reads 10 records. 
 
 PROGRAM EX1 
 
     EXTERNAL    UOPEN         ! The USEROPEN function. 
     INTEGER     ERRNUM, CTR, I 
 
 1   FORMAT (I) 
 
     ERRNUM = 0 
 
     WRITE (6,*) 'EX1. Access data using formatted I/O.' 
     WRITE (6,*) 'EX1. Open file with USEROPEN and put some data in it.' 
     OPEN (UNIT=1, FILE='ex1.dat', STATUS='NEW', USEROPEN=UOPEN, ERR=9, & 
          IOSTAT=errnum) 
 
     DO CTR=1,10 
       WRITE (1,1) CTR 
     END DO 
 
     WRITE (6,*) 'EX1. Close and re-open without USEROPEN.' 
 
     CLOSE (UNIT=1) 
 
     OPEN (UNIT=1, FILE='ex1.dat', STATUS='OLD', FORM='FORMATTED', ERR=99, & 
          IOSTAT=errnum) 
 
     WRITE (6,*) 'EX1. Read and display what is in file.' 
 
     DO CTR=1,10 
        READ (1,1) i 
        WRITE (6,*) i 
     END DO 
 
     WRITE (6,*) 'EX1.  Successful if 10 records shown.' 
 
     CLOSE (UNIT=1,STATUS='DELETE') 
     STOP 
 
   9 WRITE (6,*) 'EX1.  Error on USEROPEN is ', errnum 
     STOP 
 
  99 WRITE (6,*) 'EX1.  Error on 2nd open is ', errnum 
 
 END PROGRAM EX1 

7.8 Format of Compaq Fortran Record Types

This section describes the format of the Compaq Fortran I/O record types in detail. The Compaq Fortran record types are as follows:

For general information on Compaq Fortran record types, see Section 7.4.3.

7.8.1 Fixed-Length Records

When you specify fixed-length records, all records in the file contain the same number of bytes. When you open a file that is to contain fixed-length records, you must specify the record size by using the RECL specifier. A sequentially organized file opened for direct access must contain fixed-length records, to allow the record position in the file to be computed correctly.

For relative files, the layout and overhead of fixed-length records depends on whether the program accessing the file was compiled with the -vms option or whether the -vms option was omitted:

Figure 7-1 shows the record layout of fixed-length records.

Figure 7-1 Fixed-Length Records


For More Information:

On the default value and size limit for fixed-length records, see the RECL specifier for the OPEN statement in the Compaq Fortran Language Reference Manual.

7.8.2 Variable-Length Records

Variable-length records can contain any number of bytes, up to a specified maximum record length, and only apply to sequential files. These records are generally prefixed and suffixed by four bytes of control information containing count fields. The 4-byte integer value stored in each count field indicates the number of data bytes (excluding overhead bytes) in that particular variable-length record.

The record layout of variable-length records appears in Figure 7-2.

Figure 7-2 Variable-Length Records


The count field of a variable-length record is available when you read the record by issuing a READ statement with a Q format descriptor. You can then use the count field information to determine how many bytes should be in an I/O list.

Files written with variable-length records by Compaq Fortran programs usually cannot be accessed as text files. Instead, use the Stream_LF record format for text files with records of varying length.

7.8.3 Segmented Records

A segmented record is a single logical record consisting of one or more variable-length, unformatted records in a sequentially organized disk file. Unformatted data written to sequentially organized files using sequential access is stored as segmented records by default.

Segmented records are useful when you want to write exceptionally long records but cannot or do not wish to define one long variable-length record, perhaps because virtual memory limitations can prevent program execution. By using smaller, segmented records, you reduce the chance of problems caused by virtual memory limitations on systems on which the program may execute.

For disk files, the segmented record is a single logical record that consists of one or more segments. Each segment is a physical record. A segmented (logical) record can exceed the absolute maximum record length (2.14 billion bytes), but each segment (physical record) individually cannot exceed the maximum record length.

To access an unformatted sequential file that contains segmented records, specify FORM= ' UNFORMATTED ' and RECORDTYPE= ' SEGMENTED ' when you open the file. Otherwise, the file may be processed erroneously.

As shown in Figure 7-3, the layout of segmented records consists of four bytes of control information followed by the user data.

Figure 7-3 Segmented Records


The control information consists of a 2-byte integer record size count (includes the two bytes used by the segment identifier), followed by a 2-byte integer segment identifier that identifies this segment as one of the following:
Identifier Value Segment Identified
0 One of the segments between the first and last segments.
1 First segment.
2 Last segment.
3 Only segment.

If the specified record length is an odd number, the user data will be padded with a single blank (one byte), but this extra byte is not added to the 2-byte integer record size count.

7.8.4 Stream File Data

A Stream file is not grouped into records and contains no control information. Stream files are used with CARRIAGECONTROL= ' NONE ' and contain character or binary data that is read or written only to the extent of the variables specified on the input or output statement.

The layout of a Stream file appears in Figure 7-4.

Figure 7-4 Stream File


7.8.5 Stream_CR and Stream_LF Records

A Stream_CR or Stream_LF record is a variable-length record whose length is indicated by explicit record terminators embedded in the data, not by a count. These terminators are automatically added when you write records to a stream-type file and are removed when you read records.

Each variety uses a different 1-byte record terminator:

The layout of Stream_CR and Stream_LF records appears in Figure 7-5.

Figure 7-5 Stream_CR and Stream_LF Records



Chapter 8
Run-Time Errors and Signals

This chapter contains information on the following topics:

During execution, your program may encounter errors or exception conditions. These conditions can result from any of the following:

The Compaq Fortran Run-Time Library (RTL) generates appropriate messages and takes action to recover from errors whenever possible.

8.1 Compaq Fortran Run-Time Library Default Error Processing

The Compaq Fortran RTL processes a number of errors that may occur during program execution. A default action is defined for each error recognized by the Compaq Fortran RTL. The default actions described throughout this chapter occur unless overridden by explicit error-processing methods.

The way in which the Compaq Fortran RTL actually processes errors depends upon the following factors:

How arithmetic exception conditions are reported and handled depends on the cause of the exception and how the program was compiled. Unless the program was compiled to handle exceptions, the exception might not be reported until after the instruction that caused the exception condition. The following f90 command options are related to handling errors and exceptions:

For More Information:

8.1.1 Run-Time Message Format

When errors occur during program execution (run time) of a scalar (nonparallel) program, the Compaq Fortran RTL issues diagnostic messages. These run-time messages have the following format:


forrtl: severity (nnn): message-text

Run-time messages provide the following information:
Contents Information Given
forrtl Identifies the source as the Compaq Fortran RTL.
severity The severity levels are: severe , error , warning , or info (abbreviation of information) (see Table 8-1).
nnn This is the message number, also the IOSTAT value for I/O statements.
message_text Explains the event that caused the message.

Table 8-1 explains the severity levels of run-time messages, in the order of greatest to least severity.

Table 8-1 Severity Levels of Run-Time Messages
Severity Description
severe Must be corrected. The program's execution is terminated when the error is encountered, unless the program's I/O statements use the END, EOR, or ERR branch specifiers to transfer control, perhaps to a routine that uses the IOSTAT specifier (see Section 8.2.1 and Section 8.2.2).
error Should be corrected. The program might continue execution, but the output from this execution may be incorrect.
warning Should be investigated. The program continues execution, but output from this execution may be incorrect.
info For informational purposes only; the program continues.

If you have installed the Parallel Software Environment and compiled a program for parallel execution, additional messages specific to parallel HPF execution may appear. These messages are described in the Compaq Parallel Software Environment documentation.

8.1.2 Message Catalog Location

The Compaq Fortran RTL uses a message catalog file to store the text associated with each run-time message. When a run-time error occurs, the Compaq Fortran RTL uses the environment variable NLSPATH to locate the message catalog file, from which it obtains the text of the appropriate message. If the file is not found at the position indicated by NLSPATH, the RTL searches for the message catalog at the following location:

/usr/lib/nls/msg/en_US.ISO8859-1/for_msg.cat (TU*X ONLY)
/usr/lib/for_msg.cat (L*X ONLY)

Before executing a Compaq Fortran program on a system where Compaq Fortran is not installed, you need to install the appropriate Compaq Fortran run-time subset. For instructions on installing Compaq Fortran run-time support, see the Compaq Fortran Installation Guide for Tru64 UNIX Systems.

When a run-time error occurs on a system where the message file is not found, the following messages may appear on a Tru64 UNIX system:


forrtl: info: Fortran error message number is nnn. 
 
forrtl: warning: Could not open message catalog: for_msg.cat. 
 
forrtl: info: Check environment variable NLSPATH and protection of 
              usr/lib/nls/msg/en_US.ISO8859-1/for_msg.cat 

The Compaq Fortran RTL returns an error number (displayed after the severity level) that the calling program can use with an IOSTAT variable to handle various I/O conditions, as described in Section 8.2.2.

For more information on NLSPATH, refer to environ(5).


Previous Next Contents Index