Copyright Digital Equipment Corp. All rights reserved.

Description

   The decc$set_child_standard_streams function allows mapping of
   specified file descriptors to the child's stdin/stdout/stderr
   streams, thereby compensating, to a certain degree, the lack of a
   real fork function on OpenVMS systems.

   On UNIX systems, the code between fork and exec is executed in
   the context of the child process:

   parent:
     create pipes p1, p2 and p3
     fork
   child:

     map stdin to p1  like dup2(p1, stdin);
     map stdout to p2 like dup2(p2, stdout);
     map stderr to p3 like dup2(p3, stderr);

     exec (child reads from stdin and writes to stdout and stderr)
     exit
   parent:
     communicates with the child using pipes

   On OpenVMS systems, the same task could be achieved as follows:

   parent:
     create pipes p1, p2 and p3
     decc$set_child_standard_streams(p1, p2, p3);
     vfork
     exec (child reads from stdin and writes to stdout and stderr)
   parent:
     communicates with the child using pipes

   Once established through the call to decc$set_child_standard_
   streams, the mapping of the child's standard streams remains in
   effect until explicitly disabled by one of the following calls:

   decc$set_child_standard_streams(-1, -1, -1);

   Or:

   decc$set_child_standard_streams(0, 1, 2);

   Usually, the child process inherits all its parent's open file
   descriptors. However, if file descriptor number n was specified
   in the call to decc$set_child_standard_streams, it is not
   inherited by the child process as file descriptor number n;
   instead, it becomes one of the child's standard streams.

                                 NOTES

      o  Standard streams can be redirected only to pipes.

      o  If the parent process redefines the DCL DEFINE command,
         this redefinition is not in effect in a subprocess with
         user-defined channels. The subprocess always sees the
         standard DCL DEFINE command.

      o  It is the responsibility of the parent process to consume
         all the output written by the child process to stdout and
         stderr. Depending on how the subprocess writes to stdout
         and stderr-in wait or nowait mode-the subprocess might be
         placed in LEF state waiting for the reader. For example,
         DCL writes to SYS$OUTPUT and SYS$ERROR in a wait mode,
         so a child process executing a DCL command procedure will
         wait until all the output is read by the parent process.

         Recommendation: Read the pipes associated with the child
         process' stdout and stderr in a loop until an EOF message
         is received, or declare write attention ASTs on these
         mailboxes.

      o  The amount of data written to SYS$OUTPUT depends on the
         verification status of the process (SET VERIFY/NOVERIFY
         command); the subprocess inherits the verification status
         of the parent process. It is the caller's responsibility
         to set the verification status of the parent process to
         match the expected amount of data written to SYS$OUTPUT
         by the subprocess.

      o  Some applications, like DTM, define SYS$ERROR as
         SYS$OUTPUT. If stderr is not redefined by the caller,
         it is set in the subprocess as the parent's SYS$ERROR,
         which in this case translates to the parent's SYS$OUTPUT.

         If the caller redefines stdout to a pipe and does not
         redefine stderr, output sent to stderr goes to the pipe
         associated with stdout, and the amount of data written
         to this mailbox may be more than expected. Although
         redefinition of any subset of standard channels is
         supported, it is always safe to explicitly redefine all
         of them (or at least stdout and stderr) to avoid this
         situation.

      o  For a child process executing a DCL command procedure,
         SYS$COMMAND is set to the pipe specified for the child's
         stdin so that the parent process can feed the child
         requesting data from SYS$COMMAND through the pipe. For
         DCL command procedures, it is impossible to pass data
         from the parent to the child by means of the child's
         SYS$INPUT because for a command procedure, DCL defines
         SYS$INPUT as the command file itself.