Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing pipe in C

Tags:

c

linux

pipe

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?

like image 618
ac-lap Avatar asked Feb 20 '14 17:02

ac-lap


People also ask

How do I create a pipe in C++?

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.

How to implement pipe() concept using C language?

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.

How can I implement pipelining in C?

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):

How to create a pipe in FD?

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.


1 Answers

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();
}
like image 150
Sergey L. Avatar answered Sep 22 '22 06:09

Sergey L.