0

I want to learn how to use pipes in C, and tried to do basic things like for example cloning the behaviour of | in shell.

This is my first try:

#include <stdio.h>
#include <stdlib.h>

#include <unistd.h>


int main(void)
{
    FILE    *stdin_tmp;

    stdin_tmp   = stdin;
    stdin       = stdout;
    system("cat /tmp/test.txt");
    system("less");
    stdin       = stdin_tmp;

    return  0;
}

This is what I want to do (written in shell):

cat /tmp/test.txt |less

The behaviour is obviously not what I expected. less isn't receiving the output of cat.

How is it done correctly?

  • 3
    Piping is fairly complicated. You're not going to get anywhere trying to change `stdin` and `stdout` or calling `system()`. They're non-starters. See the linked questions and [Creating Pipes in C](http://tldp.org/LDP/lpg/node11.html) for guidance on how to do it with `pipe()`, `fork()`, and `dup2()`. – John Kugelman Apr 12 '19 at 20:47
  • @JohnKugelman As the answer here proved, it can be done easily, and it isn't needed to complicate things with `fork` (which I would like to avoid), unlike in the links provided. – alx - recommends codidact Apr 13 '19 at 14:33
  • 1
    @JL2210's answer is a decent approximation of `|` and a nice starting point, but know that it's not quite the same thing. With real piping the two processes are directly connected to each other, whereas the answer requires a third process to feed data from one process to the other. It's *Office Space*. "Why can't the customers take them directly to the software people? What would you say... you *do* here?" – John Kugelman Apr 13 '19 at 19:20

1 Answers1

1

Try the popen() function.

Here's the prototype for it:

FILE *popen(const char *command, const char *type);

And here's a correct way to use it:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int ch;
    FILE *input;
    FILE *output;

    input = popen("cat /tmp/test.txt", "r");
    output = popen("less", "w");
    if (!input || !output)
        return EXIT_FAILURE;
    while( (ch = fgetc(input)) != EOF )
        fputc(ch, output);
    pclose(input);
    pclose(output);

    return 0;
}
S.S. Anne
  • 15,171
  • 8
  • 38
  • 76