![]() |
![]() HP OpenVMS Systemsask the wizard |
![]() |
The Question is: I have routines code written in C and FORTRAN that use printf() and PRINT statements to issue messages to the user. I need to redirect these to a file. At program startup I introduced the statement: stdout = freopen("msgfile.dat", "w", stdout); This worked fine for the C-language routines, but the FORTRAN PRINT statements continued to send data to the user's terminal. As a second attempt to solve the problem, I got rid of the freopen statement, and issued a DCL statement before the run command, as follows: $ define/user SYS$OUTPUT msgfile.dat $ run app.exe This caused all the subsequent printf() statements to send their data to msgfile.dat;1, and all FORTRAN PRINT statements sent data to a different file, msgfile.dat;2. What's going on? The abstracted source code for the first attempted solution follows: File 1 [print.c]: #include <stdio.h> void printfor(); void printc(); main() { FILE *fp=NULL; stdout = freopen("msgfile.dat", "w", stdout); if (stdout == NULL) { printf("cannot reopen stdout\n"); exit(); } printc(); printfor(); } FILE 2 [printc.c]: #include <stdio.h> void printc(void) { printf(" hello from c function\n"); } FILE 3 [printfor.for]: C PRINTFOR.FOR SUBROUTINE PRINTFOR() print 25 25 format(' hello from FORTRAN subroutine') RETURN END I am using DEC C V6.0-001 and Digital Fortran 90 V7.1-330. Many thanks The Answer is : I/O is performed via independent language-specific RTLs -- one for FORTRAN, one for C. In this case, each RTL is opening its own channel and is unaware of the other, and this results in two files. Redirecting the output from a FORTRAN PRINT command can be done by defining the logical name FOR$PRINT. For example: $ DEFINE/USER FOR$PRINT PRINT_OUTPUT.TXT $ RUN program This clearly does not address the issue of "merging" the output from both C and FORTRAN. To do this, you should remove the "freopen" call from your code. This will cause C to send printf output to SYS$OUTPUT. The next step is to make sure that SYS$OUTPUT is a process permanent file (PPF). The effect is to capture both channels from the RTLs and merge them together. There are a number of ways to do this. One is with a command procedure. For example, create a command procedure called "PROG.COM" containing the line: $ RUN program Now the command: $ @PROG/OUTPUT=MSGFILE.DAT MSGFILE.DAT will contain the output from both FORTRAN and C. If there is any interactive input to the program, change the procedure to: $ DEFINE/USER SYS$INPUT SYS$COMMAND $ RUN program This connects the input stream to the terminal (SYS$COMMAND), rather than the command procedure itself. Alternatively, you could use RTL calls such as lib$put_output or a common set of application-specific I/O routines, which can (will) merge all of the I/O together as desired. If you don't want to create a command procedure, you can redirect the output of any command, or sequence of commands typed at the terminal with: $ @TT/OUTPUT=file or $ @SYS$COMMAND/OUTPUT=file The prompt will change, adding "_" at the beginning. Type your commands and finish with ^Z or EXIT. All output will be sent to the file. For example: $ @TT/OUTPUT=MSGFILE.DAT _$ RUN PRINTF _$ EXIT $ Another possibility, for OpenVMS V7.1 and later systems is the DCL PIPE command. Simply pipe the output of your program into a command or program that creates a file -- for example, COPY or CREATE. $ PIPE RUN program | CREATE MSGFILE.DAT $ PIPE RUN program | COPY SYS$PIPE MSGFILE.DAT Note that ALL the above assume that you have not used freopen on stdout.
|