Skip to content

Instantly share code, notes, and snippets.

@aesophor
Created October 20, 2020 14:12
Show Gist options
  • Save aesophor/8c729a500b15bf86ba925bc4bb7de11d to your computer and use it in GitHub Desktop.
Save aesophor/8c729a500b15bf86ba925bc4bb7de11d to your computer and use it in GitHub Desktop.
three pipes
extern "C" {
#include <sys/wait.h>
#include <unistd.h>
}
#include <iostream>
#include <string>
#include <vector>
int main() {
int pipes[2][2];
::std::vector<const char*> cmd1 = {"ls", "-la", nullptr};
::std::vector<const char*> cmd2 = {"grep", "out", nullptr};
::std::vector<const char*> cmd3 = {"rev", nullptr};
for (int i = 0; i < 3; i++) {
pid_t pid = -1;
int status = 0;
if (i == 0) {
pipe(pipes[0]);
} else if (i == 1) {
pipe(pipes[1]);
}
switch ((pid = fork())) {
case -1:
::std::perror("fork failed");
::std::exit(EXIT_FAILURE);
break;
case 0: // child
if (i == 0) {
dup2(pipes[0][1], fileno(stdout));
close(pipes[0][0]);
close(pipes[0][1]);
execvp(cmd1[0], const_cast<char**>(cmd1.data()));
::std::perror("exec fail");
} else if (i == 1) {
dup2(pipes[0][0], fileno(stdin));
close(pipes[0][0]);
close(pipes[0][1]);
dup2(pipes[1][1], fileno(stdout));
close(pipes[1][0]);
close(pipes[1][1]);
execvp(cmd2[0], const_cast<char**>(cmd2.data()));
::std::perror("exec fail");
} else if (i == 2) {
dup2(pipes[1][0], fileno(stdin));
close(pipes[1][0]);
close(pipes[1][1]);
execvp(cmd3[0], const_cast<char**>(cmd3.data()));
::std::perror("exec fail");
}
break;
default: // parent
if (i == 1) {
close(pipes[0][0]);
close(pipes[0][1]);
} else if (i == 2) {
close(pipes[1][0]);
close(pipes[1][1]);
}
wait(&status);
break;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment