Thread: Creating a Pipe between 2 processes

  1. #1
    Registered User
    Join Date
    Apr 2012
    Posts
    2

    Creating a Pipe between 2 processes

    My task is to write C code that will create a pipe between two process, writer and reader.


    The program will be called communicate and should be run as such: "communicate 10".


    When this is done it should be doing the equivalent of "writer 10 | reader".


    Writer just simply prints a message n number of times. Reader gets what writer prints and prints it out with no more than 50 characters per line.


    My writer and reader programs are correct. Here they are:


    writer.c
    Code:
    
    #include <stdio.h> /*typically in /usr/include*/
    #include <stdlib.h>
    
    
    int main (int argc, char* argv [ ])
    {
    
    
       int count, i;
       if (argc != 2)
       {
          fprintf(stderr, "usage: %s  count\n", argv[0]);
          exit (-1); /*signal error (other than 0) to shell*/
       }
       else
          count = atoi (argv[1]);
    
    
       for ( i = 0; i < count; i++ )
          printf ("Hellohello");
    
    
       return 0;
    }

    reader.c
    Code:
    
    #include <stdio.h> /*typically in /usr/include*/
    #include <stdlib.h>
    
    
    int main (int argc, char* argv [ ])
    {
    
    
       int count, c;
       if (argc != 1)
       {
          fprintf(stderr, "usage: %s", argv[0]);
          exit (-1); /*signal error (other than 0) to shell*/
       }
       else
       {
            count = 0;
            while ((c = getchar()) != EOF)
            {
                    putchar(c);
                    if(++count % 50  == 0)
                    {
                             putchar((char)'\n');
                    }
            }
            if(count % 50 != 0 )
            {
                    putchar((char)'\n');
            }
       }
    
    
      return 0;
    }

    Now my problem must be with my communicate program. I think it is pretty well commented so it should be easy to follow what's going on:
    Code:
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <sys/wait.h>
    
    
    #define READ_END 0
    #define WRITE_END 1
    
    
    int main(int argc, char* argv [ ])
    {
      if (argc != 2)
        {
          fprintf(stderr, "usage: %s  count\n", argv[0]);
          exit (-1); /*signal error (other than 0) to shell*/
        }
    
    
      int fd[2];
    
    
      pid_t childpid;
      pid_t childpid2;
    
    
      /* create pipe */
      if (pipe(fd) == -1){
        fprintf(stderr,"Pipe failed");
        return 1;
      }
    
    
      childpid = fork();
    
    
      if (childpid == -1) {
        printf("Error in fork; program terminated\n");
        return -1;
      }
    
    
      if (childpid == 0) {// child #1
        close(1);// close standard output (fd = 1)
        dup(fd[WRITE_END]);// dup the writing end of pipe it it gets fd = 1
    
    
        // close both ends of the pipe
        close(fd[WRITE_END]);
        close(fd[READ_END]);
    
    
        execlp("writer", "writer", argv[1], NULL);// exec to writer code
      }
      else {// parent
        int status;
        wait(&status);
    
    
        childpid2 = fork();// fork again
    
    
        if (childpid2 == -1) {
          printf("Error in fork; program terminated\n");
          return -1;
        }
    
    
        if (childpid2 == 0) {// child #2
          close(0);// close standard input (fd = 0)
          dup(fd[READ_END]);// dup the reading end of the pipe it gets fd = 0
    
    
          // close both ends of the pipe
          close(fd[WRITE_END]);
          close(fd[READ_END]);
    
    
          execlp("reader", "reader", NULL);// exec to reader code
        }
        else {// parent
          int status;
          wait(&status);
        }
    
    
        //close both ends of the pipe
        close(fd[WRITE_END]);
        close(fd[READ_END]);
      }
      return 0;
    }

    When I run my communicate program, 2 things are going wrong:
    1.) I have to hit like ctrl-d or ctrl-z to stop the program. Otherwise it just sits there after printing stuff. Not sure why this is happening, but that's not really a HUGE problem relatively speaking.
    2.) It only works in multiples of 5. If I do communicate 5, it works great except for bullet point 1. If I do communicate 10, same story. However if I do anything not a multiple of 5 nothing happens. So communicate 1, nothing. communicate 7, nothing.


    Could someone help me figure out what's wrong with my code? I'm a very novice C programmer, but not a novice programmer in general.


    Thanks for the help!

  2. #2
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    You want to close your pipes in the parent before you wait() at the end; otherwise, the reader will continue to expect data from your unclosed pipe in the parent.

    Also, just as a note, there's no need to cast '\n' to a char in reader.c: '\n' is an int, putchar() expects an int, so the char cast just creates two unnecessary conversions (int->char->int instead of just using the int). Even if the compiler's smart enough to not do the conversion, casts should be used sparingly, and only when necessary: they often mean that you're doing something behind the compiler's back, so to speak, and when readers of your code see a cast they might spend time wondering why it's there if it appears to be unnecessary.

  3. #3
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    And you don't want to wait for the first child before you create the second child. Move both waits to the end, after closing the pipe as cas said.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  4. #4
    Registered User
    Join Date
    Apr 2012
    Posts
    2
    Thanks guys. Got it working with your help.

    Much appreciated.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Pipe multiple programs using pipe() and c
    By HaitiBoy in forum C Programming
    Replies: 1
    Last Post: 12-07-2010, 05:19 PM
  2. Replies: 2
    Last Post: 12-06-2008, 02:17 PM
  3. Same pipe to multiple processes?
    By Ironic in forum C Programming
    Replies: 7
    Last Post: 10-25-2008, 10:10 AM
  4. Creating processes
    By xErath in forum Linux Programming
    Replies: 5
    Last Post: 10-09-2004, 01:36 PM
  5. creating n monitoring 5 processes (notepad)
    By nishzone in forum Windows Programming
    Replies: 3
    Last Post: 08-24-2003, 09:03 PM