I'm writing a program that just chains together specifically 3 programs, etc "ls | sort | wc".
I looked through the other posts I found on google about multiple pipes but I still can't figure out what I've been doing wrong. Been stuck on this for a while. I believe my program is logically correct, but for some reason it doesn't run. What am I missing?
pipe(pipe1);
pipe(pipe2);
pid = fork();
if(pid > 0){
close(pipe2[1]);
dup2(pipe2[0], 0);
execlp(argv[3], argv[3], NULL);
}
else if(pid == 0){
pid2 = fork();
if(pid2 == 0){
close(pipe1[0]);
dup2(pipe1[1], 1);
execlp(argv[1], argv[1], NULL);
}
else if(pid2 > 0){
close(pipe1[1]);
dup2(pipe1[0], 0);
close(pipe2[0]);
dup2(pipe2[1], 1);
execlp(argv[2], argv[2], NULL);
}
}
You need to fork three times each time in the parent cases, and execute your commands only inside the child cases. Take a look here
Adjusted to your case:
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
int main(int argc, char **argv) {
int pid;
int pipe1[2];
int pipe2[2];
// create pipe1
if (pipe(pipe1) == -1) {
perror("bad pipe1");
exit(1);
}
// fork (ps aux)
if ((pid = fork()) == -1) {
perror("bad fork1");
exit(1);
}
else if (pid == 0) {
// stdin --> ps --> pipe1
// input from stdin (already done), output to pipe1
dup2(pipe1[1], 1);
// close fds
close(pipe1[0]);
close(pipe1[1]);
execlp(argv[1], argv[1], NULL);
// exec didn't work, exit
perror("bad exec ps");
_exit(1);
}
// parent
// create pipe2
if (pipe(pipe2) == -1) {
perror("bad pipe2");
exit(1);
}
// fork (grep root)
if ((pid = fork()) == -1) {
perror("bad fork2");
exit(1);
}
else if (pid == 0) {
// pipe1 --> grep --> pipe2
// input from pipe1
dup2(pipe1[0], 0);
// output to pipe2
dup2(pipe2[1], 1);
// close fds
close(pipe1[0]);
close(pipe1[1]);
close(pipe2[0]);
close(pipe2[1]);
execlp(argv[2], argv[2], NULL);
// exec didn't work, exit
perror("bad exec grep root");
_exit(1);
}
// parent
// close unused fds
close(pipe1[0]);
close(pipe1[1]);
// fork (grep sbin)
if ((pid = fork()) == -1) {
perror("bad fork3");
exit(1);
}
else if (pid == 0) {
// pipe2 --> grep --> stdout
// input from pipe2
dup2(pipe2[0], 0);
// output to stdout (already done). Close fds
close(pipe2[0]);
close(pipe2[1]);
execlp(argv[3], argv[3], NULL);
// exec didn't work, exit
perror("bad exec grep sbin");
_exit(1);
}
// parent
return 0;
}