Copyright Digital Equipment Corp. All rights reserved.

Description

   The mailbox used for the pipe is a temporary mailbox. The mailbox
   is not deleted until all processes that have open channels to
   that mailbox close those channels. The last process that closes a
   pipe writes a message to the mailbox, indicating the end-of-file.

   The mailbox is created by using the $CREMBX system service,
   specifying the following characteristics:

   o  A maximum message length of 512 characters

   o  A buffer quota of 512 characters

   o  A protection mask granting all privileges to USER and GROUP
      and no privileges to SYSTEM or WORLD

   The buffer quota of 512 characters implies that you cannot write
   more than 512 characters to the mailbox before all or part of the
   mailbox is read. Since a mailbox record is slightly larger than
   the data part of the message that it contains, not all of the
   512 characters can be used for message data. You can increase the
   size of the buffer by specifying an alternative size using the
   optional, third argument to the pipe function. A pipe under the
   OpenVMS system is a stream-oriented file with no carriage-control
   attributes. It is fully buffered by default in the C RTL.
   A mailbox used as a pipe is different than a mailbox created by
   the application. A mailbox created by the application defaults
   to a record-oriented file with carriage return, carriage control.
   Additionally, writing a zero-length record to a mailbox writes an
   EOF, as does each close of the mailbox. For a pipe, only the last
   close of a pipe writes an EOF.

   The pipe is created by the parent process before vfork and
   an exec function are called. By calling pipe first, the child
   inherits the open file descriptors for the pipe. You can then use
   the getname function to return the name of the mailbox associated
   with the pipe, if this information is desired. The mailbox name
   returned by getname has the format _MBAnnnn: (Alpha only) or _
   MBAnnnnn: (Integrity servers(ONLY)) , where nnnn or nnnnn is a
   unique number.

   Both the parent and the child need to know in advance which file
   descriptors will be allocated for the pipe. This information
   cannot be retrieved at run time. Therefore, it is important to
   understand how file descriptors are used in any VSI C for
   OpenVMS program.

   File descriptors 0, 1, and 2 are open in a VSI C for OpenVMS
   program for stdin (SYS$INPUT), stdout (SYS$OUTPUT), and stderr
   (SYS$ERROR), respectively. Therefore, if no other files are open
   when pipe is called, pipe assigns file descriptor 3 for writing
   and file descriptor 4 for reading. In the array returned by pipe,
   4 is placed in element 0 and 3 is placed in element 1.

   If other files have been opened, pipe assigns the first
   available file descriptor for writing and the next available
   file descriptor for reading. In this case, the pipe does not
   necessarily use adjacent file descriptors. For example, assume
   that two files have been opened and assigned to file descriptors
   3 and 4 and the first file is then closed. If pipe is called at
   this point, file descriptor 3 is assigned for writing and file
   descriptor 5 is assigned for reading. Element 0 of the array will
   contain 5 and element 1 will contain 3.

   In large applications that do large amounts of I/O, it gets
   more difficult to predict which file descriptors are going to
   be assigned to a pipe; and, unless the child knows which file
   descriptors are being used, it will not be able to read and write
   successfully from and to the pipe.

   One way to be sure that the correct file descriptors are being
   used is to use the following procedure:

   1. Choose two descriptor numbers that will be known to both the
      parent and the child. The numbers should be high enough to
      account for any I/O that might be done before the pipe is
      created.

   2. Call pipe in the parent at some point before calling an exec
      function.

   3. In the parent, use dup2 to assign the file descriptors
      returned by pipe to the file descriptors you chose. This now
      reserves those file descriptors for the pipe; any subsequent
      I/O will not interfere with the pipe.

   You can read and write through the pipe using the UNIX I/O
   functions read and write, specifying the appropriate file
   descriptors. As an alternative, you can issue fdopen calls to
   associate file pointers with these file descriptors so that you
   can use the Standard I/O functions (fread and fwrite).

   Two separate file descriptors are used for reading from and
   writing to the pipe, but only one mailbox is used so some I/O
   synchronization is required. For example, assume that the parent
   writes a message to the pipe. If the parent is the first process
   to read from the pipe, then it will read its own message back as
   shown in Reading and Writing to a Pipe.
 

                                  NOTE

      For added UNIX portability, you can use the following
      feature logicals to control the behavior of the C RTL pipe
      implementation:

      o  Define the DECC$STREAM_PIPE feature logical name to
         ENABLE to direct the pipe function to use stream I/O
         instead of record I/O.

      o  Define the DECC$POPEN_NO_CRLF_REC_ATTR feature logical
         to ENABLE to prevent CR/LF carriage control from being
         added to pipe records for pipes opened with the popen
         function. Be aware that enabling this feature might
         result in undesired behavior from other functions such
         as gets that rely on the carriage-return character.

   Figure REF-1  Reading and Writing to a Pipe