• C

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.


vupadhyaAsked:
Who is Participating?
 
van_dyConnect With a Mentor Commented:
your program seems to work fine on
my freebsd machine and linux as well.
it appears that in p1();

     /* 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);

EOF is encountered as soon as you try to read from
stdin. possibly a libc problem on solaris. try replacing the
marked line with

   while(read(0, &c, 1))

lets know if that helps.

regards.
0
 
sunnycoderCommented:
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]
0
 
sunnycoderCommented:
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 ...
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.