![]() |
Software > OpenVMS Systems > Ask the Wizard ![]() HP OpenVMS Systemsask the wizard |
![]() |
The Question is: How can I get the version of the C-compiler into a symbol in a DCL commandprocedure without explicit use of an intermediate (temporary) file? I have tried $ pipe cc/ver | read sys$pipe a $ pipe cc/ver | read sys$pipe a | b==a without success. If not possible (maybe because of underlying different command levels) is there a way to have a new temporary file assigned without explicitly having to name it? Another question. How can I get the expanded file spec. of a file opened by DCL OPEN/WRITE in order to be sure to delete only that file version after having closed the file (A command like close/delete which rms does support would have solved this problem ). Thanks The Answer is : You have correctly surmised that the problem here is that symbols defined in the PIPE subprocesses are not propagated back into the parent process. There is no way around that. However, there is a logical name table shared by all processes in the same job tree: the job logical name table LNM$JOB. Passing values back via the logical name table is thus feasible: $ PIPE CC/VERSION | (READ SYS$PIPE ver ; DEFINE/JOB/NOLOG ver &ver) Also note that the ampersand symbol substitution is required, as the more traditional apostrophe substitution pass performed by DCL has been completed prior to the execution of the PIPE command component. DCL attempts to substitute the symbol value when the command is first entered, rather than after it has been set by the READ command. If you really need to get the value into a symbol, you can add further commands after ";". You may also want to clean up, so the complete command is: $ PIPE CC/VERSION | - (READ SYS$PIPE ver ; DEFINE/JOB/NOLOG ver &ver ) ; - ver=F$TRNLNM("ver") ; DEASSIGN/JOB ver at the end of which you'll have a symbol "ver" set to the version string returned by the CC command. The same technique can, of course, be used to convert any single line output command (or indeed the first line of output from any command) into a symbol. The JOB logical name table size is limited by the process JTQUOTA. Your second question -- please, one question to a posting -- is more of a problem. There is no documented means for determining the file specification of a Process Permanent File (PPF) as created with the OPEN/WRITE command. Looking at the problem itself, there are obviously ways to deal with the issue of potential clashes of file names. Since you are deleting the file, you obviously don't really care what the filename is, and can therefore choose a name with a vanishingly small chance of a name clash. The OpenVMS Wizard would thus suggest a combination of a prefix, the PID and some portion of a timestamp. For example: $ FileName = "prefix$" +- F$GETJPI("","PID")+- F$EDIT(F$CVTIME(,,"DATETIME"),"COLLAPSE")-":"-":"-"." Since an OpenVMS Alpha system can generate a prodigious number of file names in a hundredth a second (the resolution of DATETIME), the truly paranoid programmer will add a further field to ensure all file names are really unique. Just make sure all generating code uses the same global symbol: $ FileNum = FileNum + 1 $ FileName = "prefix$" +- F$GETJPI("","PID") + f$fao("!8XL",FileNum) +- F$EDIT(F$CVTIME(,,"DATETIME"),"COLLAPSE")-":"-":"-"." You can then use the f$parse lexical function to fill in the various other fields in the filename as required: $ FileNum = FileNum + 1 $ FileName = "prefix$" +- F$GETJPI("","PID") + f$fao("!8XL",FileNum) +- F$EDIT(F$CVTIME(,,"DATETIME"),"COLLAPSE")-":"-":"-"." $ TmpDataName = f$parse("SYS$SCRATCH:.TMP",FileName) With a filename that is almost certainly unique, how to make sure that you have the correct version number? Rather than using OPEN/WRITE, use the CREATE command. For example: ... $ TmpDataName = f$parse("SYS$SCRATCH:.TMP",FileName) $ CREATE 'TmpDataName' $ FullFileSpec = F$SEARCH(TmpDataName) $ OPEN/APPEND TempFile 'FullFileSpec' application processing $ CLOSE TempFile $ DELETE 'FullFileSpec' There is obviously a timing window between the CREATE and the F$SEARCH, and it is possible that the file returned by F$SEARCH is not the one that was CREATEd. However, once we have successfully OPENed the file, we can be guaranteed that the DELETE command will delete the one we wrote to. This is a much tighter window than between the OPEN and CLOSE then DELETE in the simpler implementation. In the case of the timing window being triggered by having two processes execute the code simultaneously -- use of the PID in the file specification will prevent this -- one of the OPENs will fail with a file sharing violation. As an aside, note that the method of using CREATE and OPEN/APPEND, rather than OPEN/WRITE also allows control over the type of file created and other properties like protection. For example, when creating files which will be shared with other operating systems, it is often better to create STREAM files, than the default VFC files. For example: $ CREATE/FDL=SYS$INPUT:/PROT=(W:RE) 'FullFileSpec' RECORD FORMAT STREAM $ OPEN/APPEND out 'FullFileSpec' As mentioned, here is no direct means to back-translate a PPF to the file specification from within DCL. Back-translations from within an application module are rather easier. PPF channels can also be viewed via tools such as the SDA command SHOW PROCESS/CHANNEL. Another approach at this whole problem is rather more simplistic, simply retain the filename used for the OPEN for later use during the DELETE. The OpenVMS Wizard believes your suggestion for CLOSE/DELETE or CLOSE/DISPOSITION=(DELETE,PRINT,etc) is a good one, and the Wizard encourages you to contact your local Compaq Customer Support Centre directly, and formally request it. You may also want to ask for a new or enhanced DCL lexical function that generates a unique string suitable for use as a filename.
|