I am simulating the linux shell pipe operator, and I got stuck. The below is the minimal reproducable example of what I tried.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int do_command(char* args[])
{
int status;
pid_t pid = fork();
if (pid == 0)
{
execvp(args[0], args);
}
else
{
wait(&status);
}
return 0;
}
int main() {
int pipefd[2];
pid_t pid;
// Create a pipe
if (pipe(pipefd) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
}
// Redirect stdout to write end of the pipe
if (dup2(pipefd[1], STDOUT_FILENO) == -1) {
perror("dup2");
exit(EXIT_FAILURE);
}
// the output will go to pipefd[1].
char* echo[] = { "echo", "Hello, World!", NULL };
do_command(echo);
close(pipefd[1]);
// Redirect stdin to read end of the pipe
if (dup2(pipefd[0], STDIN_FILENO) == -1) {
perror("dup2");
exit(EXIT_FAILURE);
}
// since there is no argument to rev, it will automatically read from pipefd[0]
char* rev[] = { "rev", NULL };
do_command(rev);
close(pipefd[0]);
return 0;
}
After I run this, the program stopped without outputting any single word. I think there is something to do with close()
, but I couldn’t figure it out. I did close both pipes. How can I fix it?
And is there any way to fix it without changing the structure of do_command()
? I want to simulate multiple pipe chain in the future, So I want the structure of function do_command
remain same, in order to call the command easily.