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)