[mod.computers.vax] VMS, FORTRAN & CTRL-c AST

brown@wucs.UUCP.UUCP (11/07/86)

Problem:

	FORTRAN analysis system with embedded command interpreter.  Need to
be able to interrupt processing(computational and i/o) via a ctrl-c and
return to analysis system's command interpreter.  This worked in
VMS v3 using the sys$unwind mechanism invoked from a condition handler.
This doesn't work in VMS v4.(I've tried it on 4.0-4.4, I don't know what
versions of the FORTRAN system were installed in all cases)

The FORTRAN run time library is apparently left in some bizarre state if
a read or write is interrupted.  Any further i/o operation terminates the
program with some error (which varies depending on the operation).

Question:

	Is there some function I can call which will cause the FORTRAN run
time library to restore itself to a consistent state?

	Is this a bug or a feature?

	I rarely work on VMS now and would appreciate any info or pointers
to documents which might show a way around this problem.

	Regards,
	Mike Brown		Biomedical Computer Laboratory
				Institute for Biomedical Computing
				Washington University
				700 S. Euclid Avenue
				St. Louis, MO  63110
				(314) 362-2135

arpa:	brown%wucs.uucp@seismo.css.gov
uucp:	{ihnp4,...}!wucs!brown

HELLER%cs.umass.edu@RELAY.CS.NET (Stride 440 User) (11/14/86)

The problem is FORTRAN I/O is non-"atomic", that is a FORTRAN statement
like:

	accept 10,x,y,x

does not generate a single call to some FOR$blah routine, but in fact
something like 5 calls to FOR$blah routines.  This sequence is really a
"critical section" of sorts.  At least for you purposes it is.  If your ^C
handler bobs along in this critical section, you will end up with a pending
I/O operation on the unit number (-3 in the case of accept) associatiated
with the interupted I/O statement.  The next I/O request on that unit number
can't be processed, and fails with a recursive I/O operation.  That unit
number is now dead.  The only thing you can do now is exit back to DCL and
start over.  So much for FORTRAN I/O.

What you have to do is poll for ^C. Your ^C handler simply sets a logical
variable in a common block. This variable is tested at "reasonable" points
in the code, and a non-local exit is done at these points. (Probably by
doing a lib$signal with some made up signal which is caught by your
condition handler, which does a sys$unwind.

There is a routine called FOR$IO_END (something like that), but you can only
call this if there is an I/O operation in progress AND if you know the unit
# of the pending I/O. There is no universal "clean up any I/O, if any" type
function. Once a unit has been bashed with a "Recursive I/O operation", it
is completely dead, with no recovery posible. The only safe thing you can do
is the ^C polling method. Also, if you setup an out-of-band AST (like DCL's
^T) to report status, DON'T do FORTRAN I/O in it, use SYS$QIOW only, using
SYS$FAO(L) or C's sprintf, not FORTRAN's ENCODE to format the message
buffer(s).

		Robert Heller
       ARPANet:	Heller@UMass-CS.CSNET
	BITNET:	Heller@UMass.BITNET
	BIX:	Heller
	GEnie:	RHeller
       FidoNet:	101/27 (Dave's Fido, Gardner MA)