From:	MERC::"uunet!CRVAX.SRI.COM!RELAY-INFO-VAX" 31-MAY-1992 16:39:31.06
To:	info-vax@kl.sri.com
CC:	
Subj:	Re: Redirecting process stdin, stdout, like in UNIX

In article <skinner.706885860@xray1.cshl.org>, skinner@cshl.org 
(John Skinner) writes:
> Under unix I can use the following code to have two processes talk to
> each other by redirecting their stdin and stdout.
> Is there any way to do this under VMS???
>  ... stuff deleted ...

I resurrected some old code which I used as a prototype, 
and this should point you in the right direction.  The code is
in two parts, parent and child.  For my application, it made 
more sense to pass along the pipe file descriptors to the child
rather than embed that information in the code.  

-- 
Jim Meinke, Simpact Associates        619-565-1865
9210 Sky Park Court                   jmeinke@dcs.simpact.com 
San Diego, CA  92123  

    "I really didn't say everything I said." -- Yogi Berra

==================================
/* 
 * Parent.c
 *
 * For each child, create 2 pipes, and start the child passing 
 * to it the file descriptors. 
 * Send each child a message through the output pipe; 
 * read a reply through the input pipe, and display it.  
 */
 
#include <stdio.h>
#include <perror.h> 

#define BUFFER_SIZE 128
#define MAX_CHILDREN 3

static int p2c_pipe[2];
static int c2p_pipe[2];
static int wfd[MAX_CHILDREN];
static int rfd[MAX_CHILDREN];

static char str1[20];
static char str2[20];
static char *gargv[] = { "xx", "yy", 0 };
static char outbuf[MAX_CHILDREN][BUFFER_SIZE];
static char inbuf[BUFFER_SIZE];

main() {
   int i, pid, len, child;
  
   strcpy( outbuf[0], "\"STRING TO & FROM 1ST CHILD\"\n" );
   strcpy( outbuf[1], "\"ANOTHER STRING TO & FROM 2ND CHILD\"\n" );
   strcpy( outbuf[2], "\"YET ANOTHER STRING TO & FROM 3RD CHILD\"\n" );
   
  /*-------------------------------------------------------------
   * For each child, create a pipe, start the process passing it
   * the file descriptor of the pipe
   *-------------------------------------------------------------
   */
   for (child=0; child<MAX_CHILDREN; child++) {
   
      if (pipe(p2c_pipe) == -1) {
         perror( "Parent: p2c_pipe failed\n" );
         exit();
      }
      wfd[child] = p2c_pipe[1];
      if (pipe(c2p_pipe) == -1) {
         perror( "Parent: c2p_pipe failed\n" );
         exit();
      }
      rfd[child] = c2p_pipe[0];
      sprintf(str1, "%d", p2c_pipe[0]);
      gargv[0] = str1;
      sprintf(str2, "%d", c2p_pipe[1]);
      gargv[1] = str2;
      
      pid = vfork();
      switch (pid) {
         case 0:
            execv( "child", gargv);
            perror( "Parent: execl failed\n" );
            exit();
         case -1:
            perror( "Parent: child process failed\n");
            exit();
         default:
            ;
      }
   }
  /*-------------------------------------------------------------
   * for each child, send it a message through the created pipe.
   *--------------------------------------------------------------
   */
   for (child=0; child<MAX_CHILDREN; child++) {
      if (write(wfd[child], outbuf[child], strlen(outbuf[child])+1) == -1) {
         perror( "Parent: write to pipe failed\n" );
         exit();
      }
   }
  /*-------------------------------------------------------------
   * for each child, read message, and display it.  
   * The child will send back it's input string in lower case.
   *-------------------------------------------------------------
   */
   for (child=0; child<MAX_CHILDREN; child++) {
      while ((len = read(rfd[child], inbuf, 512)) == 0) {
          printf("Parent: waiting on child %d\n", child);
          sleep(1);
      }
      if (len == -1) {
            perror( "Parent: read from pipe failed\n" );
            exit();
      } else  
            printf( "Parent: -->%s", inbuf );
   }
}
==================================
/*
 * Child.c
 *
 * This works when run by program parentc.c.
 *
 * Get the arguments, the file descriptors required to
 * get input from and send output to the parent.  
 * Close stdin, and dup rfd so we can use stdin to
 * read the input string.  Do the read & convert to lower case.
 * Close stdout, and dup wfd so we can use printf to
 * write the output string and have it piped to the parent.
 */
 
#include <stdio.h>
#include <perror.h> 

main(argc,argv) 
int argc;
char *argv[]; {

   char str[20], inbuf[512];
   int i, len, wfd, rfd, using_passed_fds;
   
  /* Get our file descriptor arguments, and convert to 
   * integers rfd and wfd.  The 1st argument is the file
   * descriptor to use for reading, the 2nd for writing.
   */
   using_passed_fds = 0;
   if (argc == 2) {
      rfd = atoi(argv[0]);
      wfd = atoi(argv[1]);
      using_passed_fds = 1;
   }

  /* Close stdin and stdout, dup rfd/wfd so we can use 
   * stdin/stdout again.
   */
   if (using_passed_fds) {
      close(0);
      if (dup(rfd) != 0) {
         perror("Child: error dup 0\n");
         exit();
      }  
   }
  /* read the input string, convert it to lower case.
   */
   if ((fgets(inbuf, 512, stdin)) == 0) {
     perror( "Child: fgets failed\n" );
     exit();
   } 
  
   len = strlen(inbuf);
   for (i=0; i<len; i++)
      inbuf[i] = tolower(inbuf[i]);
     
   if (using_passed_fds) {
      close(1);
      if (dup(wfd) != 1) {
         perror("Child: error dup 1\n");
         exit();
      }  
   }
   printf("%s", inbuf);
}
==================================

