I am trying to implement pipe in C. eg - $ ls | wc | wc
I have written the following code -
#include<stdio.h>
#include<stdlib.h>
#include <unistd.h>
void run_cmd(char *cmd, int* fd_in, int* fd_out)
{
int c = fork();
if (c==0)
{
if (fd_in != NULL)
{
close(fd_in[1]);
dup2(fd_in[0], 0);
}
if (fd_out != NULL)
{
close(fd_out[0]);
dup2(fd_out[1],1);
}
execlp(cmd, cmd, NULL);
}
}
int main(int argc, char **argv)
{
int fd_1[2], fd_2[2], i;
pipe(fd_1);
pipe(fd_2);
run_cmd(argv[1], NULL, fd_1);
for( i=2; i<argc-1; i++)
{
if (i%2 == 0)
run_cmd(argv[i], fd_1, fd_2);
else
run_cmd(argv[i], fd_2, fd_1);
}
if (i%2 == 0)
run_cmd(argv[i], fd_1, NULL);
else
run_cmd(argv[i], fd_2, NULL);
}
This works fine with two arguments, eg - $./a.out ls wc
But when I try with more than two arguments it does not work.
Would anyone please tell me what's wrong with my code, or any other way to do this?
First, open the desired file with appropriate flags (for >> they'll be O_WRONLY|O_CREAT|O_APPEND ). Second, using dup2, make stdout (file descriptor 1) a copy of this newly opened fd. Finally, close newly opened fd. To create a pipe, you'll need a pipe syscall. Read its manpage, it contains example code.
In this article, we will see how the pipe () function is used to implement the concept using C language. In the pipe, the data is maintained in a FIFO order, which means writing data to one end of the pipe sequentially and reading data from another end of the pipe in the same sequential order.
Implementing pipelining in C. What would be the best way to do that? This question is a bit old, but here's an answer that was never provided. Use libpipeline. libpipeline is a pipeline manipulation library. The use case is one of the man page maintainers who had to frequently use a command like the following (and work around associated OS bugs):
Finally, close newly opened fd. To create a pipe, you'll need a pipe syscall. Read its manpage, it contains example code. Then you'll also need dup2 to make file descriptors returned by pipe be stdin for one process and stdout for another, respectively.
This does virtually no error checking, but why so complicated?
int main (int argc, char ** argv) {
int i;
for( i=1; i<argc-1; i++)
{
int pd[2];
pipe(pd);
if (!fork()) {
dup2(pd[1], 1); // remap output back to parent
execlp(argv[i], argv[i], NULL);
perror("exec");
abort();
}
// remap output from previous child to input
dup2(pd[0], 0);
close(pd[1]);
}
execlp(argv[i], argv[i], NULL);
perror("exec");
abort();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With