[comp.os.vms] Fortran write sharing

heselton@admin.okanagan.bcc.CDN.UUCP (04/16/87)

Recently someone asked if there was a way for a fortran program to write
to a shared file and have other users read that information without the
fortran program having to close the file after the data was written.  I
apologize for sending this responce to info-vax, but I deleted the message
I am responding to before I thought about it (reflex action), so who ever
you were, I think this should do the trick.

The reason your other users cannot type the file is because RMS is smart
enough to buffer i/o and only write to disk when its buffers are full, in
order to have the data written to disk after each fortran write, you must
tell RMS to flush its buffers.  The following are two pieces of code to
do just what you want.  The first TEST.FOR was my program to make sure I
wasn't just shoveling kaka, the second is a set of macro routines to do
what you want.

	FLUSH_OPEN	- Fortran useropen routine to open a file
	FLUSH_CREATE	-    "        "       "    to create a new file
	FLUSH		- Flushes rms i/o buffers

There are separate open and create routines because fortran will not 
actually perform the RMS open for you if you specify a useropen routine.

	open - opens
	create - creates


Mike Heselton
Programmer/Analyst
Okanagan College
Kelowna, B.C., Canada.
V1Y 4X8


------------------Begin Test.for------------------------------------------------
	PROGRAM TEST
C
	INTEGER*4 FLUSH, FLUSH_CREATE
	EXTERNAL  FLUSH, FLUSH_CREATE
C
 	OPEN(UNIT=1,NAME='TEST.DAT',SHARED,STATUS='NEW',USEROPEN=FLUSH_CREATE)
C
	DO I=1,10000000
	   WRITE(1,100) I
	   CALL FLUSH(1)
	END DO
C
10	GOTO 10
C
100	FORMAT(' ',Z8.8)
	END
---------------------End Test.for-----------------------------------------------
---------------------Begin Flush.mar--------------------------------------------
	.title	flush

;+
; fortran flush routines
;-

;
; useropen routine to open a file and save the rab addresses
;
; define argument list offsets
;

	faboff	= 4
	raboff	= 8
	lunoff	= 12

	.entry	flush_open,^m<>

	$open	fab=@faboff(ap)			; open the file
	blbc	r0,10$				; return on error
	$connect rab=@raboff(ap)		; connect to file
	blbc	r0,10$				; return on error
	movl	@lunoff(ap),r1			; logical unit number
	movl	raboff(ap),flush_rab_addr[r1]	; save rab address
10$:	ret					; return

;
; useropen routine to create a file and save the rab addresses
;
	.entry	flush_create,^m<>

	$create	fab=@faboff(ap)			; open the file
	blbc	r0,10$				; return on error
	$connect rab=@raboff(ap)		; connect to file
	blbc	r0,10$				; return on error
	movl	@lunoff(ap),r1			; logical unit number
	movl	raboff(ap),flush_rab_addr[r1]	; save rab address
10$:	ret					; return

;
; flush routine
;
; calling sequence
;
;	status = flush(lun)
;
; define argument list offsets
;

	lunoff	= 4

	.entry	flush,^m<>

	movl	@lunoff(ap),r0			; logical unit number
	movl	flush_rab_addr[r0],r1		; rab address
	$flush	rab=(r1)			; flush the file
	ret					; return

;
; fortran common area to hold rab address for each channel
;

	.psect	flush_rab_addr,pic,ovr,rel,gbl,shr,noexe,rd,wrt,long

flush_rab_addr::
	.blkl	100				; actual length set by caller

	.end

-------------------------End Flush.mar------------------------------------------