Link to home
Start Free TrialLog in
Avatar of vupadhya
vupadhya

asked on

UNIX simple pipe() program.

/*
    Simple, simple pipe() sample.
    Main program stdout -> child stdin -> chile stdout -> Main program stdout
    cc spipe.c -o spipe

    To run
    >./spipe
    any text
    any text
    ^D
   
    or
    >./spipe < jim.txt

*/

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int fd1[2];      /* stdin pipe Main->Child */
int fd2[2];      /* stdout Pipe Child->Main */

void oops(char *err, int exit_code)
{
    fprintf(stderr, "%s\n", err);
    exit(exit_code);
}

/*
    Child process
*/
void p1(void)
{
      int c;
      /* Close pipe output */
      close(fd1[1]);
      /* Close stdin - 0, duplicate pipe input to 0 - it will new stdin */      
      if(-1 == dup2(fd1[0], 0))
          oops("dup2 error 0", 100);
      /* Close old descriptors */
      close(fd1[0]);

      /* Close pipe input*/
      close(fd2[0]);
      /* Close stdout - 1, duplicate pipe input to 1 - it will new stdout */      
      if(-1 == dup2(fd2[1], 1))
          oops("dup2 error 1", 101);
      /* Close old descriptors */
      close(fd1[1]);

      /* Then read from stdin and write to stdout */
      write(1, "\n---Begin---\n", 13);
      while(EOF != (c = getchar()))
          write(1, &c, 1);
      write(1, "\n---End---\n", 11);

      exit(0);
}


main()
{
    int c;
/* Creating pipe */
    if(-1 == pipe(fd1))
      oops("pipe error 1", 1);
    if(-1 == pipe(fd2))
      oops("pipe error 2", 2);
                        /* Split process */
    if(fork()){                  /* if fork() > 0 then parent */
                        /* Write parent stdin to child */
      close(fd1[0]);
      while(EOF != (c = getchar()))
          write(fd1[1], &c, 1);
                        /* Close pipe descriptors */
      close(fd1[1]);
                        /* Close pipe output */
      close(fd2[1]);
                        /* Read child output and send it so stdout */
      while(1 == read(fd2[0], &c, 1))
          write(1, &c, 1);
      close(fd2[0]);
      wait(0);
    }
    else                   /* If fork() == 0  then child */
      p1();
}

I am running this on UNIX solaris machine, Ideally, this program should output whatever I input to it. However, this is what happens:

$ ./spipe
saaddsad
^D
---Begin---

---End---
$

Any ideas? I should get saaddsad in the output.


Avatar of sunnycoder
sunnycoder
Flag of India image

One simple observation ... wyh do you need two pipes to communicate between two processes? A single pipe would have been sufficient ... pipes are already messy and its hard enought to make one work ... you are increasing the complexity further ... Use a single pipe


               fd[0]
A          ----------->     B
            <----------
                fd[1]
At a glance, rest of your code appears to be all right even though written a bit unconventionally ...
Close all unrequired fds at the start of the process ... It makes it easier to understand the program that way.
You can  see a similar worked out example here
http://users.actcom.co.il/~choo/lupg/tutorials/multi-process/multi-process.html#pipes_pipe_syscall

I dont have access to a *nix machine till tomorrow ... so may be then I can try to execute this code ...
ASKER CERTIFIED SOLUTION
Avatar of van_dy
van_dy

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial