Code:
// procmain.c /////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/wait.h>
#include <sys/types.h>
void forkproc(const char *proc, int pin, int pout, const char *arg) {
pid_t pid;
if ((pid = fork()) == (pid_t)-1) {
fprintf(stderr, "Error: fork %s: %s\n", proc, strerror(errno));
exit(EXIT_FAILURE);
}
if (pid == 0) {
dup2(pin, 0);
dup2(pout, 1);
execl(proc, proc, arg, (const char *)NULL);
fprintf(stderr, "Error: exec %s: %s\n", proc, strerror(errno));
exit(EXIT_FAILURE);
}
}
int main(int argc, char **argv) {
if (argc != 2) {
fprintf(stderr, "Usage: procmain MAXREPS\n");
exit(EXIT_FAILURE);
}
int p[3][2];
if (pipe(p[0]) == -1 || pipe(p[1]) == -1 || pipe(p[2]) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
}
forkproc("proc1", p[0][0], p[1][1], argv[1]);
forkproc("proc2", p[1][0], p[2][1], NULL);
forkproc("proc3", p[2][0], p[0][1], NULL);
for (int i = 0; i < 3; i++) {
close(p[i][0]); close(p[i][1]);
}
wait(NULL); wait(NULL); wait(NULL);
return 0;
}
// proc1.c /////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int main(int argc, char **argv) {
if (argc != 2)
return EXIT_FAILURE;
int maxreps = atoi(argv[1]);
char line[1000];
srand(time(NULL));
for (int r = 0; r < maxreps; r++) {
int n = rand() % 90 + 10;
for (int i = 0; i < n; i++)
printf("%d ", rand() % 5 + 5);
putchar('\n');
fflush(stdout);
if (fgets(line, sizeof line, stdin) == NULL)
break;
// Break if told to STOP by proc3
if (strcmp(line, "STOP\n") == 0)
break;
}
// Send EXIT command to proc2
printf("EXIT\n"); fflush(stdout);
return 0;
}
// proc2.c /////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int main() {
char line[1000];
srand(time(NULL));
while (fgets(line, sizeof line, stdin) != NULL) {
if (strcmp(line, "EXIT\n") == 0) {
// Pass EXIT command on to proc3
printf("EXIT\n"); fflush(stdout);
break;
}
char *pline = line;
int n = 0, delta = 0, word_cnt = 0;
while (sscanf(pline += delta, "%d%n", &n, &delta) == 1) {
for (int i = 0; i < n; i++)
putchar('a' + rand() % 26);
putchar('\n');
fflush(stdout);
word_cnt++;
}
// Indicate end of word list.
printf("LAST\n"); fflush(stdout);
}
return 0;
}
// proc3.c /////////////////////////////////////////////////////
#include <stdio.h>
#include <string.h>
int main() {
char line[1000];
int word_cnt = 0;
while (fgets(line, sizeof line, stdin) != NULL) {
if (strcmp(line, "EXIT\n") == 0)
break;
if (strcmp(line, "LAST\n") == 0) {
fprintf(stderr, "proc3 saw %d words\n", word_cnt);
// Arbitrarily stopping when proc3 sees a word
// list more than 80 words long
if (word_cnt > 80) {
// Send STOP command to proc1
printf("STOP\n"); fflush(stdout);
break;
}
else {
// Tell proc1 to continue
printf("\n"); fflush(stdout);
}
word_cnt = 0;
}
else
word_cnt++;
}
return 0;
}