Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!seismo!rutgers!ucla-cs!zen!ucbvax!CITHEX.CALTECH.EDU!carl From: carl@CITHEX.CALTECH.EDU Newsgroups: comp.os.vms Subject: Re: Command input from a file continued, and maybe a bug in VMS Message-ID: <870807141508.03n@CitHex.Caltech.Edu> Date: Fri, 7-Aug-87 17:15:08 EDT Article-I.D.: CitHex.870807141508.03n Posted: Fri Aug 7 17:15:08 1987 Date-Received: Sun, 9-Aug-87 13:27:54 EDT Sender: daemon@ucbvax.BERKELEY.EDU Distribution: world Organization: The ARPA Internet Lines: 62 > Several fellow netpeople pointed mo towards the LIB$SET_LOGICAL routine, > which seems to do what i want: assign SYS$INPUT or SYS$OUTPUT to a file > (instead of the terminal) for a while while the programs runs. Unfortunately, > i found some quite strange behaviour. Look at the following short FORTRAN > program. It should read one line from the terminal, print it, and then > redirect SYS$INPUT to the file INPUT.FILE, read one line from there, print it, > and exit: > > PROGRAM MINITEST ! mini version without loops or error handling > > IMPLICIT NONE > CHARACTER INPUT*80 > INTEGER LENGTH, STATUS > > INTEGER LIB$GET_INPUT, LIB$SET_LOGICAL > EXTERNAL LIB$GET_INPUT, LIB$SET_LOGICAL > INCLUDE '($RMSDEF)' ! not yet needed, for recognizing EOFs later > > STATUS = LIB$GET_INPUT(INPUT, 'From Terminal: ', LENGTH) > IF (.NOT.STATUS) CALL LIB$SIGNAL(%VAL(STATUS)) > PRINT *, 'Input from terminal was ', INPUT(1:LENGTH) > > STATUS = LIB$SET_LOGICAL('SYS$INPUT', 'INPUT.FILE') > IF (.NOT.STATUS) CALL LIB$SIGNAL(%VAL(STATUS)) > > STATUS = LIB$GET_INPUT(INPUT, 'From File: ', LENGTH) > IF (.NOT.STATUS) CALL LIB$SIGNAL(%VAL(STATUS)) > PRINT *, 'Input from file was ', INPUT(1:LENGTH) > > STOP > END > > Well, it does the following: > - it reads one line from the terminal and prints it > - it does reassign SYS$INPUT to INPUT.FILE (you can check it by inserting > a call to LIB$SYS_TRNLOG('SYS$INPUT'... after the assign) > - it reads ANOTHER LINE FROM THE TERMINAL and prints it ! > - Now, back at DCL, a SHOW TRANS SYS$INPUT will yield INPUT.FILE (obviously), > so i try running the program again: > - it reads the first line from the file (obviously) and prints it > - it reads the second line from the file (still obvious) and prints it. > All variations of the program (like read many lines instead of one, check > for EOFs and such, which i ommited here for the sake of brevity) seem > completely consistent: what counts for LIB$INPUT is not the translation of > SYS$INPUT at the time you call it, but AT THE TIME THE PROGRAM WAS INVOKED. > If SYS$INPUT points to the terminal at the beginning of the program, all > the LIB$SET_LOGICALS can't change the mind of LIB$GET_INPUT. > > The only question it: why is this so ? What use is LIB$SET_LOGICAL in this > case ? Is this a bug ? Should i SPR it ? Am i stupid ? Is there something > tricky (maybe using the right logical name table) i overlooked ? The reason is that the first and only the first call to LIB$GET_INPUT assigns a channel to SYS$INPUT:; all subsequent calls use that channel. If you were to comment out the first call to LIB$GET_INPUT, you'd find that the program would read from the file on the first invocation. I don't know how to force the routine to deassign the channel though, and you really wouldn't want them to, since when you reopened the channel to the original SYS$INPUT, you'd start reading at the beginning again. In summary, this is not a bug, but rather an implementation that does what you'd normally want it to do most of the time.