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.