Thread: Having trouble with a named pipe

  1. #1
    Registered User
    Join Date
    Apr 2005
    Posts
    10

    Having trouble with a named pipe

    The jist of this program is there's testgenerate that reads from a pipe called ncc, after it forks two children that both write to the pipe. The only problem is that when the processes open the pipe, the file descriptor for the pipe is 0. I didn't think that was possible, since I don't ever close standard input? In generate.c, when it writes to the fd, it's printed to the screen, and testgenerate is stuck in the while(read()) loop.

    Code:
    /*
    PJ Hyett
    usage: ./testgenerate seq-length even-wait odd-wait
    */
    
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <sys/time.h>
    #include <errno.h>
    #include <unistd.h>
    #include <fcntl.h>
    
    #define FIFO_NAME "ncc"
    extern int errno;
    
    int main(int argc, char* argv[])
    {
      int fd, i, check;
      pid_t child[2];
      char *args[6], buf[10] = {}, readbuf[10] = {};
      fd_set writefds;
              
      if(--argc != 3)
      {
        fprintf(stderr,"Invalid # of arguments\n");
        return 1;
      }    
      
      /* create fifo if it doesn't already exist */
      if(mkfifo(FIFO_NAME,0777) == -1)
      {
        if(errno != EEXIST)
        {
          perror("fifo creation error");
          return 1;
        }
      }
         
      /* setup common arguments for children */
      args[0] = "./generate"; 
      args[2] = argv[1];
      args[3] = FIFO_NAME;
      args[5] = NULL;
      
      /* create two children */
      if(child[0] = fork())
        child[1] = fork();
        
      if(child[0] == -1 || child[1] == -1){
        perror("Fork failed\n");
        return 3;
      }
      
      /* call generate on each child */
      for(i = 0; i < 2; i++)
      {
        if(!child[i])
        {
          if(i)
          {
            args[1] = "even"; 
            args[4] = argv[2];
          }
          else
          {
            args[1] = "odd"; 
            args[4] = argv[3];
          }
          
          execvp(args[0],args);
        }
      }
      
      /* --PARENT SECTION -- */
      
      /* open fifo for reading */
      if(fd = open(FIFO_NAME,O_RDONLY) == -1)
      {
        perror("Fifo error\n");
        return 2;
      }
      
      /* read from pipe */
      while(check = read(fd,readbuf,10) != 0){
        if(check == -1)
        {
          perror("Read error\n");
          return 5;
        }
        if(write(2,readbuf,10) == -1)
        {
          perror("Write error\n");
          return 6;
        }
      }
      
      /* done reading, close pipe */
      if(close(fd) == -1)
      {
        perror("close error\n");
        return 9;
      }
      
      /* wait for children */
      wait(NULL); wait(NULL);
      
      write(2,"\n",1);
      
       
      return 0;
    }
    generate.c
    Code:
    /*
    PJ Hyett
    usage: ./generate selector seq-length fifo max-wait
    (called by testgenerate)
    */
    
    #include <stdio.h>
    #include <unistd.h>
    #include <fcntl.h>
    
    int main(int argc, char* argv[]){
      int which, i, num, fd, max_wait;
      char buf[10] = {};
      
      if(--argc != 4)
      {
        fprintf(stderr,"Invalid # of arguments\n");
        return 1;
      }
      
      if(!strcmp(argv[1],"odd"))
        which = 1;
      else if(!strcmp(argv[1],"even"))
        which = 0;
      else
      {
        fprintf(stderr,"Must be odd or even!\n");
        return 2;
      }
      
      /* seed rand() */
      srand(which ? 1 : 2);
     
      /* convert args to ints */
      num = atoi(argv[2]) * 2;  
      max_wait = atoi(argv[4]);
      
      /* open fifo for writing */
      if(fd = open(argv[3], O_WRONLY) == -1)
      {
        perror("open error\n");
        return 3;
      }
    
      for(i = which; i < num; i += 2)
      {
        sprintf(buf,"%d ",i);
        if(write(fd,buf,10) == -1)
        {
          perror("write error\n");
          return 4;
        }
        if(i+2 < num)
          sleep(rand() % max_wait);
      }
      
      /* close fifo */
      if(close(fd) == -1)
      {
        perror("close error\n");
        return 5;
      }
    
      return 0;
    }
    Any help would be appreciated.

  2. #2
    Registered User
    Join Date
    Apr 2005
    Posts
    10
    If I comment out this code in testgenerate.c
    Code:
    /* read from pipe */
      while(check = read(fd,readbuf,10) != 0){
        if(check == -1)
        {
          perror("Read error\n");
          return 5;
        }
        if(write(2,readbuf,10) == -1)
        {
          perror("Write error\n");
          return 6;
        }
      }
    Then it works, but that isn't the point. It's supposed to be written from one process (in this case 2) and read from another.

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > buf[10] =
    C doesn't allow empty declarations.

    > if(child[0] == -1 || child[1] == -1)
    From this point on, you have all 3 processes (parent and 2 children) all running the same code.

    You need to be a lot more careful about what happens after each fork(), because there are two processes doing the same thing immediately afterwards, and you need to steer them both in the right directions.
    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. Getting an error with OpenGL: collect2: ld returned 1 exit status
    By Lorgon Jortle in forum C++ Programming
    Replies: 6
    Last Post: 05-08-2009, 08:18 PM
  2. Replies: 2
    Last Post: 04-22-2008, 12:07 PM
  3. Replies: 2
    Last Post: 04-19-2008, 12:06 AM
  4. Named pipe problem
    By rahul_c in forum C Programming
    Replies: 3
    Last Post: 10-02-2007, 05:40 PM
  5. Named Pipe Problems.
    By Mastadex in forum Windows Programming
    Replies: 2
    Last Post: 06-16-2006, 08:35 AM