DIGITAL Fortran 90
User Manual for

Previous Contents Index File Sharing

Depending on the value specified by the ACTION (or READONLY) specifier in the OPEN statement, the file will be opened by your program for reading, writing, or both reading and writing records. This simply checks that the program itself executes the type of statements intended.

For performance reasons, record-locking and shared-file checking are not supported by the current version of DIGITAL Fortran 90 on DIGITAL UNIX systems. When you open the file, access is always granted, regardless of whether:

Similarly, the UNLOCK statement is ignored using the current version of DIGITAL Fortran 90.

You might open a file for writing records (or reading and writing records) and know another process might simultaneously have the file open and be writing records. In this case, you need to coordinate access times among those processes to handle the possibility of simultaneous WRITE and REWRITE statements on the same record positions.

7.6.3 Specifying the Initial Record Position

When you open a disk file, you can use the OPEN statement's POSITION specifier to request one of the following initial record positions within the file:

The following I/O statements allow you to change the current record position:

Unless you use nonadvancing I/O (see Section 7.6.4), reading and writing records usually advances the current record position by one record. As discussed in Section 7.6.5, more than one record might be transferred using a single record I/O statement.

7.6.4 Advancing and Nonadvancing Record I/O

After you open a file, if you omit the ADVANCE specifier (or specify ADVANCE='YES') in READ and WRITE statements, advancing I/O (normal FORTRAN-77 I/O) will be used for record access. When using advancing I/O:

You can request nonadvancing I/O for the file by specifying the ADVANCE='NO' specifier in a READ and WRITE statement. You can use nonadvancing I/O only for sequential access to external files using formatted I/O (not list-directed or namelist).

When you use nonadvancing I/O, the current record position does not change, and part of record might be transferred, unlike advancing I/O where one entire record or records are always transferred.

You can alternate between advancing and nonadvancing I/O by specifying different values for the ADVANCE specifier ('YES' and 'NO') in the READ and WRITE record I/O statements.

When reading records with either advancing or nonadvancing I/O, you can use the END branch specifier to branch to a specified label when the end of the file is read.

Because nonadvancing I/O might not read an entire record, it also supports an EOR branch specifier to branch to a specified label when the end of the record is read. If you omit the EOR and the IOSTAT specifiers when using nonadvancing I/O, an error results when the end-of-record is read.

When using nonadvancing input, you can use the SIZE specifier to return the number of characters read. For example, in the following READ statement, SIZE=X (where variable X is an integer) returns the number of characters read in X and an end-of-record condition causes a branch to label 700:

  150 FORMAT (F10.2, F10.2, I6) 
      READ (UNIT=20, FMT=150, SIZE=X, ADVANCE='NO', EOR=700) A, F, I 

7.6.5 Record Transfer

I/O statements transfer all data as records. The amount of data that a record can contain depends on the following circumstances:

Typically, the data transferred by an I/O statement is read from or written to a single record. It is possible, however, for a single I/O statement to transfer data from or to more than one record, depending on the form of I/O used. Input Record Transfer

When using advancing I/O, if an input statement specifies fewer data fields (less data) than the record contains, the remaining fields are ignored.

If an input statement specifies more data fields than the record contains, one of the following occurs: Output Record Transfer

If an output statement specifies fewer data fields than the record contains (less data than required to fill a record), the following occurs:

If the output statement specifies more data than the record can contain, an error occurs, as follows:

For More Information:

7.7 User-Supplied OPEN Procedures: the USEROPEN Specifier

You can use the USEROPEN specifier in a DIGITAL Fortran 90 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 DIGITAL Fortran 90 I/O statements.

The DIGITAL Fortran 90 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 DIGITAL Fortran 90 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 DIGITAL Fortran 90 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 DIGITAL Fortran 90 program, the function must be declared in an EXTERNAL statement. For example, the following DIGITAL Fortran 90 code might be used to call the USEROPEN procedure UOPEN (known to the linker as 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 DIGITAL Fortran 90 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 DIGITAL Fortran 90 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 DIGITAL Fortran 90 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 DIGITAL Fortran 90 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 DIGITAL Fortran 90 program, which can do I/O with Fortran 90 statements to the file.

The open system call returns the file descriptor, which must be returned as a 4-byte integer to the DIGITAL Fortran 90 program (and DIGITAL Fortran 90 RTL). After control (and the file descriptor) is returned from the called function, the main DIGITAL Fortran 90 program can perform I/O to that logical unit with Fortran 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 DIGITAL Fortran 90 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 DIGITAL Fortran 90 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 DIGITAL Fortran 90 RTL uses exactly one file descriptor per logical unit, which must be returned by the called function. Because of this, only certain DIGITAL 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 DIGITAL Fortran 90 code calls the USEROPEN function named UOPEN:


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 DIGITAL Fortran 90 Programs

Use a single f90 command to compile the called uopen_ C function uopen_.c and the DIGITAL Fortran 90 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*/ 
/* End of file uopen.h */ 
** File: uopen_.c 
** This routine opens a file using data passed by DIGITAL Fortran 90 RTL. 
#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 DIGITAL 
**   Fortran 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 | 
       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 DIGITAL Fortran 90 Program

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

Example 7-2 DIGITAL Fortran 90 USEROPEN Main Calling Program

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. 
     EXTERNAL    UOPEN         ! The USEROPEN function. 
 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, & 
     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, & 
     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.' 
   9 WRITE (6,*) 'EX1.  Error on USEROPEN is ', errnum 
  99 WRITE (6,*) 'EX1.  Error on 2nd open is ', errnum 

7.8 Format of DIGITAL Fortran 90 Record Types

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

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

Previous Next Contents Index