I'm not going to lie. This is a homework question. However, as far as I'm concerned, the points are gone baby gone. Right now, I'm just looking for an answer, because I -think- I might be insane.
The goal of this program is to execute the command ps -A | grep (inputstring) | wc -l
in a way similar to how the shell does it. So, I spawn the processes, and have them wait on each other. The newest process, the great-grandchild, execlp("ps","ps","-A",NULL)
which replaces itself with the ps -A
process. Before it execlp
, I make sure its standard output is going to the pipe output. The next process in line is wait()
ing, and already has itself set up so that the input pipe goes to standard in, and standard out goes to the output pipe, and it will execute grep, and so on.
I'm almost positive I have it set up correctly. And yet... the program does. Not. Work.
#include <stdlib.h>
#include <iostream>
#include <string>
#define MAXLINE 1500
#define READ 0
#define WRITE 1
using namespace std;
int main( int argc, char** argv ) {
//* start of input block
if ( argc != 2 ) {
cout << "Usage: ./a.out arg1" << endl;
return 0;
}
string in = argv[1];
// end of input block */
int pipeA[2], pipeB[2], pid, stat;
// get our first set of pipes
if ( pipe(pipeA) < 0 ) {
cerr << "Pipe error.\n";
exit(-1);
}
if ( pipe(pipeB) < 0 ) {
cerr << "Pipe error.\n";
exit(-1);
}
// make the first fork
if ( (pid = fork() ) < 0 ) { cerr << "Fork error.\n"; exit(-1); }
if ( pid > 0 ) { // parent case
wait(&stat);
} else { // child case
if ( (pid = fork()) < 0 ) { cerr << "Fork Error\n"; exit(-1); }
if ( pid > 0 ) { // child
wait(&stat);
dup2(pipeA[READ],READ);
execlp("wc","wc","-l",NULL);
} else { // grand-child
if ( (pid = fork()) < 0 ) { cerr << "Fork Error\n"; exit(-1); }
if ( pid > 0 ) { // still grand-child
wait(&stat);
dup2(pipeB[READ],READ);
dup2(pipeA[WRITE],WRITE);
close(pipeB[READ]);
execlp("grep","grep",in.c_str(),NULL);
} else { // great grand-child
dup2(pipeB[WRITE],WRITE); // t now goes to pipeB[1]
close(READ);
close(pipeB[READ]);
execlp("ps", "ps", "-A", NULL);
}
}
}
return 0;
}
EDIT: Changed to the two-pipe variant of my code.