Skip to content

Instantly share code, notes, and snippets.

@ZuluagaSD
Created October 16, 2013 01:39
Show Gist options
  • Save ZuluagaSD/7001367 to your computer and use it in GitHub Desktop.
Save ZuluagaSD/7001367 to your computer and use it in GitHub Desktop.
/* npipes.cpp */
# include <stdio.h>
# include <stdlib.h>
# include <unistd.h>
# include <string.h>
# include <errno.h>
# include <iostream>
using namespace std;
// Color codes.
# define RESET "\033[0m"
# define BLACK "\033[30m" /* Black */
# define RED "\033[31m" /* Red */
# define GREEN "\033[32m" /* Green */
# define YELLOW "\033[33m" /* Yellow */
# define BLUE "\033[34m" /* Blue */
# define MAGENTA "\033[35m" /* Magenta */
# define CYAN "\033[36m" /* Cyan */
# define WHITE "\033[37m" /* White */
# define BOLDBLACK "\033[1m\033[30m" /* Bold Black */
# define BOLDRED "\033[1m\033[31m" /* Bold Red */
# define BOLDGREEN "\033[1m\033[32m" /* Bold Green */
# define BOLDYELLOW "\033[1m\033[33m" /* Bold Yellow */
# define BOLDBLUE "\033[1m\033[34m" /* Bold Blue */
# define BOLDMAGENTA "\033[1m\033[35m" /* Bold Magenta */
# define BOLDCYAN "\033[1m\033[36m" /* Bold Cyan */
# define BOLDWHITE "\033[1m\033[37m" /* Bold White */
/* Sample C++ program for generating a unidirectional ring of processes.Invoke
this program with a command-line arg ument indicating the number of processes
on the ring. Communication is done via pipes that connect the standard output
of a process to the standard input of its successor on the ring. After the ring
is created, each process identifies itself with its process ID and the process
ID of its parent. Each process then exits. */
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 */
int fd[2]; /* File descriptors returned by pipe */
int error; /* Return value from dup2 call */
cerr << flush;
cout << YELLOW << "Hello World" << RESET << endl;
/* Check command line for a valid number of processes to generate */
if ((argc != 2) || ((nprocs = atoi (argv[1])) <= 0)) {
fprintf (stderr, "Usage: %s nprocs\n", argv[0]);
exit(1);
}
/* Connect std input to std output via a pipe */
if (pipe (fd) == -1) {
perror("Could not create pipe");
exit(1);
}
if ((dup2(fd[0], STDIN_FILENO) == -1) ||
(dup2(fd[1], STDOUT_FILENO) == -1)) {
perror("Could not dup pipes");
exit(1);
}
if ((close(fd[0]) == -1) || (close(fd[1]) == -1)) {
perror("Could not close extra descriptors");
exit(1);
}
/* Create the remaining processes with their connecting pipes */
for (i = 1; i < nprocs; i++) {
if (pipe (fd) == -1) {
fprintf(stderr,"Could not create pipe %d: %s\n",
i, strerror(errno));
exit(1);
}
if ((childpid = fork()) == -1) {
fprintf(stderr, "Could not create child %d: %s\n",
i, strerror(errno));
exit(1);
}
if (childpid > 0) /* For parent process, reassign stdout */
error = dup2(fd[1], STDOUT_FILENO);
else
error = dup2(fd[0], STDIN_FILENO);
if (error == -1) {
fprintf(stderr, "Could not dup pipes for iteration %d: %s\n",
i, strerror(errno));
exit(1);
}
if ((close(fd[0]) == -1) || (close(fd[1]) == -1)) {
fprintf(stderr, "Could not close extra descriptors %d: %s\n",
i, strerror(errno));
exit(1);
}
if (childpid) {
break;
}
}
/* Say hello to the world */
cerr << "This is process " << RED << i << RESET << " with ID "
<< BLUE << (int)getpid() << RESET << " and parent id "
<< CYAN << (int)getppid() << RESET << endl;
// exit(0); /* Weird output. */
wait(0); /* Good output. */
} /* end of main program here */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment