#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 */