HP OpenVMS Systems

ask the wizard
Content starts here

Redirecting DCL I/O output?

» close window

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.
 

answer written or last revised on ( 6-FEB-2001 )

» close window