USEROPEN Specifier

The USEROPEN specifier lets you pass control to a routine that directly opens a file. The file can use system calls or library routines to establish a special context that changes the effect of subsequent Fortran I/O statements.

The USEROPEN specifier takes the following form:

USEROPEN = function-name

function-name
Is the name of an external function.

The Visual Fortran Run-time Library (RTL) I/O support routines call the function named in USEROPEN in place of the system calls normally used when the file is first opened for I/O. On Win32 platforms, the Fortran RTL would normally call CreateFile( ) to open a file.

The called function must open the file (or pipe, etc.) using CreateFile( ) and return the handle of the file (return value from CreateFile( )) when it returns control to the calling Visual Fortran program. When opening the file, the called function usually specifies options different from those provided by a normal Fortran OPEN statement.

The main purpose of the function named in USEROPEN is to jacket a call to the CreateFile( ) Win32 api. The function can be written in Fortran, C, or other languages. If the function is written in Fortran, do not execute a Fortran OPEN statement to open the file named in USEROPEN.

Examples

In the calling Fortran program, the function named in USEROPEN must first be declared in an EXTERNAL statement. For example, the following Fortran code might be used to call the USEROPEN procedure UOPEN:

  IMPLICIT INTEGER (A-Z)
  EXTERNAL UOPEN
  ...
  OPEN(UNIT=10,FILE='UOPEN.DAT',STATUS='NEW',USEROPEN=UOPEN)

When the OPEN statement is executed, the UOPEN function receives control. The function opens the file by calling CreateFile( ), performs whatever operations were specified, and subsequently returns control (with the handle returned by CreateFile( )) to the calling Fortran program.

Here is what the UOPEN function might look like:

        INTEGER FUNCTION UOPEN( FILENAME,	&
				DESIRED_ACCESS,	&
				SHARE_MODE,	&
				A_NULL,		&
				CREATE_DISP,	&
				FLAGS_ATTR,	&
				B_NULL,		&
				UNIT,		&
				FLEN )
	!DEC$ ATTRIBUTES C, ALIAS:'_UOPEN' :: UOPEN
	!DEC$ ATTRIBUTES REFERENCE :: FILENAME
	!DEC$ ATTRIBUTES REFERENCE :: DESIRED_ACCESS
	!DEC$ ATTRIBUTES REFERENCE :: SHARE_MODE
	!DEC$ ATTRIBUTES REFERENCE :: CREATE_DISP
	!DEC$ ATTRIBUTES REFERENCE :: FLAGS_ATTR
	!DEC$ ATTRIBUTES REFERENCE :: UNIT

	USE DFWIN

	IMPLICIT INTEGER (A-Z)
	CHARACTER*(FLEN) FILENAME
	TYPE(T_SECURITY_ATTRIBUTES), POINTER :: NULL_SEC_ATTR

! Set the FILE_FLAG_WRITE_THROUGH bit in the flag attributes to CreateFile( )
! (for whatever reason)
	FLAGS_ATTR = FLAGS_ATTR + FILE_FLAG_WRITE_THROUGH

! Do the CreateFile( ) call and return the status to the Fortran rtl
	STS = CreateFile( FILENAME,		&
			  DESIRED_ACCESS,	&
			  SHARE_MODE,		&
			  NULL_SEC_ATTR,	&
			  CREATE_DISP,		&
			  FLAGS_ATTR,		&
			  0 )

	UOPEN = STS
	RETURN
	END

The UOPEN function is declared to use the cdecl calling convention, so it matches the Fortran rtl declaration of a useropen routine.

The following function definition and arguments are passed from the Visual Fortran Run-time Library to the function named in USEROPEN:

	INTEGER FUNCTION UOPEN( FILENAME,	&
				DESIRED_ACCESS,	&
				SHARE_MODE,	&
				A_NULL,		&
				CREATE_DISP,	&
				FLAGS_ATTR,	&
				B_NULL,		&
				UNIT,		&
				FLEN )
	!DEC$ ATTRIBUTES C, ALIAS:'_UOPEN' :: UOPEN
	!DEC$ ATTRIBUTES REFERENCE :: DESIRED_ACCESS
	!DEC$ ATTRIBUTES REFERENCE :: SHARE_MODE
	!DEC$ ATTRIBUTES REFERENCE :: CREATE_DISP
	!DEC$ ATTRIBUTES REFERENCE :: FLAGS_ATTR
	!DEC$ ATTRIBUTES REFERENCE :: UNIT

The first 7 arguments correspond to the CreateFile( ) api arguments. The value of these arguments is set according the caller's OPEN( ) arguments:

FILENAME
Is the address of a null terminated character string that is the name of the file.
DESIRED_ACCESS
Is the desired access (read-write) mode passed by reference.
SHARE_MODE
Is the file sharing mode passed by reference.
A_NULL
Is always null. The Fortran runtime library always passes a NULL for the pointer to a SECURITY_ATTRIBUTES structure in its CreateFile( ) call.
CREATE_DISP
Is the creation disposition specifying what action to take on files that exist, and what action to take on files that do not exist. It is passed by reference.
FLAGS_ATTR
Specifies the file attributes and flags for the file. It is passed by reference.
B_NULL
Is always null. The Fortran runtime library always passes a NULL for the handle to a template file in it's CreateFile( ) call.

The last 2 arguments are the Fortran unit number and length of the file name:

UNIT
Is the Fortran unit number on which this OPEN is being done. It is passed by reference.
FLEN
Is the length of the file name, not counting the terminating null, and passed by value.