Thread: Clearing a pipe used in IPC

  1. #1
    Registered User
    Join Date
    Sep 2006
    Posts
    8

    Question Clearing a pipe used in IPC

    Hi. I am using the fork() and pipe() functions to establish communication between 2 processes. If one process writes to the pipe, and the second process reads the pipe, how does the second process clear the input that it read on the last read operation? (Or alternatively, how can I make process 1 clear the pipe before it writes to it?)

    For example, process 1 writes data as follows:

    string1
    string2
    string3

    Process 2 is waiting for the data that process 1 is writing. In a loop, as process 2 reads the pipe, this is what gets read as a string on each iteration:

    1. string1
    2. string1string2
    3. string1string2string3

    How do I clear the pipe in process 2 after each read so that I only get the latest string written by process 1? Just to clarify, I want process 2 to read the the data from process 1 in this manner:

    1. string1
    2. string2
    3. string3

    Thanks!

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    How about posting your code to read the pipe?

    pipes are like files, you get each character in turn exactly once, so I figure there's something else going on as well.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Sep 2006
    Posts
    8

    Sure. Here it is...

    Thanks for taking a look at it. I am only posting the relevant sections.

    Code:
    ...
    
    /****************************/
    /* Global variables and constants: */
    /****************************/
    
    #define RSIZE 80
    #define BUFSIZE 10
    #define NEWBUFSIZE 200
    #define FD_READ 0
    #define FD_WRITE 1
    #define STDIN 0
    #define STDOUT 1
    #define NO_OF_OPERANDS 5
    #define NO_OF_OPERATORS 4
    
    
    ...
    
     establishProcessPipe(pipeFDs);
    
     fdin = fopen("./data.in","r");
     fdout = fopen("./data.out","w");
    
      /* Create child process to load the pipe w/input. Process the result */
     /* as the parent:                                                                                */
    
     pid = fork();
    
     switch(pid)          
     {
      case -1:                                     /* fork() ERROR */
       printf("ERROR: Could not spawn child!");
       exit(1);
      case 0:                                      /* I am the child */
       close(STDOUT);
       dup2(pipeFDs[FD_WRITE]);
       close(FD_WRITE);
       processInputFile(pipeFDs,fdin,pid);          
       fclose(fdin);
       exit(0);
      default:                                       /* I am the parent */
       close(STDIN);
       dup2(pipeFDs[FD_READ]);
       close(FD_READ);
       processLoadedPipe(pipeFDs,fdout,pid);
       fclose(fdout);
       exit(0);        
     }
    
    ...
    
    void establishProcessPipe(int pipeFDs[])
    {
    
      if(pipe(pipeFDs) == -1)
      {
       printf("ERROR: Could not create pipe!");
       exit(1);
      }
    }
    
    void processLoadedPipe(int pipeFDs[],FILE *fdout,int pid)
    {
    
      /******************************/
      /* Create output file from result pipe: */
      /******************************/
    
      int nread;
      char buf[NEWBUFSIZE];  
      char newbuf[NEWBUFSIZE] = {""};
    
      nread = 0;
      close(pipeFDs[FD_WRITE]);            /* Close write descriptor */
    
      while((nread = read(pipeFDs[FD_READ],buf,NEWBUFSIZE)) != 0)
      {
        if(strcmp(buf, "EOF") == 0)        /* Detect end of file message */
         break;
    
        performCalculationsUsingReadBuffer(buf,newbuf);
    
        fprintf(fdout,"%s\n",newbuf);
      }
    
      close(pipeFDs[FD_READ]);             /* Close read descriptor */
    }
    
    void processInputFile(int pipeFDs[],FILE *fdin,int pid)
    {
    
     char buf[BUFSIZE];
     char newbuf[NEWBUFSIZE] = {""};
    
     int newbufsize = NEWBUFSIZE;
    
     int i;
    
     while(fscanf(fdin,"%s\n",buf) != EOF)
     {
       performTranslationOfReadBuffer(buf,newbuf,newbufsize,pid);
       writeToPipe(pipeFDs,newbuf,newbufsize,pid);
     }
    
     writeToPipe(pipeFDs,"EOF",newbufsize,pid);    /* EOF message */
    }
    
    void writeToPipe(int pipeFDs[],char buf[],int bufsize,int pid)
    {
       close(pipeFDs[FD_READ]);               /* Close read descriptor */
       write(pipeFDs[FD_WRITE],buf,bufsize);
    }

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > close(STDOUT);
    > dup2(pipeFDs[FD_WRITE]);
    > close(FD_WRITE);
    This makes no sense - why would you close(1) a second time?

    > processInputFile(pipeFDs,fdin,pid);
    > processLoadedPipe(pipeFDs,fdout,pid);
    Neither of these should be passed the pipes. You've already dup'ed them to stdin and stdout.
    I think you should probably close both ends of the pipe once you've dup'ed them.

    > writeToPipe
    > close(pipeFDs[FD_READ]);
    OK already, it's closed - stop closing it again and again!

    > writeToPipe(pipeFDs,newbuf,newbufsize,pid);
    Maybe something like strlen(newbuf) so you don't write a whole bunch of garbage down the pipe each time?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Sep 2006
    Posts
    8

    Thanks for replying

    Thanks for your response.

    If I do not pass the pipe array to the functions, should I use scanf to read stdin (which has now been overridden by the pipe)? When I tried to do this the screen hangs, so it seems like stdin is not being overridden to the pipe?

    Also - Is the pipe supposed to be cleared? I wind up reading the entire contents of the pipe on each read. I only want to read one row at a time.

    Thanks again.

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    This seems to work on my Linux box
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/wait.h>
    
    #define PIPE_READ_END   0
    #define PIPE_WRITE_END  1
    
    void producer ( void ) {
      int i;
      for ( i = 0 ; i < 10 ; i++ ) {
        printf( "Loop %d\n", i );
      }
      fflush(stdout);
    }
    
    void consumer ( void ) {
      char buff[BUFSIZ];
      while ( fgets( buff, sizeof buff, stdin ) != NULL ) {
        printf( "read: %s", buff );
      }
    }
    
    int main ( void ) {
      pid_t pid;
      int p[2];
      int status;
    
      status = pipe(p);
      if ( status == -1 ) {
        perror("Can't pipe");
        exit( EXIT_FAILURE );
      }
    
      pid = fork();
      if ( pid == 0 ) {
        close( p[PIPE_READ_END] );
        dup2( p[PIPE_WRITE_END], STDOUT_FILENO );
        producer();
        _exit(2);
      } else
      if ( pid > 0 ) {
        close( p[PIPE_WRITE_END] );
        dup2( p[PIPE_READ_END], STDIN_FILENO );
        consumer();
        {
          int s;
          wait(&s);
          printf( "Child exited with status=%d\n", WEXITSTATUS(s) );
        }
      }
      else {
        perror("Can't fork");
      }
      return 0;
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. cont of IPC using PIPE
    By BMathis in forum C Programming
    Replies: 1
    Last Post: 03-15-2009, 05:16 PM
  2. Segmentation fault - IPC
    By kbfirebreather in forum C Programming
    Replies: 7
    Last Post: 02-01-2009, 03:17 PM
  3. Pipe class.
    By eXeCuTeR in forum Linux Programming
    Replies: 8
    Last Post: 08-21-2008, 03:44 AM
  4. Pipe(): Interprocess or Intraprocess comm?
    By @nthony in forum C Programming
    Replies: 2
    Last Post: 03-28-2007, 07:27 PM
  5. 2 way ipc
    By mmnoname in forum C Programming
    Replies: 2
    Last Post: 03-25-2006, 10:39 AM