#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
int parse_args(int argc,  char *argv[ ], int *np){
  if ( (argc != 2) || ((*np = atoi (argv[1])) <= 0) ) {
    fprintf (stderr, "Usage: %s nprocs\n", argv[0]);
    return(-1); };
  return(0); 
}
int make_trivial_ring(){   
  int   fd[2];
  if (pipe (fd) == -1) 
    return(-1); 
  if ((dup2(fd[0], STDIN_FILENO) == -1) ||
      (dup2(fd[1], STDOUT_FILENO) == -1)) 
    return(-2); 
  if ((close(fd[0]) == -1) || (close(fd[1]) == -1))   
    return(-3); 
  return(0); }
int add_new_node(int *pid){
  int fd[2];
  if (pipe(fd) == -1) 
    return(-1); 
  if ((*pid = fork()) == -1)
    return(-2); 
  if(*pid > 0 && dup2(fd[1], STDOUT_FILENO) < 0)
    return(-3); 
  if (*pid == 0 && dup2(fd[0], STDIN_FILENO) < 0)
    return(-4); 
  if ((close(fd[0]) == -1) || (close(fd[1]) == -1)) 
    return(-5);
  return(0);
}
int main(int argc,  char *argv[ ]){
   int   i;             /* number of this process (starting with 1)   */
   int   childpid;      /* indicates process should spawn another     */ 
   int   nprocs;        /* total number of processes in ring          */ 
   if(parse_args(argc,argv,&nprocs) < 0) exit(EXIT_FAILURE);
   if(make_trivial_ring() < 0){
     perror("Could not make trivial ring");
     exit(EXIT_FAILURE); };
   for (i = 1; i < nprocs;  i++) {
     if(add_new_node(&childpid) < 0){
       perror("Could not add new node to ring");
       exit(EXIT_FAILURE); };
     if (childpid) break; };
   /* ring process code  */

   fprintf(stderr, "node %d of %d\n", i, nprocs);
   exit(EXIT_SUCCESS);
}     /* end of main program here */